在Vim中选择整个函数定义

时间:2012-07-30 14:04:31

标签: function vim select definition

我一直在尝试Vim进行近一周的文本编辑工作。我想知道选择C函数定义的最快方法。

例如,如果我有这样的函数:

void helloworlds( int num )
{
    int n;
    for ( n = 0; n < num; ++n ) {
        printf( "Hello World!\n" );
    }
}

我如何能够删除整个定义,包括函数名称?

11 个答案:

答案 0 :(得分:64)

在Vim中很常见,有很多方法!

请注意,前两个解决方案取决于缺少空行。

  • 如果光标位于包含函数名称的行上,请尝试 d } 。它将删除下一个块的所有内容(即您的函数体)。

  • 在函数体内, d a p 将删除'paragraph'。

  • 您可以使用 d a } 删除花括号块。 (如果您喜欢这种语法,我推荐Tim Pope的精彩surround.vim,它会增加更多具有类似感觉的功能。)

  • 您还可以尝试使用正则表达式删除,直到下一个左下方缩小的大括号: d / ^ } 输入

  • ] ] [ [移动到下一个/上一个第一列花括号(相当于使用上面提到的正则表达式使用/?。结合 d 运动,你会产生相同的效果。像Python-mode这样的插件,这些operators are redefined意味着你正在寻找的东西:从功能转移到功能。

如何删除整个块,包括标题

如果您在标题/名称或块之前的行上, d a } 应该可以解决问题。< / p>

如果你在一个街区下方,你也可以利用Vim搜索的方便'偏移'功能。 d ^ { - ? 1 将在第一次出现第一列开口花括号之前向后删除一行。键入此命令有点棘手。也许你可以制作一个<leader>捷径。

插件

我在Vim中没有做太多的C编程,但肯定有插件可以帮助解决这个问题。试试Vim Scripts或他们的mirror at GitHub

答案 1 :(得分:17)

删除整个功能,包括其定义,例如:

function tick() {
        // ... 
}
  • 移至功能名称行。
  • 将光标移动到左括号, f{ 应该这样做,或只是 $
  • V%d (视线,移至匹配对,删除)

如果您的功能如下:

function tick() 
{
        // ... 
}
  • 移至功能名称行。
  • J 加入当前行包含以下行。这也会将光标放在结果行的最后一个字符{{1} },只是下一个命令所需的那个。)
  • { (视线,移至匹配对,删除。)

  • 移至功能名称行。
  • V%d (视线,向下移动一行,移至匹配对,删除。)

答案 2 :(得分:5)

您可以使用此快捷方式不仅删除函数,还删除大括号之间的行,即if-else语句之间的代码,while循环等等。

在大括号开始/结束处按 Shitf + v [将以可视模式进入]。

然后按] +} ,即] + Shitf] - 如果你在开始大括号。

然后按 [+ {,即 [+ Shitf [ - 如果你在结尾。

然后删除删除所选行。

答案 3 :(得分:4)

使用这种简单的方法

   1.Go to the function definition 
   2.dd  - delete function definition 
   3.d    -start delete operation 
   4.shift+5(%) - delete the lines between { to }

答案 4 :(得分:3)

最简单,最直接的方法如下(在函数内的任何地方都有效):

v   enter visual mode
{   move to first brace in function (may have to press more than once)
o   exchange cursor from top to bottom of selection
}   extend selection to bottom of function
d   delete selected text

完整的命令序列为v{o}d。请注意,除了删除相同的方法,您还可以执行其他操作。例如,要复制该函数,请使用y(yank)而不是d

答案 5 :(得分:3)

如果您愿意安装插件,vim-textobj-function将为您提供vif用于Visual选择内部函数和vaf用于Visual选择A函数。

daf将删除该功能,包括签名行和功能正文({}

此插件定义的文本对象更具体,并且他们不依赖于函数体,将一个连续的文本块或{ beign放置在该行的第一个字符上。

缺点是你依赖外部插件。

答案 6 :(得分:1)

如果您的函数由空白行分隔,只需键入:

dip

表示“删除内部段落”。

答案 7 :(得分:0)

非视觉方式:

d/^}/e

...通过在行号处搜索}来删除,包括删除。

没有/e(上面的答案中没有提到),解决方案不完整。

使用/e - 搜索将结束匹配,因此右括号包含,并且命令也适合于yanking:

y/^}/e

答案 8 :(得分:0)

另一种方法是转到函数开头的行并点击:Vj%(或V%%如果你的样式将左括号放在同一行上)。这将使您进入Visual-Line模式,百分比将您带到匹配的右括号。在第二种样式中,第一个%将您带到您选择的线上的左大括号,第二个带到其匹配的右大括号。

也适用于括号,括号,C风格的多行注释和预处理器指令。

有关详细信息,请参阅manual

答案 9 :(得分:0)

前提条件:在函数内部。 使用

转到第一行的上一个结束花括号
[]

然后使用

删除第一行的下一个结束花括号
d][

答案 10 :(得分:0)

大多数发布的方法都有一两个缺点。通常,当使用某些面向对象语言的类定义时,在函数体后可能没有空行,因为许多代码格式化程序将last方法和类的右括号放在连续的行上。另外,您可能在函数顶部有注释。更糟的是,您的功能体内可能有空行。另外,您更喜欢一种可以在函数内任何地方使用光标的方法,因为必须将光标移动到特定行或更糟的字符上会花费宝贵的时间。想象一下

public class Test {

    /* ... */

    @Test
    public void testStuff() {
        // given
        doSetup();

        // when
        doSomething();

        // then
        assertSomething();
    }
}

在这种情况下,vap不会对您有任何帮助,因为它会停在函数内的第一个空行处。 v{o}出于相同的原因而退出。 va{V更好,但不会在方法顶部捕获注释。因此,在最一般的情况下,我要做的是va{o{va{选择整个函数体(注意:如果光标位于嵌套块内,例如内部的if语句,则只会得到该块),o将将光标移到所选内容的开头,然后{选择整个段落,然后再进行选择。这意味着您将获得函数定义,所有注释和文档注释。