Compact C складной в Vim - PullRequest
3 голосов
/ 12 мая 2009

Я пытаюсь создать простой скрипт Vim, который бы создавал очень компактные сгибы верхнего уровня для c-файлов. В идеале, если он запускался по этому коду:

static void funca(...)
{
   ... 
}

/* Example comment */
static void funcb(...)
{
   ... 
}

Тогда это создаст складки, которые при закрытии будут выглядеть так:

+-- x Lines: static void funca(...)----------------------
+-- x Lines: static void funcb(...)----------------------

Таким образом, в основном это будет похоже на foldmethod = синтаксис с foldlevel = 1, за исключением того, что каждый сгиб будет начинаться на одну строку дальше вверх и расширяться дальше вниз, включая все последующие пустые строки.

Я знаю, как сделать одну из этих складок (при условии, что метод сгиба = ручной):

/^{<cr>kVnn?^$<cr>zf

Но я не уверен, как поместить это в функцию. Это мое усилие:

function Cfold()
  set foldmethod=manual  " Manual folds
  ggzE                   " Delete all folds
  while (/^{<cr>)        " Somehow loop through each match
     kVnn?^$<cr>zf       " This would work fine except for the last function
  endwhile
endfunction
map <Leader>f  :call Cfold()<cr>

Но это не правильно, я не совсем уверен, как работают функции. Кроме того, он не будет работать для последней функции в файле, поскольку он не найдет «^ {» снова. Если бы кто-то мог помочь мне заставить это работать и каким-то образом добавить кейс для последней функции в файле, я был бы чрезвычайно благодарен.

Заранее спасибо:)

1 Ответ

3 голосов
/ 13 мая 2009

Вы можете создавать складки программно, используя foldexpr и foldtext. Попробуйте это, хотя вам, возможно, придется настроить CFoldLevel, чтобы он не глотал не функциональные части кода:

function! CFoldLevel(lnum)
  let line = getline(a:lnum)
  if line =~ '^/\*'
    return '>1' " A new fold of level 1 starts here.
  else
    return '1' " This line has a foldlevel of 1.
  endif
endfunction

function! CFoldText()
  " Look through all of the folded text for the function signature.
  let signature = ''
  let i = v:foldstart
  while signature == '' && i < v:foldend
    let line = getline(i)
    if line =~ '\w\+(.*)$'
      let signature = line
    endif 
    let i = i + 1
  endwhile

  " Return what the fold should show when folded.
  return '+-- ' . (v:foldend - v:foldstart) . ' Lines: ' . signature . ' '
endfunction

function! CFold()               
  set foldenable
  set foldlevel=0   
  set foldmethod=expr
  set foldexpr=CFoldLevel(v:lnum)
  set foldtext=CFoldText()
  set foldnestmax=1
endfunction

Подробнее см. :help 'foldexpr'.

...