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に指示することは可能であると確信しています(まあ、その特定の動きではないかもしれませんが、いくつかのユーザー定義のアクション)。これを達成する方法について何か考えはありますか?
[[
、]]
、[m
、]m
など$VIMRUNTIME/ftplugin/python.vim
now(2018)は、:h ]]
および:h ]m
で文書化されているすべての組み込みマッピングをpython言語に再マッピングします。マッピングは:
]] 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
マッピングが追加され、コミットで改善されました abd468ed (2016-09-08)、 1164a6546b4 (2017-11-02)、および 7f2e9d7c9cd =(2017-11-11)。
このファイルの新しいバージョンをまだお持ちでない場合は、ダウンロードして~/.vim/ftplugin/python.vim
に入れることができます。このフォルダは$VIMRUNTIME/ftplugin
の前に優先されます。
これらのマッピングが$VIMRUNTIME
に追加される前に、python-mode
、[[
、]]
、および[M
を提供するプラグイン]M
がありました。さらに、python-mode
は、テキストオブジェクトaC
、iC
、aM
、およびiM
も定義します。
この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)
========== ============================
このプラグインは同様のモーションを提供しますが、わずかに変更されています。
ストックVim8.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の関数を選択する最も速い方法は何ですか? を参照してください。
pythonコードブロック内を移動するのがはるかに簡単になります。
ショートカット:
]t
-ブロックの先頭にジャンプ]e
-ブロックの最後にジャンプします]v
ビジュアルラインモード)ブロックを選択します]<
-ブロックを左にシフト]>
-ブロックを右にシフト]#
-コメントの選択]u
-コメント解除の選択]c
-現在/前のクラスを選択します]d
-現在/前の機能を選択します]<up>
-同じ/低いインデントで前の行にジャンプします]<down>
-同じ/低いインデントで次の行にジャンプします%
を拡張します:
%
-if/Elif/else、try/exception/catch、for/continue/breakを循環しますg%
-%
の反対側に移動します[%
-現在のコードブロックの先頭に移動します]%
-現在のコードブロックの最後に移動します上記のすべてのモーションは、通常、視覚、およびオペレーター保留モードで機能するため、次のようになります。
d]%
-現在のブロックが終了するまで削除しますv]%d
-何が削除されているかを確認できるように、ビジュアルモードを使用して同じことを行う必要がありますV]%d
-上記、ただし行選択あり_set foldmethod=indent
_がある場合、インデントされたブロックを移動するのは非常に簡単です。たとえば、次のスニペットのdef main():
行を使用している場合:
_def main():
+-- 35 lines: gps.init()-----------------------------------------------------
if __== "__main__": main()
_
次に、dj
がメイン関数全体を取得し、他の場所に貼り付けることができます。
最後の段落に対処するために、次のスクリプトは、アクションを実行できる新しい「インデント」テキストオブジェクトを定義します。例えば、 dii カーソルが置かれている行と同じレベルでインデントされているすべてのものを削除します。
詳細については、プラグインのドキュメントを参照してください: http://www.vim.org/scripts/script.php?script_id=3037