Aliasing de um comando no vim

151

Vim é o meu editor de texto preferido quando programa e, portanto, sempre encontro um problema particularmente irritante.

Freqüentemente, quando preciso salvar o buffer rapidamente e continuar com outras tarefas diversas, faço as tarefas típicas

:w

No entanto, eu - o que parece ser mais de 50% do tempo - sempre consigo capitalizar isso :w. Naturalmente, o vim grita comigo porque Wé um comando inválido

E492: Not an editor command: W

Minha pergunta é como alguém pode usar o comando colon-command no vim . Particularmente, você poderia exemplificar como criar um alias Wpara w.

Estou ciente do processo para mapear chaves para determinados comandos . Infelizmente, não é isso que estou procurando.

Sean
fonte
1
possível duplicata de Posso (re) mapear comandos no vim?
23612 Chris Morgan
1
Para evitar, :Wvocê pode mapear uma chave para realizar o salvamento. Se você está acostumado a algum programa que salva com Ctrl-s, existem esses mapeamentos de $ VIM / mswin.vim:" Use CTRL-S for saving, also in Insert mode noremap <C-S> :update<CR> vnoremap <C-S> <C-C>:update<CR> inoremap <C-S> <C-O>:update<CR>
mMontu
Pergunta semelhante sobre a troca do Vi Stack: vi.stackexchange.com/q/2665/7244
Flimm

Respostas:

127

Para deixar a conclusão intocada, tente usar

cnoreabbrev W w

, ele será substituído Wna linha de comando por w, mas somente se não for seguido nem precedido pelo caractere da palavra, :W<CR>será substituído por :w<CR>, mas :Writenão será. (Observe que isso afeta quaisquer comandos que correspondam, incluindo aqueles que você não pode esperar, por exemplo, o comando :saveas W Zserá substituído por :saveas w Z, portanto, tenha cuidado com isso.)

Atualizar

Aqui está como eu escreveria agora :

