Vim Tips Wiki
(More manual cleaning to standardise format)
No edit summary
 
(5 intermediate revisions by 4 users not shown)
Line 9: Line 9:
 
|version=6.0
 
|version=6.0
 
|rating=16/6
 
|rating=16/6
  +
|category1=
  +
|category2=
 
}}
 
}}
 
If you are comfortable
 
* with Vim's modes and
 
* with using the <Esc> key (meaning you rarely hit <Esc> unnecessarily)
 
and you
 
* would prefer entering : commands in a modal command window rather than on the command line
 
Then this tip is for you.
  +
 
Some key features of the command window (see {{help|cmdwin}}) that would lead one to be interested in it are:
 
* One can edit the buffer any way one wants
 
* Hitting <CR> results in the line one was on being executed
 
* editing in the command window is much nicer than editing on the command line
  +
  +
[[Command-line window|Basic use of the command window]] is easy, but this tip allows you to improve the command window with simple mappings to enter and leave it, as well as providing missing functionality from the command line such as using <C-D> to view matches for what you have typed so far.
  +
  +
Begin with some mappings to easily enter and leave the command window with a single key-stroke:
 
<pre>
 
<pre>
 
nmap <Esc> q:<C-W>_
"Enhanced Command Window
 
 
nmap q/ q/<C-W>_
"
 
  +
nmap q? q?<C-W>_
"If you are comfortable
 
" 1) with Vim's modes and
 
" 2) with using the &lt;ESC&gt; key (meaning
 
" you rarely hit &lt;ESC&gt; unnecessarily)
 
"and you
 
" 3) would prefer entering : commands in a modal
 
" command window rather than on the command line
 
"Then this tip is for you.
 
"
 
"Some key features of the command window (see ;help cmdwin)
 
"that would lead one to be interested in it are:
 
" - One can edit the buffer any way one wants
 
" - Hitting &lt;CR&gt; results in the line one was one being executed
 
" - (editing in the command window is much nicer than editing
 
" on the command line)
 
"
 
"Begin with some mappings:
 
nmap &lt;ESC&gt; q:&lt;C-W&gt;_
 
nmap q/ q/&lt;C-W&gt;_
 
nmap q? q?&lt;C-W&gt;_
 
 
augroup ECW_au
 
augroup ECW_au
 
au!
 
au!
au CmdwinEnter * nmap &lt;ESC&gt; :q&lt;CR&gt;
+
au CmdwinEnter * nmap <Esc> :q<CR>
au CmdwinLeave * nmap &lt;ESC&gt; q:&lt;C-W&gt;_
+
au CmdwinLeave * nmap <Esc> q:<C-W>_
 
augroup END
 
augroup END
  +
</pre>
   
 
Some nice things about the command line that are not present in the usual command window are:
"Simple observation: with these mappings, one can go
 
 
* The <UP> and <DOWN> arrow find all the commands that match the text entered to the left of the cursor
"from normal-mode to cmdwin and back via escape (&lt;ESC&gt;)!
 
 
* Hitting <C-D> shows the ways in which the typed text can be completed (see {{help|cmdline-completion}})
"
 
  +
"Some nice things about the command line that are not present
 
 
It is possible to have similar features in the command-window too. For the <UP> <DOWN> feature, add the following au-command event triggered maps:
"in the usual command window are:
 
  +
<pre>
" - The &lt;UP&gt; and &lt;DOWN&gt; arrow find all the commands that match
 
" the text entered to the left of the cursor
 
" - Hitting &lt;C-D&gt; shows the ways in which the typed text can be
 
" completed (see :help cmdline-completion)
 
"
 
"It is possible to have similar features in the command-window too.
 
"For the &lt;UP&gt; &lt;DOWN&gt; feature, add the following au-command event
 
"triggered maps:
 
 
augroup ECW_au
 
augroup ECW_au
 
" musn't do au! again
 
