一千萬個為什麽

搜索

在終端中重新映射Alt鍵:宏的問題

我正在使用xfce4-terminal。

我重新映射了.virmc中加載的文件中的大多數Alt +組合鍵。 該文件(稱為alt_bindings.vim,僅在vim 8終端模式下加載)如下所示:

set =^]a
set =^]A
set =^]b
set =^]B
set =^]c
set =^]C

大多數鑰匙等。我排除了一些立即給我帶來錯誤的組合,例如 alt + Oalt + [

然後我有像這樣的宏:

"w   0vf'snno^I ^[lywio^[plxxx  :set <80>kD<80>kD^[wwD<80>kd

^[ is Esc key, but the macro seems to trigger my defined keys instead, and it breaks the macro totally. For example, ^[plxxx would be Escplxxx that is: back to normal mode, paste, right, delete 3x. It does something else entirely instead (like inserting xxx and other chars). The problem goes away if I don't load those mappings.

我試過類似的東西:

set =^]
set =A
set =b
set =B
set =c
set =C

但它不起作用。我也嘗試過類似的東西:

set =^]
set =A
set =b
set =B
set =c
set =C

但奇怪的事情發生了,鍵也不起作用。

然後我使用了(取自這裏):

let c='a'
while c <= 'z'
  exec "set =".c
  exec "nnoremap ".c." "
  let c = nr2char(1+char2nr(c))
endw

它工作,但它表現出相同的問題(破碎的宏)。

有幫助嗎?謝謝。

最佳答案

該問題是由終端歷史上處理 Alt / Meta 鍵。

回到歷史的迷霧中,一些計算機/終端有一個 Meta 鍵。當按下另一個鍵時按下該鍵時,該字符的第8位被設置。所以例如無論是否按下 Meta 鍵,按 a 鍵都會產生以下密鑰代碼:

       Hex  Binary
     p 0x70 01110000 
Meta+p 0xF0 11110000
            ^
            |
            8th bit

但是,在將此信息發送到網絡時,第8位有時用於其他目的(如果協議/環境不是“8位清除”),則無法使用此方法。另一種解決方案是傳輸ESC字符,後跟未修改的字符。例如<�代碼> ^ [P </代碼>。然後,這將被接收為 Meta-P 按鍵的程序解釋。

這就是Vim將宏中的 Esc p 解釋為 Meta-P 並觸發映射的原因。

手動鍵入 Esc p 時沒有出現問題的原因是,當Vim收到ESC字符時,它會等待很短的一段時間才能看出它是否是後跟另一個字符(參見:help'ttimeout')。如果在設置中指定的時間內沒有,Vim會將其解釋為 Esc 按鍵。如果Vim在該時間範圍內收到另一個字符,它會將該對解釋為元鍵和弦並觸發映射。

播放宏時,盡可能快地重放按鍵,因此Vim會錯誤地解釋它們。

不幸的是,我不知道一個很好的解決方案。

我能想到的選擇是:

  1. Use GUI Vim: this handles the Alt key itself, and so the mappings will work transparently,
  2. Configure your terminal to send some other keycode for each Alt-chord, and then map these keycodes in Vim,
  3. Use Neovim. I'm led to believe Neovim doesn't have this issue (although I'm not sure how it gets around it).
  4. Alter the way you record your macro so that the key following the Esc isn't one that would trigger a mapping. e.g. while recording, type EscCtrl-Cp instead of Escp,
  5. Don't use Alt-mappings. :(
  6. EDIT: Your comment gave me an idea: instead of manually sourcing files before and after running a macro, you can get Vim to do it for you:

    function! SetKeycodes()
      " N.B. Type ^[ as 
      set =^[o
      set =^[p
      "etc
    endfunction
    call SetKeycodes()
    
    function! UnsetKeycodes()
      set =
      set =
      "etc
    endfunction
    
    function! RunMacro()
      let r = getchar()
      echom r
      call UnsetKeycodes()
      execute "normal! @" . nr2char(r)
      call SetKeycodes()
    endfunction
    
    nnoremap @ :call RunMacro()
    inoremap  Mapping (o)
    inoremap  Mapping (p)
    set ttimeoutlen=10
    

轉載註明原文: 在終端中重新映射Alt鍵:宏的問題