最近発見した方法。
基礎知識
ユーザ定義コマンドを定義する際、-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 も現在は区別できない方法を使っているので、そのうちこの方法を使うように修正する予定。