どのモードでもマッピングが機能するように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モードに対して、キーシーケンスは、Vimの現在のモード(挿入モードなど)から通常モードに<SID><\O>適切にエスケープされるようにマッピングされます。<C-\><C-O>各マップの右側は左側で終わるため、(例えば<SID><\O>)脱出は再帰的に再試行されます。最後のエスケープキーシーケンスがVimの通常モード(キーシーケンスマップが空の場合)に達すると、スクリプトローカル(<script>、)の再帰が停止します。<SID><SID><\O><Nop>

同様に、<SID><\N>キーシーケンスは、<SID><\O>return()の前に挿入モードを一度終了するだけでなく、永続的に通常モードを維持するようにマッピングされます。

上記の定義を使用して、ファンクションキーを次のように<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

単にこのキーを使用して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

関連情報