Qual é o seu atalho mais produtivo com o Vim?

Eu ouvi muito sobre o Vim , tanto os prós e contras. Parece que você deveria ser (como desenvolvedor) mais rápido com o Vim do que com qualquer outro editor. Estou usando o Vim para fazer algumas coisas básicas e estou 10 vezes menos produtivo com o Vim.

As duas únicas coisas com as quais você deve se preocupar quando fala sobre velocidade (você pode não se importar o suficiente com elas, mas deveria) são:

  1. Usar alternativamente as mãos esquerda e direita é a maneira mais rápida de usar o teclado.
  2. Nunca tocar no mouse é a segunda maneira de ser o mais rápido possível. Leva muito tempo para você mover a mão, pegar o mouse, movê-lo e trazê-lo de volta para o teclado (e muitas vezes é necessário olhar o teclado para ter certeza de que você retornou a mão corretamente para o lugar certo)

Aqui estão dois exemplos demonstrando porque eu sou muito menos produtivo com o Vim.

Copiar / recortar e colar. Eu faço isso o tempo todo. Com todos os editores contemporâneos, você pressiona Shift com a mão esquerda e move o cursor com a mão direita para selecionar o texto. Em seguida, Ctrl + C copia, você move o cursor e cola Ctrl + V.

Com o Vim é horrível:

  • yy para copiar uma linha (você quase nunca quer a linha inteira!)
  • [number xx]yy para copiar xx linhas para o buffer. Mas você nunca sabe exatamente se selecionou o que queria. Muitas vezes tenho que fazer [number xx]dd depois u desfazer!

Outro exemplo? Pesquise e substitua.

  • Na PSPad : Ctrl + f , digite o que você deseja pesquisar e pressione Enter .
  • Em Vim: / , digite o que você deseja procurar, então, se houver alguns caracteres especiais colocados \ antes de cada caractere especial, pressione Enter .

E tudo com o Vim é assim: parece que não sei como lidar da maneira certa.

NB: Eu já li a folha de cola do Vim 🙂

Minha pergunta é:

Qual é a maneira que você usa o Vim que o torna mais produtivo do que com um editor contemporâneo?

   

Seu problema com o Vim é que você não aumenta o vi .

Você menciona cortar com yy e reclamar que você quase nunca quer cortar linhas inteiras. Na verdade, os programadores, editando o código fonte, muitas vezes querem trabalhar em linhas inteiras, intervalos de linhas e blocos de código. No entanto, yy é apenas uma das muitas maneiras de enviar texto para o buffer de cópia anônimo (ou “registrar”, como é chamado no vi ).

O “Zen” do vi é que você está falando uma língua. O y inicial é um verbo. A declaração yy é sinônimo de y_ . O y é duplicado para facilitar a digitação, já que é uma operação tão comum.

Isso também pode ser expresso como dd P (excluir a linha atual e colar uma cópia de volta no lugar, deixando uma cópia no registro anônimo como um efeito colateral). Os y e d “verbos” tomam qualquer movimento como seu “assunto”. Assim yW é “arrancar daqui (o cursor) até o final da palavra atual / próxima (grande)” e y'a é “puxar daqui para a linha contendo a marca chamada ‘ a ‘.”

Se você entender apenas os movimentos básicos do cursor para cima, baixo, esquerda e direita, então o vi não será mais produtivo do que uma cópia do “bloco de notas” para você. (Ok, você ainda terá destaque de syntax e a capacidade de lidar com arquivos maiores que ~ 45KB ou mais; mas trabalhe aqui comigo).

vi tem 26 “marcas” e 26 “registros”. Uma marca é definida para qualquer localização do cursor usando o comando m . Cada marca é designada por uma única letra minúscula. Assim, ma define a marca ‘ a ‘ como a localização atual e mz define a marca ‘ z ‘. Você pode mover para a linha que contém uma marca usando o comando ' (aspas simples). Assim, 'a move-se para o começo da linha contendo a marca’ a ‘. Você pode mover para a localização precisa de qualquer marca usando o comando ` (backquote). Assim, o `z se moverá diretamente para a localização exata da marca ‘ z ‘.

Como esses são “movimentos”, eles também podem ser usados ​​como sujeitos para outras “declarações”.

