2011-07-27 9 views
11

Vimは非常に便利なモーションコマンドを提供し、次のメソッドにジャンプします:] m、] M、[m、] m。Vim [m motion with c#

これらはJavaまたは類似の構造化言語で動作します。 (に記載されているように:ヘルプ] Mと:29.3を助ける)

クラス 宣言及びメソッド宣言などの中括弧の次のレベルとして、中括弧の最も外側のペアを考慮動作するように思われます。

これらのモーションコマンドは、クラス定義の外側の中括弧 がある場合は機能しません。これはC#のように言語では多少共通です。

([、V M] Mは、オペレータ、例えば、Yを前に付けのみと )このコードでは動作し

それらのコマンドを作るために、いくつかのトリックがある場合、私は思っていた:

namespace ABC.DEF 
{ 
    class A 
    { 
     protected string strID; 
     public string PortID { get { return strID; } set { strID = value; } } 

     protected MyType x; 
     public MyType X 
     { 
      get { return x; } 
      set { x = value; if (x != null) func1(); } 
     } 


     int func1() 
     { 
      return 1; 
     } 

     int func2(int flag) 
     { 
      if (flag == 0) 
       return flag; 


      if (flag > 3) 
      { 
       return flag; 
      } 
      return 2; 
     } 

     int func3() 
     { 
      return 3; 
     } 
    } 
} 
+0

に(この質問に別の答えから取られた)これらのマッピングを使用しています。たぶん、このコマンドを利用できるVisual Studioプラグインがあり、期待どおりに動作します。どのIDEを使用していますか?あるいはコマンドラインからVimを使うだけですか? –

+0

@Gweebz - コードを編集するためにgVimを使用していますので、Vimプラグインを好むでしょう:) – mMontu

答えて

4

私にはありません]mマッピングのファミリをカスタマイズできると考えてください。このような場合、通常の方法はカスタムロジックでオーバーライドすることです。私はあなたは何を記述する必要がありますいくつかのvimscriptを思い付いた。基本的に、中括弧を飛び越えて、関連する行を見て何をすべきかを決定します。この場合、単に "class"と "namespace"宣言を無視します。それはすべての場合に正しく動作しない場合がありますので、私は本当に、C#のの多くを知らないが、あなたは私に壊れ例を与えれば、私は何かを把握することができるかもしれない心の中で

