Ви можете спробувати наступну команду:
: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само збільшується ( c+1), інакше це означає, що ми перебуваємо в іншому списку, так cсамо скидається ( 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