Pelo menos um truque do Vim que você não conhecia

Trabalho na Vim há oito anos e constantemente descobri algo novo. É considerado uma virtude do Vim. Quanto a mim, isso é uma falta de abertura: um monte de funções ocultas estão ocultas demais.

Eles falam sobre a beleza da edição modal e dos objetos de texto, mas me parece que a essência do Vim não é essa. O Vim é uma colcha de retalhos de subsistemas entupidos com ferramentas adicionais. Somente no modo de edição normal, mais de cem atalhos de teclado! Essa densidade de kits de ferramentas explica em grande parte por que o Vim é tão útil. Se “mostrar todas as tags para uma palavra-chave” for apenas g] , esse comando será usado com muito mais frequência.

Sistemas com falta de abertura precisam confiar na liderança. Mas para o Vim não existem muitos deles. Existem artigos para iniciantes, como ciw (que não devem ser confundidos com a CIA, o manual da CIA para o Vim ) e similares. E há artigos de especialistas imersos em subsistemas. Mas ninguém fala sobre esses truques especiais que fazem você exclamar: caramba, como eu precisei nos últimos seis anos!

Este artigo é sobre alguns dos pequenos truques que uso no Vim. Nenhum deles é desmontado em todos os detalhes; portanto, se algo estiver interessado, recomendo que você desenterre informações adicionais. Eles também não estão relacionados um com o outro. Mas isso é normal. Em geral, existem mais que o suficiente para realmente ajudar quase todo mundo.

Estrutura do artigo


Muito rudes, os usuários do Vim se enquadram em duas categorias. Os puristas apreciam o tamanho pequeno e a onipresença. Como regra, eles minimizam a configuração caso você precise trabalhar em um computador desconhecido (por exemplo, via ssh). Os extensores, por outro lado, preenchem o Vim com plug-ins, funções e mapeamentos locais em uma tentativa fútil de fingir usar o Emacs. Se você tirar o vimrc deles, os caras permanecerão completamente indefesos.

Como você provavelmente adivinha, estou muito mais próximo dos expansores do que dos puristas. Dividi os truques em duas seções, dependendo se as alterações são necessárias no Vim base.

Puristas


Para comandos modais, são usadas as visualizações de ajuda padrão, ou seja, <cr> significa pressionar a tecla Enter. Quando você precisar de ajuda :h para uma linha específica, por exemplo :h E676 , a linha estará entre parênteses.

Vários comandos no modo normal


": e @:


": é um registro que mantém o último comando executado. Você pode digitar ":p para imprimi-lo no buffer. @: repete o último comando.

"=


Registre-se para "expressões". Aqui você pode inserir qualquer expressão do vimL e inseri-la, use com ctrl-R, etc. Assim, por exemplo, o registro de data e hora local é inserido digitando "=strftime("%c")<cr>p .

mA, 'A


m{letter} coloca a marca na posição do cursor. Então '{letter} irá para esta linha. Para letras minúsculas, atua no buffer, sendo adequado para navegação. Funciona globalmente para letras maiúsculas: mesmo se você estiver em outro arquivo, 'A irá para o arquivo rotulado Você pode ver todas as suas tags com o comando :marks:

ctrl-A e ctrl-X


Aumenta e diminui o próximo número na linha no local do cursor ou à direita dele. Como ele vai imediatamente para o número, a combinação pode ser usada de qualquer lugar. 10c-A muito mais simples que wwwwwciw20 .

q:


Abre o histórico das equipes anteriores. Você pode trabalhar com ele como em qualquer texto do Vim, mas as alterações não são salvas. No entanto, você pode executar o comando modificado usando <CR> . Isso permite que você mude muito rapidamente e reinicie os comandos ou procure pelos antigos para reutilização.

q / q?


O mesmo que q: exceto pesquisa.

Ctrl-I, Ctrl-O


Move para o local seguinte ou anterior no jumplist. Útil para verificação rápida e depois voltar atrás. É muito bom ler os arquivos de ajuda.

Macros


Veja esta postagem para uma visão mais profunda do uso de macros.

Modo visual


gv


Seleciona o item visual anterior.

v_o


Vai para o outro lado do bloco visual. Útil se você iniciou uma linha muito baixa ou algo assim. No modo de bloco, ele vai para o ângulo diagonal oposto e use v_O para alternar para o v_O horizontal oposto.

g Ctrl-A / Ctrl-X


No modo visual, ctrl-A simplesmente incrementa o primeiro número em cada linha. Por outro lado, g ctrl-A aumentará uma linha com cada linha. Isso é muito mais fácil de explicar na tabela:

