Você pode tentar o seguinte comando:
:let c=0 | g/^* /let c+=1 | s//\=c.'. '
Primeiro, inicializa a variável c
( let c=0
), depois executa o comando global g
que procura o padrão ^*
(um início de linha, seguido por um asterisco e um espaço).
Sempre que uma linha que contém esse padrão é encontrada, o comando global executa o comando:
let c+=1 | s//\=c.'. '
Incrementa a variável c
( let c+=1
) e ( |
) substitui ( s
) o padrão pesquisado anterior ( //
) pela avaliação de uma expressão ( \=
):
o conteúdo da variável c
concatenada ( .
) com a string'. '
Se você não quiser modificar todas as linhas do seu buffer, mas apenas um parágrafo específico, poderá passar um intervalo para o comando global. Por exemplo, para modificar apenas as linhas cujo número está entre 5 e 10:
:let c=0 | 5,10g/^* /let c+=1 | s//\=c.'. '
Se você tiver um arquivo contendo várias listas semelhantes que deseja converter, por exemplo, algo como isto:
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
Você pode fazer isso com o seguinte comando:
:let [c,d]=[0,0] | g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
É apenas uma variante do comando anterior, que redefine a variável c
quando você alterna para outra lista. Para detectar se você está em outra lista, a variável d
é usada para armazenar o número da última linha em que uma substituição foi feita.
O comando global compara o número da linha atual ( line('.')
) com d+1
. Se eles são iguais, significa que estamos na mesma lista de antes, por isso c
é incrementado ( c+1
); caso contrário, significa que estamos em uma lista diferente, por isso c
é redefinido ( 1
).
Dentro de uma função, o comando let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')]
pode ser reescrito assim:
let c = line('.') == d+1 ? c+1 : 1
let d = line('.')
Ou assim:
if line('.') == d+1
let c = c+1
else
let c = 1
endif
let d = line('.')
Para salvar algumas teclas, você também pode definir o comando personalizado :NumberedLists
, que aceita um intervalo cujo valor padrão é 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.'. '
Quando :NumberedLists
será executado <line1>
e <line2>
será automaticamente substituído pelo intervalo usado.
Portanto, para converter todas as listas no buffer, digite: :NumberedLists
Somente as listas entre as linhas 10 e 20: :10,20NumberedLists
Somente a seleção visual: :'<,'>NumberedLists
Para mais informações, veja:
:help :range
:help :global
:help :substitute
:help sub-replace-expression
:help list-identity (section list unpack)
:help expr1
:help :command