Edição de várias linhas do Vim como no sublimetexto?

132

Comecei a usar o gvim e não consigo entender como a edição de múltiplas linhas funciona no gvim.

Por exemplo:

Texto original:

asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

ctrl + q, jjjjjj, $ everything está selecionado, então eu pressiono I para fazer uma inserção de várias linhas.

Minha intenção é inserir aspas como na primeira linha e pressionar Esc:

asd "asd asd" asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

O que aconteceu? Eu esperava um comportamento semelhante ao do sublimetext:

insira a descrição da imagem aqui

Se você não sabe como isso funciona, apenas repete as ações para cada linha. Como conseguir isso? E o que o vim está fazendo aqui?

AlfredoVR
fonte
Basta gravar uma macro do teclado para alterar a primeira linha e depois reproduzir a macro para todas as outras linhas.
high5

Respostas:

214

Faça um favor a si próprio soltando a camada de compatibilidade do Windows.

O atalho normal para entrar no modo de bloqueio visual é <C-v>.

Outros já lidaram com macros de gravação, eis algumas outras idéias:

Usando apenas o modo de bloqueio visual .

  1. Coloque o cursor na segunda palavra:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Pressione <C-v>para entrar no modo de bloco visual e expanda sua seleção para baixo:

    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    
  3. Clique I"<Esc>para obter:

    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  4. Coloque o cursor no último caractere da terceira palavra:

    asd "asd as|d| asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  5. Pressione <C-v>para entrar no modo de bloco visual e expanda sua seleção para baixo:

    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    
  6. Clique A"<Esc>para obter:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

Com modo de bloqueio visual e Surround.vim .

  1. Coloque o cursor na segunda palavra:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Pressione <C-v>para entrar no modo de bloco visual e expanda sua seleção na parte inferior e direita:

    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    
  3. Clique S"para cercar sua seleção com ":

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

Com o modo de linha visual e:normal .

  1. Pressione Vpara selecionar a linha inteira e expanda-a para a parte inferior:

    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    
  2. Execute este comando: :'<,'>norm ^wi"<C-v><Esc>eea"<CR>para obter:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    
    • :norm[al]permite executar normal comandos do modo em várias linhas (a '<,'>peça é adicionada automaticamente pelo Vim e significa "atuar na área selecionada")

    • ^ coloca o cursor no primeiro caractere da linha

    • w passa para a próxima palavra

    • i" insere um " antes do cursor

    • <C-v><Esc>é a maneira do Vim inserir um caractere de controle nesse contexto, aqui é <Esc>usado para sair do modo de inserção

    • ee move para o final da próxima palavra

    • a"acrescenta a "depois do cursor

    • <CR> executa o comando

    Usando o Surround.vim, o comando acima se torna

    :'<,'>norm ^wvees"<CR>
    
romainl
fonte
7
Nas etapas 4 e 5, eu recomendaria pressionar gvpara recuperar sua seleção visual anterior e depois mover horizontalmente, talvez com 2e. (Quanto mais linhas, o mais valioso gvé!)
joeytwiddle
4
usos surround.vim um pequeno sno modo normal, mas uma grande Sno modo visual, isso na etapa 3 do método surround.vim, as teclas devem serS"
joeytwiddle
1
Ponto 3 do visual-block + Surround.vim deve ser S", nãos"
Zool
1
Em vez das etapas 5 e 6 do modo de bloco visual, você pode simplesmente colocar o cursor após a terceira palavra e pressionar ..
Jonas19:
2
Isso é legal, mas isso só funciona em alguns casos em que os caracteres que você deseja editar nas diferentes linhas estão exatamente na mesma posição horizontal em cada linha e as linhas editadas estão corretas uma após a outra. Não podemos escolher onde entrar no modo de edição em qual linha do Vim? Podemos em Sublim ... EDIT: Na verdade, a segunda resposta é o que eu estava procurando
Alexandre Bourlier
30

Essas são algumas boas soluções prontas para uso fornecidas acima, mas também podemos experimentar alguns plugins que fornecem vários cursores como o Sublime.

Eu acho que este parece promissor:

Pareceu abandonado por um tempo, mas teve algumas contribuições em 2014.

É bastante poderoso, embora demorei um pouco para me acostumar com o fluxo (que é bastante sublime, mas ainda modal como o Vim).

Na minha experiência, se você tiver muitos outros plugins instalados, poderá encontrar alguns conflitos!

Existem outras tentativas para esse recurso:

Sinta-se à vontade para editar se você perceber alguma dessas melhorias.

joeytwiddle
fonte
Parece que o github.com/osyo-manga/vim-over é o mais ativo do grupo no momento.
Wernight 24/09/15
Excelente, era o que eu procurava #
Alexandre Bourlier 15/06
1
Depois de ter testado a maioria deles, hlissner / vim-multiedit parece o melhor AFAIAC #
Alexandre Bourlier
1
Verifique mg979 / vim-visual-multi como um bom substituto para vim-multiple-cursors
Mushex Antaranian
29

Existem várias maneiras de conseguir isso no Vim. Não sei quais são mais parecidas com as do Sublime Text.


