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

时间:2009-05-22 02:25:37

标签: python vim editing

给出一个python文件,其中无休止地重复:

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

我想使用熟悉的vim动作四处移动并编辑此文件。例如,使用(,),[[,]],{,}或使用像di}这样的命令删除/ yanking /更改文本。

在其他语言(如C ++,Java,C#等)中,你有大括号,所以使用像di这样的运动可以很容易地找到匹配的大括号并对该块进行操作。事实上,如果我在上面的文本中使用'b'字符并在vim中执行di),它会成功删除两个parens之间的文本。

我认为问题在于python检测代码块。使用(,),[[,]],{或}作为动作几乎都做同样的事情,带你到开始(在def线上方或在def线上)或结束(在函数的最后一行之后)功能。据我所知,没有办法轻易告诉vim“为这个缩进块选择所有东西。”在上面的例子中,我想在if行的'i'中输入di,并删除整个if块(到这个特定函数的末尾)。

我确信应该可以告诉vim在缩进的基础上进行这样的动作(好吧,也许不是那个特定的动作,而是一些用户定义的动作)。有关如何实现这一点的任何想法?

4 个答案:

答案 0 :(得分:25)

方形括号映射[[]][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

在提交abd468ed0(2016-09-08),01164a6546b4(2017-11-02)和7f2e9d7c9cd(2017-11-)中添加并改进了映射11)。

如果您还没有此版本的新版本,可以下载并将其放入~/.vim/ftplugin/python.vim。此文件夹优先于$VIMRUNTIME/ftplugin

在将这些映射添加到$VIMRUNTIME之前,已有插件python-mode提供[[]][M和{{1 }}。此外,]M还定义了文本对象python-modeaCiCaM

插件python-mode

这个vim插件提供类似于内置动作的动作:

iM

插件Pythonsense

此插件提供了类似的动作,但略有修改:

  

库存Vim 8.0“类”运动(“]]”,“[[”等),查找从第一列开始的块,无论这些是否是类或功能块,而其方法/ function motion(“[m”,“] m”等)查找任何缩进的所有块,无论这些块是类还是功能块。相比之下,“Pythonsense”类动作用于查找所有和唯一的类定义,无论它们的缩进级别如何,而其方法/函数动作用于查找所有且唯一的方法/函数定义,而不管它们的缩进级别。

所有详细信息和示例均在https://github.com/jeetsukumaran/vim-pythonsense#stock-vim-vs-pythonsense-motions处提供。 此外,此插件定义文本对象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) ========== ============================ (类),ic/ac(函数),if/af(docstring)。

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

答案 1 :(得分:20)

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 - 上面,但有行选择

答案 2 :(得分:6)

当你set foldmethod=indent时,移动缩进块非常容易。例如,如果您位于以下代码段中的def main():行:

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

if __name__ == "__main__": main()

然后dj获取整个主函数,它可以粘贴到其他地方。

答案 3 :(得分:0)

要解决最后一段,以下脚本定义了一个可以对其执行操作的新“缩进”文本对象。例如, d i i 删除与光标所在行相同级别缩进的所有内容。

有关详细信息,请参阅插件的文档:http://www.vim.org/scripts/script.php?script_id=3037