Assim, uma maneira de cortar uma seleção arbitrária de texto seria deixar uma marca (normalmente, uso ” a ” como minha “primeira”, ” z ” como minha próxima, ” b ” como outra e ” e ” como ainda outro (não me lembro de ter usado interativamente mais de quatro marcas em 15 anos de uso do vi ; criamos as próprias convenções sobre como marcas e registros são usados ​​por macros que não perturbam o contexto interativo). para o outro lado do nosso texto desejado, podemos começar em cada extremidade, não d`a , podemos simplesmente usar d`a para cortar ou y`a para y`a todo o processo tem uma sobrecarga de 5 pressionamentos de tecla (seis se começamos no modo “inserir” e necessário para o modo de comando Esc out. Uma vez que cortamos ou copiamos, em seguida, colar em uma cópia é um único pressionamento de tecla: p .

Eu digo que esta é uma maneira de cortar ou copiar texto. No entanto, é apenas um entre muitos. Freqüentemente podemos descrever de forma mais sucinta a faixa de texto sem mover o cursor e soltando uma marca. Por exemplo, se eu estiver em um parágrafo de texto, posso usar { e } movimentos no início ou no final do parágrafo, respectivamente. Então, para mover um parágrafo de texto, eu o corto usando { d} (3 pressionamentos de tecla). (Se eu já estiver na primeira ou última linha do parágrafo, posso simplesmente usar d} ou d{ respectivamente.

A noção de “parágrafo” é padronizada para algo que geralmente é intuitivamente razoável. Assim, muitas vezes funciona tanto para código quanto para prosa.

Frequentemente, conhecemos algum padrão (expressão regular) que marca uma extremidade ou outra do texto em que estamos interessados. Pesquisando para frente ou para trás são movimentos no vi . Assim, eles também podem ser usados ​​como “sujeitos” em nossas “declarações”. Então eu posso usar d/foo para cortar da linha atual para a próxima linha contendo a string “foo” e y?bar para copiar da linha atual para a linha mais recente (anterior) contendo “bar”. Se eu não quiser linhas inteiras, eu ainda posso usar os movimentos de busca (como instruções próprias), largar as minhas marcas e usar os comandos `x conforme descrito anteriormente.

Além de “verbos” e “sujeitos” vi também tem “objects” (no sentido gramatical do termo). Até agora eu só descrevi o uso do registro anônimo. No entanto, posso usar qualquer um dos 26 registradores “nomeados” prefixando a referência “object” com " (o modificador de aspas duplas). Assim, se eu usar "add , estou cortando a linha atual no registro ‘ a ‘ e se Eu uso "by/foo então eu estou puxando uma cópia do texto daqui para a próxima linha contendo” foo “no registro ‘ b ‘. Para colar de um registrador, simplesmente prefixo a pasta com a mesma sequência modificadora: "ap cola uma cópia do conteúdo do registro ‘ a ‘ no texto após o cursor e "bP cola uma cópia de ‘ b ‘ em antes da linha atual.

Esta noção de “prefixos” também adiciona os análogos gramaticais “adjetivos” e “advérbios” à nossa linguagem de manipulação de texto. “A maioria dos comandos (verbos) e movimento (verbos ou objects, dependendo do contexto) também podem ter prefixos numéricos. 3J significa “unir as próximas três linhas” e d5} significa “excluir da linha atual até o final do quinto parágrafo a partir daqui”.

Isso tudo é nível intermediário vi . Nada disso é específico do Vim e há muito mais truques avançados no vi se você estiver pronto para aprendê-los. Se você fosse dominar apenas esses conceitos intermediários, provavelmente descobriria que raramente precisa escrever macros, porque a linguagem de manipulação de texto é suficientemente concisa e expressiva para fazer a maioria das coisas com bastante facilidade usando a linguagem “nativa” do editor.


Uma amostra de truques mais avançados:

Existem vários comandos:, mais notavelmente a técnica de substituição global :% s/foo/bar/g . (Isso não é avançado, mas outro : comandos podem ser). O conjunto : conjunto de comandos foi historicamente herdado pelas encarnações anteriores do vi como os utilitários ed (editor de linhas) e depois o ex (editor de linhas estendido). Na verdade vi é assim chamado porque é a interface visual para ex .

: comandos normalmente operam sobre linhas de texto. ed e ex foram escritos em uma época em que as canvass dos terminais eram incomuns e muitos terminais eram dispositivos “teletipo” (TTY). Por isso, era comum trabalhar com cópias impressas do texto, usando comandos através de uma interface extremamente concisa (velocidades de conexão comuns eram de 110 baud ou, aproximadamente, 11 caracteres por segundo – o que é mais lento que um typescriptr rápido; sessões interativas multi-usuário, além disso, muitas vezes houve alguma motivação para economizar papel).

Portanto, a syntax da maioria dos comandos inclui um endereço ou intervalo de endereços (número de linha) seguido por um comando. Naturalmente, é possível usar números de linhas literais :127,215 s/foo/bar para alterar a primeira ocorrência de “foo” em “bar” em cada linha entre 127 e 215. Também é possível usar algumas abreviações como . ou $ para as linhas atuais e últimas, respectivamente. Pode-se também usar prefixos relativos + e - para se referir a offsets após ou antes da linha atual, respectivamente. Assim:: :.,$j significa “da linha atual para a última linha, junte todas em uma linha”. :% é sinônimo de :1,$ (todas as linhas).

Os comandos :... g e :... v têm alguma explicação, pois são incrivelmente poderosos. :... g é um prefixo para “globalmente” aplicar um comando subseqüente a todas as linhas que correspondem a um padrão (expressão regular) enquanto :... v aplica tal comando a todas as linhas que NÃO correspondem ao padrão dado (“v “de” conVerse “). Tal como acontece com outros ex- comandos, estes podem ser prefixados por referências de endereçamento / intervalo. Assim :.,+21g/foo/d significa “delete qualquer linha contendo a string” foo “do atual até as próximas 21 linhas” enquanto :.,$v/bar/d significa “daqui até o final do arquivo, exclua todas as linhas que NÃO contenham a string “bar”.

É interessante que o comando comum do Unix grep foi realmente inspirado por este comando ex (e é nomeado após a maneira em que foi documentado). O comando ex :g/re/p (grep) foi a forma como documentaram como “globalmente” “imprimir” linhas contendo uma “expressão regular” (re). Quando ed e ex foram usados, o comando :p foi um dos primeiros que alguém aprendeu e freqüentemente o primeiro usado ao editar qualquer arquivo. Foi como você imprimiu o conteúdo atual (geralmente apenas uma página cheia de cada vez usando :.,+25p ou algo assim).

Note que :% g/.../d ou (sua contrapartida reversa / conVerse :% v/.../d são os padrões de uso mais comuns. Entretanto, há alguns outros ex comandos que valem a pena lembrar:

Podemos usar m para mover linhas ao redor e j para unir linhas. Por exemplo, se você tem uma lista e deseja separar todas as correspondências (ou, inversamente, NÃO corresponder a algum padrão) sem excluí-las, você pode usar algo como :% g/foo/m$ … e todas as ” foo “linhas terão sido movidas para o final do arquivo. (Observe a outra dica sobre como usar o final do seu arquivo como um espaço de rascunho). Isso preservará a ordem relativa de todas as linhas “foo” enquanto as extraiu do resto da lista. (Isso seria equivalente a fazer algo como: 1G!GGmap!Ggrep foo1G:1,'ag/foo'/d (copie o arquivo para sua própria cauda, ​​filtre a cauda pelo grep e exclua todas as coisas da cabeça).

Para juntar linhas normalmente eu posso encontrar um padrão para todas as linhas que precisam ser unidas ao seu predecessor (todas as linhas que começam com “^” ao invés de “^ *” em alguma lista de marcadores, por exemplo). Para esse caso eu usaria:: :% g/^ /-1j (para cada linha correspondente, suba uma linha e junte-as). (BTW: para listas com marcadores que tentam procurar pelas linhas de marcação e juntar-se à próxima não funciona por algumas razões … pode juntar uma linha de marcadores a outra, e não irá juntar-se a nenhuma linha a todas suas continuações, só funcionará em pares nos jogos).

Quase desnecessário mencionar que você pode usar nossos velhos amigos s (substituto) com os comandos g e v (global / converse-global). Normalmente você não precisa fazer isso. No entanto, considere alguns casos em que você deseja executar uma substituição apenas em linhas que correspondam a outro padrão. Muitas vezes você pode usar um padrão complicado com capturas e usar referências posteriores para preservar as partes das linhas que você NÃO deseja alterar. No entanto, será mais fácil separar a correspondência da substituição:: :% g/foo/s/bar/zzz/g – para cada linha que contenha “foo” substitua “bar” por “zzz”. (Algo como :% s/\(.*foo.*\)bar\(.*\)/\1zzz\2/g só funcionaria para os casos daquelas instâncias de “bar” que foram PRECEDIDAS por “foo” em a mesma linha, é bastante deselegante já, e teria que ser mutilado ainda mais para capturar todos os casos em que “bar” precedeu “foo”)

O ponto é que existem mais do que apenas linhas p , se d no conjunto de comandos ex .

Os endereços : também podem se referir a marcas. Assim, você pode usar:: :'a,'bg/foo/j para unir qualquer linha contendo a string foo à sua linha subseqüente, se ela estiver entre as linhas entre as marcas ‘ a ‘ e ‘ b ‘. (Sim, todos os exemplos de comandos ex anteriores podem ser limitados a subconjuntos das linhas do arquivo prefixando esses tipos de expressões de endereçamento).

Isso é bem obscuro (eu só usei algo assim algumas vezes nos últimos 15 anos). No entanto, admito francamente que muitas vezes fiz coisas iterativa e interativamente, o que provavelmente poderia ter sido feito com mais eficiência, se eu tivesse tido tempo para pensar no encantamento correto.

Outro comando vi ou ex muito útil é :r ler o conteúdo de outro arquivo. Assim:: :r foo insere o conteúdo do arquivo chamado “foo” na linha atual.

Mais poderoso é o :r! comando. Isso lê os resultados de um comando. É o mesmo que suspender a session do vi , executar um comando, redirect sua saída para um arquivo temporário, retomar sua vi session e ler o conteúdo do temp. Arquivo.

Ainda mais poderosos são os ! (bang) e :... ! ( ex bang) comandos. Estes também executam comandos externos e lêem os resultados no texto atual. No entanto, eles também filtram as seleções do nosso texto através do comando! Isso podemos classificar todas as linhas em nosso arquivo usando 1G!Gsort ( G é o comando vi “goto”; o padrão é ir para a última linha do arquivo, mas pode ser prefixado por um número de linha, como 1, o primeira linha). Isso é equivalente à variante ex :1,$!sort . Escritores costumam usar ! com os utilitários fmt ou fold do Unix para reformatar ou seleções de texto “word wrapping”. Uma macro muito comum é {!}fmt (reformate o parágrafo atual). Por vezes, os programadores utilizam-no para executar o seu código, ou apenas partes dele, através de um recuo ou de outras ferramentas de reformatação de código.

Usando o :r! e ! Comandos significa que qualquer utilitário ou filtro externo pode ser tratado como uma extensão do nosso editor. Ocasionalmente, usei-os com scripts que extraíam dados de um database ou com comandos wget ou lynx que extraíam dados de um site ou comandos ssh que extraíam dados de sistemas remotos.

Outro comando ex útil é :so (abreviação de :source ). Isso lê o conteúdo de um arquivo como uma série de comandos. Quando você inicia o vi normalmente, executa implicitamente :source no arquivo ~/.exinitrc (e o Vim geralmente faz isso em ~/.vimrc , naturalmente). O uso disso é que você pode alterar o perfil do seu editor rapidamente simplesmente obtendo um novo conjunto de macros, abreviações e configurações do editor. Se você é sneaky você pode até usar isso como um truque para armazenar seqüências de ex- edição de comandos para aplicar aos arquivos sob demanda.

Por exemplo, eu tenho um arquivo de sete linhas (36 caracteres) que executa um arquivo através de wc e insere um comentário no estilo C na parte superior do arquivo que contém esses dados de contagem de palavras. Eu posso aplicar essa “macro” a um arquivo usando um comando como: vim +'so mymacro.ex' ./mytarget

(A opção de linha de comando + para vi e Vim é normalmente usada para iniciar a session de edição em um determinado número de linha. No entanto, é um fato pouco conhecido que um pode seguir o + por qualquer comando / expressão ex válido, como uma “origem” comando como eu fiz aqui, para um exemplo simples eu tenho scripts que invocar: vi +'/foo/d|wq!' ~/.ssh/known_hosts para remover uma input do meu arquivo hosts conhecidos SSH não interativamente enquanto eu estou re-imaging um conjunto de servidores).

Geralmente é muito mais fácil escrever tais “macros” usando Perl, AWK, sed (que é, na verdade, como o grep, um utilitário inspirado no comando ed ).

O comando @ é provavelmente o comando vi mais obscuro. Ocasionalmente, ao ministrar cursos avançados de administração de sistemas por quase uma década, conheci pouquíssimas pessoas que já o utilizaram. @ executa o conteúdo de um registro como se fosse um comando vi ou ex .
Exemplo: Eu frequentemente uso:: :r!locate ... para encontrar algum arquivo no meu sistema e ler seu nome no meu documento. De lá eu apago quaisquer accesss estranhos, deixando apenas o caminho completo para o arquivo que me interessa. Ao invés de laboriosamente Tab- through através de cada componente do caminho (ou pior, se eu ficar preso em uma máquina sem conclusão Tab suporte na sua cópia do vi ) eu uso apenas:

  1. 0i:r (para transformar a linha atual em um comando válido : r ),
  2. "cdd (para apagar a linha no registro” c “) e
  3. @c execute esse comando.

São apenas 10 pressionamentos de tecla (e a expressão "cdd @c é efetivamente uma macro de dedo para mim, para que eu possa digitá-la quase tão rapidamente quanto qualquer palavra comum de seis letras).


Um pensamento sóbrio

Eu apenas arranhei a superfície do poder do vi e nada do que eu descrevi aqui é parte das “melhorias” para as quais o vim é chamado! Tudo o que descrevi aqui deve funcionar em qualquer cópia antiga do vi de 20 ou 30 anos atrás.

Há pessoas que usaram consideravelmente mais poder do vi do que eu jamais irei.

Você está falando sobre seleção de texto e cópia, eu acho que você deveria dar uma olhada no Modo Visual do Vim .

No modo visual, você pode selecionar texto usando os comandos do Vim, então você pode fazer o que quiser com a seleção.

Considere os seguintes cenários comuns:

Você precisa selecionar o próximo parêntese correspondente.

Você poderia fazer:

  • v% se o cursor estiver no parêntese inicial / final
  • vib se o cursor estiver dentro do bloco parêntese

Você deseja selecionar texto entre aspas:

  • vi “ para aspas duplas
  • vi ‘ para aspas simples

Você deseja selecionar um bloco de chaves (muito comum em linguagens no estilo C):

  • viB
  • vi{

Você deseja selecionar o arquivo inteiro:

  • ggVG

Seleção de bloco visual é outro recurso realmente útil, ele permite que você selecione uma área retangular de texto, você só tem que pressionar CtrlV para iniciá-lo e, em seguida, selecione o bloco de texto desejado e executar qualquer tipo de operação, como yank, exclua, cole, edite, etc. É ótimo editar o texto orientado por colunas .

Algumas dicas de produtividade:

Movimentos inteligentes

  • * e # procura a palavra sob o cursor para frente / para trás.
  • w para a próxima palavra
  • W para a próxima palavra separada por espaço
  • b / e para o início / fim da palavra atual. ( B / E para espaço separado apenas)
  • gg / G pula para o início / fim do arquivo.
  • % pula para a correspondência {..} ou (..), etc.
  • { / } pule para o próximo parágrafo.
  • '. pular de volta para a última linha editada.
  • g; pular de volta para a última posição editada.

Comandos de edição rápida

  • I insiro no começo.
  • A acréscimo ao fim.
  • o / O abre uma nova linha após / antes da atual.
  • v / V / Ctrl+V modo visual (para selecionar texto!)
  • Shift+R replace texto
  • C altera parte restante da linha.

Combinando Comandos

A maioria dos comandos aceita uma quantidade e direção, por exemplo:

  • cW = muda até o final da palavra
  • 3cW = muda 3 palavras
  • BcW = para começar a palavra completa, mudar palavra completa
  • ciW = altera a palavra interna.
  • ci" = altera o interior entre” .. ”
  • ci( = muda o texto entre (..)
  • ci< = altera o texto entre < ..> (precisa set matchpairs+=<:> no vimrc)
  • 4dd = excluir 4 linhas
  • 3x = deletar 3 caracteres.
  • 3s = substitua 3 caracteres.

Comandos úteis do programador

  • r replace um caractere (por exemplo, rd substitui o caractere atual por d ).
  • ~ muda caso.
  • J une duas linhas
  • Ctrl + A / Ctrl + X incrementa / decrementa um número.
  • . Repetir o último comando (uma macro simples)
  • == recuo da linha de correção
  • > bloco de recuo (no modo visual)
  • < bloco não indicado (no modo visual)

Gravação em macro

  • Pressione q[ key ] para iniciar a gravação.
  • Em seguida, pressione q para parar a gravação.
  • A macro pode ser reproduzida com @[ key ] .

Usando comandos e movimentos muito específicos, o VIM pode reproduzir essas ações exatas para as próximas linhas. (por exemplo, A para acrescentar ao fim, b / e para mover o cursor para o início ou o fim de uma palavra, respectivamente)

Exemplo de configurações bem construídas

 # reset to vim-defaults if &compatible # only if not set before: set nocompatible # use vim-defaults instead of vi-defaults (easier, more user friendly) endif # display settings set background=dark # enable for dark terminals set nowrap # dont wrap lines set scrolloff=2 # 2 lines above/below cursor when scrolling set number # show line numbers set showmatch # show matching bracket (briefly jump) set showmode # show mode in status bar (insert/replace/...) set showcmd # show typed command in status bar set ruler # show cursor position in status bar set title # show file in titlebar set wildmenu # completion with menu set wildignore=*.o,*.obj,*.bak,*.exe,*.py[co],*.swp,*~,*.pyc,.svn set laststatus=2 # use 2 lines for the status bar set matchtime=2 # show matching bracket for 0.2 seconds set matchpairs+=<:> # specially for html # editor settings set esckeys # map missed escape sequences (enables keypad keys) set ignorecase # case insensitive searching set smartcase # but become case sensitive if you type uppercase characters set smartindent # smart auto indenting set smarttab # smart tab handling for indenting set magic # change the way backslashes are used in search patterns set bs=indent,eol,start # Allow backspacing over everything in insert mode set tabstop=4 # number of spaces a tab counts for set shiftwidth=4 # spaces for autoindents #set expandtab # turn a tabs into spaces set fileformat=unix # file mode is unix #set fileformats=unix,dos # only detect unix file format, displays that ^M with dos files # system settings set lazyredraw # no redraws in macros set confirm # get a dialog when :q, :w, or :wq fails set nobackup # no backup~ files. set viminfo='20,\"500 # remember copy registers after quitting in the .viminfo file -- 20 jump links, regs up to 500 lines' set hidden # remember undo after quitting set history=50 # keep 50 lines of command history set mouse=v # use mouse in visual mode (not normal,insert,command,help mode # color settings (if terminal/gui supports it) if &t_Co > 2 || has("gui_running") syntax on # enable colors set hlsearch # highlight search (very useful!) set incsearch # search incremently (search while typing) endif # paste mode toggle (needed when using autoindent/smartindent) map  :set paste map  :set nopaste imap  :set paste imap   set pastetoggle= # Use of the filetype plugins, auto completion and indentation support filetype plugin indent on # file type specific settings if has("autocmd") # For debugging #set verbose=9 # if bash is sh. let bash_is_sh=1 # change to directory of current file automatically autocmd BufEnter * lcd %:p:h # Put these in an autocmd group, so that we can delete them easily. augroup mysettings au FileType xslt,xml,css,html,xhtml,javascript,sh,config,c,cpp,docbook set smartindent shiftwidth=2 softtabstop=2 expandtab au FileType tex set wrap shiftwidth=2 softtabstop=2 expandtab # Confirm to PEP8 au FileType python set tabstop=4 softtabstop=4 expandtab shiftwidth=4 cinwords=if,elif,else,for,while,try,except,finally,def,class augroup END augroup perl # reset (disable previous 'augroup perl' settings) au! au BufReadPre,BufNewFile \ *.pl,*.pm \ set formatoptions=croq smartindent shiftwidth=2 softtabstop=2 cindent cinkeys='0{,0},!^F,o,O,e' " tags=./tags,tags,~/devel/tags,~/devel/C # formatoption: # t - wrap text using textwidth # c - wrap comments using textwidth (and auto insert comment leader) # r - auto insert comment leader when pressing  in insert mode # o - auto insert comment leader when pressing 'o' or 'O'. # q - allow formatting of comments with "gq" # a - auto formatting for paragraphs # n - auto wrap numbered lists # augroup END # Always jump to the last known cursor position. # Don't do it when the position is invalid or when inside # an event handler (happens when dropping a file on gvim). autocmd BufReadPost * \ if line("'\"") > 0 && line("'\"") < = line("$") | \ exe "normal g`\"" | \ endif endif # has("autocmd") 

As configurações podem ser armazenadas em ~/.vimrc , ou em todo o sistema em /etc/vimrc.local e, em seguida, pela leitura do arquivo /etc/vimrc usando:

 source /etc/vimrc.local 

(você terá que replace o caractere # comment por " para que funcione no VIM, eu queria dar um realce de syntax apropriado aqui).

Os comandos que listei aqui são bem básicos, e os principais que uso até agora. Eles já me fazem muito mais produtivo, sem ter que conhecer todas as coisas extravagantes.

O mecanismo Control + R é muito útil 🙂 No modo de inserção ou no modo de comando (isto é, na linha : ao digitar comandos), continue com um registro numerado ou nomeado:

  • az os registradores nomeados
  • " o registro não nomeado, contendo o texto da última exclusão ou
  • % o nome do arquivo atual
  • # o nome do arquivo alternativo
  • * o conteúdo da área de transferência (X11: seleção principal)
  • + o conteúdo da área de transferência
  • / o último padrão de pesquisa
  • : a última linha de comando
  • . o último texto inserido
  • - o último pequeno (menos de uma linha) delete
  • = 5 * 5 insira 25 no texto (mini-calculadora)

Veja :help i_CTRL-R e :help c_CTRL-R para mais detalhes, e procure por mais coisas do CTRL-R.

Plugins Vim

Há muitas boas respostas aqui, e uma incrível sobre o zen do vi. Uma coisa que não vejo mencionada é que o vim é extremamente extensível via plugins. Existem scripts e plugins para fazer todo tipo de coisas malucas que o autor original nunca considerou. Aqui estão alguns exemplos de plugins vim incrivelmente úteis:

rails.vim

Rails.vim é um plugin escrito pelo tpope. É uma ferramenta incrível para pessoas que estão desenvolvendo rails. Ele faz coisas sensíveis ao contexto mágico que permitem que você pule facilmente de um método em um controlador para a visão associada, para um modelo e para testes de unidade para esse modelo. Ele salvou dezenas, se não centenas de horas, como um desenvolvedor de rails.

gist.vim

Este plugin permite que você selecione uma região de texto no modo visual e digite um comando rápido para publicá-lo em gist.github.com . Isso permite um fácil access ao pastebin, que é incrivelmente útil se você estiver colaborando com alguém por IRC ou IM.

space.vim

Este plugin fornece funcionalidade especial para a barra de espaço. Ele transforma a barra de espaço em algo análogo ao período, mas em vez de repetir ações, repete os movimentos. Isso pode ser muito útil para se mover rapidamente por um arquivo de uma maneira que você define na hora.

surround.vim

Este plugin permite que você trabalhe com texto delimitado de alguma forma. Dá-lhe objects que denotam coisas dentro de parênteses, coisas dentro de citações, etc. Pode vir a calhar para manipular texto delimitado.

supertab.vim

Este script traz a funcionalidade de conclusão de guias sofisticadas para o vim. O material de autocomplete já está lá no núcleo do vim, mas isso o leva a uma guia rápida, em vez de vários atalhos diferentes. Muito útil e incrivelmente divertido de usar. Embora não seja o intellisense do VS, é um ótimo passo e traz uma grande quantidade de funcionalidades que você gostaria de esperar de uma ferramenta de conclusão de guias.

syntastic.vim

Esta ferramenta traz comandos externos de verificação de syntax para o vim. Eu não usei isso pessoalmente, mas eu ouvi ótimas coisas sobre isso e o conceito é difícil de superar. Verificar a syntax sem ter que fazer isso manualmente é uma grande economia de tempo e pode ajudá-lo a capturar erros sintáticos à medida que você os apresenta, em vez de quando você finalmente para para testar.

fugitive.vim

Acesso direto ao git de dentro do vim. Novamente, eu não usei este plugin, mas posso ver o utilitário. Infelizmente eu estou em uma cultura onde o svn é considerado “novo”, então eu provavelmente não verei o git no trabalho por um bom tempo.

nerdtree.vim

Um navegador de tree para o vim. Eu comecei a usar isso recentemente e é muito útil. Ele permite que você coloque uma treeview em uma divisão vertical e abra arquivos facilmente. Isso é ótimo para um projeto com muitos arquivos de origem que você costuma alternar entre eles.

FuzzyFinderTextmate.vim

Este é um plugin não mantido, mas ainda incrivelmente útil. Ele fornece a capacidade de abrir arquivos usando uma syntax descritiva “difusa”. Isso significa que, em uma tree esparsa de arquivos, você precisa digitar apenas caracteres suficientes para desambiguar os arquivos dos quais está interessado no resto do arquivo.

Conclusão

Existem muitas ferramentas incríveis disponíveis para o vim. Tenho certeza de que apenas arranhei a superfície aqui e vale a pena pesquisar as ferramentas aplicáveis ​​ao seu domínio. A combinação do poderoso conjunto de ferramentas do vi tradicional, as melhorias do vim nele e os plugins que estendem ainda mais o vim, é uma das maneiras mais poderosas de editar o texto já concebido. O Vim é tão poderoso quanto o emacs, o eclipse, o visual studio e o textmate.

obrigado

Obrigado a duwanis por suas configurações do vim, das quais aprendi muito e peguei emprestado a maioria dos plugins listados aqui.

. Repeat last text-changing command

I save a lot of time with this one.

Visual mode was mentioned previously, but block visual mode has saved me a lot of time when editing fixed size columns in text file. (accessed with Ctrl-V).

gi

Go to last edited location (very useful if you performed some searching and than want go back to edit)

^P and ^N

Complete previous (^P) or next (^N) text.

^O and ^I

Go to previous ( ^O"O" for old) location or to the next ( ^I"I" just near to "O" ). When you perform searches, edit files etc., you can navigate through these “jumps” forward and back.

I recently (got) discovered this site: http://vimcasts.org/

It’s pretty new and really really good. The guy who is running the site switched from textmate to vim and hosts very good and concise casts on specific vim topics. Confira!

CTRL + A increments the number you are standing on.

All in Normal mode:

f to move to the next instance of a particular character on the current line, and ; to repeat.

F to move to the previous instance of a particular character on the current line and ; to repeat.

If used intelligently, the above two can make you killer-quick moving around in a line.

* on a word to search for the next instance.

# on a word to search for the previous instance.

Sessão

uma. save session

:mks sessionname

b. force save session

:mks! sessionname

c. load session

gvim or vim -S sessionname


Adding and Subtracting

uma. Adding and Subtracting

CTRL-A ;Add [count] to the number or alphabetic character at or after the cursor. {not in Vi

CTRL-X ;Subtract [count] from the number or alphabetic character at or after the cursor. {not in Vi}

b. Window key unmapping

In window, Ctrl-A already mapped for whole file selection you need to unmap in rc file. mark mswin.vim CTRL-A mapping part as comment or add your rc file with unmap

c. With Macro

The CTRL-A command is very useful in a macro. Example: Use the following steps to make a numbered list.

  1. Create the first list entry, make sure it starts with a number.
  2. qa – start recording into buffer ‘a’
  3. Y – yank the entry
  4. p – put a copy of the entry below the first one
  5. CTRL-A – increment the number
  6. q – stop recording
  7. @a – repeat the yank, put and increment times

Last week at work our project inherited a lot of Python code from another project. Unfortunately the code did not fit into our existing architecture – it was all done with global variables and functions, which would not work in a multi-threaded environment.

We had ~80 files that needed to be reworked to be object oriented – all the functions moved into classs, parameters changed, import statements added, etc. We had a list of about 20 types of fix that needed to be done to each file. I would estimate that doing it by hand one person could do maybe 2-4 per day.

So I did the first one by hand and then wrote a vim script to automate the changes. Most of it was a list of vim commands eg

 " delete an un-needed function " g/someFunction(/ d " add wibble parameter to function foo " %s/foo(/foo( wibble,/ " convert all function calls bar(thing) into method calls thing.bar() " g/bar(/ normal nmaf(ldi(`aPa. 

The last one deserves a bit of explanation:

 g/bar(/ executes the following command on every line that contains "bar(" normal execute the following text as if it was typed in in normal mode n goes to the next match of "bar(" (since the :g command leaves the cursor position at the start of the line) ma saves the cursor position in mark a f( moves forward to the next opening bracket l moves right one character, so the cursor is now inside the brackets di( delete all the text inside the brackets `a go back to the position saved as mark a (ie the first character of "bar") P paste the deleted text before the current cursor position a. go into insert mode and add a "." 

For a couple of more complex transformations such as generating all the import statements I embedded some python into the vim script.

After a few hours of working on it I had a script that will do at least 95% of the conversion. I just open a file in vim then run :source fixit.vim and the file is transformed in a blink of the eye.

We still have the work of changing the remaining 5% that was not worth automating and of testing the results, but by spending a day writing this script I estimate we have saved weeks of work.

Of course it would have been possible to automate this with a scripting language like Python or Ruby, but it would have taken far longer to write and would be less flexible – the last example would have been difficult since regex alone would not be able to handle nested brackets, eg to convert bar(foo(xxx)) to foo(xxx).bar() . Vim was perfect for the task.

Use the builtin file explorer! The command is :Explore and it allows you to navigate through your source code very very fast. I have these mapping in my .vimrc :

 map   :Explore map   :sp +Explore 

The explorer allows you to make file modifications, too. I’ll post some of my favorite keys, pressing will give you the full list:

  • : The most useful: Change to upper directory ( cd .. )
  • mf : Mark a file
  • D : Delete marked files or the file the cursor is on, if nothing ismarked.
  • R : Rename the file the cursor is on.
  • d : Create a new directory in the current directory
  • % : Create a new file in the current directory

I am a member of the American Cryptogram Association. The bimonthly magazine includes over 100 cryptograms of various sorts. Roughly 15 of these are “cryptarithms” – various types of arithmetic problems with letters substituted for the digits. Two or three of these are sudokus, except with letters instead of numbers. When the grid is completed, the nine distinct letters will spell out a word or words, on some line, diagonal, spiral, etc., somewhere in the grid.

Rather than working with pencil, or typing the problems in by hand, I download the problems from the members area of their website.

When working with these sudokus, I use vi, simply because I’m using facilities that vi has that few other editors have. Mostly in converting the lettered grid into a numbered grid, because I find it easier to solve, and then the completed numbered grid back into the lettered grid to find the solution word or words.

The problem is formatted as nine groups of nine letters, with - s representing the blanks, written in two lines. The first step is to format these into nine lines of nine characters each. There’s nothing special about this, just inserting eight linebreaks in the appropriate places.

The result will look like this:

 TO-----C -E-----S- --AT--NL ---NASO-- ---ET--- --SPCL--- ET--OS-- -A-----P- S-----CT 

So, first step in converting this into numbers is to make a list of the distinct letters. First, I make a copy of the block. I position the cursor at the top of the block, then type :y}}p . : puts me in command mode, y yanks the next movement command. Since } is a move to the end of the next paragraph, y} yanks the paragraph. } then moves the cursor to the end of the paragraph, and p pastes what we had yanked just after the cursor. So y}}p creates a copy of the next paragraph, and ends up with the cursor between the two copies.

Next, I to turn one of those copies into a list of distinct letters. That command is a bit more complex:

 :!}tr -cd AZ | sed 's/\(.\)/\1\n/g' | sort -u | tr -d '\n' 

: again puts me in command mode. ! indicates that the content of the next yank should be piped through a command line. } yanks the next paragraph, and the command line then uses the tr command to strip out everything except for upper-case letters, the sed command to print each letter on a single line, and the sort command to sort those lines, removing duplicates, and then tr strips out the newlines, leaving the nine distinct letters in a single line, replacing the nine lines that had made up the paragraph originally. In this case, the letters are: ACELNOPST .

Next step is to make another copy of the grid. And then to use the letters I’ve just identified to replace each of those letters with a digit from 1 to 9. That’s simple: :!}tr ACELNOPST 0-9 . O resultado é:

 8-5-----1 -2-----7- --08--4-3 ---4075-- ---2-8--- --7613--- 2-8--57-- -0-----6- 7-----1-8 

This can then be solved in the usual way, or entered into any sudoku solver you might prefer. The completed solution can then be converted back into letters with :!}tr 1-9 ACELNOPST .

