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