在vim中编辑python文件更高效的移动

oymdgrw7  于 2022-11-24  发布在  Python
关注(0)|答案(4)|浏览(160)

给定一个python文件,下面的语句不断重复:

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

我想使用熟悉的vim动作来移动和编辑这个文件。例如,使用(,),,{,}或者使用di}之类的命令删除/拖动/更改文本。
在其他语言中(如C++、Java、C#等),大括号随处可见,因此使用像di}这样的移动可以很容易地找到匹配的大括号并对该块执行操作。事实上,如果我在上面文本的'b'字符上,在vim中执行di),它会成功地删除两个括号之间的文本。
我认为问题出在python对代码块的检测上。(,),,{,或}作为动作,几乎都做同样的事情,将您带到起点(在def行之上或之上)或结束(在函数的最后一行之后)的函数。而且没有办法,据我所知,为了方便地告诉vim“select everything for this indentation block.”在上面的例子中,我想在if行的'i'中打开,键入di}并让它删除整个if块(直到这个特定函数的结尾)。
我相信应该可以告诉vim在缩进的基础上操作这样的移动(好吧,也许不是那个特定的移动,而是一些用户定义的动作)。

r9f1avp5

r9f1avp51#

方括号Map[[]][m]m及类似

$VIMRUNTIME/ftplugin/python.vim现在(2018年)重新Map所有python语言的:h ]]:h ]m下的内置Map。

]] 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

以下示例源代码(带有注解)说明了不同的Map

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年9月8日)、01164a6546b4(2017年11月2日)和7f2e9d7c9cd(2017年11月11日)中添加并改进了Map。
如果您还没有这个文件的新版本,您可以下载它并将其放入~/.vim/ftplugin/python.vim。此文件夹的优先级高于$VIMRUNTIME/ftplugin
在这些Map被添加到$VIMRUNTIME之前,存在提供[[]][M]M的插件python-mode。此外,python-mode还定义了文本对象aCiCaMiM

插件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”类动作用于查找所有且仅查找类定义,而不管它们的缩进级别,而其方法/函数动作用于查找所有且仅查找方法/函数定义,而不管它们的缩进级别。
所有详细信息和示例都在www.example.com上提供https://github.com/jeetsukumaran/vim-pythonsense#stock-vim-vs-pythonsense-motions。此外,此插件定义了文本对象ic/ac(类)、if/af(函数)和id/ad(文档字符串)。
新 vim
对于neovim,你可以使用treesitter和neovim插件nvim-treesitter-textobjects。
文本对象if/af & ic/ac
$VIMRUNTIME/ftplugin/python.vim中不包含这些功能,但由一些插件提供

有关python的textobjects的讨论,请参见what's the fastest way to select a function of Python via VIM?

bihw5rsg

bihw5rsg2#

python.vim的名字

使得在python代码块中导航更加容易。
快捷键:

  • ]t-跳转到块开头
  • ]e-跳转到块结尾
  • ]v-选择(可视行模式)块
  • ]<-将块左移
  • ]>-块右移
  • ]#--注解选择
  • ]u--取消注解选择
  • ]c--选择当前/上一个类
  • ]d--选择当前/上一个函数
  • ]<up>--跳转到上一行,缩进相同或更小
  • ]<down>--跳到下一行,缩进相同或更小

python_match.vim的名字

扩展%

  • %-循环执行if/elif/else、try/except/catch、for/continue/break
  • g%-向%的相反方向移动
  • [%-移动到当前代码块的开头
  • ]%-移动到当前代码块的末尾

上述所有运动均适用于正常、视觉和操作员等待模式,因此:

  • d]%-删除直到当前块的结尾
  • v]%d-应该执行相同的操作,通过可视模式,以便您可以看到正在删除的内容
  • V]%d-以上,但有行选择
mzsu5hc0

mzsu5hc03#

当你有set foldmethod=indent时,移动缩进的块是非常容易的。例如,如果你在下面的代码片段中的def main():行:

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

if __name__ == "__main__": main()

那么dj将获得整个main函数,并且可以将其粘贴到其他地方。

zphenhs4

zphenhs44#

为了处理最后一个段落,下面的脚本定义了一个新的“indent”文本对象,您可以对它执行操作。例如,dii删除与光标所在行同级缩进的所有内容。
有关详细信息,请参阅插件的文档:http://www.vim.org/scripts/script.php?script_id=3037

相关问题