見出し画像

vim pluginについての勉強メモ

vimプラグインの作成方法について勉強しつつメモしていきます。

プラグインについて勉強方法

プラグインについてのネット上の記事を探してみたけど、断片的な記事が多い印象なので、プラグインについてはvimのヘルプを読みつつ学ぶのがよさそう。

ipad proでVBAの勉強サイトを参照しつつ、ネットにつながっていないwindows98のエクセルにVBAの勉強サイトの内容を写経することで勉強しているのだけれど、写経していくと、地道な作業だけれど、とてもしっかり勉強できて覚えやすいことが分かったので、さすがに全部じゃないけれど、要点はvimのマニュアルを写経しつつ勉強していこうと思います。

写経しつつ自分でなりの解釈や意見も付加しつつこのコンテンツに書いていきます。


vimでプラグインについてのヘルプはコマンドラインモードで確認することができる。

:h write-plugin

上記でvimのヘルプファイルusr_41.txtが開かれる。

vimのpluginとは

vimのプラグイン=vim scriptで書かれたソースコードのこと。

pluginディレクトリにプラグインの一連のファイルのコピーを保存することで、すぐに使うことができる。

もしvimが-evalでコンパイルされているバージョンの場合はプラグインを使うことができないとのこと。

$ vim --version

でvimのバージョンを確認したときに、eval featureが+evalだと有効。


プラグインには2種類ある。

global plugins:

すべてのタイプのファイルに対応するプラグイン。


filetype plugins:

ある特定のファイルタイプだけに対応するプラグイン。

.htmlファイルの場合のインデントと.cppファイルの場合のインデントなど、ファイル形式に合わせて自動でvimの設定がされるようにしたい場合などに使う。


vimのコンパイル時にデフォルトで組み込まれているような機能じゃなく、あとからプラグインとして追加して組み込みたいような機能をプラグインとして利用していく。


vimがスタートしたとき、自動的にglobal pluginが読み込まれる。

vim起動時に読み込まれるプラグインをstandard pluginと呼ぶ。


vimのヘルプのstandard-plugin-listにstandard pluginに該当するファイルが記載されている。


standard-plugin-listを確認したところ、自分で追加したプラグインのうち、standard pluginに該当するプラグインはvimのヘルプのstandard-plugin-listの下の方に、LOCAL ADDITIONSという項目名で追加で記載されていました(dein.vimやairlineなど)。


プラグイン名

プラグインをつくるときは、まずプラグインの名前を決める。

プラグイン名は、自分の使っているvim環境で重複した名前をつけないようにしないといけない。

同じ名前で違う機能のプラグインがないかに注意が必要。

プラグイン名から中身が想像できるようにしないと、どんな機能のプラグインなのかがわかりにくくなってしまう。

MS-windowsに対応するためにも、プラグイン名は8文字以内にするのがいい。

別に8文字以上でも大丈夫みたい。


プラグインの構成

Body

プラグインのスクリプトを書く。


Header

ファイルの上部に、ヘッダー情報として作成者、バージョン、作成日などのメタ情報を書く。

License情報も書く。

ライセンス情報としては、public domainまたはvim Licenseを使う。

public domainとは、知的財産権のない状態。

vim licenseについてはヘルプでLicenseを参照。


特定のプラグインをロードしない設定方法

下記のように書くとできる

if exists("g:loaded_typecorr")
 finish
endif
let g:loaded_typecorr = 1

"g:loaded_typecorr"の変数の名前は、loaded_に続けて、無効にしたいプラグインのファイル名をそのまま書く。


mapの利用

プラグインを使うときにmapを使うと、プラグインで定義されているコマンドを使うときに、プラグインのコマンドをショートカットキーに割り当てることができる。

例)

map <unique> <Leader>a  <Plug>TypecorrAdd;

<unique>を付加すると、コマンド(<Plug>TypecorrAdd)に対するマップがすでに存在しているときにエラーメッセージを出してくれる。

<Leader>キーはデフォルトはバックスラッシュなので、リーダーキーを設定しない場合はバックスラッシュを使う。

上記の例では、\aとなる。

リーダーキーの設定方法: 例)let mapleader = "_"
この場合は"_"がリーダーキーになるので、"<Leader>a"は"_a"となる。


mapをユーザーが自分で定義できるようにする方法

if !hasmapto('<Plug>TypecorrAdd;')
map <unique> <Leader>a  <Plug>TypecorrAdd;
endif

<plug>TypecorrAddという機能に対するマップが定義されていないかチェックし、なければこの<plug>TypecorrAddに対してリーダーキーを設定するというスクリプト。

上記のように書いておくと、ユーザーがvimrcに下記のように書くことで自分でmapを定義できる。

プラグインファイル作成側がプラグインのファイルに上記を書いておき、ユーザーがvimrcで自分の好きなmapを定義することができる。

# .vimrcでユーザーが<Plug>TypecorrAddに対し自由にmapを定義
map ,c <Plug>TypecorrAdd;

# ,cキーで<Plug>TypecorrAddが実行できるようになる。


関数に"s:"を活用する

プラグインが増えてくると、他のプラグインと同じ関数名が存在してしまうということが発生する。

関数定義で関数名の前にs:をつけると、そのプラグインのvim scriptファイル内だけ有効なローカルスコープになる。

例えばグローバルスコープの関数でadd()という関数、スクリプトスコープでs:add()が定義されていて、vim scriptファイル内だけで有効な同じ関数名のs:add()を呼び出したいときは,

s:add()とすればよい。グローバルスコープの関数を呼び出したいときは、add()とすればよい。

<SID>+関数名 で関数のIDを作ってくれる

マッピングのときに<SID>を関数名の前につけると、関数のIDを生成してくれる。この生成したIDを利用して、他のマッピングからこのIDの関数を参照して利用するといった使い方で使う。

関数の結果を他で使える。

例えばsum(1 + 2)という関数の結果を他で使いたいとき。


if !hasmapto('<Plug>TypecorrAdd;')
map <unique> <Leader>a  <Plug>TypecorrAdd;
endif


noremap <unique> <script> <Plug>TypecorrAdd  <SID>Add
...

noremap <SID>Add  :call <SID>Add(expand("<cword>"), 1)<CR>

<unique> <script> <Plug>TypecorrAddを<SID>Addにマッピングする。

<SID>Addを:call <SID>Add(expand("<cword>"), 1)<CR>にマッピングする。


1. \aで関数のTypecorrAddが実行される

2. TypecorrAddに<SID>Addがマッピングされ<SID>Addが呼ばれる。

3. <SID>Addで :call <SID>Add(expand("<cword>"), 1)<CR>が実行される。

\a -> <Plug>TypecorrAdd -> <SID>Add -> :call <SID>Add(expand("<cword>"), 1)<CR>という順番で、シーケンスのようにマッピングで関数が呼ばれていく。

同時に、他のvim scriptでも<SID>Addを上記とは別内容でmapすると、別のscript IDが付与されるので、同じAddでもちゃんと別ものとして分けられる。そのため、別のマッピングとしてAddが使える。

<SID> Add()はmapで使いs:Add()は使わないようにするとよい。mapはプラグインを使うユーザーがvim scriptの外側で使うものであるから。

というかmapでvim scriptのファイル内で定義されているs:スコープの関数は使えなさそうな気もする。

<script>を付与することによって、他でマッピングが重複していても、このスクリプト内特有の関数として再マッピングできるようになる。

{rhs} (右側)の"<SID>" で始まるマップだけが再マップされる。





jfaof@
















またどんどん内容を追記していきます。







nko

この記事が気に入ったらサポートをしてみませんか?