There is power in vi that is matched by very few others. The biggest problem is that only a very few of the vi tutorial books, websites, help-files, etc., do more than barely touch the surface of what is possible.

Bulk text manipulations!

Either through macros:

  • Start with recording: qq
  • Do stuff
  • Stop recording: q
  • Repeat: @q (the first time), @@ after that.
  • Repeat 20 times: 20@@

Or through regular expressions:

  • Replace stuff: :%s/[fo]+/bar/g

(But be warned: if you do the latter, you’ll have 2 problems :).)

I recently discovered q: . It opens the “command window” and shows your most recent ex-mode (command-mode) commands. You can move as usual within the window, and pressing executes the command. You can edit, etc. too. Priceless when you’re messing around with some complex command or regex and you don’t want to retype the whole thing, or if the complex thing you want to do was 3 commands back. It’s almost like bash’s set -o vi , but for vim itself (heh!).

See :help q: for more interesting bits for going back and forth.

I just discovered Vim’s omnicompletion the other day, and while I’ll admit I’m a bit hazy on what does which, I’ve had surprisingly good results just mashing either Ctrl + x Ctrl + u or Ctrl + n / Ctrl + p in insert mode. It’s not quite IntelliSense , but I’m still learning it.

Try it out! :help ins-completion

These are not shortcuts, but they are related:

  1. Make capslock an additional ESC (or Ctrl)
  2. map leader to “,” (comma), with this command: let mapleader=”,”

