Como consistentemente iniciar a linha de comando do Vim para fazer um mapeamento funcionar em qualquer modo?

5

Eu tento normalizar o acesso ao modo de linha de comando do Vim de qualquer outro modo para simplificar meus mapeamentos reais. Por exemplo, para fazer a chave <f6> funcionar em qualquer lugar, defino os seguintes mapeamentos:

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

Os mapeamentos acima remapearam para o mapeamento de chave <sid>: dado abaixo antes de começarem a funcionar:

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

Existe uma maneira correta em vez da minha abordagem ofuscada?

    
por Tim Friske 07.01.2013 / 02:24

2 respostas

2

Quando o seguinte não funciona?

nnoremap <F6> <ESC><ESC>:command<CR>
    
por 12.02.2013 / 06:39
0

Nesse meio tempo, desenvolvi a seguinte abordagem:

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>

Para cada modo Vim, a sequcia chave <SID><\O> mapeada para escapar apropriadamente (por exemplo, <C-\><C-O> ) do modo actual do Vim (por exemplo, modo de insero) para o seu modo normal. O lado direito de cada mapeamento termina no lado esquerdo (por exemplo, <SID><\O> ) para recursivamente tentar escapar novamente. A recursão local do script ( <script> , <SID> ) pára assim que a última seqüência de teclas de escape atinge o modo normal do Vim, no qual a seqüência de teclas <SID><\O> é mapeada para nada ( <Nop> ).

Da mesma forma, a sequência de teclas <SID><\N> é mapeada para não apenas escapar uma vez ( <SID><\O> ) de, e. insert-mode antes de retornar, mas permanecer permanentemente no modo normal.

Com a ajuda das definições acima, mapeei as teclas de função <F1> e <S-F1> da seguinte forma:

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

Em vez de ter a tecla <F1> simplesmente abrir a ajuda do Vim em uma nova janela, ele inicia o comando :help com a palavra interna ( <cword> ) sob o cursor. Pressionando consecutivamente a tecla <F1> , alterna-se para a palavra externa ( <cWORD> ) e volta-se novamente.

Os 4 mapeamentos do caso de uso acima também podem ser definidos da seguinte forma para não se repetir; ou seja, mantendo-o "seco":

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
    
por 22.01.2013 / 14:40