この記事は Vim 8.0 Advent Calendar の 21 日目の記事です。
今回は新しく追加された組み込み変数を紹介します。
タイプを表す定数
type()
関数を使うと、変数のタイプを得ることができます。ここで得られる値は数値で、各タイプに数値が割り当てられています。
ある変数が特定のタイプであるかどうかを判定したい場合、今までは以下のようにしていました。
" 以下の例では変数 var が文字列かどうかを判定しています。
" 文字列の type の値は 1 なので、これと比較して判定します。
if type(var) == 1
endif
" マジックナンバーを避けるため、以下のようにすることが多いです。
if type(var) == type('')
endif
この方法には、以下のような問題がありました。
- 若干トリッキーで、慣れないと理解しづらいコードになります。
-
type()
関数を余計に呼ぶため、オーバーヘッドがあります。 - 関数参照の場合は
type(function('type'))
のようになり、長い上にfunction()
関数に渡す関数名が人によってバラバラで統一感がありません。 - 新しく追加された
job
型などの値は気軽に生成できません。
そこで、type()
関数の戻り値を表す定数が新たに追加されました。以下の表が定数の一覧です。
型 | 定数 | 定数の値 | 型の値の例 |
---|---|---|---|
数値 | v:t_number |
0 | 10 |
文字列 | v:t_string |
1 | 'foo' |
関数参照 | v:t_func |
2 | function('type') |
リスト | v:t_list |
3 | [0, 1, 2] |
辞書 | v:t_dict |
4 | {'one': 1} |
浮動小数点数 | v:t_float |
5 | 1.23 |
真偽値 | v:t_bool |
6 |
v:true v:false
|
特殊値 | v:t_none |
7 |
v:null v:none
|
ジョブ | v:t_job |
8 | job_start(cmd) |
チャンネル | v:t_channel |
9 | ch_open(host) |
v:completed_item
補完された対象を表す変数です。
以前までは、CompleteDone
イベントにより補完の完了を知ることはできましたが、どの候補が選択されたかを知ることができませんでした。新しく追加されたこの変数を参照することで、どの候補が選択されたのかわかります。
選択された候補は辞書です。詳しい構造については :help complete-items
で説明されています。補完に失敗した場合は空の辞書になります。
v:hlsearch
検索による強調表示が行われているかを表す変数です。
検索のハイライトは 'hlsearch'
オプションをオンにして検索を行うことで行われますが、:nohlsearch
Ex コマンドを使うことで、一時的にハイライトを無効にできます。このとき 'hlsearch'
オプションの値はそのままなので、ハイライトが行われているのか、:nohlsearch
Ex コマンドで消されているのかが今まではわかりませんでした。
v:hlsearch
変数は、ハイライトが行われている時は 1、行われていない時は 0 になります。
また、値を書き換えることでハイライトの状態を変更できます。ただし、'hlsearch'
オプションがオフの場合はハイライトを有効にできないため、1 を入れても値は 0 のままです。エラーも発生しません。
また、関数の呼び出しは、最後に使用された検索パターンを保存して呼び出し終了後にリストアします。つまり関数内でこの変数を書き換えても、関数の終了時に復元されてしまうので注意してください。
v:progpath
Vim を起動した際のコマンドを示す文字列です。つまり、Vim コマンド自身のコマンドライン引数の 0 番目です。
システムに複数の Vim がある場合に、どの Vim で起動されたかのヒントになります。Vim 内から別の Vim を起動して処理を行いたい場合などに便利です。
echo exepath(v:progpath)
コマンドが相対パスでカレントディレクトリが移動した場合や、$PATH
が変更された場合など、確実に起動した Vim が得られるわけではない点に注意してください。
v:vim_did_enter
Vim が起動して、VimEnter
イベントが発生する直前までは 0 です。VimEnter
イベントが発生する直前に 1 になります。
似たような値に has('vim_starting')
があります。こちらの値は逆で、起動中は 1、起動後は 0 になります。値が変わるタイミングは v:vim_did_enter
と同じです。両者は完全に代替可能です。
ではなぜこの変数が追加されたのかと言うと、実はこれを追加した際、Bram さんは has('vim_starting')
の存在を完全に忘れていました。あとで指摘された際、この変数の追加をリバートすることも検討したようです。
しかし、has()
関数は基本的に Vim のコンパイル時に組み込まれている機能を調べるためのもので、一部の例外を除き Vim 実行中に値が変化しないこと、そのような慣習のため、Vim が起動中かどうかを調べる方法が has()
関数にあることはユーザーにとってわかりづらいことなどを Gary さんに指摘され、残すことになったようです。