cnoreabbrev <expr> W ((getcmdtype() is# ':' && getcmdline() is# 'W')?('w'):('W'))

Como uma função:

fun! SetupCommandAlias(from, to)
  exec 'cnoreabbrev <expr> '.a:from
        \ .' ((getcmdtype() is# ":" && getcmdline() is# "'.a:from.'")'
        \ .'? ("'.a:to.'") : ("'.a:from.'"))'
endfun
call SetupCommandAlias("W","w")

Isso verifica se o tipo de comando é :e o comando é W, portanto, é mais seguro do que apenas cnoreabbrev W w.

ZyX
fonte
2
Esta resposta é a mais segura e confiável para mim.
Sean
2
Se você usar a solução recomendada, esteja ciente de que os dois comandos abaixo funcionarão como o mais baixo, o que pode apresentar um resultado inesperado, dependendo do conteúdo real do buffer e das configurações do VIM::%s/W/foo/g<CR> :%s/w/foo/g<CR>
cprn
2
Na verdade, isso significa que W será substituído em qualquer lugar da barra de comandos, incluindo, por exemplo, em pesquisas, para que s / W foo / bar / g seja transformado em s / w foo / bar / g. isso pode ficar irritante muito rápido. veja minha resposta para uma solução abrangente.
Airstrike
4
Absolutamente; essa é uma ideia horrível . Você nunca , nunca , jamais fará isso.
23612 Chris Morgan
4
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
kev
97

Com pesquisas complementares, descobri que alguém fez quase a mesma pergunta que eu.

:command <AliasName> <string of command to be aliased>

fará o truque.

Esteja ciente de que, como Richo aponta, o comando do usuário deve começar com uma letra maiúscula.

Sean
fonte
5
Usando: command é uma boa solução. : cnoreabbrev não entende cmd1 | cmd2,: o comando entende.
Pavel Strakhov
1
Uma maneira menos confusa de escrever isso é::command AliasName string of command to be aliased
Alec Jacobson
8
Isso não vai lidar com / para a frente quaisquer commandargumentos, como -nargs, -completeetc
blueyed
Que tal :Q!ou :W!?
31414 Jack
5
Apenas para ser muito literal: coloque :command W wno .vimrcarquivo.
Isomorphismes
20

Acho que o mapeamento da ;chave :seria uma solução melhor e o tornaria mais produtivo para digitar outros comandos.

nnoremap ; :
vnoremap ; :
fent
fonte
Esta é a melhor dica para o vim. Agora estou tão acostumado a isso que toda vez que encontro o comportamento normal, preciso de algumas tentativas para recuperar minha mente.
ataque aéreo
Esta não é uma resposta para a pergunta.
Flimm
5
@Flimm Não, mas faz com que o problema do OP desapareça.
Duncan X Simpson
1
Ao usar tou f, geralmente é possível usar ;para ir para a próxima ocorrência. É possível mapear com segurança o contrário, mesmo que você tenha mapeado ponto-e-vírgula para dois pontos. Não haverá um loop de alias. nnoremap : ;
Luc
9

A melhor solução envolve escrever uma função personalizada para lidar com abreviações que ocorrem apenas no início da barra de comandos.

Para isso, adicione o seguinte arquivo vimrc ou qualquer outro lugar.

" cabs - less stupidity                                                      {{{
fu! Single_quote(str)
  return "'" . substitute(copy(a:str), "'", "''", 'g') . "'"
endfu
fu! Cabbrev(key, value)
  exe printf('cabbrev <expr> %s (getcmdtype() == ":" && getcmdpos() <= %d) ? %s : %s',
    \ a:key, 1+len(a:key), Single_quote(a:value), Single_quote(a:key))
endfu
"}}}

 

" use this custom function for cabbrevations. This makes sure that they only
" apply in the beginning of a command. Else we might end up with stuff like
"   :%s/\vfoo/\v/\vbar/
" if we happen to move backwards in the pattern.

" For example:
call Cabbrev('W', 'w')

Algumas abreviações úteis do material de origem onde encontrei este material:

call Cabbrev('/',   '/\v')
call Cabbrev('?',   '?\v')

call Cabbrev('s/',  's/\v')
call Cabbrev('%s/', '%s/\v')

call Cabbrev('s#',  's#\v')
call Cabbrev('%s#', '%s#\v')

call Cabbrev('s@',  's@\v')
call Cabbrev('%s@', '%s@\v')

call Cabbrev('s!',  's!\v')
call Cabbrev('%s!', '%s!\v')

call Cabbrev('s%',  's%\v')
call Cabbrev('%s%', '%s%\v')

call Cabbrev("'<,'>s/", "'<,'>s/\v")
call Cabbrev("'<,'>s#", "'<,'>s#\v")
call Cabbrev("'<,'>s@", "'<,'>s@\v")
call Cabbrev("'<,'>s!", "'<,'>s!\v")
ataque aéreo
fonte
1
Há uma função interna string()que faz a mesma coisa que a sua Single_quote().
ZyX
6

Talvez você queira mapear uma de suas teclas de função (F1..F12) para: w? Em seguida, coloque isso no seu .vimrc:

noremap  <f1> :w<return>
inoremap <f1> <c-o>:w<return>

(ctrl-o no modo de inserção muda temporariamente para o modo normal).

Benoit
fonte
6

Suponha que você queira adicionar um alias para o comando tabnew no gvim. você pode simplesmente digitar o seguinte comando no arquivo .vimrc (se não estiver na pasta inicial, crie um)

cabbrev t tabnew
Sandip
fonte
1
Isso fará com que um comando como :saveas t examplepara ser substituído com:saveas tabnew example
Flimm
5

O mais seguro e fácil é um plug-in como o cmdalias.vim ou meu vim-alias da atualização recente que leva em consideração

  • espaços em branco ou modificadores anteriores, como :sil(ent)(!)ou :redi(r),
  • modificadores de faixa, como '<,'>para a seleção visual atual,
  • escapar caracteres especiais como aspas e
  • verifique se o alias escolhido é uma abreviação de linha de comando válida.
Enno
fonte