Vim Scripting: подсчитать строки, соответствующие выражению, и сложить - PullRequest
2 голосов
/ 04 июня 2011

В настоящее время я разрабатываю плагин для Vim для управления контрольными списками.

В настоящее время я использую ": setlocal foldmethod = indent" в файле синтаксиса для обработки всего свертывания в каждом документе контрольного списка. Однако я хотел бы создать более гибкую функцию свертывания, которая не будет полагаться на отступ строки для определения того, будет ли она сложена.

Вот пример контрольного списка:

+ Parent
  * Child
  * Child
  * Child

Когда пользователь нажимает <leader> vv на строке «+ Parent», он складывает линии под ним, потому что они имеют отступ на один уровень. Проблема в том, что метод сгиба остаётся вокруг других буферов и складывает линии, которые не нужно складывать.

Вот как я думал об этом до сих пор:

function! FoldLines()
  let l:line = getline(line(".") + 1)

  " If next line is a child
  if match(l:line, '^\s*\*') >= 0

  " Loop until blank line is found, and store line numbers in a list
  endif

  " Select lines from list and fold
endfunction

Я не знаю, как обращаться с петлей и складыванием. Есть предложения?

UPDATE

Что ж, решение karategeek6 работает в некоторой степени, но я не упомянул, что мой плагин также переключает элементы контрольного списка.

* * Пример тысяча двадцать-один: * * 1 022
+ Parent
  × Child - Toggled
  * Child - Standard

Я могу ошибаться, но я не думаю, что foldexpr сможет обрабатывать строки как *, так и × в начале.

Я пробовал:

set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^[*|×]].*','',''))

но это тоже не работает.

Ответы [ 2 ]

2 голосов
/ 04 июня 2011

Звучит так, как вы хотите, чтобы это складывалось выражением.В соответствии с руководством пользователя , сгибая по выражению, вы используете выражение для установки уровня сгиба каждой строки.В руководстве пользователя приведен пример, который, я думаю, может быть адаптирован к вашим потребностям.

:set foldmethod=expr
:set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^*].*','','')) 

Подробнее об этом примере можно прочитать в руководстве пользователя, но в двух словах он устанавливает уровень сгиба, равныйэто число ведущих «*», независимо от пробелов.

Надеюсь, это либо именно то, что вы искали, либо может указать вам правильное направление.Ключевой аспект, который следует помнить при складывании по выражению, заключается в том, что вы решаете уровень сгиба каждой линии, а не то, какие линии следует сгибать.

1 голос
/ 04 июня 2011

Ну, похоже, я нашел решение.Я закончил тем, что использовал это:

setlocal foldlevel=0
setlocal foldmethod=expr
setlocal foldexpr=FoldLevel(v:lnum)

function! FoldLevel(linenum)
  let linetext = getline(a:linenum)
  let level = indent(a:linenum) / 4
  if linetext =~ '^\s*[\*|×]'
    let level = 20
  endif
  return level
endfunction
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...