5

在 Vim 中,我不断发现自己希望通过击键来重写某些参数列表的其余部分。例如,在以下 Python 函数中:

def myfun(a, b=12, c=(1,2,3), d=15):
    pass

我希望将 替换c=(1,2,3), d=15e=12。击键ci(允许我替换整个参数列表中的所有内容,但我发现我经常想保留一些 Vim 文本对象的前缀。一般来说,我假设我正在搜索的这个击键在替换函数调用的最终参数和定义的上下文中会很有用。

这个问题的理想答案也适用于带引号的字符串、[]块和其他文本对象。请注意,我了解“如何在 Vim 中的括号(或引号或...)之间进行选择? ”中回答的所有有关文本对象的信息。

@pb2q 和@romainl 都提供了很好的搜索快捷方式,但它们要求我在视觉上找到封闭块的结尾,以设计一个搜索,该搜索对于块中的任何其他垃圾来说是明确的(例如,考虑嵌套函数调用)。特别是,当我在要操作的括号集中嵌套括号时,我经常发现自己想要这个。我真正想要的答案类似于ci)ca)在概念上完全基于最近的封闭括号),并且完全优雅地处理其他嵌套)块。

4

5 回答 5

10

有一堆命令从]某种结构的末尾开始,并尊重嵌套。])转到带括号的块的末尾,]}转到带括号的块的末尾,]/转到 C 注释(/*...*/样式)的末尾。使用[代替]去开始而不是结束。

所以要做你的c=(1,2,3), d=15类型的替换c])

这些命令的完整列表在下面列出:help various-motions。不幸的是,没有一个用于由方括号分隔的块,因为[[and]]在经典 vi 中已经具有不同的含义,而 vim 已经定义][[]很好地适应了这些。

于 2012-07-26T17:34:21.103 回答
5

用这个创建地图

mavi)o`a
  • 标记当前位置 a
  • 视觉选择 inside () 以选择您所在的 () 内的完整字符集
  • 转到突出显示文本的另一端以:h v_o获取更多信息
  • 移动到之前标记的位置

现在您可以执行诸如 c 或 d 之类的操作...

编辑:我仍然最喜欢@Alan-Curry 的解决方案,因为键序列很短。然而,这种技术也有使用 ] 的好处。

我还发现了我的解决方案的简化:

vi)o``

`` 跳转到最后一个位置。因此,您无需创建标记。

于 2012-07-26T17:36:20.617 回答
1

如果您不介意使用插件,我相信vim-ninja-feet完全符合您的要求。

  • c]i)将更改参数列表的其余部分,
  • d[i"将向后删除到引用的开头,并且
  • z]i]将在 [] 块的末尾将您置于插入模式。
于 2018-03-14T19:23:09.293 回答
0

ct:在这种情况下,将更改所有内容,但不包括:. 前面t带有数字参数将允许您轻松更改嵌套的大括号/括号/引号,例如c2t).

如果光标已经在您要更改的行上,fc将使用上述命令将您放在要开始更改的字符上,或使用搜索,例如:/c=对于更一般的情况,即如果您有c字符较早的行,或光标当前位于前一行。

于 2012-07-26T16:38:10.903 回答
0

我拼凑了一个小解决方案。它可能有一些边缘情况,可能有一些错误,但我今天没有时间测试了。有时间我会再去看看。

function! UntilTextObject(op)
    " Save marks
    let save_a = getpos("'a")
    let save_b = getpos("'b")

    " Read in the object type and set '< and '> to the ends of the
    " range of the text-object and 'a to the current position
    let object_type = nr2char(getchar())
    execute "normal! mavi" . object_type . "\<esc>"

    " Adjust end position (off by one)
    let pos = getpos("'>")
    let pos[2] += 1
    call setpos("'b", pos)

    " Operate on the range `a to `b
    execute "normal! `a" . a:op . "`b"

    " Restore marks
    call setpos("'a", save_a)
    call setpos("'b", save_b)
endfunction

onoremap u :call UntilTextObject(v:operator)<cr>

这允许您du)删除-直到-the-end-of-the-)-text-object。也适用于其他文本对象。

我添加了一些更改,通过不踩踏你的标记使这更加礼貌。如果你给它一个不选择任何东西的文本对象,它仍然有点古怪。我会在以后重新审视这个,看看我是否能解决这个问题。出于演示目的,故意过度评论。

于 2012-07-26T19:28:01.897 回答