Vim のユーザ定義コマンドで式を受け取って評価する場合の注意点

Vim のコマンドではこんな感じに受け取った式をそのまま評価する事が出来ます。

command! -nargs=1 Echo echo <q-args>." = ".string(<args>)

Echo 1 + 1
" => 1 + 1 = 2


上記のようなコマンドでは関数のローカル変数や関数の引数などを渡して評価する事も出来ます。

function! s:func(n)
    let m = 10

    Echo m + 10
    " => m + 10 = 20
    Echo m + a:n
    " => m + a:n = 52
endfunction
call s:func(42)


しかし、次のようなスクリプトローカル変数やスクリプトローカル関数は評価する事ができません。

" Echo とは別の .vim ファイルで定義する
function! s:plus(a, b)
    return a:a + a:b
endfunction

let s:n = 42

Echo 10 + s:n
" E121: 未定義の変数です: s:n
Echo 10 - s:plus(2, 1)
" E117: 未知の関数です: s:plus


これは Echo が s:n や s:plus を評価する場合に Echo が定義されているスクリプトファイルを参照しようとする為です。
(逆にいえばコマンドを定義する時には定義したスクリプトファイルのスクリプトローカル関数や変数なんかを直接使うことが出来ます。
上記のような場合では関数名に を付けるとスクリプトローカル関数でも使用する事が出来るようになります。

function! s:plus(a, b)
    return a:a + a:b
endfunction

" s: の代わりに <SNR>{スクリプト固有の番号} を使用する
" 詳細は
" :help <SID>
Echo 10 - <SNR>228_plus(2, 1)
" => 10 - <SNR>228_plus(2, 1) = 7


スクリプトローカル関数の場合は上記のような形で回避する事ができます。
ただし、スクリプトローカル変数は を付けても参照することができませんので注意して下さい。