" musn't do au! again
au CmdwinEnter : imap &lt;UP&gt; &lt;C-O&gt;y0&lt;C-O&gt;:let@/='^'.@0&lt;CR&gt;&lt;C-O&gt;?&lt;ESC&gt;&lt;ESC&gt;
+
au CmdwinEnter : imap <UP> <C-O>y0<C-O>:let@/='^'.@0<CR><C-O>?<Esc><Esc>
au CmdwinLeave : iunmap &lt;UP&gt;
+
au CmdwinLeave : iunmap <UP>
au CmdwinEnter : imap &lt;DOWN&gt; &lt;C-O&gt;y0&lt;C-O&gt;:let@/='^'.@0&lt;CR&gt;&lt;C-O&gt;/&lt;ESC&gt;&lt;ESC&gt;
+
au CmdwinEnter : imap <DOWN> <C-O>y0<C-O>:let@/='^'.@0<CR><C-O>/<Esc><Esc>
au CmdwinLeave : iunmap &lt;DOWN&gt;
+
au CmdwinLeave : iunmap <DOWN>
 
au CmdwinLeave : :let @/=""
 
au CmdwinLeave : :let @/=""
 
augroup END
 
augroup END
  +
</pre>
   
"Now, while in the command window, going to insert mode and hitting
+
Now, while in the command window, going to insert mode and hitting the <UP> arrow followed by the n key results in one visiting all the commands that match the text to the left of the cursor when the <UP> key was hit &ndash; then hitting <CR> while on any line causes it to be executed. Likewise, for the <DOWN> arrow.
  +
"the &lt;UP&gt; arrow followed by the n key results in one visiting all
 
 
Next for the <C-D> feature. This is slightly more complex. Begin by adding the following autocommand event triggered maps:
"the commands that match the text to the left of the cursor when
 
  +
<pre>
"the &lt;UP&gt; key was hit -- then hitting &lt;CR&gt; while on any line causes
 
"it to be executed. Likewise, for the &lt;DOWN&gt; arrow.
 
"
 
"Next for the &lt;C-D&gt; feature. This is slightly more complex.
 
"Begin by adding the following autocommand event triggered maps:
 
 
augroup ECW_au
 
augroup ECW_au
 
" musn't do au! again
 
" musn't do au! again
au CmdwinEnter : imap &lt;C-D&gt; &lt;C-O&gt;y0&lt;C-O&gt;:ECWCtrlD&lt;CR&gt;&lt;ESC&gt;
+
au CmdwinEnter : imap <C-D> <C-O>y0<C-O>:ECWCtrlD<CR><Esc>
au CmdwinLeave : iunmap &lt;C-D&gt;
+
au CmdwinLeave : iunmap <C-D>
 
augroup END
 
augroup END
  +
</pre>
"Then provide this function: function! s:ECWCtrlD()
 
  +
"With this function, hitting &lt;C-D&gt; while in insert mode in the
 
 
Then provide this function: function! s:ECWCtrlD()
"command window results in more information about the text to
 
 
With this function, hitting <C-D> while in insert mode in the
"the left of the cursor appearing on the lines below the cursor.
 
 
command window results in more information about the text to
"This information can left on the command window or removed
 
 
the left of the cursor appearing on the lines below the cursor.
"by typing u (undo).
 
 
This information can left on the command window or removed
"
 
 
by typing u (undo).
"The nature of the information provided by &lt;C-D&gt; depends on what
 
  +
"is to the left of the cursor:
 
 
The nature of the information provided by <C-D> depends on what
"
 
" If the stuff to the left of the cursor looks, essentially
+
is to the left of the cursor:
" like "map " or "map foo" then the information provided by
+
*If the stuff to the left of the cursor looks, essentially like "map " or "map foo" then the information provided by <C-D> is the same as the information that appears when the the same stuff is typed on the command line and return is hit.
  +
*If the stuff to the left of the cursor begins, essentially like "sf " or like "find " then what is displayed on <C-D> is the glob of the remaining stuff (after appending the remaining stuff with a *)
" &lt;C-D&gt; is the same as the information that appears when the
 
  +
*If the stuff to the left of the cursor looks like neither of the above two cases then what is displayed is the glob of the very last non-space separated "word" (after appending that "word" with a *)
" the same stuff is typed on the command line and return is hit.
 
  +
"
 
  +
<pre>
" If the stuff to the left of the cursor begins, essentially
 
" like "sf " or like "find " then what is displayed on &lt;C-D&gt; is
 
" the glob of the remaining stuff (after appending the remaining
 
" stuff with a *)
 
"
 
" If the stuff to the left of the cursor looks like neither of
 
" the above two cases then what is displayed is the glob of the
 
