在Vim中,如何在同名的.h和.cpp文件之间快速切换?

在Vim中,如何在同名的.h和.cpp文件之间快速切换?,vim,Vim,假设我有一个包含大量.h和.cpp文件的文件夹。我经常需要做以下工作: 打开一个文件前缀\u SomeReallyLongFileName.h 对它做一些修改, 然后打开前缀\u SomeReallyLongFileName.cpp 我可以使用auto complete使用:e来完成此操作,但由于许多文件的前缀相同,这就变得不方便了 是否有一种快速方法可以打开与当前文件同名但扩展名不同的文件? 其他人也遇到过这种情况,如果是这样,你最喜欢的是在目录中导航C++文件?谢谢。您可以使用:r(root

假设我有一个包含大量.h和.cpp文件的文件夹。我经常需要做以下工作:

  • 打开一个文件
    前缀\u SomeReallyLongFileName.h
  • 对它做一些修改,
  • 然后打开
    前缀\u SomeReallyLongFileName.cpp
    我可以使用auto complete使用
    :e
    来完成此操作,但由于许多文件的前缀相同,这就变得不方便了

    是否有一种快速方法可以打开与当前文件同名但扩展名不同的文件?


    其他人也遇到过这种情况,如果是这样,你最喜欢的是在目录中导航C++文件?谢谢。

    您可以使用
    :r
    (root)文件名修饰符删除最后一个扩展名(有关详细信息,请查看
    :h文件名修饰符)

    在哪里

    • %
      是当前文件名的缩写
    • :r
      删除扩展名
    • .cpp
      只需将该字符串追加到末尾
    这将有效地用另一个扩展名替换当前文件的扩展名,然后用新的扩展名打开文件


    一条更短的路(由


    :e%根据Vim维基,有很多

    我将概述文章中的几个选项:

    • 或插件
    • 使用CTAG

    • :e%安装“unpaired”,然后使用
      ]f
      [f
      转到上一个和下一个文件。由于源文件和头文件除了后缀外都有相同的名称,所以它们是下一个和上一个文件。

      这只是使用简单的(?!)vimscript,因此您可以将其放入
      vimrc
      , 现在它适用于
      .c
      文件,但是可以很容易地修改
      .cpp
      (显然,它甚至在内部if语句中有一些“错误处理”(这可能是毫无意义的),但是如果有人需要它,嘿,它就在那里了!没有它,它会短得多(只需保留
      :e%是一个选项)

      配置后,递归搜索当前目录和源文件所在的目录,以查找要切换到的文件。

      添加我的两分钱;)到上述重要答案:

    • 安装旺盛的CTAG
    • 将以下代码放入
      .vimrc
    • “跳转到扩展名与当前文件扩展名对应的文件
      “文件.`标签'文件,由以下内容创建:
      “$ctags--extra=+f-R。
      “必须存在于当前目录中。
      函数!JumpToCorrespondingFile()
      设l:extensions={'c':'h','h':'c','cpp':'hpp','hpp':'cpp'}
      设l:fe=展开('%:e')
      if有_键(l:extensions,l:fe)
      执行“:tag”.expand('%:t:r')。.l:extensions[l:fe]
      其他的
      调用PrintError(“>>>未指定“”的相应扩展名。l:fe.”)
      恩迪夫
      端函数
      “跳转到具有相应扩展名(aka)的文件”
      nnoremap:调用JumpToCorrespondingFile()
      inoremap:调用JumpToCorrespondingFile()
      “打印错误消息。
      函数!打印错误(msg)中止
      执行'normal!\'
      echohl ErrorMsg
      a:msg
      无回声
      端功能
      
      我不确定这是否会发生在很多人身上。通常,你的头文件与源文件(例如
      include/
      src/
      )放在一个单独的文件夹中,因此你要求的不会发生(除非在
      。/include/
      。/src/
      中查找文件)。我通常会打开两个终端,其中一个终端保持头文件打开,另一个终端保持源文件打开,因为我通常会在文件之间来回移动。您可以键入
      :e
      ,然后按ctrl-r%。这会将当前文件名置为行,然后您可以替换扩展名。相关问题和。不同的目录superet:| | SU对我来说,在
      a.c
      文件中,
      :e%:e.h
      变成
      c.h
      而不是预期的
      a.h
      @Shahbaz,很抱歉,我应该使用
      :r
      。我会更正帖子。Vim高尔夫时间!
      :e%@PeterRincker,你赢了。更新帖子。@PeterRincker注意:删除扩展名的帮助页面现在说Operator是为了向后兼容而包括的,最好使用:r符号。我发现的一个区别是:r有一个保护措施,防止删除隐藏文件(例如“.vimrc:r”将产生“.vimrc”,但是".vimracother插件真正值得一提的是,一个更好的a.vim。它不仅支持
      .h
      .cpp
      ,而且还支持其他替代插件,并且可以自定义。我正在使用上述命令,但我使用
      标记
      而不是
      e
      。但是,它说
      标记未找到
      。这是因为它是从
      调用的吗>.vimrc
      文件而不是源文件?@Paschalis
      :tag
      :e
      是完全不同的命令。
      :e
      编辑给定的文件,而
      :tag
      跳转到给定的标记。上面的命令(映射)基本上采用当前文件名
      %
      ,并应用一些替换技巧来更改
      .h
      ->
      .cpp
      .cpp
      ->
      .h
      。这意味着该命令将在源文件和头文件之间切换(然后再次切换)。通过使用
      :tag
      和此映射,您基本上是在搜索没有任何意义的扩展名的文件名。有关更多帮助,请参阅
      :h:tag
      :h:e
      、和
      :h c_uuz%
      。我应该向下滚动并阅读您的答案,然后用vimscript修补一个小时作为你的一行代码,仅供谷歌参考:
      ]f
      [f
      只浏览当前目录中的文件。因此这确实回答了OP的问题,但对那些将头文件和源文件拆分到不同目录的人没有帮助,等等。
      :e %:r.cpp
      
      :e %<.cpp
      
      function! HeaderToggle() " bang for overwrite when saving vimrc
      let file_path = expand("%")
      let file_name = expand("%<")
      let extension = split(file_path, '\.')[-1] " '\.' is how you really split on dot
      let err_msg = "There is no file "
      
      if extension == "c"
          let next_file = join([file_name, ".h"], "")
      
          if filereadable(next_file)
          :e %<.h
          else
              echo join([err_msg, next_file], "")
          endif
      elseif extension == "h"
          let next_file = join([file_name, ".c"], "")
      
          if filereadable(next_file)
              :e %<.c
          else
              echo join([err_msg, next_file], "")
          endif
      endif
      endfunction
      
      let mapleader = "," " <Leader>
      nnoremap <Leader>h :call HeaderToggle()<CR>
      
      " Jump to a file whose extension corresponds to the extension of the current
      " file. The `tags' file, created with:
      " $ ctags --extra=+f -R .
      " has to be present in the current directory.
      function! JumpToCorrespondingFile()
          let l:extensions = { 'c': 'h', 'h': 'c', 'cpp': 'hpp', 'hpp': 'cpp' }
          let l:fe = expand('%:e')
          if has_key(l:extensions, l:fe)
              execute ':tag ' . expand('%:t:r') . '.' . l:extensions[l:fe]
          else
              call PrintError(">>> Corresponding extension for '" . l:fe . "' is not specified") 
          endif
      endfunct
      
      " jump to a file with the corresponding extension (<C-F2> aka <S-F14>)
      nnoremap <S-F14> :call JumpToCorrespondingFile()<CR>
      inoremap <S-F14> <C-o>:call JumpToCorrespondingFile()<CR>
      
      " Print error message.
      function! PrintError(msg) abort
          execute 'normal! \<Esc>'
          echohl ErrorMsg
          echomsg a:msg
          echohl None
      endfunction