matchit.vimの[%、]%、a%は何をしますか?


7

matchitの%/ g%は使用するのに十分単純ですが、他のマッピングを理解するのに苦労しています。これは潜在的に有用に聞こえますが、理解できる方法で機能していないようです。

]%  Go to [count] next unmatched group, as specified by
    |b:match_words|.  Similar to |]}|.

私は、これは多分私がにジャンプできるようにすることを期待するendifendfunction(などが内蔵されたVIM ftpluginを使用して、次vimscriptの例を取り、b:match_words設定することが表示されます。)

function! SuperTab()
  let l:part = strpart(getline('.'),col('.')-2,1)
  if (l:part=~'^\W\?$')
      return "\<Tab>"
  else
      return "\<C-n>"
  endif
endfunction

[%ほとんどの場合、にジャンプしfunction!、時々(カーソル位置に応じて一貫性のない)がにジャンプし、s ifを完全に無視し(ます。 sに]%ジャンプし)、それ以外は何もしません。 この例とva%同じように動作し[%、何も選択しません。これは正常な動作ですか?これらのマッピングが意味を持ついくつかの例はありますか?


1
良い質問!私はそれを有効にして答えを出すと思いましたが、私はあなたと同じくらい困惑しています。私が見る限り、]%ほとんど何もしません。コードを確認する必要があります。
Bレイヤー

バギーかもしれません。ドキュメントとコードのコメントからわかる限り、あなたの提案どおりに動作するはずです。おそらく誰か(@BLayer?または多分私です!)が実際のコードを見て、なぜ/どのようにうまくいかないかを教えてくれます。
リッチ

今週末に返答しようと思います。私は少し前に少し突っ込んで、それがひどくバグがあることを確信していますが、それを深くデバッグしていません。
Bレイヤー

私はちょうどneovimのmatchitでVimを試してみました(意外にVimのとは異なります)、それが動作しているようです。..奇妙github.com/neovim/neovim/blob/master/runtime/plugin/matchit.vim
ミサ

1
ただし、neovim va% ((( )))は繰り返されても「拡張」されませんa%。vimがこれまでに実行されたかどうかはわかりませんが、imoはa(
マス

回答:


6

私は、Vimのgithubリポジトリで現時点で見つけることができる最新のmatchitプラグインバージョン1.13.3を使用していると仮定します。

[%ほとんどの場合、にジャンプしfunction!、時々(カーソル位置に応じて一貫性のない)がにジャンプし、s ifを完全に無視し(ます。

を押す[%と、s:MultiMatch()関数が呼び出されます。後者の最後には、while反復回数がであるループがありますv:count1。この変数は、最後の通常のコマンドのカウントを格納します。ここでは、これ1までに何もヒットしなかったので、になるはずです[%。ただし、関数の途中で:normal、画面とカーソル位置を保存するためにいくつかのコマンドが実行されます。これらの通常のコマンドは、の値を変更しますv:count1

これは次のように確認できます。

nno cd :<c-u>call Func()<cr>
fu! Func()
    echom v:count1
endfu

ソースこのコードは、キーを押しcd、あなたのメッセージを(読んで:messages):あなたが表示されるはずです1、あなたが前に、任意の数をヒットしなかったのでcd。次に、このコードをソースします。

nno cd :<c-u>call Func()<cr>
fu! Func()
    norm! 3G
    echom v:count1
endfu

同様の実験を行い、cd3行を超えるファイルを押し込みます。今回は、メッセージで、3ではなくが表示されるはず1です。

このためsearchpair()、ループ内の関数が何度も呼び出されています。これは、あなたが説明した動作を説明していると思います。少なくとも、私のマシンではそうです(Linux、Vim 8.0パッチ1-134)。

これを修正するには、729行を削除します。

let level = v:count1

そして、それを関数の最初に移動します(コマンドを含む他のコマンドが:normalを変更する前にv:count1):

fun! s:MultiMatch(spflag, mode)
  if !exists("b:match_words") || b:match_words == ""
    return ""
  end
  let level = v:count1

ここに画像の説明を入力してください


私はちょうどvimでneovimのmatchitを試してみました(驚くべきことにvimのものとは異なります)。

これはおそらく、neovimが1年前にマージしたプルリクエスト#5124が原因です。コミットメッセージによると、その目的はmatchit不要なエントリをジャンプリストに追加しないようにすることでした。これを解決するために、画面とカーソルの位置の保存方法が変更されました。:normalコマンドはもう使用しませんが、関数winsaveview()とを呼び出しますwinrestview()。を削除することで:normal、別の目的で、以前に説明した問題がv:count1修正されました。関数の途中にいくつかのコマンドが追加されれば、将来的には可能性があります。


]%)sにジャンプし、それ以外は何もしません。

s:MultiMatch()関数の終わりに向かって、行722で、トークンのグループの終わりの部分を表すパターンは次のように定義されています。

let closepat = substitute(closepat, ',', '\\|', 'g')

置換の目的は、トークンの2つの連続したグループを区切る各コンマを、Vimの正規表現エンジンによって代替(2つのブランチ間の分離)として解釈される二重のエスケープバーで置き換えることです。置換は:、各グループ内のトークンを区切るコロンも置き換える必要があると思います。したがって、次のように置換を書き直すことができます。

let closepat = substitute(closepat, '[,:]', '\\|', 'g')

この変更により、]%は、だけでなく、b:match_wordsおよび&l:matchpairsで説明されているさまざまなトークンにカーソルを移動します)。少なくとも、私のマシンではそうです。

ここに画像の説明を入力してください


va%[%この例と同じように動作し、何も選択しません。

以前の変更、特に2番目の変更ではva%、周囲の2つのトークン間のテキストを選択する必要があります。ただし、プラグインはトークンのグループの中央部分(など)を終了部分として処理するようelseですif|else|endifsearchpair()2番目ではなく3番目の引数を介して渡されます)。したがって、それが周囲のトークンであると見なすものは、時々あなたを驚かせるかもしれません。


ただし、neovim va% ((( )))は繰り返されても「拡張」されませんa%。vimが今までにあったかどうかはわかりませんが、imoはそうであるはずです。のようにa(

現在、ビジュアルマッピングa%は次のように71行目に定義されています。

vmap a% <Esc>[%v]%

oの先頭に追加する{rhs}と、選択範囲の先頭(:h v_o)にカーソルが移動し、目的の動作が得られます。

vmap a% o<Esc>[%v]%

ここに画像の説明を入力してください


これはプラグインのバージョンで、matchitこれまでに説明した3つの小さな変更があります。
そして、もう1つ、NeovimからのPR#5124も含めようとしました。

マシンでコードをテストしたいが、デフォルトのmatchitプラグインを変更する権限がない(または変更したくない)場合は、ファイルを作成し、そこに~/.vim/plugin/matchit.vim実験的なmatchitプラグインを記述できます。

runtimepathの~/.vim前に来るので$VIMRUNTIME、Vimはデフォルトのバージョンの前にカスタムバージョンを調達する必要があります。そして、以来、デフォルトのプラグインにはガードがあります:

if exists("loaded_matchit") || &cp
  finish
endif
let loaded_matchit = 1

...バージョンのみを完全に調達する必要があります。



@ChristianBrabandtわかりました。少し変更される可能性があるマッピング]%v_a%マッピングについて議論するために2つの問題をオープンしました。
user852573 2017

すばらしい答えです!明らかにこれらの機能を使用している人が少ないことに少し驚いていますが、現在何が起こっているのか理解できて嬉しいです。
Mass
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.