vim-users.jp

Hack #35: ex コマンドを実行するキーマッピングを定義する

Posted at 2009/07/02
このエントリーをはてなブックマークに追加

Vim のキーマッピングは、単にキーを入れ替えたり短くするだけでなく、ex コマンドを実行させることもできます。

ex コマンドを実行するキーマッピングの定義方法

Vim のキーマッピングは、定義した通りのキーシーケンスを発生させます。つまり、実際にコマンドを打つときと同じような定義をすればコマンドを実行させることができます。

nnoremap <Space>n :setlocal number! number?<CR>

最初の : で Command-line mode に入り、コマンドを入力した後、最後に <CR> でコマンドを実行します。最後の <CR><Return><Enter> などの別名も用意されているので、これらを使っても構いません。この例では、行番号の表示の on/off を切り替えてその結果を表示しています。

このキーマッピングの定義は :nnoremap を使っているので、 Normal mode でのみ利用可能ですが、その中で Command-line mode に入るのはまったく問題ありません。途中で mode が切り替わった場合、その後のキーシーケンスはそのモードのものが適用されます。これはまさしく、そのキーシーケンスを入力しているのと同じになります。

ex コマンドを伴うキーマッピングを設定する際の注意

実は、先ほどの例は細かい点で不完全です。別の例で説明します。 例えば、以下のようなキーマッピングを設定していたとします。

nnoremap <Space>w :write<CR>

これは <Space>w でファイルを保存するものですが、誤って事前に数字 (ここでは例として 3) を入力してしまうと、以下のようなコマンドが実行されてしまいます。

:.,.+2write

数値を前置したため、範囲指定が自動で挿入されてしまいます。こうなるとこれは指定範囲のみを保存しようとするコマンドになり、(実際には ! を付けない限り実行されませんが、)実行した場合指定範囲外の部分は消えてしまうため非常に危険です。 これを防ぐためには、Command-line mode に入った際に自動入力される部分を削除する必要があります。以下のようにします。

nnoremap <Space>w :<C-u>write<CR>

Command-line mode での <C-u> は、カーソル位置までの入力を削除します。一般的に数値の前置による範囲指定が必要になることはほとんどないので、キーマッピングから ex コマンドを実行させる場合は <C-u> で範囲指定を削除しておく方が安全です。

コマンドライン履歴の扱い

Vim はユーザが実行した ex コマンドを履歴に保存していますが、完全にキーマッピングから実行されたコマンドは履歴に記録されません。ここで言う「完全にキーマッピングから実行されたコマンド」とは、ユーザが直接コマンドラインで文字を入力せずに実行されたコマンドです。これにより、履歴を辿る際に余計なコマンドが混ざるのを防げます。

便利な ex コマンドや ex コマンドでしか提供されていない機能はたくさんありますが、よく使うものや長いものはいちいち入力していると気付かないうちに FP を消費していきます。キーマッピングをうまく使って FP の消費を抑えましょう。

thinca

もどる
blog comments powered by Disqus