如何始终如一地启动 Vim 的命令行以在任何模式下进行映射?

Tim*_*ske 5 scripting vim keyboard-shortcuts vimrc key-mapping

我尝试从任何其他模式对 Vim 命令行模式的访问进行规范化,以简化我的实际映射。例如,为了让<f6>密钥在任何地方工作,我定义了以下映射:

noremap <script> <unique> <silent> <f6> <sid>:echomsg 'Hello World!'<cr>
noremap! <script> <unique> <silent> <f6> <sid>:echomsg 'Hello World!'<cr>
Run Code Online (Sandbox Code Playgroud)

上述映射<sid>:在开始工作之前重新映射到下面给出的键映射:

noremap <unique> <expr> <sid>: <sid>StartCmdLineMode()
noremap! <unique> <expr> <sid>: <sid>StartCmdLineMode()
function! s:StartCmdLineMode()
  let a=mode()
  if a ==# 'n' 
    return ':'
  " Type <c-v><c-v> to insert ^V. 
  elseif a =~ '[vV^V]'
    return ":\<c-u>"
  elseif a ==# 'no'
    return "\<c-c>:"
  elseif a ==# 'i' 
    return "\<c-o>:"
  elseif a ==# 'c' 
    let b=getcmdtype()
    if b ==# ':' 
      return "\<c-e>\<c-u>"
    else
      return "\<c-c>:"
    endif
  else
    return ''
  endif
endfunction
Run Code Online (Sandbox Code Playgroud)

有没有一种直截了当的方式而不是我的混淆方法?

Tim*_*ske 0

与此同时,我想出了以下方法:

noremap <script> <unique> <SID><\O> <Nop>
inoremap <script> <unique> <SID><\O> <C-\><C-O><SID><\O>
cnoremap <script> <unique> <SID><\O> <C-\><C-N><SID><\O>
noremap <script> <unique> <SID><\N> <Nop>
noremap! <script> <unique> <SID><\N> <C-\><C-N><SID><\N>
Run Code Online (Sandbox Code Playgroud)

对于每个 Vim 模式,<SID><\O>键序列都会被映射,以便适当地<C-\><C-O>从 Vim 的当前模式(例如插入模式)转义(例如)到其正常模式。每个映射的右侧在其左侧结束(例如<SID><\O>),以便递归地尝试再次转义。一旦最后一个转义键序列达到 Vim 的正常模式(其中键序列映射为空),脚本本地( <script>, ) 递归就会停止。<SID><SID><\O><Nop>

同样,<SID><\N>键序列被映射为不仅<SID><\O>在返回之前从例如插入模式退出一次(),而且永久地停留在正常模式。

在上述定义的帮助下,我将<F1><S-F1>功能键映射如下:

noremap <script> <unique> <expr> <F1> <SID>ToggleHelp(':<C-U>help', '<SID>')
noremap! <script> <unique> <expr> <F1> <SID>ToggleHelp(':<C-U>help', '<SID>')
noremap <script> <unique> <expr> <S-F1> <SID>ToggleHelp(':<C-U>helpgrep', '<SID>')
noremap! <script> <unique> <expr> <S-F1> <SID>ToggleHelp(':<C-U>helpgrep', '<SID>')
function! s:ToggleHelp(cmd, sid)
  ToggleVar s:HelpCwordOn
  let a=s:HelpCwordOn ? '<cword>' : '<cWORD>'
  return a:sid . '<\O>' . a:cmd . ' ' . expand(a) . ' '
endfunction
command! -bang -nargs=+ ToggleVar call <SID>ToggleVar(<bang>0, <f-args>)
function! s:ToggleVar(bang, var)
  let {a:var}=exists(a:var) ? !{a:var} : !a:bang
endfunction
Run Code Online (Sandbox Code Playgroud)

它不是简单地使用该键在新窗口中打开 Vim 的帮助,而是以光标下的内部单词 ( )<F1>启动命令。通过连续按下该键,可以切换到外部单词 ( ) 并再次切换回来。:help<cword><F1><cWORD>

上面用例中的 4 个映射也可以定义如下,以免重复;即保持“干燥”:

let a='noremap'
let b='<script> <unique> <expr>'
let c='<F1>'
let d='<S-F1>'
let e='<SID>ToggleHelp('':<C-U>help'
let f='grep'
let g=''', ''<SID>'')'
let h=b . ' ' . c . ' ' . e . g
let i=b . ' ' . d . ' ' . e . f . g
exec a . ' ' . h
exec a . '! ' . h
exec a . ' ' . i
exec a . '! ' . i
Run Code Online (Sandbox Code Playgroud)