" very last non-space separated "word" (after appending that "word"
 
" with a *)
 
"
 
 
function! s:ECWCtrlD()
 
function! s:ECWCtrlD()
if (match(@", '^ *[a-z]\?map\s\s*\(\S\S*\)\?\s*$') &gt;=0 )
+
if (match(@", '^ *[a-z]\?map\s\s*\(\S\S*\)\?\s*$') >=0 )
 
let s:foo = @"
 
let s:foo = @"
let save_more=&amp;more
+
let save_more=&more
 
set nomore
 
set nomore
 
execute ':redir @" |'.s:foo.'|redir END'
 
execute ':redir @" |'.s:foo.'|redir END'
let &amp;more = save_more
+
let &more = save_more
 
put=@"
 
put=@"
"Keep this next command even though Vim comlains -- it is
+
"Keep this next command even though Vim complains -- it is
 
"a work-around for some "unknown bad thing"
 
"a work-around for some "unknown bad thing"
 
silent normal
 
silent normal
Line 113: Line 93:
 
endif
 
endif
 
"sf and find can have space separated arguments
 
"sf and find can have space separated arguments
if (match(@", '^ *\(\(sf\)\|\(find\)\)\ *') &gt;=0 )
+
if (match(@", '^ *\(\(sf\)\|\(find\)\)\ *') >=0 )
 
let s:foo = substitute(@", '^ *\(\(sf\)\|\(find\)\)\ *', '', '')
 
let s:foo = substitute(@", '^ *\(\(sf\)\|\(find\)\)\ *', '', '')
 
else "pick the trailing non-space separated stuff
 
else "pick the trailing non-space separated stuff
Line 125: Line 105:
   
 
if !exists(":ECWCtrlD")
 
if !exists(":ECWCtrlD")
command -nargs=0 ECWCtrlD call s:ECWCtrlD()
+
command -nargs=0 ECWCtrlD call s:ECWCtrlD()
 
endif
 
endif
  +
</pre>
   
"If one wants to get even more fancy, one can start with the map
+
If one wants to get even more fancy, one can start with the map
  +
"
 
  +
<pre>
" nmap &lt;S-ESC&gt; :ECWtobedefined
+
nmap <S-ESC> :ECWtobedefined
"
 
  +
</pre>
" wherein the function ECWtobedefined opens up a new buffer
 
  +
" in which one can do anything one likes. Even if this new
 
" buffer merely mimics the command window, it will the feature
+
wherein the function ECWtobedefined opens up a new buffer in which one can do anything one likes. Even if this new buffer merely mimics the command window, it will the feature of co-existing with other buffers -- which is a feature that the command window does not have!
" of co-existing with other buffers -- which is a feature that
 
" the command window does not have!
 
   
 
==Comments==
 
==Comments==
  +
{{todo}}
  +
*Define the undefined :ECWtobedefined, or remove it
  +
*Test whether this tip even works
  +
*: How does it work? I thought the first example needs s/nmap/nnoremap/, but it works.
  +
*Reword as desired for better "flow" and layout
  +
  +
----
  +
  +
Still needs review. Only did minor rewordings. --[[User:Fritzophrenic|Fritzophrenic]] 16:51, 28 July 2008 (UTC)
   
 
----
 
----

Latest revision as of 17:03, 20 April 2013

Tip 681 Printable Monobook Previous Next

created March 18, 2004 · complexity intermediate · author Suresh Govindachar · version 6.0


If you are comfortable

  • with Vim's modes and
  • with using the <Esc> key (meaning you rarely hit <Esc> unnecessarily)

and you

  • would prefer entering : commands in a modal command window rather than on the command line

Then this tip is for you.

Some key features of the command window (see :help cmdwin) that would lead one to be interested in it are:

  • One can edit the buffer any way one wants
  • Hitting <CR> results in the line one was on being executed
  • editing in the command window is much nicer than editing on the command line

Basic use of the command window is easy, but this tip allows you to improve the command window with simple mappings to enter and leave it, as well as providing missing functionality from the command line such as using <C-D> to view matches for what you have typed so far.

Begin with some mappings to easily enter and leave the command window with a single key-stroke:

nmap <Esc> q:<C-W>_
nmap q/ q/<C-W>_
nmap q? q?<C-W>_
augroup ECW_au
  au!
  au CmdwinEnter * nmap <Esc> :q<CR>
  au CmdwinLeave * nmap <Esc> q:<C-W>_
augroup END

Some nice things about the command line that are not present in the usual command window are:

  • The <UP> and <DOWN> arrow find all the commands that match the text entered to the left of the cursor
  • Hitting <C-D> shows the ways in which the typed text can be completed (see :help cmdline-completion)

It is possible to have similar features in the command-window too. For the <UP> <DOWN> feature, add the following au-command event triggered maps:

augroup ECW_au
  " musn't do au! again
  au CmdwinEnter : imap <UP> <C-O>y0<C-O>:let@/='^'.@0<CR><C-O>?<Esc><Esc>
  au CmdwinLeave : iunmap <UP>
  au CmdwinEnter : imap <DOWN> <C-O>y0<C-O>:let@/='^'.@0<CR><C-O>/<Esc><Esc>
  au CmdwinLeave : iunmap <DOWN>
  au CmdwinLeave : :let @/=""
augroup END

Now, while in the command window, going to insert mode and hitting the <UP> arrow followed by the n key results in one visiting all the commands that match the text to the left of the cursor when the <UP> key was hit – then hitting <CR> while on any line causes it to be executed. Likewise, for the <DOWN> arrow.

Next for the <C-D> feature. This is slightly more complex. Begin by adding the following autocommand event triggered maps:

augroup ECW_au
  " musn't do au! again
  au CmdwinEnter : imap <C-D> <C-O>y0<C-O>:ECWCtrlD<CR><Esc>
  au CmdwinLeave : iunmap <C-D>
augroup END

Then provide this function: function! s:ECWCtrlD() With this function, hitting <C-D> while in insert mode in the command window results in more information about the text to the left of the cursor appearing on the lines below the cursor. This information can left on the command window or removed by typing u (undo).

The nature of the information provided by <C-D> depends on what is to the left of the cursor:

  • If the stuff to the left of the cursor looks, essentially like "map " or "map foo" then the information provided by <C-D> is the same as the information that appears when the the same stuff is typed on the command line and return is hit.
  • If the stuff to the left of the cursor begins, essentially like "sf " or like "find " then what is displayed on <C-D> is the glob of the remaining stuff (after appending the remaining stuff with a *)
  • If the stuff to the left of the cursor looks like neither of the above two cases then what is displayed is the glob of the very last non-space separated "word" (after appending that "word" with a *)
function! s:ECWCtrlD()
  if (match(@", '^ *[a-z]\?map\s\s*\(\S\S*\)\?\s*$') >=0 )
    let s:foo = @"
    let save_more=&more
    set nomore
    execute ':redir @" |'.s:foo.'|redir END'
    let &more = save_more
    put=@"
    "Keep this next command even though Vim complains -- it is
    "a work-around for some "unknown bad thing"
    silent normal
    return
  endif
  "sf and find can have space separated arguments
  if (match(@", '^ *\(\(sf\)\|\(find\)\)\ *') >=0 )
    let s:foo = substitute(@", '^ *\(\(sf\)\|\(find\)\)\ *', '', '')
  else "pick the trailing non-space separated stuff
    let s:foo = substitute(@", '\(.\{-}\)\(\S\S*\s*\)$', '\2', '')
  endif
  let s:foo = substitute(s:foo, '\s*$', '*', '') "OK if ending has two wild-cards
  let @"=glob(s:foo)
  if(@" == "") | let @"='no match' | endif
  put=@"
endfunction

if !exists(":ECWCtrlD")
  command -nargs=0 ECWCtrlD call s:ECWCtrlD()
endif

If one wants to get even more fancy, one can start with the map

nmap <S-ESC> :ECWtobedefined

wherein the function ECWtobedefined opens up a new buffer in which one can do anything one likes. Even if this new buffer merely mimics the command window, it will the feature of co-existing with other buffers -- which is a feature that the command window does not have!

Comments[]

 TO DO 

  • Define the undefined :ECWtobedefined, or remove it
  • Test whether this tip even works
    How does it work? I thought the first example needs s/nmap/nnoremap/, but it works.
  • Reword as desired for better "flow" and layout

Still needs review. Only did minor rewordings. --Fritzophrenic 16:51, 28 July 2008 (UTC)