nnoremap <buffer> ]m :<c-u>call <SID>JumpMethod('{', 'W', 'n')<cr> 
nnoremap <buffer> [m :<c-u>call <SID>JumpMethod('{', 'Wb', 'n')<cr> 
nnoremap <buffer> ]M :<c-u>call <SID>JumpMethod('}', 'W', 'n')<cr> 
nnoremap <buffer> [M :<c-u>call <SID>JumpMethod('}', 'Wb', 'n')<cr> 

xnoremap <buffer> ]m :<c-u>call <SID>JumpMethod('{', 'W', 'v')<cr> 
xnoremap <buffer> [m :<c-u>call <SID>JumpMethod('{', 'Wb', 'v')<cr> 
xnoremap <buffer> ]M :<c-u>call <SID>JumpMethod('}', 'W', 'v')<cr> 
xnoremap <buffer> [M :<c-u>call <SID>JumpMethod('}', 'Wb', 'v')<cr> 

onoremap <buffer> ]m :<c-u>call <SID>JumpMethod('{', 'W', 'o')<cr> 
onoremap <buffer> [m :<c-u>call <SID>JumpMethod('{', 'Wb', 'o')<cr> 
onoremap <buffer> ]M :<c-u>call <SID>JumpMethod('}', 'W', 'o')<cr> 
onoremap <buffer> [M :<c-u>call <SID>JumpMethod('}', 'Wb', 'o')<cr> 

function! s:JumpMethod(char, flags, mode) 
    let original_cursor = getpos('.') 

    if a:mode == 'v' 
    normal! gv 
    elseif a:mode == 'o' 
    normal! v 
    endif 

    while search(a:char, a:flags) > 0 
    if a:char == '}' 
     " jump to the opening one to analyze the definition 
     normal! % 
    endif 

    let current_line = line('.') 

    if getline(current_line) =~ '^\s*{' 
     " it's alone on the line, check the above one 
     let method_line = current_line - 1 
    else 
     let method_line = current_line 
    endif 

    let method_line_body = getline(method_line) 

    if method_line_body =~ '\k\+\s*(.*)' && method_line_body !~ '\<\(for\|foreach\|if\|while\|switch\|using\|catch\|get\|set\)\>' 
     " it's probably a function call 

     if a:char == '}' 
     " we need to go back to the closing bracket 
     normal! % 
     endif 

     echo 
     return 
    else 
     if a:char == '}' 
     " we still need to go back to the closing bracket 
     normal! % 
     endif 
    endif 
    endwhile 

    " if we're here, the search has failed, restore cursor position 
    echo 
    call setpos('.', original_cursor) 
endfunction 

ベア。

これを試してみるには、vimfilesディレクトリの "ftplugin"の下のどこかに "cs.vim"と書いてください。すでに "cs.vim"ファイルがある場合、 "cs"で始まり ".vim"で終わるその他のファイル名も適切です。

+0

私はC#の多くを知りませんが、コードでテストしました。メソッド/プロパティの定義の中にある中括弧のペアをスキップしない限り、うまく動作しているように見えました。このようなコードを含めるように質問を更新しました。あなたの助けをありがとう – mMontu

+0

したがって、ctagsの要件...コントロールステートメントに対するテストは簡単ですが、C#が分離された{}ブロックを受け入れる場合(CまたはC++のようにスコープを制限する)、コードを解析するのは非常に面倒になりますvimlに手を差し伸べて、コメントなどを考えてください。 –

+0

私は少し条件を編集しましたが、あなたの新しい例ではうまくいくようです。 @ luc-hermitteは一般的に正しいですが、メソッドを使って作業する唯一の完全な方法はctagsです。しかし、これは設定や更新に関する多くの問題を意味します。私のスクリプトはいくつかの問題で失敗するかもしれませんが、これはまだ完全にうまくいくはずですが、良いctagsを設定していれば、彼のプラグインも試してみるとよいでしょう。 –

1

数週間前、同様の質問がvimメーリングリストで尋ねられましたが、C++では尋ねられました。 ここにthe solution I came up withです。

これは、ctagsとlh-dev、lh-tag、lh-vim-libの他のいくつかのプラグインに依存しています。 lh-devはvim-addon-managerからインストールできます。これにより、lh-tagとlh-vim-libが順番にインストールされます。

HTH、

0

あなたが9]}使用することができます。ちょっと強制されますが、ちょっと、うまくいきます。

+0

私が理解するところでは、9]は、次の/前の方法の開始または終了ではなく、下の9番目の '}'にジャンプします。 – mMontu

+0

これは9番目の囲みにジャンプします}、これは通常現在のメソッドの終わりです。それは次の方法の始まりではありませんが、私にとって「十分に近い」ものです。 –

+3

第9番目の}は、クラス/名前空間の終わりにすることもできます。それはOPの質問を解決しません。 –

2

OmniSharpは現在:OmniSharpNavigateUp:OmniSharpNavigateDownです。常に「開始」に行きます(したがって、これは]m[mのマッピングです)。私はVimのスタイルのように、あなたのIDE、IntelliJのでコマンドや他のIDEは、これらのコマンドを提供してVimのプラグインを持っている場合は、Java開発のためにftplugin\cs.vim

nnoremap <buffer> ]m :OmniSharpNavigateDown<cr> 
nnoremap <buffer> [m :OmniSharpNavigateUp<cr> 
nnoremap <buffer> ]M :OmniSharpNavigateDown<cr> 
nnoremap <buffer> [M :OmniSharpNavigateUp<cr> 

xnoremap <buffer> ]m :OmniSharpNavigateDown<cr> 
xnoremap <buffer> [m :OmniSharpNavigateUp<cr> 
xnoremap <buffer> ]M :OmniSharpNavigateDown<cr> 
xnoremap <buffer> [M :OmniSharpNavigateUp<cr> 

onoremap <buffer> ]m :OmniSharpNavigateDown<cr> 
onoremap <buffer> [m :OmniSharpNavigateUp<cr> 
onoremap <buffer> ]M :OmniSharpNavigateDown<cr> 
onoremap <buffer> [M :OmniSharpNavigateUp<cr> 
+0

OmniSharpの著者はこちら。私はMについて知りませんでした。私はメソッドの最後にジャンプするためのサポートを追加します。 – jasoni