Сворачивание по шаблону поиска по регулярному выражению

13

Я получил простой текстовый файл с разделенными пробелами столбцами значений. Как это:

AU 3030 .... ... ....  
AU 3031 .... ... ....  
AU 3032 .... ... .... 
AU 3033 .... ... .... 
IT 48100 ... .. .....
IT 40100 ... .. .....
IT 48123 ... .. .....
UK 3333 ... ... ..... 
UK 4444 ... ... .....
UK 5555 ... ... .....

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

/^\(\([A-Z0-9]\+\)\s\+.*\n\)\(\2\)\@=

(или сделать его менее "волосатым"):

/^\v([A-Z0-9]+)\s+.*\n(\1)@=

Можно ли сложить линии по линии, которая не была сопоставлена? Имея этот результат:

+-- 4 lines AU ....
+-- 3 lines IT ....
+-- 3 lines UK ....
Гвидо
источник

Ответы:

14

Сделайте set foldmethod=exprи используйте, 'foldexpr'чтобы установить выражение сценария vim, которое определит начальные точки сгиба.

set foldmethod=expr
set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'='

Это выглядит сложнее, чем есть, потому что мы не можем легко использовать пробелы в :set, но с пробелами и переводом строки или 2, это выглядит так:

get(split(getline(v:lnum - 1)), 0, '') != get(split(getline(v:lnum)), 0, '')
    \ ? '>1'
    \ : '='

обзор

В основном это сравнивает первое слово каждой строки с предыдущей строкой. Если слова различны , то линия начать складки, >1. В противном случае она сохраняет тот же уровень фолд, =.

Слава деталей

  • set foldmethod=expr сказать Vim использовать выражение сценария vim для определения свертывания
  • 'foldexpr' опция содержит выражение скрипта vim
  • Оценка состояния с помощью троичного, который возвращается, >1когда следует начать сгиб и =когда следует продолжить уровень сгиба
  • v:lnumтекущая строка, на которой 'foldexpr'выполняется обновление сгибов
  • Получить содержимое текущей строки ( v:lnum) и предыдущей строки ( v:lnum - 1) черезgetline()
  • Разделите каждую строку на слова с помощью split()
  • Используйте, get()чтобы получить первый индекс недавно разделенных слов
  • Используйте значение по умолчанию ''в случае пустой строки. напримерget(words, 0, '')
  • Сравните первое слово текущей строки с первым словом предыдущей строки в условной части троичной

Примечание: этот метод может иметь некоторые проблемы с производительностью с очень большими документами

Для получения дополнительной помощи см .:

:h 'foldmethod'
:h 'foldexpr'
:h getline(
:h v:lnum
:h split(
:h get(
Питер Ринкер
источник