O primeiro seria através do modo de inserção de múltiplas linhas . Coloque o cursor no segundo "a" na primeira linha, pressione Ctrl-V, selecione todas as linhas, depois pressione Ie coloque aspas duplas. Pressionar <esc>repetirá a operação em todas as linhas.


O segundo é via macros. Coloque o cursor no primeiro caractere e comece a gravar uma macro com qa. Vá à sua direita com llll, entre no modo de inserção com a, coloque uma citação dupla, saia do modo de inserção e volte ao início da sua linha com <home>(ou equivalente). Pressione jpara descer uma linha. Pare de gravar com q. E, em seguida, reproduza a macro com @a. Várias vezes.


Alguma das abordagens acima funciona para você?

Torre
fonte
15

se você usar o comando "global", poderá repetir o que pode fazer em uma linha ou em qualquer número de linhas.

:g/<search>/.<your ex command>

exemplo:

:g/foo/.s/bar/baz/g

O comando acima localiza todas as linhas que possuem foo e substitui todas as ocorrências de barra nessa linha por baz.

:g/.*/

vai fazer em todas as linhas

srini.venigalla
fonte
1
Isso é tão útil que eu não sabia. Parece uma combinação de comandos tão poderosa e inteligente.
0xc0de 12/03/19
Por conveniência, escrevi uma pequena função que coloca a palavra sob o cursor (ou a palavra selecionada visualmente), solicita uma substituição e, em seguida, executa o :gcomando descrito aqui. Eu gosto de usar /gcpara pedir "confirmações" para que eu possa clicar em you npara cada substituição, ou apara alterar todas elas.
Joeytwiddle 19/07/19
11
Ctrl-v ................ start visual block selection
6j .................... go down 6 lines
I" .................... inserts " at the beginning
<Esc><Esc> ............ finishes start
2fdl. ................. second 'd' l (goes right) . (repeats insertion)
SergioAraujo
fonte
Na etapa 3, Inão é possível entrar no modo de inserção, você sabe por que isso acontece?
Ninja
Tente carregar o vim sem plugins: vim -u NONEe tente executar a ação desejada novamente, pode haver algum mapa ou plugin alterando o comportamento do seu vim.
SergioAraujo 5/11
6

Não tenho certeza do que vimestá fazendo, mas é um efeito interessante. A maneira como você está descrevendo o que deseja soa mais como as macros funcionam ( :help macro). Algo assim faria o que você quer com macros (iniciando no modo normal):

  1. qa: Grave macro para aregistrar.
  2. 0w: 0vá para o início da linha, wpule uma palavra.
  3. i"<Esc>: Entre no modo de inserção, insira a "e retorne ao modo normal.
  4. 2e: Salte para o final da segunda palavra.
  5. a"<Esc>: Anexar a ".
  6. jq Vá para a próxima linha e termine a gravação de macro.

Tomados em conjunto: qa0wi"<Esc>2ea"<Esc>

Agora você pode executar a macro com @a, repita a última macro com @@. Para aplicar ao restante do arquivo, faça algo como o 99@aque supõe que você não tenha mais de 99 linhas, a execução da macro será encerrada quando atingir o final do arquivo.

Aqui está como conseguir o que deseja visual-block-mode(iniciando no modo normal):

  1. Navegue até onde deseja que a primeira cotação esteja.
  2. Digite visual-block-mode, selecione as linhas que deseja afetar, Gpara ir para a parte inferior do arquivo.
  3. Hit I"<Esc>.
  4. Vá para o próximo ponto que você deseja inserir a ".
  5. Você deseja repetir o que acabou de fazer para que um simples .seja suficiente.
Thor
fonte
4
Não há necessidade de 99 @ a. Se você deseja executar uma macro em todas as linhas de um arquivo, tente:% norm! @uma.
Rook
Sem os pontos (eles são extremidades apenas de frases, não faz parte dos comandos)
Rook
9999@apode ser feio, mas é muito mais fácil digitar :%norm! @ae não é executado novamente na linha que você acabou de editar. Ainda é bom saber de qualquer maneira. :)
joeytwiddle
0

Minha solução é usar esses 2 mapeamentos:

map <leader>n <Esc><Esc>0qq
map <leader>m q:'<,'>-1normal!@q<CR><Down>

Como usá-los:

  1. Selecione suas linhas. Se eu quiser selecionar as próximas 12 linhas, basta pressionarV12j
  2. pressione <leader>n
  3. Faça as alterações na linha
  4. Verifique se você está no modo normal e pressione <leader>m

Para fazer outra edição, você não precisa fazer a seleção novamente. Basta pressionar <leader>n, fazer sua edição e pressionar <leader>mpara aplicar.


Como isso funciona:

  • <Esc><Esc>0qq Saia da seleção visual, vá para o início da linha e comece a gravar uma macro.

  • q Pare de gravar a macro.

  • :'<,'>-1normal!@q<CR> Desde o início da seleção visual até a linha antes do final, toque a macro em cada linha.

  • <Down> Volte para a última linha.


Você também pode mapear a mesma tecla, mas para modos diferentes:

vmap <leader>m <Esc><Esc>0qq
nmap <leader>m q:'<,'>-1normal!@q<CR><Down>

Embora isso atrapalhe sua capacidade de fazer outra edição. Você terá que selecionar novamente suas linhas.

willmcpherson2
fonte