Aliasing un comando en vim

151

Vim es mi editor de texto preferido cuando programo y, por lo tanto, siempre me encuentro con un problema particularmente molesto.

Con frecuencia, cuando necesito guardar rápidamente el búfer y continuar con alguna otra tarea miscelánea, hago lo típico

:w

Sin embargo, yo, que parece ser más del 50% del tiempo, siempre logro capitalizar eso :w. Naturalmente, vim me grita porque Wes un comando no válido

E492: Not an editor command: W

Mi pregunta es cómo puede uno alias dos comandos en vim . En particular, se puede ejemplificar cómo alias Wa w.

Soy consciente del proceso para asignar teclas a ciertos comandos . Desafortunadamente, eso no es lo que estoy buscando.

Sean
fuente
1
posible duplicado de ¿Puedo (re) asignar comandos en vim?
Chris Morgan
1
Para evitar :W, podría asignar una clave para realizar el guardado. Si está acostumbrado a algún programa que guarda con Ctrl-s, existen estas asignaciones 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
Pregunta similar sobre el intercambio de Vi Stack: vi.stackexchange.com/q/2665/7244
Flimm

Respuestas:

127

Para dejar la finalización intacta, intente usar

cnoreabbrev W w

, se reemplazará Wen la línea de comando con w, pero solo si no está seguido ni precedido por un carácter de palabra, :W<CR>se reemplazará con :w<CR>, pero :Writeno lo hará. (Tenga en cuenta que esto afecta a cualquier comando que coincida, incluidos los que no espere, por ejemplo, el comando :saveas W Zserá reemplazado por :saveas w Z, así que tenga cuidado con esto).

Actualizar

Así es como lo escribiría ahora :

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

Como una función:

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

Esto comprueba que el tipo de comando es :y el comando es W, por lo que es más seguro que solo cnoreabbrev W w.

ZyX
fuente
2
Esta respuesta es la más segura y confiable para mí.
Sean
2
Si utiliza la solución recomendada, tenga en cuenta que los dos comandos siguientes funcionarán como el inferior, lo que puede presentar un resultado inesperado dependiendo del contenido real del búfer y la configuración de VIM::%s/W/foo/g<CR> :%s/w/foo/g<CR>
cprn
2
En realidad, esto significaría que W se reemplazará en cualquier lugar de la barra de comandos, incluso, por ejemplo, en las búsquedas, por lo que s / W foo / bar / g se convertiría en s / w foo / bar / g. Esto puede ser molesto muy rápido. Vea mi respuesta para una solución integral.
ataque aéreo
44
Absolutamente; Esta es una idea horrible . Usted debe Nunca , nunca , nunca hacer esto.
Chris Morgan
44
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
kev
97

Con la búsqueda complementaria, descubrí que alguien hizo casi la misma pregunta que yo.

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

Hará el truco.

Tenga en cuenta que, como señala Richo , el comando del usuario debe comenzar con una letra mayúscula.

Sean
fuente
55
Usar: el comando es una buena solución. : cnoreabbrev no entiende cmd1 | cmd2,: el comando sí.
Pavel Strakhov
1
Una forma menos confusa de escribir esto es:command AliasName string of command to be aliased
Alec Jacobson
8
Esto no manejará / reenviará ningún commandargumento, como -nargs, -completeetc.
azulado
¿Qué hay de :Q!o :W!?
Jack
55
Solo para ser muy literal: poner :command W wen el .vimrcarchivo.
isomorphismes
20

Creo que asignar la ;clave :sería una mejor solución y te haría más productivo para escribir otros comandos.

nnoremap ; :
vnoremap ; :
fent
fuente
Este es el mejor consejo para vim. Estoy tan acostumbrado ahora que cada vez que me encuentro con el comportamiento normal, me toma algunos intentos recuperar mi mente.
ataque aéreo
Esta no es una respuesta a la pregunta.
Flimm
55
@Flimm No, pero hace que el problema de OP desaparezca.
Duncan X Simpson
1
Cuando se usa to f, generalmente se puede usar ;para ir a la siguiente aparición. Uno puede asignarlo de manera segura de la otra manera, incluso si asignó punto y coma a dos puntos. No habrá un bucle de alias. nnoremap : ;
Luc
9

La mejor solución consiste en escribir una función personalizada para manejar abreviaturas que solo tienen lugar al comienzo de la barra de comandos.

Para esto, agregue lo siguiente a su archivo vimrc o en cualquier otro 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')

Algunas abreviaturas útiles del material fuente donde encontré estas cosas:

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
fuente
1
Hay una función incorporada string()que hace lo mismo que la tuya Single_quote().
ZyX
6

Tal vez le gustaría asignar una de sus teclas de función (F1..F12) a: w? Luego pon esto en tu .vimrc:

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

(Ctrl-o en modo de inserción cambia temporalmente al modo normal).

Benoit
fuente
6

Suponga que desea agregar un alias para el comando tabnew en gvim. simplemente puede escribir el siguiente comando en su archivo .vimrc (si no está en la carpeta de inicio, cree uno)

cabbrev t tabnew
Sandip
fuente
1
Esto hará que un comando :saveas t examplesea ​​reemplazado por:saveas tabnew example
Flimm
5

El complemento más seguro y sencillo es cmdalias.vim o mi reciente actualización vim-alias que tiene en cuenta

  • espacios en blanco o modificadores anteriores como :sil(ent)(!)o :redi(r),
  • modificadores de rango como '<,'>para la selección visual actual,
  • escapar de caracteres especiales como citas y
  • compruebe si el alias elegido es una abreviatura de línea de comando válida.
Enno
fuente