ユーザ定義コマンドで [range] が与えられたかどうかを調べる方法

最近発見した方法。

基礎知識

ユーザ定義コマンドを定義する際、-range= 引数を使うことで :[range]Command のように [range] を受け取ることができるようになる。
指定の仕方で無指定の場合のデフォルト値が変わり、-range で現在行、-range=% でファイル全体、-range=N で N 行目になる。
入力された行番号は、<line1> <line2> で取れる。

:command -range=% RangeTest echo <line1> <line2>
" バッファが10行だったとすると…
:RangeTest     => 1 10
:%RangeTest    => 1 10
:2,5RangeTest  => 2 5

問題点

ユーザが範囲を無指定で実行したのか、デフォルト値と同じ範囲を指定したのかどうかが判断できない。

解決策

以下のようにする。

function s:cmd(range_given, line1, line2)
  if a:range_given
    " 範囲が与えられた
  else
    " 範囲無指定
  endif
endfunction
:command -range=0 RangeTest call s:cmd(<count>, <line1>, <line2>)

-range のデフォルト値を0にする。こうすると [range] を与えられなかった場合は <count> に 0 が入る。[range] が与えられた場合は、line1 と同じ値が入る。普通行番号は 1 から始まるので、必然的に <count> には 1 以上が入る。
一応ユーザが :0RangeTest とすることも可能だが、それこそ意図的に入力しない限りありえない入力だろうし、ここは区別できなくても問題ないと考えられる。

ちなみに先日更新した scouter.vim でこの方法を使って [range] を受け取って処理できるようにした。quickrun.vim も現在は区別できない方法を使っているので、そのうちこの方法を使うように修正する予定。