【问题标题】:Selecting entire function definition in Vim在 Vim 中选择整个函数定义
【发布时间】:2012-07-30 14:04:30
【问题描述】:

近一个星期以来,我一直在尝试使用 Vim 进行任何文本编辑工作。我想知道选择 C ​​函数定义的最快方法。

例如,如果我有这样的功能:

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

我怎样才能删除包括函数名在内的整个定义?

【问题讨论】:

  • 将光标放到函数体中,例如函数体的第一行。然后,va}o-0。如果{与函数签名在同一行,例如void helloworlds( int num ) {,则使用va}o0

标签: function vim select definition


【解决方案1】:

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

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

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

  • 在函数体内,dap 将删除“段落”。

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

  • 您也可以尝试使用正则表达式删除直到下一个最左边缩进的右大括号:d/^ }输入

  • ]][[ 移动到下一个/上一个第一列大括号(相当于将/? 与我上面提到的正则表达式结合使用。结合 d 动作,您将获得相同的效果。在像Python-mode 这样的插件中,这些operators are redefined 的确切含义您正在寻找:从一个功能转移到另一个功能。

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

如果您在标题/名称或块前的行上,da} 应该可以解决问题。

如果你在一个块下面,你也可以利用 Vim 搜索的方便的“偏移”功能。 d?^{?-1 将向后删除到第一次出现第一列左大括号之前的一行。这个命令输入起来有点棘手。也许你可以用它做一个&lt;leader&gt; 快捷方式。

插件

我在 Vim 中没有做太多的 C 编程,但肯定有插件可以帮助完成这样的事情。试试Vim Scripts 或他们的mirror at GitHub

【讨论】:

  • da}(或daB)是内置的Vim功能,它不需要插件(见:help aB
  • 糟糕!该插件以“Vim 感觉”完成了如此出色的工作,我忘记了内置的内容。谢谢指点!不过,我的其余技巧都经过vim -u NONE 测试。 =)
  • 谢谢,我尝试了这些命令,如果我只想删除功能块,它们效果很好。有没有办法完全删除函数头/名称?
  • @Jacky,我是作为评论回复的,但它太长了。我做了另一个编辑来解决你的问题。让我知道这是否适合您的需求。
  • da} 不包含声明,一种简单的方法是使用视觉选择并将其转换为视觉线条选择以获取整个函数:va}V 然后 yank/delete @ 987654336@/d
【解决方案2】:

删除整个函数,包括其定义,例如:

function tick() {
        // ... 
}
  • 移动到函数名称所在的行。
  • 将光标移动到左大括号,f{ 应该这样做,或者干脆$
  • V%d(视线,移动到匹配对,删除)

如果你的函数看起来像这样:

function tick() 
{
        // ... 
}
  • 移动到函数名称所在的行。
  • J加入当前行和下面的行。这也将光标放在结果行的最后一个字符{,只是下一个命令需要的。)
  • V%d(视觉线,移动到匹配对,删除。)

  • 移动到函数名称所在的行。
  • V[Down]%d(视觉线,下移一行,移动到匹配对,删除。)

【讨论】:

  • 为什么不Vj%d?不需要[Down]
【解决方案3】:

如果你愿意安装插件vim-textobj-function 会给你vif 用于Visual select Inside Function 和vaf 用于Visual select A Function。

daf 将删除函数,包括签名行和函数体 ({})

这个插件定义的文本对象更具体,它们不依赖于函数体是一个连续的文本块或{被放置在行的第一个字符处。

缺点是您依赖外部插件。

【讨论】:

    【解决方案4】:

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

    在花括号开始/结束时按 Shitf + v [将让您进入可视模式]。

    然后按 ] + }] + Shitf ] - 如果您在开始大括号中。

    然后按 [ + {[ + Shitf [ - 如果你在大括号中。

    然后 DEL 删除选中的行。

    【讨论】:

      【解决方案5】:

      最简单最直接的方法如下(在函数内的任何地方都可以使用):

      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

      【讨论】:

        【解决方案6】:

        用这个简单的方法

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

        【讨论】:

        • dW if func() {
        • dt{ 如果func () { :P
        【解决方案7】:

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

        dip
        

        意思是“删除内部段落”。

        【讨论】:

          【解决方案8】:

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

          也适用于圆括号、方括号、C 风格的多行 cmets 和预处理器指令。

          请参阅manual 了解更多信息。

          【讨论】:

          • % 跳转到 ) 而不是 }
          【解决方案9】:

          前置条件:在函数内部的某个地方。 使用

          转到第一行的上一个右大括号
          []
          

          然后使用删除到第一行的下一个右大括号

          d][
          

          【讨论】:

            【解决方案10】:

            大多数发布的方法都有一两个缺点。通常,在处理某些面向对象语言的类定义时,函数体之后可能没有空行,因为许多代码格式化程序将最后一个方法和类的右大括号放在连续的行上。此外,您可能在函数顶部有注释。更糟糕的是,你的函数体内可能有空行。此外,您更喜欢在函数中的任何位置使用光标的方法,因为必须将其移动到特定的行或更糟的字符,需要宝贵的时间。想象一下

            public class Test {
            
                /* ... */
            
                @Test
                public void testStuff() {
                    // given
                    doSetup();
            
                    // when
                    doSomething();
            
                    // then
                    assertSomething();
                }
            }
            

            在这种情况下,vap 不会对您有任何好处,因为它会在您的函数中的第一个空行处停止。 v{o} 出于同样的原因退出。 va{V 更好,但没有捕获方法顶部的注释。所以在最一般的情况下我会做的是va{o{va{ 选择整个函数体(注意:如果您的光标位于嵌套块内,例如内部的 if 语句,那么您只会得到该块),o 将光标放在selection 和 { 选择在您的选择之前的整个段落。这意味着您将获得函数定义、所有注释和 doc cmets。

            【讨论】:

              【解决方案11】:

              非视觉方式:

              d/^}/e
              

              ...通过在行首搜索} 删除,包括它以进行删除。

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

              使用/e - 搜索到匹配结束,因此包含了右括号,并且命令也适合拉动:

              y/^}/e
              

              【讨论】:

                【解决方案12】:

                如果你使用neovim 版本:>0.5
                现代方法是使用treesitter 并构建您的模型,然后您可以是selectedyankeddeleted...

                Tree-sitter 是一个解析器生成工具和一个增量解析库。它可以为源文件构建具体的语法树,并在编辑源文件时有效地更新语法树

                我在 youtube 上推荐了这个 video 来学习如何使用 treesitter 来构建你的模型:Let's create a Neovim plugin using Treesitter and Lua

                【讨论】:

                  【解决方案13】:

                  我在这里尝试了所有最重要的答案,但除了 Nick 提出的一个建议按 f{ 到达开头的花括号外,它们都不起作用。然后V%d删除整个函数。

                  请注意,整个函数会被拉出,因此您可以将其粘贴到其他位置。我经常遇到这种用例,尤其是在将 if 块移到另一个块中时。

                  【讨论】:

                  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
                  猜你喜欢
                  • 2021-11-12
                  • 1970-01-01
                  • 2013-02-23
                  • 2015-02-06
                  • 2022-01-22
                  • 2018-06-02
                  • 2023-02-14
                  • 1970-01-01
                  • 2019-09-21
                  相关资源
                  最近更新 更多