They boost my productivity.

Another useful vi “shortcut” I frequently use is ‘xp’. This will swap the character under the cursor with the next character.

+ W, V to split the screen vertically
+ W, W to shift between the windows

!python % [args] to run the script I am editing in this window

ZF in visual mode to fold arbitrary lines

Visual Mode

As several other people have said, visual mode is the answer to your copy/cut & paste problem. Vim gives you ‘v’, ‘V’, and Cv. Lower case ‘v’ in vim is essentially the same as the shift key in notepad. The nice thing is that you don’t have to hold it down. You can use any movement technique to navigate efficiently to the starting (or ending) point of your selection. Then hit ‘v’, and use efficient movement techniques again to navigate to the other end of your selection. Then ‘d’ or ‘y’ allows you to cut or copy that selection.

The advantage vim’s visual mode has over Jim Dennis’s description of cut/copy/paste in vi is that you don’t have to get the location exactly right. Sometimes it’s more efficient to use a quick movement to get to the general vicinity of where you want to go and then refine that with other movements than to think up a more complex single movement command that gets you exactly where you want to go.

The downside to using visual mode extensively in this manner is that it can become a crutch that you use all the time which prevents you from learning new vi(m) commands that might allow you to do things more efficiently. However, if you are very proactive about learning new aspects of vi(m), then this probably won’t affect you much.

