Vim Tips Wiki
Register
(Remove link to "Open file in new tab if current buffer is non-empty" (deleted))
(Change <tt> to <code>, perhaps also minor tweak.)
(11 intermediate revisions by 5 users not shown)
Line 1: Line 1:
  +
__NOTOC__
 
{{TipImported
 
{{TipImported
 
|id=1285
 
|id=1285
|previous=1284
+
|previous=1282
 
|next=1286
 
|next=1286
|created=July 17, 2006
+
|created=2006
 
|complexity=intermediate
 
|complexity=intermediate
 
|author=Yakov Lerner
 
|author=Yakov Lerner
Line 11: Line 12:
 
|category2=
 
|category2=
 
}}
 
}}
You can use <tt>:command</tt> to define your own commands, but user-defined commands must start with an uppercase letter to avoid confusion with built-in commands.
+
You can use <code>:command</code> to define your own commands, but user-defined commands must start with an uppercase letter to avoid confusion with built-in commands.
   
This tip shows how to replace a built-in command using <tt>:cabbrev</tt> to automatically replace the existing command when it is typed.
+
This tip shows how to replace a built-in command using <code>:cabbrev</code> to automatically replace the existing command when it is typed.
   
For example, you may want to change the behavior of a built-in command like <tt>:e</tt>. Or, you may make a common typo, like using <tt>:w1</tt> instead of <tt>:w!</tt>. For whatever reason, if you want to change the behavior of a built-in command, you can't just use <tt>:command</tt> to override it, because user-defined commands must begin with a capital letter.
+
For example, you may want to change the behavior of a built-in command like <code>:e</code>. Or, you may make a common typo, like using <code>:w1</code> instead of <code>:w!</code>. For whatever reason, if you want to change the behavior of a built-in command, you can't just use <code>:command</code> to override it, because user-defined commands must begin with a capital letter.
 
Suppose you have a user-defined <tt>:E</tt> command that you want to use to override the default <tt>:e</tt> command. You could do the following:
 
   
 
Suppose you have a user-defined <code>:E</code> command that you want to use to override the default <code>:e</code> command. You could do the following:
 
<pre>
 
<pre>
:cabbrev e &lt;c-r&gt;=(getcmdtype()==':' && getcmdpos()==1 ? 'E' : 'e')&lt;CR&gt;
+
:cabbrev e <c-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'E' : 'e')<CR>
 
</pre>
 
</pre>
   
The <tt>(getcmdtype()==':' && getcmdpos())</tt> makes sure the replacement happens ''only'' in the first column of the command line (i.e. not later in the line, where it is most likely NOT intended to be used as a command, and not on the search line, which is also affected by cabbrev).
+
The <code>(getcmdtype()==':' && getcmdpos())</code> makes sure the replacement happens ''only'' in the first column of the command line (i.e. not later in the line, where it is most likely NOT intended to be used as a command, and not on the search line, which is also affected by cabbrev).
   
 
If you do this a lot, it would be useful to define a function to do it for you. Use this to quickly and easily define lowercase abbreviations for whatever command you want:
 
If you do this a lot, it would be useful to define a function to do it for you. Use this to quickly and easily define lowercase abbreviations for whatever command you want:
 
 
<pre>
 
<pre>
 
function! CommandCabbr(abbreviation, expansion)
 
function! CommandCabbr(abbreviation, expansion)
execute 'cabbr ' . a:abbreviation . ' &lt;c-r&gt;=getcmdpos() == 1 && getcmdtype() == ":" ? "' . a:expansion . '" : "' . a:abbreviation . '"&lt;CR&gt;'
+
execute 'cabbr ' . a:abbreviation . ' <c-r>=getcmdpos() == 1 && getcmdtype() == ":" ? "' . a:expansion . '" : "' . a:abbreviation . '"<CR>'
 
endfunction
 
endfunction
command! -nargs=+ CommandCabbr call CommandCabbr(&lt;f-args&gt;)
+
command! -nargs=+ CommandCabbr call CommandCabbr(<f-args>)
 
" Use it on itself to define a simpler abbreviation for itself.
 
" Use it on itself to define a simpler abbreviation for itself.
 
CommandCabbr ccab CommandCabbr
 
CommandCabbr ccab CommandCabbr
 
</pre>
 
</pre>
   
This not only creates the function, but also provides the (lowercase!) command <tt>:ccab</tt> to define such abbreviations "on the fly".
+
This not only creates the function, but also provides the (lowercase!) command <code>:ccab</code> to define such abbreviations "on the fly".
   
Note that because of the use of <tt><f-args></tt>, you will need to escape (<tt>"\ "</tt>), or use <tt><space></tt>, to include literal spaces in your expansion. This is explained in the help for Vim 7.1 (<tt>:help &lt;f-args&gt;</tt>).
+
Note that because of the use of <code><f-args></code>, you will need to escape (<code>"\ "</code>), or use <code><Space></code>, to include literal spaces in your expansion. This is explained in {{help|<f-args>}}.
   
 
==See also==
 
==See also==
Line 44: Line 43:
 
*[[Find in files within Vim]]
 
*[[Find in files within Vim]]
 
*[[Handle common command typos]]
 
