Вы можете попробовать следующую команду:
:let c=0 | g/^* /let c+=1 | s//\=c.'. '
Сначала он инициализирует переменную c( let c=0), затем выполняет глобальную команду, gкоторая ищет шаблон ^*(начало строки, затем звездочка и пробел).
Всякий раз, когда строка, содержащая этот шаблон, найдена, глобальная команда выполняет команду:
let c+=1 | s//\=c.'. '
она увеличивает переменную c( let c+=1), затем ( |) заменяет ( s) предыдущий искомый шаблон ( //) оценкой выражения ( \=):
содержимое переменной cсцепляется ( .) со строкой'. '
Если вы не хотите изменять все строки из буфера, а только определенный абзац, вы можете передать диапазон глобальной команде. Например, чтобы изменить только строки с номерами от 5 до 10:
:let c=0 | 5,10g/^* /let c+=1 | s//\=c.'. '
Если у вас есть файл, содержащий несколько похожих списков, которые вы хотите преобразовать, например, что-то вроде этого:
some random stuff some random stuff
* foo 1. foo
* bar 2. bar
* baz 3. baz
some other random stuff some other random stuff
==>
some random stuff some random stuff
* foo 1. foo
* bar 2. bar
* baz 3. baz
* qux 4. qux
some other random stuff some other random stuff
Вы можете сделать это с помощью следующей команды:
:let [c,d]=[0,0] | g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
Это просто вариант предыдущей команды, которая сбрасывает переменную cпри переключении на другой список. Чтобы определить, находитесь ли вы в другом списке, переменная dиспользуется для хранения номера последней строки, где была сделана замена.
Глобальная команда сравнивает текущий номер строки ( line('.')) с d+1. Если они совпадают, это означает, что мы находимся в том же списке, что и раньше, то cесть incremental ( c+1), в противном случае это означает, что мы находимся в другом списке, то cесть reset ( 1).
Внутри функции команду let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')]можно переписать так:
let c = line('.') == d+1 ? c+1 : 1
let d = line('.')
Или вот так:
if line('.') == d+1
let c = c+1
else
let c = 1
endif
let d = line('.')
Чтобы сохранить некоторые нажатия клавиш, вы также можете определить пользовательскую команду :NumberedLists, которая принимает диапазон со значением по умолчанию 1,$( -range=%):
command! -range=% NumberedLists let [c,d]=[0,0] | <line1>,<line2>g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
Когда :NumberedListsбудет выполнено, <line1>и <line2>будет автоматически заменено диапазоном, который вы использовали.
Итак, чтобы преобразовать все списки в буфере, вы должны набрать: :NumberedLists
Только списки между строкой 10 и 20: :10,20NumberedLists
Только визуальный подбор: :'<,'>NumberedLists
Для получения дополнительной информации см .:
:help :range
:help :global
:help :substitute
:help sub-replace-expression
:help list-identity (section list unpack)
:help expr1
:help :command