I’ll also re-emphasize that the visual line and visual block modes give you variations on this same theme that can be very powerful…especially the visual block mode.

On Efficient Use of the Keyboard

I also disagree with your assertion that alternating hands is the fastest way to use the keyboard. It has an element of truth in it. Speaking very generally, repeated use of the same thing is slow. This most significant example of this principle is that consecutive keystrokes typed with the same finger are very slow. Your assertion probably stems from the natural tendency to use the s/finger/hand/ transformation on this pattern. To some extent it’s correct, but at the extremely high end of the efficiency spectrum it’s incorrect.

Just ask any pianist. Ask them whether it’s faster to play a succession of a few notes alternating hands or using consecutive fingers of a single hand in sequence. The fastest way to type 4 keystrokes is not to alternate hands, but to type them with 4 fingers of the same hand in either ascending or descending order (call this a “run”). This should be self-evident once you’ve considered this possibility.

The more difficult problem is optimizing for this. It’s pretty easy to optimize for absolute distance on the keyboard. Vim does that. It’s much harder to optimize at the “run” level, but vi(m) with it’s modal editing gives you a better chance at being able to do it than any non-modal approach (ahem, emacs) ever could.

On Emacs

Lest the emacs zealots completely disregard my whole post on account of that last parenthetical comment, I feel I must describe the root of the difference between the emacs and vim religions. I’ve never spoken up in the editor wars and I probably won’t do it again, but I’ve never heard anyone describe the differences this way, so here it goes. The difference is the following tradeoff:

Vim gives you unmatched raw text editing efficiency Emacs gives you unmatched ability to customize and program the editor

The blind vim zealots will claim that vim has a scripting language. But it’s an obscure, ad-hoc language that was designed to serve the editor. Emacs has Lisp! Enough said. If you don’t appreciate the significance of those last two sentences or have a desire to learn enough about functional programming and Lisp to develop that appreciation, then you should use vim.

The emacs zealots will claim that emacs has viper mode, and so it is a superset of vim. But viper mode isn’t standard. My understanding is that viper mode is not used by the majority of emacs users. Since it’s not the default, most emacs users probably don’t develop a true appreciation for the benefits of the modal paradigm.

In my opinion these differences are orthogonal. I believe the benefits of vim and emacs as I have stated them are both valid. This means that the ultimate editor doesn’t exist yet. It’s probably true that emacs would be the easiest platform on which to base the ultimate editor. But modal editing is not entrenched in the emacs mindset. The emacs community could move that way in the future, but that doesn’t seem very likely.

So if you want raw editing efficiency, use vim. If you want the ultimate environment for scripting and programming your editor use emacs. If you want some of both with an emphasis on programmability, use emacs with viper mode (or program your own mode). If you want the best of both worlds, you’re out of luck for now.

Spend 30 mins doing the vim tutorial (run vimtutor instead of vim in terminal). You will learn the basic movements, and some keystrokes, this will make you at least as productive with vim as with the text editor you used before. After that, well, read Jim Dennis’ answer again 🙂

