我正在开发一个 C++ 项目,它的源代码和包含文件布局有点不常见(好吧,至少到目前为止我所看到的是不常见的),我正在尝试提出一个用于切换的辅助 emacs 函数在 .cpp 和相应的 .h 文件之间(仅针对这种特殊情况,因此不需要非常灵活),因为 ff-find-other-file 在此设置上失败。这对我来说也是一次elisp的学习经历。
项目结构设置如下:
- 源文件在 projectname/src/namespacepath/*.cpp 中
- 各自的包含文件属于 projectname/include/namespacepath/*.h
此外,我可能对该项目 (projectname2/....) 进行了额外的检查,并且 cpp 和 h 之间的切换应该发生在项目边界内。
换句话说,对于命名空间 a::b::c 中类 Foo 的源文件 Foo.cpp 我有:
- 项目/src/a/b/c/Foo.cpp
- 项目/include/a/b/c/Foo.h
“项目”本身保存在“src”目录中,我保存所有源代码(因此完整路径类似于 ~/src/project/src/....),这意味着函数应该只将路径中最后一次出现的“src”替换为“include”。
我想出了下面的 elisp 函数;它用当前文件路径中的“include”替换最后一次出现的“src”,用“h”替换“cpp”扩展名(反之亦然),并尝试访问生成的文件。
由于我是 lisp 的新手,我很想知道它是否可以变得更简单?或者可以定制 ff-find-other-file 来做到这一点? (是的,我见过 ff-search-directories,但在处理同一项目的多个 checkout 时这无济于事)。
(defun alternate-include-or-src()
(interactive)
(let (
(name)
(newname "")
(repl t)
)
(setq name (nreverse (split-string (buffer-file-name) "/")))
(setq filename (car name))
(dolist (p (cdr name)) ;; iterate over reversed list of path components
(if repl ;; do the src <-> substitution only once
(if (string= p "src")
(progn
(setq p "include"
repl nil)
(setq filename (concat (file-name-sans-extension filename) ".h"))
)
(if (string= p "include")
(progn
(setq p "src"
repl nil)
(setq filename (concat (file-name-sans-extension filename) ".cpp"))
)
)
)
)
(setq newname (concat p "/" newname))
)
(setq newname (concat newname filename))
(if (file-exists-p newname)
(find-file newname)
)
)
)
最佳答案
我建议你看一下 cc-other-file-alist
,它与 ff-find-other-file
一起使用。它允许自定义函数调用,您可以节省一些编码:
例子:
(setq cc-other-file-alist
`(
("\\.cxx$" ,(my-look-for-other-file-1))
("\\.hxx$" ,(my-look-for-other-file-2))))
关于c++ - 用于在非标准项目结构的 header 和实现之间切换的 emacs 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19843005/