我正在开发一个 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
- 项目/包括/a/b/c/Foo.h
“项目”本身保存在一个“src”目录中,我保存所有源代码(因此完整路径类似于 ~/src/project/src/....),这意味着该函数应该只替换“src” " 使用 "include" 表示路径中最后出现的 "src"。
我想出了下面的elisp函数;它将当前文件路径中最后出现的“src”替换为“include”,将“cpp”扩展名替换为“h”(反之亦然),并尝试访问生成的文件。
由于我是 lisp 的新手,我很想知道它是否可以变得更简单?或者也许可以定制 ff-find-other-file 来做到这一点?(是的,我看过 ff-search-directories,但是在处理同一个项目的多个结帐时这无济于事)。
(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)
)
)
)