*:set-termcap* *E522*
For {option} the form "t_xx" may be used to set a terminal option. This will
override the value from the termcap. You can then use it in a mapping. If
the "xx" part contains special characters, use the <t_xx> form: >
:set <t_#4>=^[Ot
This can also be used to translate a special code for a normal key. For
example, if Alt-b produces <Esc>b, use this: >
:set <M-b>=^[b
(the ^[ is a real <Esc> here, use CTRL-V <Esc> to enter it)
The advantage over a mapping is that it works in all situations.
You can define any key codes, e.g.: >
:set t_xy=^[foo;
There is no warning for using a name that isn't recognized. You can map these
codes as you like: >
:map <t_xy> something
当然,如果你真能在100ms内连续按下 ESC和 X的话,那是另外一回事情了,你可以调短 ttimeoutlen到50ms解决,但是不建议该值低于 25ms,否则在低速网络情况下,你按功能键会被vim错误识别成几个单独的按键序列。这不是 vim 的锅,而是终端标准的锅,ncurses 和 tmux 也都靠超时来检测功能键。
好了,帖一段代码吧:
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
command! -nargs=0 -bang VimMetaInit call Terminal_MetaMode(<bang>0)
上面在 SecureCRT / XShell 中设置了将 alt 键作为发送 +ESC x 的 meta 键后,你会发现,终端软件中固有的一些 ALT 组合键全部失效了,比如原来在终端中 ALT1 到 ALT9 可以切换终端的 TAB,ALT_B 可以打开链接管理器,这下都全部用不了了,这是件比较坑爹的事情,能不能保留有限的几个 ALT 组合键给终端软件使用,剩下的全部当作 meta 键呢?答案是可以的,先取消终端里 ALT 当作 meta 键的设置,恢复成默认状态,然后打开终端软件 keymap 设置窗口,将你不需要保留的 ALT 组合键全部设置成发送 +ESC x 字符串。
那么一个个设置可能有些麻烦,对于 SecureCRT 的话,我生成了一个配置文件:
A VK_A "\033a"
A VK_D "\033d"
A VK_E "\033e"
A VK_G "\033g"
A VK_H "\033h"
....
AS VK_A "\033A"
AS VK_B "\033B"
AS VK_C "\033C"
AS VK_D "\033D"
%:p - File name of current buffer with full path
%:t - File name of current buffer without path
%:p:h - File path of current buffer without file name
%:e - File extension of current buffer
%:t:r - File name of current buffer without path and extension
% - File name relativize to current directory
%:h:. - File path relativize to current directory
<cwd> - Current working directory
<cword> - Current word under cursor
<cfile> - Current file name under cursor
运行一个命令前,环境变量也会做如下设置:
$VIM_FILEPATH - File name of current buffer with full path
$VIM_FILENAME - File name of current buffer without path
$VIM_FILEDIR - Full path of current buffer without the file name
$VIM_FILEEXT - File extension of current buffer
$VIM_FILENOEXT - File name of current buffer without path and extension
$VIM_CWD - Current directory
$VIM_RELDIR - File path relativize to current directory
$VIM_RELNAME - File name relativize to current directory
$VIM_CWORD - Current word under cursor
$VIM_CFILE - Current filename under cursor
$VIM_GUI - Is running under gui ?
$VIM_VERSION - Value of v:version
$VIM_MODE - Execute via 0:!, 1:makeprg, 2:system()
$VIM_COLUMNS - How many columns in vim's screen
$VIM_LINES - How many lines in vim's screen
let $VIM_FILEPATH = expand("%:p")
let $VIM_FILENAME = expand("%:t")
let $VIM_FILEDIR = expand("%:p:h")
let $VIM_FILENOEXT = expand("%:t:r")
let $VIM_FILEEXT = "." . expand("%:e")
let $VIM_CWD = expand("%:p:h:h")
let $VIM_RELDIR = expand("%:h")
let $VIM_RELNAME = expand("%:p:.")
let $VIM_CWORD = expand("<cword>")
let $VIM_VERSION = ''.v:version
let $VIM_MODE = ''. a:mode
let $VIM_GUI = '0'
let $VIM_SCRIPT = g:vimmake_path
let $VIM_SVRNAME = v:servername
if has("gui_running")
let $VIM_GUI = '1'
endif
Recent Comments