*[[Handle common command typos]]
  +
*[[Run a command in multiple buffers]]
*[[Windo and Bufdo]]
 
   
 
This is a good reference in case this tip causes you problems:
 
This is a good reference in case this tip causes you problems:
 
*[[Disabling cabbrev]]
 
*[[Disabling cabbrev]]
  +
  +
This plugin does the same thing (possibly in the same way):
  +
*{{script|id=746}}
   
 
==References==
 
==References==
Line 57: Line 59:
 
==Comments==
 
==Comments==
 
===Using <expr> (Vim 7)===
 
===Using <expr> (Vim 7)===
With Vim 7 ("or later"), you can use <tt>:cabbrev <expr></tt> &#8212; here is an example, replacing the <tt>:h</tt> command to open the help window at the bottom of the Vim screen:
+
With Vim 7 ("or later"), you can use <code>:cabbrev <expr></code> &#8212; here is an example, replacing the <code>:h</code> command to open the help window at the bottom of the Vim screen:
   
 
<pre>cabbrev <expr> h ((getcmdtype() == ':' && getcmdpos() <= 2)? 'bot h' : 'h')</pre>
 
<pre>cabbrev <expr> h ((getcmdtype() == ':' && getcmdpos() <= 2)? 'bot h' : 'h')</pre>
Line 63: Line 65:
 
See also {{help|:map-<expr>}}
 
See also {{help|:map-<expr>}}
   
<tt>getcmdpos()</tt> will usually be 2 because the cursor is on the space after <tt>:h</tt> (I tested it with <tt>getcmdpos() == 1</tt> and that doesn't work). -- [[User:Tonymec|Tonymec]] 07:03, 12 May 2008 (UTC)
+
<code>getcmdpos()</code> will usually be 2 because the cursor is on the space after <code>:h</code> (I tested it with <code>getcmdpos() == 1</code> and that doesn't work). -- [[User:Tonymec|Tonymec]] 07:03, 12 May 2008 (UTC)
  +
  +
:In this example, you can do <code>::h</code> or <code>: h</code> (from normal mode) to call the built-in :help command (bypassing the abbreviation).
  +
  +
:: or <code>:he</code> or <code>:help</code> since abbreviations only trigger when followed by a non-id character (such as a space or the Enter key) &#8212; [[User:Tonymec|Tonymec]] 18:01, 21 August 2008 (UTC)

Revision as of 06:17, 13 July 2012

Tip 1285 Printable Monobook Previous Next

created 2006 · complexity intermediate · author Yakov Lerner · version n/a


You can use :command to define your own commands, but user-defined commands must start with an uppercase letter to avoid confusion with built-in commands.

This tip shows how to replace a built-in command using :cabbrev to automatically replace the existing command when it is typed.

For example, you may want to change the behavior of a built-in command like :e. Or, you may make a common typo, like using :w1 instead of :w!. For whatever reason, if you want to change the behavior of a built-in command, you can't just use :command to override it, because user-defined commands must begin with a capital letter.

Suppose you have a user-defined :E command that you want to use to override the default :e command. You could do the following:

:cabbrev e <c-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'E' : 'e')<CR>

The (getcmdtype()==':' && getcmdpos()) makes sure the replacement happens only in the first column of the command line (i.e. not later in the line, where it is most likely NOT intended to be used as a command, and not on the search line, which is also affected by cabbrev).

If you do this a lot, it would be useful to define a function to do it for you. Use this to quickly and easily define lowercase abbreviations for whatever command you want:

function! CommandCabbr(abbreviation, expansion)
  execute 'cabbr ' . a:abbreviation . ' <c-r>=getcmdpos() == 1 && getcmdtype() == ":" ? "' . a:expansion . '" : "' . a:abbreviation . '"<CR>'
endfunction
command! -nargs=+ CommandCabbr call CommandCabbr(<f-args>)
" Use it on itself to define a simpler abbreviation for itself.
CommandCabbr ccab CommandCabbr

This not only creates the function, but also provides the (lowercase!) command :ccab to define such abbreviations "on the fly".

Note that because of the use of <f-args>, you will need to escape ("\ "), or use <Space>, to include literal spaces in your expansion. This is explained in :help <f-args>.

See also

These are all good candidates for this technique (or use it already):

This is a good reference in case this tip causes you problems:

This plugin does the same thing (possibly in the same way):

References

Comments

Using <expr> (Vim 7)

With Vim 7 ("or later"), you can use :cabbrev <expr> — here is an example, replacing the :h command to open the help window at the bottom of the Vim screen:

cabbrev    <expr>    h    ((getcmdtype() == ':' && getcmdpos() <= 2)? 'bot h' : 'h')

See also :help :map-<expr>

getcmdpos() will usually be 2 because the cursor is on the space after :h (I tested it with getcmdpos() == 1 and that doesn't work). -- Tonymec 07:03, 12 May 2008 (UTC)

In this example, you can do ::h or : h (from normal mode) to call the built-in :help command (bypassing the abbreviation).
or :he or :help since abbreviations only trigger when followed by a non-id character (such as a space or the Enter key) — Tonymec 18:01, 21 August 2008 (UTC)