vimrcから呼び出すことができるプラグインでコマンドを設計する方法


8

ユーザーがカスタムオペレーターを作成できるようにするプラグインに取り組んでいます。オペレーターは、移動するモーションまたはテキストオブジェクトにVimL式を適用します。

クリーンなユーザーインターフェイスを維持する

カスタムオペレーターを定義するための最もクリーンなインターフェイスは、コマンドを使用することだと思います。:MapExpress次のようなコマンドを呼び出すコマンドを定義しました。

:MapExpress cd '/* ' . v:val . ' */'

これはcd、Cスタイルのコメント区切りでモーションまたは選択を囲むために、ノーマルモードオペレーターとビジュアルモードマッピングを作成します。

もちろん、ここに問題があります。プラグインで定義されているコマンドを.vimrcファイルから呼び出すことはできません。

不十分な回避策

私は完全に満足していないいくつかの回避策を考え出しました。

ユーザーautocmd VimEnter *がコマンドを呼び出すために使用する

これは機能しますが、多くの「精神的オーバーヘッド」が追加されます。多くのVimユーザーはどのようにautocmd機能するかをしっかりと把握していないと思います。

ユーザーが~/.vim/after/plugin/コマンドを呼び出すファイルを作成します

これも機能しますが、この構成の一部が独自のファイルでオフになり、簡単に失われて忘れられるという欠点があります。

コマンド定義をプラグインのautoload/ディレクトリに移動し、ユーザーがファイルのロードをトリガーするいくつかのメソッドを呼び出して、コマンドを定義します

これは次のようになります。

call express#init()
MapExpress cd '/* ' . v:val . ' */'

少し良いですがexpress#init()、プラグインが機能するためにメソッドが必要かどうかについて混乱を招きます。

コマンドを使用する代わりの方法

オペレーターを定義するコマンドを使用するいくつかの代替案も検討しましたが、それぞれに注意点があります。

ユーザーは関数を呼び出して演算子を定義します

これは次のようになります。

call express#operator('cd', '"/* ".v:val." */"')

これはひどいことではありませんが、引用符で囲まれた式が必要になるという欠点があります。式で引用符を使用したい場合は、煩わしいことがあります。

ユーザーが<expr>マッピングを使用

このような:

nmap <expr> cd express#nmap('"/* ".v:val." */"')
xmap <expr> cd express#xmap('"/* ".v:val." */"')

これは同じ退屈な引用式の要件があり、変数を導入しない限り(理想的ではない)、DRYにも違反します。

さて、それで何?

ここに私のアイデアのすべてと、それらのどれも好きではない理由があります。私はうるさいですか?私が考えていないいくつかのより良い解決策はありますか?


2
オートロードソリューションは、特にそれがやっていることに対して少し具体的な関数名を使用する場合は、それほど悪くないように思えます。あなたのプラグインがautoload initが必要とされていない他の機能を知らずに良い例を思いつくことは難しいですが、多分何かcall express#initMapCommands()?ただし、追加の引用が必要なものはすべて、非常に悪い考えです。
リッチ

これは私が傾いていることだと思います。
tommcdo 2015年

@tommcdoと今日私は<q-args>実際にどのように機能するかを学びました。ありがとう
D.ベンノーブル

回答:


5

あなたが探しているようです:runtime。.vimrcからプラグインで定義されたコマンドを完全に実行できますが、その前に(プラグインを定義する)プラグイン名を知っている必要があります。

" 1- Prepare the plugin-suite if it's managed through VAM/Vundle/NeoBundle/...
ActivateAddons FooBar

" 2- Be sure the plugin is loaded
runtime plugin/foobar.vim

" 3- And finally run (defensively) the command
if !exists(':FooBar')
   echo "Sorry some initializations will be ignored as foobar is nowhere to be found"
else
   FooBar abc
   FooBar 135468
endif

注:オートロードソリューションとは異なり、このアプローチでは.vimrcソースがクラッシュしません。autoloadプラグインが(関数の実行によって)見つからない場合、vimはエラーをスローします。:runtimeプラグインをロードできない場合はサイレントのままです。


1
これはエンドユーザーにとって多くの作業です。プラグイン開発者として、私はプラグインを使用するために必要な労力を最小限に抑えようとしています。
tommcdo 2015年

このソリューションは、プラグインがインストールされていない場所にデプロイできる.vimrc用です。簡略化されたインストールガイドについては、それだけ:runtimeです。それ以外の場合は、romainlが提案するオプションを使用します。
Luc Hermitte 2015年

それでも、ユーザーはファイルの場所を知る必要があります。彼らがプラグインマネージャーを使用している場合、それはどこよりも明白ではないかもしれませんplugin/
tommcdo 2015年

彼らがプラグインマネージャーを使用する場合、それは常に存在しますplugin/-このように「プロジェクト」/リポジトリを整理する場合。プラグインマネージャは'runtimepath'オプションを自動的に更新します。
Luc Hermitte、2015年

ああ、良い点。
tommcdo 2015年

2

リストはIMOが最も簡単なソリューションです。

let g:pluginname_my_operators = [
    ['cd', '/* ' . v:val . ' */'],
    ['cm', '<em>' . v:val . '</em>']
]

チェックしg:pluginname_my_operators、あなたのプラグインと実行を初期化する際に:MapExpress適用される間は、まだユーザーがオンザフライ定義するためのコマンドを使用することを可能にする場合は、各項目に。


2
これは実際にはより多くの引用が必要になります... v:valマップの内部が呼び出されたときに評価されるため、文字列の一部である必要があります。引用を含むソリューションは理想的とは言えないと思います。
tommcdo 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.