Home Pass ALT(Meta) key to putty
Post
Cancel

Pass ALT(Meta) key to putty

Putty 里正确设置 ALT(Meta) 键

此处感谢此帖 终端里正确设置 ALT 键和 BS 键 的作者,同时也在此作一下整理与备份。

背景

本人工作环境使用windows+putty通过ssh连接服务器,在配置vimAuto-pairs插件的时候,无意中被<M-p>这类快捷键无效的问题难住。经过一些分析与对比,发现是ALT(Meta)键无法正确发送给终端造成的,试过很多种方法并未能解决此问题。

调查

网上找了一些文件后得知,不管你在终端下使用vimneovimemacsnano或者zsh,你都会碰到使用ALT键的情况(终端下叫做Meta键),而由于历史原因,大部分终端软件的默认设置都无法正确使用ALT键。

要在终端下正确使用ALT键最简单的做法是:首先将终端软件的 “使用ALT键作为Meta键” 的功能打开,意思是如果你在终端下按下ALT+X,那么终端软件将会发送<ESC>,x两个字节过去,字节码为:0x270x78

使用如下命令可以察看发送的字节码:

1
$ showkey -a

试了一下ALT+X,果然是0x27, 0x78

各终端解决

SecureCRTXshell都有设置解决此类问题,如“Use ALT key as Meta key”,勾上就行。

其他终端软件里,可以按如下的方法来尝试:

  • Putty/MinTTY 默认ALT+X就是发送<ESC>,x过去;

  • Mac下面的iTerm2/Terminal.app需要跟XShell/SecureCRT一样设置一下;

  • Ubuntu下面的GnomeTerminal默认也是发送<ESC>,x过去的;

  • 任意平台下面的xterm可以配置~/.Xdefaults来设置这个行为。

  • 唯有vim,由于历史原因,需要在你的.vimrc里加一段键盘码配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function! Terminal_MetaMode(mode)
    set ttimeout
    if $TMUX != ''
        set ttimeoutlen=30
    elseif &ttimeoutlen > 80 || &ttimeoutlen <= 0
        set ttimeoutlen=80
    endif
    if has('nvim') || has('gui_running')
        return
    endif
    function! s:metacode(mode, key)
        if a:mode == 0
            exec "set <M-".a:key.">=\e".a:key
        else
            exec "set <M-".a:key.">=\e]{0}".a:key."~"
        endif
    endfunc
    for i in range(10)
        call s:metacode(a:mode, nr2char(char2nr('0') + i))
    endfor
    for i in range(26)
        call s:metacode(a:mode, nr2char(char2nr('a') + i))
        call s:metacode(a:mode, nr2char(char2nr('A') + i))
    endfor
    if a:mode != 0
        for c in [',', '.', '/', ';', '[', ']', '{', '}']
            call s:metacode(a:mode, c)
        endfor
        for c in ['?', ':', '-', '_']
            call s:metacode(a:mode, c)
        endfor
    else
        for c in [',', '.', '/', ';', '{', '}']
            call s:metacode(a:mode, c)
        endfor
        for c in ['?', ':', '-', '_']
            call s:metacode(a:mode, c)
        endfor
    endif
endfunc

call Terminal_MetaMode(0)

到此,vimALT组合键<M-p><A-p>等就可以工作了。

This post is licensed under CC BY 4.0 by the author.

Farewell, X-2.1. Farewell, Hasco.

The solution to L2TP VPN connection failure in Win10