1. Qiita
  2. 投稿
  3. Vim

Vim 8.0 Advent Calendar 21 日目 新しい組み込み変数

  • 4
    いいね
  • 0
    コメント
に投稿

この記事は 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 さんに指摘され、残すことになったようです。

この投稿は Vim 8.0 Advent Calendar 201621日目の記事です。
Comments Loading...