回答:
ここに私がそれをする方法があります。これを追加します.vimrc
vnoremap if [[O][
説明:vnoremap は、視覚モードのときにif
左側[[mO][
を右側にマップすることを意味します。In Functionをif
意味しますが、必要に応じて名前を変更できます。関数の先頭にジャンプします。視覚的に選択したテキストのもう一方の端に移動してから、関数の最後に移動します。[[
O
][
したがって、関数で検索する場合は、で視覚モードに入りv
、で関数全体を選択しますif
。で視覚モードを終了し<esc>
、で検索し/\%V
ます。\%V
以前に選択したテキストに検索を制限します。ヒット<esc>/\%V
する必要がない場合は、これをに追加することもできます.vimrc
。
vnoremap / <esc>/\%V
次に、キーストロークのシーケンスは次のようになります。
vif/foo<enter>
これにより、現在の関数でfooがすべて出現します。
このメソッドの唯一の欠点は、開き中括弧と閉じ中括弧の両方にインデントが0あることを期待することです。これを持たないコードを定期的に使用する場合、例えば
int foo() {
bar()
}
この少し複雑なバージョンが機能します:
vnoremap if ][ma%O'a
これは、右中括弧に0のインデントがあることのみを想定しています。開始ブレースにインデントがある場合、マークは使用しますが、機能します。マーク「a」を定期的に使用する場合は、これを移動できます
vnoremap if ][mb%O'b
vnoremap if ][mc%O'c
...
{
からを使用%
して、一番下の行に到達できます。C ++で関数がどのように開始されるかはわかりませんが、これはJavascriptでは問題なく動作しますvnoremap if <Esc>?^\s*function<CR>v/{<CR>%o
CTRL-]
カーソルの下のタグにジャンプします。現在の機能の開始ではありません。助けにはなりません。
:linenumber
、vimはプラグインで私がしたことを実行できます。しかし、保証はなく、これらのコマンドは代わりに検索することができます-Vimは/pattern
すべてのパターンをテストして、どれが現在の機能に一致するかを知ることができません.IOW 、私は現在の開始にジャンプするvimアクションを認識していません関数
DJ McMayhemのソリューションは、関数の境界の適切な分析を行うためにctagsとmatchitに依存する独自のものを書くように私を刺激しました。
難しい部分は、lh-devとlh-tagsによって数年間すでに行われています:
template
、inline
一部が欠落している場合があります)end
、C、C ++、Python、およびVimで使用できるフィールドを提供しており、関数の終わりを見つけるためにも使用できます。このアルゴリズムのどの部分も、ファイルタイプごとにオーバーライドできることに注意してください。つまり、Python関数の境界検出はdef
、インデントを検索および分析できfunction
、javascriptで検索できるなどです。つまり、現在のバージョンはJava、Vim、および他の言語でも動作します(まだ作業があります) Pythonで行うこと)
そこで、視覚モードマッピングとオペレーター保留モードマッピングの2つの新しいマッピングを定義します。
onoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr>
xnoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr><esc>gv
依存するもの:
function! lh#dev#_select_current_function() abort
let fn = lh#dev#find_function_boundaries(line('.'))
exe fn.lines[0]
normal! v
exe fn.lines[1]
endfunction
数百行のコードをhundredしまない lh#dev#find_function_boundaries()
そして、DJ McMayhemのマッピングのおかげで
" Note that my vim settings requires two backslashes here instead of one
vnoremap / <esc>/\\%V
現在の関数でvif/pattern
検索を行うことができますpattern
。
で関数をdif
削除したりyif
、などでヤンクしたりすることもできます。
特にfunction
キーワードのない言語や、多くの矛盾するインデントスタイルでは、関数の始まりと終わりを見つけるのは困難です。
関数が独自の行に閉じ括弧だけで終了する場合(ここにリストされている 13のスタイルのうち10のように)、次のようなもので視覚的に選択できます。
xnoremap if /^\s*}<CR><Esc>V%
そこからfoo
、関数内での検索は次のことのみです。
:'<,'>g/foo/#
すべてをまとめると、かなり良いマッピングを取得できます。
xnoremap if /^\s*}<CR><Esc>V%
nmap <key> vif:g//#<Left><Left>
言った、ビジュアルモードのマッピングは、おそらく簡単にだまされてしまうwhile
かif
、それはおそらく、研磨のビットから恩恵を受けるようにします。また、視覚的な選択を維持することはあまり良い考えではないかもしれません…
if
、for
、while
、など
不完全な解決策は折り畳みを使用することです。すべてを折りたたむ:
set foldmethod=syntax
set foldlevel=0
set foldminlines=0
検索結果のために折り畳まれた領域を開かないようにVimに指示します。
set foldopen-=search
そして、問題の関数のフォールドを開きます(zO
)。
これで、折り畳まれた領域で検索されたテキストのすべてのヒットは、Vimが一度折り畳みラインにジャンプし、次のヒットに進むという結果になります。
たとえば、次の場合:
折りたたまれた機能は、多くの用途がありsize
ますが、n
周りのすべての使用方法私をリードしていないだろうsize
という機能では。
別の方法:
Osyo Mangaの検索演算子(vim-operator-userに依存)を使用して、現在のブロック内のみを検索します。例えば:
" configure the plugin (once, vimrc):
map g/ <Plug>(operator-search)
" 1. use ctags etc. to jump to the beginning of the target function;
" 2. move cursor inside the function definition, then:
g/i{
...これで、指定したプロンプトで検索語を挿入できます。n
検索結果が現在提供されているモーション/テキストオブジェクトにどのように制限されるかを確認するためにヒットします。これはVim(つまり構成可能な)演算子であるため、適切な関数text-objectがある場合、検索する前に定義本体内を移動する必要はありませんがg/if
、smthing likeなどを直接使用します。
lh#dev#find_function_boundaries
LH-devのから