Vimプラグインを作っているときに,input()
で<Esc>
キーを感知できればいいなと思ったのがきっかけである.
どうやら,ここに書いてあるinput()
のラッパー関数を使えばOKのようだ.
function! s:input(...) abort new cnoremap <buffer> <Esc> __CANCELED__<CR> let ret = call('input', a:000) bwipeout! redraw if ret =~# '__CANCELED__$' throw 'Canceled' endif return ret endfunction
このラッパー関数が行っていることは,
- 新しいバッファを作成.
- バッファローカルなコマンドモードの
<Esc>
キーのマッピングを定義. input()
関数コール時に,<Esc>
キーの入力を検知すると,__CANCELED__<CR>
を入力したことになる.例えば,aa<Esc>
という入力はaa__CANCELED__
という入力と等価になる.- 入力文字列の末尾が
__CANCELED__
ならば,が押されたと判断し,例外を投げる.
ただし,redrawは必ずしも必要でないことや,<C-c>
の割り込みを考慮すると,以下のようにするのがよいだろう.
(個人的な好みで,<Esc>
時には数値0を,<C-c>
時には数値-1を返却するようにしてある.)
function! s:input(...) abort new cnoremap <buffer> <Esc> __CANCELED__<CR> try let input = call('input', a:000) let input = input =~# '__CANCELED__$' ? 0 : input catch /^Vim:Interrupt$/ let input = -1 finally bwipeout! return input endtry endfunction
今回の方法は非常に画期的ではあるが,inputlist()
では同様の手法を用いることができなかった....