How to change Vim’s command type mode programmatically

key mappingkeyboard shortcutsscriptingvim

Is there a simple way to switch from one command type mode to another without loosing the current command line?

In my ~/.vimrc file I remap the <space> and <c-space> character, coming from, to:

  1. N,V,O => :
  2. I => :
  3. : => / => ?

The code that accomplishes the above behavior is:

function! s:ModMapSpaceChar()
  noremap <unique> <space> :
  map <unique> <nul> <c-space>
  map! <unique> <nul> <c-space>
  noremap <unique> <c-space> /
  inoremap <unique> <c-space> <c-o>:
  cnoremap <unique> <c-space> <c-\>eg:ToggleCmdTypes()<cr><c-c>@"
  let g:CmdTypes={':' : '/', '/' : '?', '?': ':'}
  function! g:ToggleCmdTypes()
    let a=getcmdtype()
    let b=get(g:CmdTypes, a, a)
    let c=getcmdline()
    let @"=b . c
    return ''
  endfunction
endfunction

call s:ModMapSpaceChar()

What bothers me in my approach is the impure function g:ToggleCmdTypes. It should ideally return the command that it currently assigns to the " register. The resulting command shall then be executed.

Best Answer

Instead of the detour through the register, you could probably also use feedkeys() for this, to avoid clobbering the register. This has only the disadvantage that it won't work when recorded and replayed as a macro.

In general, I would recommend to re-think your general approach; I don't see how it's useful to switch command-line modes like that. Who starts a search only to realize half-way through that he wants that executed as a command instead?!

Related Question