What is the way you use Vim that makes you more productive than with a contemporary editor?

Being able to execute complex, repetitive edits with very few keystrokes (often using macros ). Take a look at VimGolf to witness the power of Vim!

After over ten years of almost daily usage, it’s hard to imagine using any other editor.

Use \c anywhere in a search to ignore case (overriding your ignorecase or smartcase settings). Eg /\cfoo or /foo\c will match foo , Foo , fOO , FOO , etc.

Use \C anywhere in a search to force case matching. Eg /\Cfoo or /foo\C will only match foo.

I was surprised to find no one mention the t movement. I frequently use it with parameter lists in the form of dt, or yt,

Odd nobody’s mentioned ctags. Download “exuberant ctags” and put it ahead of the crappy preinstalled version you already have in your search path. Cd to the root of whatever you’re working on; for example the Android kernel distribution. Type “ctags -R .” to build an index of source files anywhere beneath that dir in a file named “tags”. This contains all tags, nomatter the language nor where in the dir, in one file, so cross-language work is easy.

Then open vim in that folder and read :help ctags for some commands. A few I use often:

  • Put cursor on a method call and type CTRL-] to go to the method definition.

  • Type :ta name to go to the definition of name.

Automatic indentation:

gg (go to start of document)
= (indent time!)
shift-g (go to end of document)

You’ll need ‘filetype plugin indent on’ in your .vimrc file, and probably appropriate ‘shiftwidth’ and ‘expandtab’ settings.

You asked about productive shortcuts, but I think your real question is: Is vim worth it? The answer to this stackoverflow question is -> “Yes”

You must have noticed two things. Vim is powerful, and vim is hard to learn. Much of it’s power lies in it’s expandability and endless combination of commands. Don’t feel overwhelmed. Go slow. One command, one plugin at a time. Don’t overdo it.

All that investment you put into vim will pay back a thousand fold. You’re going to be inside a text editor for many, many hours before you die. Vim will be your companion.

Multiple buffers, and in particular fast jumping between them to compare two files with :bp and :bn (properly remapped to a single Shift + p or Shift + n )

vimdiff mode (splits in two vertical buffers, with colors to show the differences)

Area-copy with Ctrl + v

And finally, tab completion of identifiers (search for “mosh_tab_or_complete”). That’s a life changer.

Agreed with the top poster – the :r! command is very useful.

Most often I use it to “paste” things:

 :r!cat **Ctrl-V to paste from the OS clipboard** ^D 

This way I don’t have to fiddle with :set paste .