VimLのいくつかの機能



この記事では、Vimの優れたアドオンを作成したい人が知っておく必要のあるVimLのいくつかの機能について説明します。 この記事を理解するには、vimscriptの知識が必要です。少なくとも1つのアドオンを作成することをお勧めします。 独自のサプリメントを書きたくない人にとって、この記事はほとんどの場合役に立たないでしょう。

バインディング

再バインド



ありふれたよく知られていることから始めましょう:再バインド。 Vimには、 *map



および*noremap



2つの主要なコマンドファミリがあります。 1つ目では右側を再定義できますが、2つ目ではできません。 さらに、ユーザーがどのバインディングを持っているのかわからないため、2番目のみを使用する必要があります。 古典的な例:
 noremap : ; noremap ; :
      
      



壊れます
 nmap <F4> :PluginToggle<CR>
      
      



しかしではない
 nnoremap <F4> :PluginToggle<CR>
      
      



。 留意すべきその他のコマンド:

また、 「remap」設定の存在に注意することもできます。これにより、 *map



すべてのコマンドが、対応する*noremap



と同じ方法で動作するようになります。 使用できません
 nnoremap <Plug>PluginAction :DoAction<CR> if !hasmapto('<Plug>PluginAction') nmap <Leader>a <Plug>PluginAction endif
      
      



ユーザーがlhsをオーバーライドできるようにし、この設定を有効にしているユーザーをサポートするには、代わりにフォームへのバインディングのすべての定義をリストする必要があります
 execute 'nnoremap '.get(g:, 'plugin_action_key', '<Leader>a').' :DoAction<CR>'
      
      



Vimの古いバージョンと互換性があります
 if !exists('g:plugin_action_key') let g:plugin_action_key='<Leader>a' endif execute 'nnoremap '.g:plugin_action_key.' :DoAction<CR>'
      
      





特殊文字





ファイル(<script>)バインディング



Vimには、バインディングの右側を、同じファイルで定義されているバインディングのみでオーバーライドする機能があります。 ユーザーがバインディングを使用してバインディングの左側をオーバーライドする場合に、限られた有用性(より正確には、その欠如)を残します
 nnoremap <Plug>PluginAction :DoAction<CR> if !hasmapto('<Plug>PluginAction') nmap <Leader>a <Plug>PluginAction endif
      
      



または
 execute 'nnoremap '.get(g:, 'plugin_action_key', '<Leader>a').' :DoAction<CR>'
      
      



この方法を使用すべきでない別の考慮事項があります:コマンド用
 nnoremap <script> lhs rhs
      
      



そして
 nnoremap lhs rhs
      
      



maparg('lhs', 'n', 0, 1)



を呼び出すと、同じ辞書が返されます。 つまり、別の開発者が、たとえば、同じlhs



で一時的に別のバインディングを作成してから古いバインディングを復元したい場合、ファイルバインディングは正しく復元されません。

設定

Vimには、簡単にあなたの人生を台無しにする多くの設定があります:

互換性設定



最も破壊的な設定は'compatible'です。 原則として、それを処理するための最も正しい方法は、ダウンロードを拒否することです。おそらくメッセージが表示されます。
 if &compatible finish endif
      
      



アドオンに対する2番目に破壊的な効果は「cpoptions」設定です:これを使用すると、コマンドの一部が次の行に転送されないようにしたり、バインディングを作成する コマンド 動作を 変更し たり、正規表現 動作を 変更したり できます。 通常、これは部分的に使用して処理されます
 let s:saved_cpo=&cpo set cpo&vim <...> let &cpo=s:saved_cpo unlet s:saved_cpo
      
      



ただし、正規表現の動作が変更されると、何もできなくなります。 関数に影響を与えないことは良いことです(ユーザー定義関数ではなく、 match *()replace()などの組み込み関数を意味します)。

大文字と小文字を区別しない



もう1つの「楽しい」設定は'ignorecase'です。 ただし、互換性の設定とは異なり、単純なルールに従ってそれに対処するのは非常に簡単です。

魔法と繰り返し





ワイルドファイル



expand()glob()またはglobpath()を使用する場合、オプションの引数の最初に1つを指定する必要があります。指定しない場合、 「wildignore」および suffixes」の設定が考慮され、出力から一部のファイルが除外される場合があります。 ただし、逆に有用な場合もあります。

