Como inserir texto repetitivo com pouca diferença no vim?

11

Quero inserir texto como este:

similar text wordA similar text ...
similar text wordB similar text ...
similar text wordC similar text ...

Sei que posso colar o texto várias vezes e depois usar a substituição para alterar uma única palavra para cada linha, mas ainda acho esse método muito inconveniente.

Existe uma maneira de salvar uma palavra ou uma lista de palavras em uma "variável" e usar essa variável para gerar texto semelhante?


EDIT Eu fiz algo pouco claro na pergunta original, na verdade estou tentando fazer algumas definições de funções muito parecidas, então wordA wordB... podem aparecer muitas vezes em cada clone de texto e o texto pode conter muitas linhas. o padrão é exatamente assim:

similar_text1 wordA similar_text2 wordA similar_text3 ...
similar_text1 wordB similar_text2 wordB similar_text3 ...
similar_text1 wordC similar_text2 wordC similar_text3 ...

(o texto pode conter novas linhas e wordA, wordB ... pode existir várias vezes)


2ª EDIÇÃO As partes "similar_text" podem ser diferentes cada vez que faço esse trabalho, portanto é melhor que a solução para esse trabalho seja reutilizável. Porque estou tentando fazer definições de funções muito parecidas, ou uma string para a tabela de mapeamento de funções.

Depois de ler as respostas e algumas práticas, acho que é mais conveniente pensar nesse trabalho como algum tipo de substituição, porque é difícil escrever "parte1", "parte2" ... "parteN", que pode conter novas linhas, por isso escreva um modelo primeiro:

similar_text1 $WORD similar_text2 $WORD similar_text3 ...
(text may contain <ENTER>, make sure $WORD not exist in "similar_text" parts )

Então, tentar colocar clones do texto, mas substituir $ WORD por uma lista de palavras é um pensamento mais direto.

Parece que meu problema mudou para "como clonar um bloco de texto várias vezes, mas sempre substituindo uma palavra-chave por uma palavra de uma lista?"

social_loser
fonte
É por isso que os registros são usados. Você pode puxar (copiar) o texto para um registro e usá-lo. As macros podem ser usadas para executar tarefas semelhantes e repetitivas.
precisa saber é o seguinte

Respostas:

7

Você pode usar a seguinte função:

function! GenerateLines()
    let firstpart="similar text part 1"
    let secondpart="similar text part 2"

    let words=["wordA","wordB","wordC","wordD","wordE"]

    for word in words
        let line = firstpart . word . secondpart
        call append(line('.')+1, line)
        normal j
    endfor
endfunction

Nas variáveis firstparte secondpartcoloque o texto a ser repetido antes e depois das palavras e na lista wordscoloque as palavras que devem mudar.

Em seguida, o loop criará o conteúdo da linha para cada palavra da lista, insira a linha no buffer e vá para essa nova linha.

Você pode então simplesmente chamar a função: call GenerateLines().


Editar Para facilitar a manipulação, você também pode passar as diferentes partes como argumentos, a função deve ser assim:

function! GenerateLines(firstpart, secondpart, words)
    for word in a:words
        call append(line('.')+1, a:firstpart . word . a:secondpart)
        normal j
    endfor
endfunction

E você pode chamar assim:

call GenerateLines("first part", "second part", ["wordA","wordB","wordC","wordD","wordE"])
statox
fonte
Você pode evitar o loop com call map(a:words, 'a:firstpart . v:val . a:secondpart')e call append(line('.'), a:words).
Antony
Como eu costumo fazer esse tipo de edição com "firstpart" e "secondpart" muito longos, e até "thirdpart", e essas partes podem conter novas linhas, parece ser muito longo para digitar isso no modo de comando, por isso talvez seja mais conveniente para puxar o texto para os registradores e usar funções para gerar texto a partir dos registradores?
social_loser
Eu editei a pergunta, ela muda muito, desculpe pela inconveniência.
social_loser
5

Minha estratégia nesses casos varia, mas geralmente segue as seguintes etapas:

  1. Escreva a (s) palavra (s) única (s), por exemplo

    wordA
    wordB
    ...
    wordK
    
  2. Ou

    a) faça uma pesquisa e substitua, por exemplo

    :%s/\w\+/similar text \0 similar text .../
    

    b) ou use o modo de bloqueio visual, consulte :h blockwise-visual. Em particular, selecionarei as palavras e as utilizarei Ipara inserir texto semelhante na frente ou Apara adicionar texto semelhante depois.

Eu argumentaria que essa estratégia faz sentido quando você realiza esse tipo de tarefa de edição relativamente raramente. No entanto, se você achar necessário fazer isso com frequência, siga a sugestão de @ statox com uma função que expanda a lista de palavras.

Karl Yngve Lervåg
fonte
Eu acho que a solução depende de onde a lista de palavras vem. Se for de um arquivo, :readseguido de sua substituição faz muito sentido.
Antony
sua solução é fácil de resolver e resolver o problema que eu fiz na pergunta original com facilidade. No entanto, existem alguns erros no meu post original, eu fiz 2 edições e muda muito, obrigado pela resposta, desculpe a minha mudança e mau Inglês :)
social_loser
@social_loser, você pode adaptar esta solução usando "\ r" para representar uma nova linha na parte de substituição da substituição.
frangio
2

Argumentarei que este é um trabalho para o bloco visual ( Ctrl+ v). Primeiro eu escreveria todas as palavras distintas:

wordA
wordB
wordC
wordD
wordE

Começando com o cursor no primeiro, weu executaria:

<c-v>5j$yA <esc>pA <esc>p

Posso controlar quantas colunas preciso pressionando A <esc>pquantas vezes quiser. Vamos supor que eu precisei de três colunas, como mostra o comando acima. Agora temos o seguinte:

wordA wordA wordA
wordB wordB wordB
wordC wordC wordC
wordD wordD wordD
wordE wordE wordE

E o cursor está no início do terceiro wordAna primeira linha. Em seguida, eu bloquearia a seleção da coluna de espaço em branco entre as colunas, retrocedendo e adicionando o texto entre elas. No local atual do cursor:

h<c-v>5jI similar text 3<esc>

Isso resulta em (o% marca a posição do cursor):

wordA wordA%similar text 3 wordA
wordB wordB similar text 3 wordB
wordC wordC similar text 3 wordC
wordD wordD similar text 3 wordD
wordE wordE similar text 3 wordE

Repita para a próxima coluna:

bh<c-v>5jI similar text 2<esc>

E a última / primeira coluna (a do lado esquerdo):

b<c-v>5jIsimilar text 1 <esc>

Finalmente resultando em:

similar text 1 wordA similar text 2 wordA similar text 3 wordA
similar text 1 wordB similar text 2 wordB similar text 3 wordB
similar text 1 wordC similar text 2 wordC similar text 3 wordC
similar text 1 wordD similar text 2 wordD similar text 3 wordD
similar text 1 wordE similar text 2 wordE similar text 3 wordE

Atualização: adicionado um screencast

insira a descrição da imagem aqui


Parece haver muita digitação, mas na verdade é muito fácil se acostumar. Ele oferece a liberdade de alterar o número de palavras, o número de colunas e até o espaçamento entre as colunas.

A desvantagem é que você precisa saber o número de palavras distintas que está usando. Eu tenho um 5código fixo em todos os comandos acima, porque é o número de linhas em que os comandos estão operando.

Nota sobre a depuração: todos os comandos iniciam e terminam no modo normal; se você se encontra no modo visual ou de inserção no final de um comando, está fazendo algo errado.

grochmal
fonte