How to create an alias for a command in Vim?

VimAliasCommand

Vim Problem Overview


Vim is my preferred text editor when I program, and thus I always run into a particularly annoying issue.

Frequently, when I quickly need to save the buffer and continue on to some other miscellaneous task, I do the typical

:w

However, I always — what seems to be like more than 50% of the time — manage to capitalize that :w. Naturally, Vim yells at me because W is an invalid command:

E492: Not an editor command: W

My question is how can one alias colon-commands in Vim. Particularly, could you exemplify how to alias W to w.

I am aware of the process to map keys to certain commands, but that is not what I’m looking for.

Vim Solutions


Solution 1 - Vim

To leave completion untouched, try using

cnoreabbrev W w

It will replace W in command line with w, but only if it is neither followed nor preceded by word character, so :W<CR> will be replaced with :w<CR>, but :Write won’t. (Note that this affects any commands that match, including ones that you might not expect. For example, the command :saveas W Z will be replaced by :saveas w Z, so be careful with this.)

Update

Here is how I would write it now:

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

As a function:

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

This checks that the command type is : and the command is W, so it’s safer than just cnoreabbrev W w.

Solution 2 - Vim

With supplementary searching, I've found that someone asked nearly the same question as I.

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

will do the trick.

Please be aware that, as Richo points out, the user command must begin with a capital letter.

Solution 3 - Vim

I find that mapping the ; key to : would be a better solution, and would make you more productive for typing other commands.

nnoremap ; :
vnoremap ; :

Solution 4 - Vim

The best solution involves writing a custom function for handling abbreviations that only take place in the beginning of the command bar.

For this, add the following your vimrc file or anywhere else.

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

A few useful abbreviations from the source material where I found this stuff:

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

Solution 5 - Vim

Suppose you want to add alias for tabnew command in gvim. you can simply type the following command in your .vimrc file (if not in home folder than create one)

cabbrev t tabnew

Solution 6 - Vim

Maybe you would like to map one of your function keys (F1..F12) to :w ? Then put this into your .vimrc:

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

(ctrl-o in insert mode switches temporarily to normal mode).

Solution 7 - Vim

Safest and easiest is a plugin such as cmdalias.vim or my recent update vim-alias of it that take into account

  • preceding blanks or modifiers such as :sil(ent)(!) or :redi(r),

  • range modifiers such as '<,'> for the current visual selection,

  • escape special characters such as quotes, and

  • check if the chosen alias is a valid command line abbreviation.

Solution 8 - Vim

I think @ZyX's answer is great, but if you're using a newer version of neovim (0.5+), you might want to define the function using lua instead. Here's one way you could do it:

function _G.abbreviate_or_noop(input, output)
  local cmdtype = vim.fn.getcmdtype()
  local cmdline = vim.fn.getcmdline()

  if (cmdtype == ":" and cmdline == input) then 
    return output
  else
    return input
  end
end

function SetupCommandAlias(input, output)
  vim.api.nvim_command("cabbrev <expr> " .. input .. " " .. "v:lua.abbreviate_or_noop('" .. input .. "', '" .. output .. "')")
end

Then, you'd drop the call from call SetupCommandAlias("pg", "postgres://") and just use the function like this: SetupCommandAlias("pg", "postgres://").

n.b. If using it from a .vim file instead of a .lua file, you'd need to prefix the function call with lua, i.e. lua SetupCommandAlias("pg", "postgres://").

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSeanView Question on Stackoverflow
Solution 1 - VimZyXView Answer on Stackoverflow
Solution 2 - VimSeanView Answer on Stackoverflow
Solution 3 - VimfentView Answer on Stackoverflow
Solution 4 - VimairstrikeView Answer on Stackoverflow
Solution 5 - VimSandipView Answer on Stackoverflow
Solution 6 - VimBenoitView Answer on Stackoverflow
Solution 7 - VimEnnoView Answer on Stackoverflow
Solution 8 - VimachalkView Answer on Stackoverflow