Aliaser une commande dans vim

151

Vim est mon éditeur de texte préféré lorsque je programme, et donc je rencontre toujours un problème particulièrement ennuyeux.

Souvent, lorsque je dois rapidement enregistrer le tampon et passer à une autre tâche diverse, je fais le typique

:w

Cependant, je - ce qui semble être plus de 50% du temps - parviens toujours à capitaliser cela :w. Naturellement, vim me crie dessus parce que Wc'est une commande invalide

E492: Not an editor command: W

Ma question est de savoir comment un alias deux-points-commandes dans vim . En particulier, pourriez-vous illustrer comment créer un alias Wvers w.

Je connais le processus de mappage des clés vers certaines commandes . Malheureusement, ce n'est pas ce que je recherche.

Sean
la source
1
duplication possible de Puis-je (re) mapper des commandes dans vim?
Chris Morgan
1
Pour éviter, :Wvous pourriez une carte une clé pour effectuer la sauvegarde. Si vous êtes habitué à un programme qui enregistre avec Ctrl-s, il y a ces mappages 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
Question similaire sur l'échange Vi Stack: vi.stackexchange.com/q/2665/7244
Flimm

Réponses:

128

Pour ne pas modifier l’achèvement, essayez d’utiliser

cnoreabbrev W w

, il remplacera Wen ligne de commande par w, mais seulement s'il n'est ni suivi ni précédé d'un caractère mot, il :W<CR>sera donc remplacé par :w<CR>, mais :Writene le fera pas. (Notez que cela affecte toutes les commandes qui correspondent, y compris celles auxquelles vous ne vous attendez peut-être pas, par exemple, la commande :saveas W Zsera remplacée par :saveas w Z, alors soyez prudent avec cela.)

Mettre à jour

Voici comment je l'écrirais maintenant :

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

En tant que fonction:

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

Cela vérifie que le type de commande est :et la commande est W, donc c'est plus sûr que juste cnoreabbrev W w.

ZyX
la source
2
Cette réponse est la plus sûre et la plus fiable pour moi.
Sean
2
Si vous utilisez la solution recommandée, veuillez noter que les deux commandes ci-dessous fonctionneront comme la commande inférieure, ce qui peut présenter un résultat inattendu en fonction du contenu réel de la mémoire tampon et des paramètres VIM::%s/W/foo/g<CR> :%s/w/foo/g<CR>
cprn
2
En fait, cela signifierait que W sera remplacé n'importe où dans la barre de commandes, y compris, par exemple, dans les recherches, donc s / W foo / bar / g serait transformé en s / w foo / bar / g. cela peut devenir très vite ennuyeux. voir ma réponse pour une solution complète.
frappe aérienne
4
Absolument; c'est une idée horrible . Vous ne devriez jamais , jamais , jamais faire ça.
Chris Morgan
4
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
kev
97

Avec une recherche supplémentaire, j'ai constaté que quelqu'un avait posé à peu près la même question que moi.

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

fera l'affaire.

Veuillez noter que, comme noter souligne Richo , la commande utilisateur doit commencer par une majuscule.

Sean
la source
5
Utiliser: la commande est une bonne solution. : cnoreabbrev ne comprend pas cmd1 | cmd2,: command le fait.
Pavel Strakhov le
1
Une façon moins déroutante d'écrire ceci est,:command AliasName string of command to be aliased
Alec Jacobson
8
Cela ne traitera / ne transmettra aucun commandargument, comme -nargs, -completeetc.
blueyed
Et :Q!ou :W!?
Jack
5
Juste pour être très littéral: mettez :command W wdans le .vimrcfichier.
isomorphismes
20

Je trouve que mapper la ;clé :serait une meilleure solution et vous rendrait plus productif pour taper d'autres commandes.

nnoremap ; :
vnoremap ; :
fent
la source
C'est la meilleure astuce pour vim. J'y suis tellement habitué maintenant qu'à chaque fois que je rencontre le comportement normal, il m'en faut quelques-uns pour essayer de me recycler l'esprit.
frappe aérienne du
Ce n'est pas une réponse à la question.
Flimm
5
@Flimm Non, mais cela fait disparaître le problème d'OP.
Duncan X Simpson
1
Lorsque vous utilisez tou f, vous pouvez généralement utiliser ;pour passer à l'occurrence suivante. On peut mapper en toute sécurité dans l'autre sens, même si vous avez mappé un point-virgule sur deux points. Il n'y aura pas de boucle d'alias. nnoremap : ;
Luc
9

La meilleure solution consiste à écrire une fonction personnalisée pour gérer les abréviations qui n'ont lieu qu'au début de la barre de commandes.

Pour cela, ajoutez ce qui suit à votre fichier vimrc ou ailleurs.

" 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')

Quelques abréviations utiles du matériel source où j'ai trouvé ce truc:

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")
frappe aérienne
la source
1
Il existe une fonction intégrée string()qui fait la même chose que la vôtre Single_quote().
ZyX
6

Vous souhaitez peut-être mapper l'une de vos touches de fonction (F1..F12) sur: w? Ensuite, mettez ceci dans votre .vimrc:

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

(ctrl-o en mode insertion passe temporairement en mode normal).

Benoit
la source
6

Supposons que vous souhaitiez ajouter un alias pour la commande tabnew dans gvim. vous pouvez simplement taper la commande suivante dans votre fichier .vimrc (si ce n'est pas dans le dossier personnel, créez-en un)

cabbrev t tabnew
Sandip
la source
1
Cela entraînera :saveas t examplele remplacement d' une commande par:saveas tabnew example
Flimm
5

Le plus sûr et le plus simple est un plugin tel que cmdalias.vim ou ma récente mise à jour vim-alias de celui-ci qui prend en compte

  • les espaces ou les modificateurs précédents tels que :sil(ent)(!)ou :redi(r),
  • des modificateurs de plage tels que '<,'>pour la sélection visuelle actuelle,
  • échapper les caractères spéciaux tels que les guillemets et
  • vérifiez si l'alias choisi est une abréviation de ligne de commande valide.
Enno
la source