Meu objetivo final é dividir um texto em delimitadores de frase. No entanto, não deve ser dividido em frases, mas em pedaços ca. 1000 linhas e mais o restante da frase atual. Mas no experimento abaixo eu uso apenas 2 linhas para simplificar.
Considere o seguinte texto em um buffer VIM:
line 1. line 1. line 1.
line 2. line 2. line 2.
line 3. line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.
Após a execução de:
:2 | exec 'normal! )hvgg' | exec "'<,'>w /tmp/part1.txt" | exec 'normal! gvd'
O resultado é o esperado. Buffer contém:
line 2. line 2.
line 3. line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.
Mas depois da próxima corrida
:2 | exec 'normal! )hvgg' | exec "'<,'>w /tmp/part2.txt" | exec 'normal! gvd'
buffer contém:
line 2.
line 3. line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.
O que está acontecendo aqui? Por que não se move para a segunda linha que é line 3. line 3. line 3.
?
Mas eu esperaria que o seguinte texto permanecesse no buffer
line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.
A raiz do problema está
gv
no final. É desnecessário, pois a seleção visual persiste da parte anterior do comando. Pior, não é inofensivo porque quando você fazgv
quando já está no modo Visual, a área Visual atual e anterior são trocadas . Significa que a seleção anterior foi selecionada novamente!Mesmo que a seleção anterior tenha sido excluída, a seleção é aplicada à mesma área... ou pelo menos o que resta dela. Nesse caso, essa seria a primeira das
line 2.
frases restantes.Para demonstrar, observe o que acontece quando você entra nisso duas vezes:
2G)hvgggvd
. Isso é exatamente o que está acontecendo na linha de comando, menos a gravação no disco, mas com comandos de modo 100% Normal.De qualquer forma, só precisamos perder o
gv
e isso funcionará:Além disso, há muito ruído neste comando que pode ser limpo. Dois dos
exec
s e as aspas que os acompanham não são necessários:Atualização: Em resposta a um de seus comentários, este...
é uma operação linear que seleciona da primeira linha da última área visual selecionada até a última linha da mesma área. Para obter intervalos sábios de caracteres, você precisa usar back-tics como este:
No entanto, isso não funcionará com
:w
... é apenas uma operação linear.Gostaria de salientar que isso está fora do escopo da sua pergunta, que pergunta por que um determinado texto está sendo excluído .... portanto, você pode fazer uma pergunta separada para gravação em arquivo.
Atualização 2: Aqui está uma abordagem totalmente diferente para o seu problema...
Crie uma macro com o seguinte comando
:let @a = 0
.@q
Isso se comportará da maneira que você descreve: a frase e tudo acima dela serão gravados em um arquivo chamado
/tmp/part1.txt
e o texto salvo será excluído. Agora vá para qualquer outra frase e faça@q
novamente e desta vez a mesma coisa acontecerá, mas ela será gravada em/tmp/part2.txt
. Cada vez que você executar a macro, o nome do arquivo será incrementado automaticamente. Você pode redefinir o índice novamente com:let @a = 0
.Como a atualização anterior, isso não está abordando a pergunta real, mas como sou legal, estou fornecendo uma ajuda extra. (E o OP ainda não aceita minha resposta.)
Finalmente cheguei à solução aceita. Obrigado a @B Layer pela cooperação (por exemplo, mencionar que o
w
comando apenas grava linhas completas em um arquivo). Eu votei a favor da sua resposta.Depois disso, repita o comando pressionando
@:
se o último pedaço for menor que 1000 linhas, você receberá um erro. Basta salvar o restante manualmente.Após 5 execuções tive como esperado:
Para quem quiser usá-lo, explicarei resumidamente os principais passos:
:1000
Mover para a linha 1000 (os pedaços devem ter pelo menos 1000 linhas)
Mova para o início da próxima frase e um caractere para trás para que o primeiro caractere da próxima frase não seja excluído posteriormente. Para funcionar corretamente em frases que estão espalhadas por várias linhas,
whichwrap=h,l
deve ser definido, o que não é o padrão até onde eu sei. Selecione tudo, desde a posição atual do cursor até o início e exclua-o. O conteúdo deletado será salvo no cadastro.Escreva o conteúdo do registrador (o pedaço) em um arquivo
Parti do pressuposto de que não haverá mais de 99 blocos. Se precisar de mais, ajuste a parte relacionada ao preenchimento conforme necessário.