Ответ 1
Ну, чтобы функция выполнялась только один раз над диапазоном, добавьте ключевое слово range
. Например.
fun Foo() range
...
endfun
Тогда ваша функция может позаботиться о самом диапазоне со специальными параметрами a: firstline
и a: lastline. (Подробнее см. :help a:firstline
.)
Однако я думаю, что в этом случае ваши требования достаточно просты, чтобы их можно было выполнить с помощью
однострочный с использованием :global
.
На самом деле мы могли бы лучше определить входы и выходы. Но предполагая файл, содержащий
Item a: <total>
Subitem: 10 min
Subitem 2: 20 min
Item b: <total>
Subitem: 10 min
Subitem 2: 23 min
Item c: <total>
Subitem: 10 min
Subitem 2: 23 min
Subitem 3: 43 min
и функция, определенная как
fun! Sum(n)
let g:s += a:n
return a:n
endfun
то это суммирует подпункты (все одна строка)
:g/^Item/ let g:s = 0 | mark a | +,-/\nItem\|\%$/ s/\v(\d+)\ze\s+min$/\=Sum(submatch(0))/g | 'a s/<total>/\=(g:s . ' min')/
и произвести этот вывод
Item a: 30 min
Subitem: 10 min
Subitem 2: 20 min
Item b: 33 min
Subitem: 10 min
Subitem 2: 23 min
Item c: 76 min
Subitem: 10 min
Subitem 2: 23 min
Subitem 3: 43 min
Кстати, вышеупомянутая команда действует на весь буфер. Если сначала выделить диапазон, а затем нажать клавишу :
, vim автоматически добавит вашу команду с помощью '<,'>
, что означает, что следующая команда будет работать от начала до конца выделенного диапазона.
например. выделение строк с 1 по 5, а затем выполнение команды (:'<,'> g/...
) создает этот вывод
Item a: 30 min
Subitem: 10 min
Subitem 2: 20 min
Item b: 33 min
Subitem: 10 min
Subitem 2: 23 min
Item c: <total>
Subitem: 10 min
Subitem 2: 23 min
Subitem 3: 43 min
Последнее замечание. Если одна из групп не имеет подпунктов, например
Item a: <total>
Subitem: 10 min
Subitem 2: 20 min
Item b: <total>
Item c: <total>
Subitem: 10 min
Subitem 2: 23 min
Subitem 3: 43 min
тогда команда будет прервана с ошибкой "Недопустимый диапазон", когда она достигнет второго элемента. Вы можете заставить Vim игнорировать это
и продолжать, независимо от того, префикс всей команды с помощью :silent!
.
ИЗМЕНИТЬ
Просто краткое объяснение моего рабочего процесса и почему длинный однострочный.
- Мне нравится
:g
и ex команды много. - Я создал команду интерактивно, используя историю командной строки и окно командной строки для редактирования.
- Когда я закончил, я вставляю одноразовые команды, подобные этому в буфер: у меня есть сопоставление, чтобы выполнить текущую строку как команду ex. Таким образом, команда всегда легко доступна, когда мне это нужно. Для более регулярного использования вам может понадобиться команда, функция или ftplugin.