その他の設定





ローカル設定



また、以下に注意する必要があります。setlocalは、排他的にグローバルな設定を変更しようとしても例外をスローしません。 したがって、ヘルプを使用して設定を変更する前に、ドキュメントを調べてからグローバル設定の使用を拒否するか、 BufLeaveイベントで設定を復元し、 BufEnterイベントで値を設定する必要はありません

奇妙なファイル名



ページネーションとコメント

改行と垂直バーの意味、およびコメントを使用する機能は、コンテキストに非常に敏感です。
  1. 組み込みコマンドが引数として式を使用する場合(例:echo )、ダブルストロークは文字列リテラルの開始と見なされ、改行と垂直バーが2つのコマンドを分離します(ただし、文字列リテラル内にある場合はそうではありません)。 チームでこの効果を達成することはできません。
  2. しかし、それがバインディング/略語-式である場合ではなく、パーサーの観点から実際に式を受け入れません。
  3. ファイルからの読み取り/を使用した関数の作成の場合
     execute "function Abc()\n DoSomething\nendfunction"
          
          



    、ここでは新しい行が常に2つのコマンドを区切ります。
  4. チームが垂直バーを引数の一部と見なす場合、改行文字も引数の一部になります(上記を除く)。
  5. 新しい行の先頭にあるバックスラッシュは、コマンドの一部の転送を示します。 ファイルを実行する前にコマンドを使用するかのように動作します
     %s/\n\s*\\//
          
          



  6. ただし、ファイルが実行されている場合のみ。 転送を適用できる場所は他にありません。
  7. バインディング/略語/メニューを作成するコマンドは特別です。ダブルストロークはそれらの一部と見なされますが、文字列リテラルを開始せず、それでも垂直バーはコマンドを中断します。 チームでこの効果を達成することもできません。
  8. endfunction



    を別の行に配置することはできません。 function



    コマンドの後のパーサーは、 function



    属するすべての行を愚かに単にかみendfunction



    、新しい行にあるendfunction



    コマンドに遭遇するまでそれらを配列に格納します。


* Cmd

正しい(Buf |ファイル)(読み取り|書き込み)Cmdの作成は、一見思われるよりもはるかに複雑です。 実際のところ、vimはエンコーディングの自動検出や行の折り返し方法、または++ optの簡単なサポートを提供していません。 gzipで圧縮されたファイルを読み取る標準のアドオンを見ると、解凍されたコンテンツを一時ファイルに保存してから:readを使用してこのファイルを読み取ることがわかります。 これにより、設定'fileformats'および'fileencodings'を使用して行の折り返しとエンコードの方法を推測する必要がなくなりますが、KOI8-Rでエンコードされた圧縮ファイルを開きますfileencodings=utf8,cp1251



場合、 CP1251でエンコード。 アドオンでこれを実行したくない場合は、サービスにv:cmdargがあります。 この変数には常にユーザーデータ++設定が短い形式で含まれているため、++ encおよび++エンコーディングをサポートする必要はありません。 ここに例があります (読み取り、次の関数は書き込み)( 「fileformats」「fileencodings」はここでは無視されます)が、場合によってはv:cmdargは単に:read with :executeに接続できます。 注:readは、シェルコマンド出力の読み取り時に++設定を無視します。

致命的でないエラー

コマンドのリストを読んだばかりの人には、コマンド:echoerrがエラーを表示する良い方法のように思えるかもしれません。 実際、これはそうではありません。表示されたエラーがプログラムの実行を中断しないようにする方法はありません。 このコマンドにプログラム実行の中断を保証することができますが、代わりに
 try echoerr 'Error' endtry
      
      



あなたは簡単に書くでしょう
 echoerr 'Error' " some code here
      
      



ブロック内にコードを配置するかどうかに応じて、「コード」が実行されるかどうかに関連する奇妙な問題をデバッグする必要があるという事実に備えて:try



:try



ブロックの中に、決して実行されないコードのみを配置することはできないことを考慮して:try



ユーザーは、次のように記述してコードを正確に配置する理由を複数持つことができます。

