2

使用 foldmethod=syntax 时,有没有办法自动展开小折叠(<10 行)?

我知道可以选择使用

set foldminlines=10

但是如果我使用这个设置,即使我以后想这样做,我也无法折叠这些部分。

编辑

感谢Ingo Karkat ,我的配置现在可以满足我的要求。

au BufReadPre * if !exists('b:folddict') | let b:folddict = {} | endif
function! s:UnfoldSmallFolds( count )
  if empty(b:folddict)
    "fill list
    let l:_none = s:checkInnerFolds(['1',line('$')], a:count)
  else
    "folddict should be filled by now
    " check if lnum is in fold
    let l:index = s:checkFoldIndex(keys(b:folddict), getpos('.')[1])
    if l:index != 0
      "check if open -> close
      if b:folddict[l:index] == 1
        foldclose
        let b:folddict[l:index] = 0
      else
        foldopen
        let b:folddict[l:index] = 1
        let l:_none = s:checkInnerFolds(split(l:index,'-'),a:count)
      endif
    endif
  endif
endfunction

function! s:checkInnerFolds(index,count)
  let l:lnum = a:index[0]
  while l:lnum <= a:index[1]
    if foldclosed(l:lnum) == -1
      let l:lnum += 1
      continue
    endif

    let l:endLnum = foldclosedend(l:lnum)
    let l:innerIndex = l:lnum."-".l:endLnum
    if has_key(b:folddict,l:innerIndex)
      if b:folddict[l:innerIndex] == 1
        foldopen
        let l:_none = s:checkInnerFolds(l:innerIndex,a:count)
      endif
    else                        
      let b:folddict[l:innerIndex] = 0
      if l:endLnum - l:lnum < a:count
        execute printf('%d,%dfoldopen!', l:lnum, l:endLnum)
        let b:folddict[l:innerIndex] = 1
        let l:_none = s:checkInnerFolds(l:innerIndex,a:count)
      endif
    endif
    let l:lnum = l:endLnum + 1
  endwhile
endfunction


function! s:checkFoldIndex(folds, pos)
  let l:retLine = ['0','0']
  for line in a:folds
    let l:splitLine = split(line,'-')
    if a:pos >= l:splitLine[0] && a:pos <= l:splitLine[1]
      if a:pos-l:splitLine[0] < a:pos-l:retLine[0]
        let l:retLine = l:splitLine
      endif
    endif
  endfor
  return join(l:retLine,"-")
endfunction 
4

1 回答 1

2

这可以通过一个自定义函数来完成,该函数检查所有关闭的折叠并打开那些只有几行的折叠,如下所示:

" [count]z<r        Open all small folds that contain up to 3 / [count] lines.
function! s:UnfoldSmallFolds( count )
    let l:openCnt = 0
    let l:lnum = 1
    while l:lnum <= line('$')
        if foldclosed(l:lnum) == -1
            let l:lnum += 1
            continue
        endif

        let l:endLnum = foldclosedend(l:lnum)
        if l:endLnum - l:lnum < a:count
            execute printf('%d,%dfoldopen!', l:lnum, l:endLnum)
            let l:openCnt += 1
        endif
        let l:lnum = l:endLnum + 1
    endwhile

    if l:openCnt == 0
        echo printf('No small folds over up to %d lines found', a:count)
    else
        echo printf('%d folds opened', l:openCnt)
    endif
endfunction
nnoremap <silent> z<r :<C-u>call <SID>UnfoldSmallFolds(v:count ? v:count : 3)<CR>
于 2013-04-03T08:24:56.390 回答