64

以下が際限なく繰り返される python ファイルがあるとします。

def myFunction(a, b, c):
    if a:
        print b
    elif c:
        print 'hello'

使い慣れた vim の動きを使用して、このファイルを移動して編集したいと思います。たとえば、(、)、[[、]]、{、} を使用するか、di} などのコマンドを使用してテキストを削除/ヤンク/変更します。

他の言語 (C++、Java、C# など) では中かっこがたくさんあるので、di} のような動きを使用すると、一致する中かっこを簡単に見つけて、そのブロックに作用することができます。実際、上記のテキストで「b」文字を使用していて、vim で di) を実行すると、2 つの括弧の間のテキストが正常に削除されます。

問題は、Python のコード ブロックの検出にあると思います。(、)、[[、]]、{、または } を移動として使用すると、ほとんど同じことが行われ、最初 (定義行の上または上) または最後 (関数の最後の行の後) に移動します。関数。そして、私の知る限り、vim に「このインデント ブロックのすべてを選択する」ように簡単に指示する方法はありません。上記の例では、if 行の 'i' でオンになり、di} と入力して、if ブロック全体 (この特定の関数の最後まで) を削除します。

そのような動きのインデントに基づいて動作するようにvimに指示できるはずです(特定の動きではないかもしれませんが、ユーザー定義のアクションです)。これを達成する方法について何か考えはありますか?

4

4 に答える 4

52

角かっこのマッピング[[]][m]mおよび同様の

$VIMRUNTIME/ftplugin/python.vim現在 (2018)は、Python 言語で文書:h ]]化されているすべての組み込みマッピングを再マップします。:h ]mマッピングは次のとおりです。

]] Jump forward to begin of next toplevel
[[ Jump backwards to begin of current toplevel (if already there, previous toplevel)
]m Jump forward to begin of next method/scope
[m Jump backwords to begin of previous method/scope

][ Jump forward to end of current toplevel
[] Jump backward to end of previous of toplevel
]M Jump forward to end of current method/scope
[M Jump backward to end of previous method/scope

コメント付きの次のサンプル ソース コードは、さまざまなマッピングを示しています。

class Mapping:                              # [[[[
    def __init__(self, iterable):
        pass

    def update(self, iterable):
        pass

    __update = update                       # []

class Reverse:                              # [[ or [m[m
    def __init__(self, data):               # [m
        self.data = data
        self.index = len(data)              # [M

    def __iter__(self):                     # <--- CURSOR
        return self                         # ]M

    def __next__(self):                     # ]m
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]        # ][

class MappingSubclass(Mapping):             # ]] or ]m]m

    def update(self, keys, values):
        pass

マッピングは、コミットabd468ed0 (2016-09-08)、01164a6546b4 (2017-11-02)、および 7f2e9d7c9cd (2017-11-11)で追加および改善されました。

このファイルの新しいバージョンをまだ持っていない場合は、ダウンロードして に入れることができます~/.vim/ftplugin/python.vim。このフォルダは よりも優先されます$VIMRUNTIME/ftplugin

これらのマッピングが に追加される前に、、、、およびを提供する$VIMRUNTIMEプラグインがありました。さらに、テキスト オブジェクト、、、およびも定義します。python-mode[[]][M]Mpython-modeaCiCaMiM

プラグインpython-mode

この vim プラグインは、組み込みのものと同様のモーションを提供します。

2.4 Vim motion ~
                                                                *pymode-motion*

Support Vim motion (See |operator|) for python objects (such as functions,
class and methods).

`C` — means class
`M` — means method or function
                                                            *pymode-motion-keys*

==========  ============================
Key         Command (modes)
==========  ============================
[[          Jump to previous class or function (normal, visual, operator)
]]          Jump to next class or function  (normal, visual, operator)
[M          Jump to previous class or method (normal, visual, operator)
]M          Jump to next class or method (normal, visual, operator)
aC          Select a class. Ex: vaC, daC, yaC, caC (normal, operator)
iC          Select inner class. Ex: viC, diC, yiC, ciC (normal, operator)
aM          Select a function or method. Ex: vaM, daM, yaM, caM (normal, operator)
iM          Select inner func. or method. Ex: viM, diM, yiM, ciM (normal, operator)
==========  ============================

プラグインPythonsense

このプラグインは同様のモーションを提供しますが、わずかに変更されています:

標準の Vim 8.0 の「クラス」モーション ("]]"、"[[" など) は、これらがクラス ブロックであるか関数ブロックであるかに関係なく、最初の列から始まるブロックを見つけます。 ("[m"、"]m" など) クラスまたは関数ブロックであるかどうかに関係なく、任意のインデントにあるすべてのブロックを検索します。対照的に、「Pythonsense」クラス モーションは、インデント レベルに関係なく、すべてのクラス定義のみを検索しますが、そのメソッド/関数モーションは、インデント レベルに関係なく、すべてのメソッド/関数定義のみを検索します。

詳細と例はすべてhttps://github.com/jeetsukumaran/vim-pythonsense#stock-vim-vs-pythonsense-motionsにあります。さらに、このプラグインは、テキスト オブジェクトic/ac(クラス)、if/af(関数)、id/ad(docstring) を定義します。

Python のtextobjects に関する議論については、VIM 経由で Python の関数を選択する最速の方法は何ですか? を参照してください。.

于 2015-02-02T18:44:46.663 に答える
21

python.vim

Pythonコードブロック内を移動するのがはるかに簡単になります。

ショートカット:

  • ]t -ブロックの先頭にジャンプします
  • ]e -ブロックの最後にジャンプします
  • ]v -(ビジュアルラインモード)ブロックを選択します
  • ]< -ブロックを左にシフト
  • ]> -ブロックを右にシフト
  • ]# -コメントの選択
  • ]u -コメント解除の選択
  • ]c -現在/前のクラスを選択します
  • ]d -現在/前の機能を選択します
  • ]<up> -同じ/下のインデントで前の行にジャンプします
  • ]<down>-同じ/下のインデントで次の行にジャンプします

python_match.vim

拡張%

  • % -if / elif / else、try / exception / catch、for / continue/breakを循環します
  • g%-反対側に移動します%
  • [%-現在のコードブロックの先頭に移動します
  • ]%-現在のコードブロックの最後に移動します

上記のすべてのモーションは、通常、視覚、およびオペレーター保留モードで機能するため、次のようになります。

  • d]% -現在のブロックの終わりまで削除します
  • v]%d-何が削除されているかを確認できるように、ビジュアルモードを使用して同じことを行う必要があります
  • V]%d-上記、ただし行選択あり
于 2009-09-08T13:56:12.580 に答える
6

がある場合、インデントされたブロックを移動するのは非常に簡単ですset foldmethod=indent。たとえばdef main():、次のスニペットで回線に接続している場合:

def main():
+-- 35 lines: gps.init()-----------------------------------------------------

if __name__ == "__main__": main()

次にdj、メイン関数全体を取り、他の場所に貼り付けることができます。

于 2009-05-22T15:45:11.193 に答える
0

最後の段落に対処するために、次のスクリプトは、アクションを実行できる新しい「インデント」テキスト オブジェクトを定義します。たとえばdii、カーソルがある行と同じレベルでインデントされているものをすべて削除します。

詳細については、プラグインのドキュメントを参照してください: http://www.vim.org/scripts/script.php?script_id=3037

于 2015-08-18T12:32:14.940 に答える