selecionadoctrl-Ag ctrl-A2 g ctrl-A
  a 0
 b 0
 c
 d 0 
  a 1
 b 1
 c
 d 1 
  a 1
 b 2
 c
 d 3 
  a 2
 b 4
 c
 d 6 

Operadores: v, V, cv (: h o_v)


Você provavelmente sabe que, no modo visual, pode selecionar caracteres (v), linhas (V) e blocos (ctrl-V). Mas essas três combinações podem ser usadas como operadores de movimento para o fragmento correspondente. Por exemplo, você tem o seguinte texto:

abc
abc
abc


Se você colocar o cursor na parte superior b pressionar d2j , ele excluirá todas as três linhas, porque j se moverá linha a linha. Se d<cV>2j pressionado, o movimento se tornará bloco a bloco e somente a coluna do meio com três letras b será excluída.

Um caso de uso é excluído na pesquisa. Normal d/ move caractere por caractere. Portanto, eu uso dV/ para movimento linha por linha com exclusão. Há outra maneira de fazer isso:

/ regex / {n}


Mova n linhas abaixo da partida ou o máximo de linhas se o valor for negativo. Como efeito colateral, o movimento ocorre linha por linha. Portanto, se você desejar excluir a primeira linha correspondente à regex , poderá inserir d/regex//0 .

Ex-equipes


Você insere ex-comandos no modo de comando, por exemplo, o comando :s . Além da substituição, existem muitos outros comandos úteis. Todos esses exemplos exigem um intervalo, como % .

: g / regex / ex


Executa o comando apenas nas linhas correspondentes à expressão regular. Por exemplo, você pode inserir g/regex/d para excluir todas as linhas correspondentes a regex. O comando v é semelhante a g , mas funciona em todas as linhas que não correspondem à expressão regular.

Truques se tornam mais poderosos com a norma e alguns outros.

: norma {Vim}


Age como se você executasse {Vim} em cada linha do intervalo. Por exemplo, g/regex/norm f dw excluirá a primeira palavra após o primeiro espaço em cada linha correspondente à expressão regular da expressão regular. Isso geralmente é muito mais simples que uma macro.

norm obedece a todas as suas comparações. Por exemplo, se você atribuiu jk a <esc> no modo de inserção, a norm I jk$diw adicionará um espaço ao início da linha, deixe o modo de inserção e exclua a última palavra da linha. Eu realmente gosto dessa funcionalidade, mas se você preferir não usar seus mapeamentos, poderá aplicar a norm! .

: co.


Copia um intervalo para a linha atual. Você também pode especificar valores arbitrários em vez de um período, por exemplo, +3 ou 'a. mv 'a. mv para mover.

: y {reg}


Copia o intervalo para o {reg} . Se {reg} maiúscula, ele será adicionado ao caso existente. ou seja, uma equipe

let @a = '' | %g/regex/y A

copiará para todas as linhas correspondentes à regex no arquivo inteiro. Isso ajuda a extrair o texto corrompido do arquivo e copiá-lo para a área de transferência do sistema (usando let @+ = @a ).

: windo {ex}


Executa um comando em todas as janelas. Por exemplo :windo $ todas as janelas para baixo. Existem bufdo , cdo , tabdo e outros.

Funciona muito bem com g e s . Para substituir todas as combinações de AA pelo BB com uma visualização das substituições, você pode inserir o vimgrep AA carregando todas as correspondências no quickfix e, em seguida, cdo s/AA/BB/cge para pesquisar / substituir todas as correspondências.

Vim para Extensores


Aqui estão listados truques que exigem salvar nas configurações ou alterar uma sessão do Vim. Hipoteticamente, eles podem ser usados ​​no modo "puritano", simplesmente digitando comandos, mas alguns envolvem mudanças bastante sérias que contradizem o espírito do purismo.

Aqui é apenas o mais incomum. Muitas pessoas atribuem H ao limite ^ , portanto não vale a pena mencionar essas coisas. Além disso, não faz sentido falar sobre vim-sensible ou vim-surround , mas apenas sobre plugins mais exóticos.

Se você está constantemente configurando seu vimrc, por favor, adicione um comando separado para isso:

command! Vimrc :vs $MYVIMRC

Configurações


Eu tenho todas as configurações, combinações de teclas e funções armazenadas em um único arquivo vimrc. Dividir em vários arquivos dificulta a pesquisa.

A maioria das configurações não são realmente "truques". É melhor olhar para o vim-sensible : quase todas as configurações de lá se adequam ao seu vimrc.

set lazyredraw


