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 gque 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 cconcatenada ( .) 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 cquando 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 :NumberedListsserá 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