在vim中更高效地编辑python文件

在vim中更高效地编辑python文件,python,vim,editing,Python,Vim,Editing,给定一个python文件,其中不断重复以下内容: def myFunction(a, b, c): if a: print b elif c: print 'hello' 我想用熟悉的vim移动来移动和编辑这个文件。例如,使用(,),[[,]],{,}或使用类似di}的命令删除/拖动/更改文本 在其他语言(如C++、爪哇、C等)中,你有卷曲括号丰富,所以使用像DI}这样的移动可以很容易地找到匹配的卷曲括号并在该块上起作用。事实上,如果我在上面文本

给定一个python文件,其中不断重复以下内容:

def myFunction(a, b, c):
    if a:
        print b
    elif c:
        print 'hello'
我想用熟悉的vim移动来移动和编辑这个文件。例如,使用(,),[[,]],{,}或使用类似di}的命令删除/拖动/更改文本

在其他语言(如C++、爪哇、C等)中,你有卷曲括号丰富,所以使用像DI}这样的移动可以很容易地找到匹配的卷曲括号并在该块上起作用。事实上,如果我在上面文本的“b”字符上,在vim中执行di),它会成功地删除两个参数之间的文本

我认为,问题在于python对代码块的检测。使用(,),[[,]],{,或}作为移动几乎都做相同的事情,将您带到函数的开始(在def行的上方或上方)或结束(在函数的最后一行之后)。据我所知,没有办法轻松地告诉vim“为这个缩进块选择所有内容”。在上面的示例中,我希望在if行的'I'中输入di},并让它删除整个if块(直到这个特定函数的末尾)


我相信应该可以告诉vim在缩进的基础上对这些移动进行操作(好吧,可能不是那个特定的移动,而是一些用户定义的操作)。关于如何实现这一点有什么想法吗?

当您设置了
foldmethod=indent
时,移动缩进块非常容易。例如,如果您在以下代码段的
def main():
行上:

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

if __name__ == "__main__": main()
然后,
dj
获取整个主函数,并可以将其粘贴到其他位置

使围绕python代码块导航变得更加容易

快捷方式:

  • ]t
    --跳转到块的开头
  • ]e
    --跳转到块的末尾
  • ]v
    --选择(可视线路模式)块
  • ]
    --将块向右移位
  • ]#
    --注释选择
  • ]u
    --取消注释选择
  • ]c
    --选择当前/上一个类
  • ]d
    --选择当前/上一个功能
  • ]
    --使用相同/更低的缩进跳转到上一行
  • ]
    --使用相同/更低的缩进跳转到下一行
扩展
%

  • %
    -循环执行if/elif/else、try/except/catch、for/continue/break
  • g%
    -移动到
    %
  • [%
    -移动到当前代码块的开头
  • ]%
    -移动到当前代码块的末尾
上述所有动作均在正常、可视和操作员挂起模式下工作,因此:

  • d]
    -删除,直到当前块结束
  • v]%d
    -也应该这样做,通过视觉模式,以便 您可以看到正在删除的内容
  • V]%d
    -以上,但带有行选择
方括号映射
[[
]
[m
]m
及类似映射 现在(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
插件 此插件提供了类似的动作,但稍作修改:

库存Vim 8.0“类”运动(“]]”、“[[”)等)查找从第一列开始的块,不管它们是类还是功能块,而其方法/功能运动(“[m]”、“]m”等)查找任何缩进处的所有块,不管它们是类还是功能块。相反,“pythonse”类运动用于查找所有且仅限类定义,而不管它们的缩进级别如何;而其方法/函数运动用于查找所有且仅限方法/函数定义,而不管它们的缩进级别如何

所有详细信息和示例见。 此外,该插件还定义了文本对象
ic/ac
(类)、
if/af
(函数)、
id/ad
(docstring)


有关python的textobjects的讨论,请参见。

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


有关更多信息,请参阅插件文档:

在2016年,这是标准答案。您好:谢谢您的回答。非常简单:第一种方法是否可以正确处理装饰器?@clog14抱歉,我不知道答案。如果您指的是第一种方法,
$VIMRUNTIME/ftplugin/python.vim
中给出的映射,我会ld建议您在下的上游存储库中提出一个问题。请给出一个示例文件,并说明不同方括号映射的预期行为。