オートコンプリート中にfoldexprを無効にする方法はありますか?


7

vimのfoldメソッドがオートコンプリートの効率に影響を与えることに気づきました。たとえばC-N、低速で、C-X L比較的高価なfoldexprs を含む中サイズのファイルではひどく遅いです。

オートコンプリートの実行中にfoldexprを参照することの価値がわからないので、これを何らかの方法で無効にして、使用可能なオートコンプリートを取得できるようにします。

助言がありますか?


編集:テストケース

テストケース:プラグインなし。これだけで、これは可能な限り最小の foldexpr関数でなければなりません(呼び出しを数えることを除いて、完全に役に立たない).vimrc

let g:c = 0 
function! Myfoldexpr() 
   let g:c = 1 + g:c 
   return '0' 
endfunction

空白のドキュメントからvimを起動します。Vim独自のヘルプファイルの最初の100行をコピーし、オートコンプリート行を実行して、10番目の提案を選択し、foldexprが呼び出された回数を確認します。

:help
y100j:q
P:set foldexpr=Myfoldexpr()
:set fdm=expr
O<C-X><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><Esc>
:echo g:c
2088

これは、100行のファイルで、比較的短い行であり、foldexprは2088回呼び出されました(ただし、最初にfoldexprを設定するときにこれらの100が実行されます)。効率的なfoldexprは明らかに優れていますが、プログラマーは多くのfoldexprに質問するため、それらは必ずしも自明ではなく、実行時間が数千倍になると、オートコンプリートまたはインデントのどちらかを選択して生産性を高めることができます。貪欲/怠惰であること両方を使用できるようにしたいと思います!かなりよく確立されたいくつかのfoldexprベースの折りたたみプラグインを書き直そうとする以外に(phpの折りたたみを書き直してみましたが、何日か実行可能な状態に最適化しようとしたので、phpのfoldexprをあきらめました)、おそらく使用する方法がありますfdm=manualオートコンプリートなどの前にマッピングする必要がありますか?


vim_devリストへの投稿を検討しましたか?
lcd047

私はここに何か役立つものを投稿しますが、これはvim_devリストの投稿です
artfulrobot

あなたのテストケースは間違っていると思います。テストファイルを作成し、テキストを追加する場合(を実行するだけiHello<Esc>で、g:c変数もに増加し20、実行oWorld<Esc>するとそれが実行されます38...したがって、評価の数はfoldexpr補完の使用とは無関係のようです... 最小限のvimrcでVimをロードしてみてくださいファイルを作成し、問題が引き続き発生するかどうかを確認します。別の設定またはプラグインである可能性があります
Martin Tournoij

「オートコンプリートを実行しているときにfoldexprを参照しても意味がありません」テキストを挿入しています。そのため、Vimは折りたたむ行を再計算する必要があります。
Martin Tournoij、2015年

テストケースは意図的に愚かであり、=を返します。しかし、大きさのオーダーから、何かが上がっていることがわかります。2番目のコメントでは、そうですが、挿入候補の最後に(の場合と同様にp)実行する必要があると思います。これは、挿入候補の文字ごとに行うことだと思います。
artfulrobot 2015年

回答:


4

しばらく前に構文フォールディングPHPで問題がありました。{対応するクロージングを入力するまで、タイプすると後続のフォールドが妨げられます}。挿入モードのときに、foldmethodを一時的に手動に設定するようにという提案(Vim Wikiにあったと思います)を見つけました。これがあれば、私にはわからないProposのàの答えではなく、コメントを作るのに十分な、しかし、コメント内のコードが推奨され、おそらくあなたの状況のためにそれを適応させることができます。ここに私の.vimrcからの2つの関連する行があります。

autocmd InsertEnter * if !exists('w:last_fdm') | let w:last_fdm=&foldmethod | setlocal foldmethod=manual | endif
autocmd InsertLeave,WinLeave * if exists('w:last_fdm') | let &l:foldmethod=w:last_fdm | unlet w:last_fdm | endif

2

おそらく、マッピングを使用してfdm=manualオートコンプリートなどの前に有効にする方法はありますか?

まあ、これはそれを行います:

inoremap <C-x> <Esc>:setlocal foldmethod=manual<CR>a<C-x>
autocmd CompleteDone * :setlocal foldmethod=expr
autocmd InsertLeave * :setlocal foldmethod=expr

を呼び出す前<C-x>にまずtoを設定するfoldmethodようmanualに再マッピング<C-x>し、CompleteDoneおよびInsertLeaveautocommandsを使用してにリセットしexprます。

これを<C-l>11回押すことでテストしました。私のg:c価値観:

  • Vimの起動後:202
  • このハックで:408
  • このハックなし:2130

コメントで述べたように、このハックは必要ありません。「比較的高価なfoldexpr」とおっしゃっていましたが、これが本当の問題だと思います。もちろん、あなたがを投稿しなかったため、確信が持てませんが、foldexprこれについて新しい質問をすることは価値があると思います(「このfoldexprをより速くするにはどうすればよいですか?」)。


ありがとう、これを試してみます。特定のfoldexprについては、Pythonの場合はgithub.com/tmhedberg/SimpylFoldを、phpの場合はgithub.com/swekaj/php-foldexpr.vimを参照してください。しかし、はい、私たち2人はそれが別の質問であることに同意します!
artfulrobot 2015年

@artfulrobot Python foldexprも私にとって非常に遅いです...この特定のケースでこれを改善できるかどうかは不明なので、この回避策はここで最善かもしれません:-/ PHP foldexprが必要な理由がわかりませんか?構文ファイルはそれを行うことができません(これは通常より高速です)
Martin Tournoij
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.