如何一致地启动 Vim 命令行以使映射在任何模式下工作?

如何一致地启动 Vim 命令行以使映射在任何模式下工作?

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

noremap <script> <unique> <silent> <f6> <sid>:echomsg 'Hello World!'<cr>
noremap! <script> <unique> <silent> <f6> <sid>:echomsg 'Hello World!'<cr>

上面的映射<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

有没有一种直接的方法来代替我的混淆方法?

答案1

以下内容什么时候不起作用?

nnoremap <F6> <ESC><ESC>:command<CR>

答案2

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

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>

对于每个 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

它不是<F1>简单地使用该键在新窗口中打开 Vim 的帮助,而是以光标下的: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

相关内容