プログラムを中断せずにエラーを表示する必要がある場合は、
 echohl ErrorMsg echomsg 'Error' echohl None
      
      



。 実行を中断する必要がある場合は、 throwがあります。 そして、 :throw



によって生成されたエラーメッセージにまったく満足していない場合のみ
 try echoerr 'Error' endtry
      
      



。 シンプル:echoerr



いいえ、忘れる必要があります。

テキストファイルではない

ファイルを操作し、Vimでゼロを含むか新しい行で終了しない可能性のあるコマンドを出力すると、その正確さを維持する必要がある場合に多くの「楽しい」分を提供できます。 以下にいくつかの事実を示します。

不平等

Vimには、同等性をチェックするための6つの演算子と、不平等をチェックするための同じ数の演算子があります。

したがって、推奨される使用規則:
  1. スカラー型の比較でis#



    使用しis?



    isnot#



    またはisnot?



    (違いは設定/ケースを無視セクションで説明されています)。
  2. 非スカラー型の比較では、アイデンティティではなく値の等価性を見つける必要がある場合、 ==#



    ==?



    を使用する必要があり==?



    !=#



    または!=?



  3. 演算子==



    is



    isnot



    !=



    およびisnot



    を完全に忘れてはなりません。


私が順守し、セットの文字数を減らすことができるルールの別のセットがあります:
  1. 引数の1つが数値定数であり、コードのそれ以降のもう1つが数値としてのみ使用される場合、 ==



    を使用できます。
  2. 引数の1つが数値定数の場合、 is



    を使用できます。
  3. 次に、前のリストのルールを使用します。 ==#



    数値を「特別な引数」として使用する必要があるかどうかを考えたくないので、文字列には適用しません( None



    代わりに0



    など)。


機能

Vimの興味深い機能の1つは、関数を参照する変数を使用することです。 既にそのような変数を取得できると聞いた場合
 let Func=function("tr")
      
      



、変数名が大文字で始まることもおそらくご存知でしょう。さもないと、Vimがエラーを表示するからです。 ただし、あまり知られていないもう1つの事実があります。そのため、変数に関数参照を割り当てないでください。「Func」関数をどこかで定義した場合、Vimもエラーを表示します。 関数参照を使用する安全な方法は2つしかありません。それを引数として渡し、複雑な構造を使用する:辞書またはリスト:
 let d={} let d.func=function("tr")
      
      



同様に
 function Apply(func, list) return call(a:func, a:list, {}) endfunction echo Apply(function("tr"), ["abc", "a", "d"])
      
      



a:func()



関数を定義a:func()



可能性があるにもかかわらず、完全に安全です。

特殊キャラクター!

ご覧のとおり、ファイル名の代わりに%記号を使用すると便利です。たとえば、次のようになります。
 nnoremap <F4> :!python %<CR>
      
      



? これはVimのもう1つの便利な機能であり、うまく機能していれば便利です。 ファイル名にはスペース/ストローク/ドル(* sh)を使用し、ファイル名の代わりに、このバインディングのインタープリターは何でも取得できます。 Vimには%:t



[ail](名前の最後の部分のみを残す)のような現在のファイル名に対する多くの修飾子がありますが、修飾子%:E



[ scape ]はshellescape()を介しファイル名を実行します。 したがって、呼び出しのコンテキストを忘れずに、すべてを自分でスクリーニングする必要があります: system()を使用する場合、 shellescape()は、1つ目の引数または2つ目の代わりにゼロで呼び出す必要があり、 :!:読んでください!:書く! およびその他の感嘆符-2つの引数と1つが2番目の引数です。 例:
 nnoremap <F4> :execute '!python' shellescape(@%, 1)<CR> nnoremap <F5> :call system('javac '.shellescape(expand('%')))<CR>
      
      





正規表現機能



Vim , . : . , , -complete=dir



-complete=file



, :
 command -complete=dir -nargs=1 -bar Echo :echo [<f-args>] command -nargs=1 EchoN :echo [<f-args>]
      
      



 :Echo abc E172:       :EchoN abc ['ab c'] :Echo * E77:     :Echo $HOME ['/home/zyx'] :Echo `date` ['. . 28 17:17:47 MSK 2012']
      
      



。 , , , . , . , . .



All Articles