web-dev-qa-db-ja.com

Vim-関数を記述せずにカスタムコマンドに複数の引数を渡すことはできますか

.vimrcファイルに次のカスタムコマンドを記述しました。

command! -nargs=+ Sub :%s/<args>/g

これにより、ある単語を別の単語に置き換えることができ、次のように実行されます。

:Sub <Word>/<new Word>

次のように、複数の引数を使用してコマンドを記述したいと思います。

:Sub <Word> <new Word>

複数の引数を受け入れるようにコマンドを書き直すことはできますか?

理想的には、次のようなものが欲しいです。

command! -nargs=+ Sub :%s/<arg1>/<arg2>/g

前もって感謝します。

2
Alex Mckay

自分で解析を行う

_:help <q-args>_ を使用すると、引用符で囲まれた文字列を取得できます。これは、スペースで区切られた2つの部分に split() できます。

_command! -nargs=+ Sub execute '%substitute/' . split(<q-args>, ' ')[0] . '/' . split(<q-args>, ' ')[1] . '/g'
_

少しのメタプログラミング(call())とprintf()を使用して、これを2回解析することを回避できます。

_command! -nargs=+ Sub execute call('printf', ['%%substitute/%s/%s/g'] + split(<q-args>, ' '))
_

これは機能しますが、エラー処理はまだ適切ではありません(1つの引数のみを渡すと、E766: Insufficient arguments for printf()で文句を言います)。コードを_:function_に抽出することで、より詳細に制御できます。

Vimは引数を解析できます

別の_:function_を使用すると、Vimは _:help <f-args>_ を介して引数の解析を行うこともできます。

_command! -nargs=+ Sub call Sub(<f-args>)
function! Sub( ... )
    execute printf('%%substitute/%s/%s/g', a:1, a:2)
endfunction
_

関数を使用すると、引数の正しい数を簡単に確認できます。

_function! Sub( ... )
    if a:0 != 2
        echo "Need two arguments"
        return
    endif
    ...
_

関数の欠点は、エラー(パターンが一致しない、バッファを変更できないなど)により、複数行のわかりにくいエラーメッセージが表示されることです。 _try...catch_を使用して、ニースの1行のエラーメッセージを取得する必要があります。

ボーナス:そこからどこに持っていくか

  • _:s_コマンド(および使用される区切り文字)をユーザーから隠しているので、区切り文字をエスケープする必要はないと思います。 _a:1_/_a:2_の代わりにescape(a:1, '/')を使用してください。
  • _:help :command-range_ を使用すると、コマンドをデフォルトでバッファ全体で機能するようにすることができますが、他の範囲を渡すこともできます。

また、コマンドが実際にその重みを引き出すかどうかも検討してください。使用される構文解析に関係なく、引数の空白には問題があり、元の_:s_にはない欠点があります。私が見る唯一の利点は、入力が少し簡単なことですが、コマンドラインに不完全な_:s_コマンドを事前に入力し、カーソルを右に置くマッピングを介して同じことを実現することもできます。真ん中。

2
Ingo Karkat