ソースとインクルード ファイルの少し珍しいレイアウトの C++ プロジェクトに取り組んでおり (少なくとも、これまで見てきたものでは珍しいことです)、.cpp を切り替えるためのヘルパー emacs 関数を考え出そうとしています。およびそれぞれの .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」のみを置き換える必要があります。 " パス内の最後の「src」オカレンスに対して「include」を使用します。
以下の 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)
)
)
)