Não redesenhe a tela no meio de uma macro (para melhorar o desempenho).

definir smartcase / ignorecase


Com essas duas configurações, uma pesquisa sem letras maiúsculas torna maiúsculas e minúsculas e uma pesquisa com letras maiúsculas diferencia maiúsculas de minúsculas.

definir undofile


Salvando ações, mesmo se você fechar e abrir o Vim, para que as ações de desfazer estejam sempre disponíveis. Muito útil em combinação com o plugin undotree.

definir foldcolumn = {n}


Coluna lateral com blocos recolhidos. Quanto maior n , mais blocos recolhidos são mostrados na coluna e, no restante, o número é indicado.

definir sufixosadd = {str}


gf geralmente significa "ir para o arquivo abaixo do cursor", mas requer uma extensão de arquivo na linha. suffixesadd adiciona a extensão especificada. Se suffixesadd=.md , o comando gf na linha 'foo' procurará os arquivos foo e foo.md

set inccommand = nosplit


Somente para Neovim. A incommand mostra em tempo real as mudanças que a equipe fará. Atualmente, apenas s é suportado, mas mesmo isso é incrivelmente útil. Se você digitar :s/regex , todas as correspondências serão destacadas. Se você adicionar /change , ele mostrará todas as substituições. Funciona com todas as propriedades de regex, incluindo backlinks e grupos.

definir statusline (: h statusline)


Determina o que exibir no painel na parte inferior de cada janela. Aqui a formatação é muito mais complicada e complicada do que em outras configurações, então você precisa gastar tempo explicando isso. Existem alguns truques simples. Primeiro, observe a barra de status padrão do Vim:

:set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P

Aqui é mais fácil substituir %P (porcentagem do arquivo sobre o cursor). O formato da barra de status é o valor após o sinal de porcentagem entre chaves. Portanto, para arquivos Markdown, você pode escrever isto:

:set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %{wordcount()[\"words\"]}

E substitua a porcentagem do arquivo pelo número de palavras no documento.

Ou instale o tabline . Se você não usar guias, essa linha poderá ser transformada em uma "linha de status global". Por exemplo

set tabline=%{strftime('%c')}

sempre mostrará a data no topo.

Key Bindings


Eu tenho muitas ligações.

Muitas teclas convenientes no Vim são estupidamente atribuídas por padrão. Por exemplo, salvar o pressionamento de tecla s é sinônimo de cl (salvar um pressionamento de tecla) e U é o mesmo que u , exceto para escrever desfazer como uma nova alteração, que é funcionalmente inútil. Q idêntico ao gQ e, de qualquer forma, é uma tremenda armadilha. Z usado apenas para ZZ e ZQ . Puxa, até o manual do Vim recomenda reatribuir as teclas _ e para algumas funções, porque "você provavelmente nunca as usa". Eu preferiria não salvar um clique, mas adicionar funções completamente novas ao teclado. Aqui estão algumas das minhas ligações:

nnoremap Q @@


Sem desacelerar a transição para o modo ex, repete a última macro.

nnoremap s "_d


Faz com que a tecla s (com as configurações apropriadas para ss e S ) funcione como d, apenas sem salvar o texto excluído no registro. Útil para não entupir o registro.

nnoremap <cj> <cw> j


Vá para a janela abaixo. Designações apropriadas para h , k , l . Trabalhar com o Windows é muito mais fácil.

nnoremap <líder> e: exe getline (linha ('.')) <cr>


Execute a linha atual como se fosse um comando. Em experimentos, geralmente é mais conveniente que q:

Argumentos especiais (: h map-argumentos)


O map <buffer> lhs rhs ativa o mapeamento de chave somente para esse buffer. Ele realmente funciona convenientemente com comandos automáticos como uma combinação temporária de teclas ou ao definir atribuições por meio de uma função. As designações de buffer têm precedência sobre as globais, ou seja, você pode substituir o comando geral mais útil em uma situação específica.

O map <expr> {lhs} {expr} verifica {expr} e usa o valor de retorno como o remapeamento final das chaves. Um caso de uso simples é obrigatório com base em condições. Eu tenho estes:

nnoremap <expr> k (v:count == 0 ? 'gk' : 'k')
nnoremap <expr> j (v:count == 0 ? 'gj' : 'j')


O que faz j e k moverem ao longo da linha até que um número seja encontrado e, depois disso, a tecla é cancelada. Portanto, posso navegar em longos parágrafos da prosa sem quebrar combinações como 10j .

O argumento <silent> ajuda se alguma ligação executar comandos ex.

inoremaps


Graças ao inoremap ligações funcionam no modo de inserção. Lá eles começam a trabalhar, então inoremap ;a aaaa apresentará 'aaaa' em vez de '; a'. Se você quiser fazer algo no modo normal, use <cO> . Por exemplo, se tivermos

inoremap ;1 <co>ma

então ;1 definirá 'a .

Eu gosto de especificar o uso de ponto e vírgula como uma chave para reatribuições, porque em textos normais quase sempre há um espaço ou uma nova linha após o ponto e vírgula.

autocmd


Comandos automáticos são ótimos para configuração. Geralmente você os configura assim:

 augroup {name} autocmd! " Prevents duplicate autocommands au {events} {file regex} {command} augroup END 

Então, se algum dos eventos {events} ocorrer no arquivo {file regex}, o comando {command} será acionado. Os eventos estão listados :h event . Por exemplo, se você escrever

 augroup every autocmd! au InsertEnter * set norelativenumber au InsertLeave * set relativenumber augroup END 

o vim desativará o número relativo apenas para o modo de inserção.

O comando au {event} <buffer> {ex} aplica o comando auto apenas ao buffer atual. Às vezes eu uso isso para adicionar manipuladores de eventos de curto prazo a um arquivo específico.

BufNewFile, BufRead


BufnewFile inicia quando um novo arquivo é criado, BufRead - quando o buffer é aberto pela primeira vez. Eles geralmente são usados ​​para adicionar parâmetros e remaps a tipos de arquivos específicos. Eu tenho um desses:

 augroup md autocmd! au BufNewFile,BufRead *.md syntax keyword todo TODO au BufNewFile,BufRead *.md inoremap <buffer> ;` ```<cr><cr>```<Up><Up> augroup END 

Somente nos arquivos Markdown a linha TODO é destacada e os caracteres ;` no modo de inserção adicionam uma notação de código.

As equipes automáticas permitem que você faça coisas muito mais complexas. Por exemplo, au para BufWriteCmd substitui o salvamento padrão, permitindo implementar a lógica personalizada. Isso vai além dos "truques" e entra no reino da "magia negra".

Plugins


A maioria das pessoas conhece plugins populares como o vim-surround e o NERDtree . Aqui está uma lista de alguns pouco conhecidos que acho muito úteis.

Undotree


Na maioria dos editores de texto, as ações de desfazer ocorrem linearmente. Se você fizer uma alteração em A, desfaça-a e faça uma alteração em B, então A será perdido para sempre. No entanto, o Vim armazena toda a árvore de ações desfeitas. O comando u reverte a ação no galho de árvore atual e g vai para a versão cronológica anterior. Você pode visualizar a lista de ações canceladas com o comando :undolist .

Mas esse formato não é muito claro. É muito melhor ver a árvore real. É exatamente isso que o Undotree faz: apresenta uma boa representação ASCII da árvore de ações canceladas com navegação conveniente.

vim.swap


O plug-in fornece comandos para a troca de argumentos, para que você possa substituir (a, f(b, c)) por (f(b, c), a) em algumas teclas. Eu regularmente tenho que fazer essas edições, então essa é uma grande melhoria na qualidade de vida.

Neoterm


Conecta uma API de nível superior ao terminal incorporado neo / vim. Por exemplo :T {text} envia {text} para o console. Bom para criar um ambiente interativo.

"TODO {{{


Muitos tópicos não são abordados neste artigo porque são muito técnicos ou precisam ser explicados em detalhes, como a gravação de funções ou o sistema de sintaxe. E eu não sei muito. Gostaria de estudar os seguintes tópicos com mais detalhes:

Janelas de visualização, Quickfix e lista


Às vezes, uso ferramentas com essas janelas, mas não sei como manipulá-las. Gostaria de adicionar erros de correção rápida ao meu plug-in TLA + . Também gosto da ideia de colocar informações de suporte e comandos de retorno de chamada na janela de visualização. Isso abre algumas possibilidades que são difíceis de reproduzir no IDE.

API Neovim


O Neovim oferece uma API avançada para integrar o Vim a programas externos. Seu script Python pode enviar comandos para a instância do Neovim e você pode controlar o editor através do servidor, por exemplo. Eu vi algumas demos conceituais interessantes em que o preenchimento automático acontece com base nas informações de um navegador. Parece ser muito legal!

Objetos de texto


Nunca criou tal.



Portanto, essa foi uma breve visão geral de algumas das funções implícitas do Vim. Espero que você tenha descoberto algo útil!

Source: https://habr.com/ru/post/pt454742/


All Articles