This elisp can keeping in touch between header file and source file for C or C++.
;; Author:Tatsuhiko Kubo
;; This elisp can keeping in touch between header file and source file for C or C++
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
(defun c-open-relational-file-get-opened-file-name-prefix (file-name)
(string-match "/\\([^./]+\\)\\.[^.]+$" file-name)
(match-string 1 file-name))
(defun c-open-relational-file-get-ext-type (file-name)
(string-match "\\.\\([^.]+\\)$" file-name)
(match-string 1 file-name))
(defun c-open-relational-file-get-opening-file-name (file-name-prefix ext-list)
(let ((opening-file-name (concat file-name-prefix "." (car ext-list))))
(cond ((null (car ext-list)) nil)
((file-exists-p opening-file-name) opening-file-name)
(t (c-open-relational-file-get-opening-file-name file-name-prefix
(cdr ext-list))))))
(defun c-open-relational-file (how-open-type)
"keeping in touch between header file and source file for C or C++"
(interactive "nOpen-Type 1:elscreen,2:split; ")
(let* ((c-or-cpp-header-map (list "c" "cpp" "cxx" "cc" "c++" "C"))
(c-source-map (list "h" "s"))
(asm-source-map (list "c"))
(cpp-source-map (list "hpp" "h" "hxx" "h++" "hh" "H"))
(cpp-header-map (list "cpp" "cxx" "cc" "c++" "C"))
(ext-map (list
(cons "h" c-or-cpp-header-map)
(cons "c" c-source-map)
(cons "s" asm-source-map)
(cons "C" cpp-source-map)
(cons "cc" cpp-source-map)
(cons "cpp" cpp-source-map)
(cons "cxx" cpp-source-map)
(cons "c++" cpp-source-map)
(cons "H" cpp-header-map)
(cons "hh" cpp-header-map)
(cons "hpp" cpp-header-map)
(cons "hxx" cpp-header-map)
(cons "h++" cpp-header-map)))
(opened-file-name (buffer-file-name (window-buffer)))
(opened-file-name-prefix (c-open-relational-file-get-opened-file-name-prefix opened-file-name))
(opened-file-ext-type (c-open-relational-file-get-ext-type opened-file-name))
(opening-file-ext-type-list (cdr (assoc opened-file-ext-type ext-map)))
(opening-file-name (c-open-relational-file-get-opening-file-name opened-file-name-prefix
opening-file-ext-type-list))
(opening-file-buffer (if (null opening-file-name)
nil
(find-file-noselect opening-file-name))))
(if (null opening-file-buffer)
(message "not found relational file")
(cond ((= how-open-type 1) (switch-to-buffer opening-file-buffer))
((= how-open-type 2) (progn (split-window-horizontally)
(other-window 1)
(switch-to-buffer opening-file-buffer)))
(t (message "Illegal Type"))))))How to
If you execute ‘c-open-relational-file’ when current buffer is ‘test.h’ and ‘Open-Type’ is 1, current buffer switches C source file(’test.c’) And, if current buffer is ‘test.c’ and ‘Open-Type’ is 1, current buffer switches C header file(’test.h’) You can select 1 or 2 for ‘Open-Type’. If type is 1, current buffer switches relational file’s buffer, and if type is 2, emacs splits window horizontally and the buffer on other-window switches relational file’s buffer. This supports c and c++.
Modified version
I was having trouble using the code posted above, so I made a few minor changes. For one thing, I added support for Objective-C/C++ file extensions. For another, I removed the regular expressions, which stripped out the directory information, and replaced them with the elisp functions for extracting the extension etc of a file-name. This seems to work more reliably for me.
;; Minor additions by Nicholas D. Matsakis:
;; - added "m" etc for obj. c files
;; - added (provide 'cOpenRelational) at the end
;; - modified to use emacs built-in functions for removing extension, etc,
;; which preserves full path
;; Author:Tatsuhiko Kubo
;; This elisp can keeping in touch between header file and source file for C or C++
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
(defun c-open-relational-file-get-opening-file-name (file-name-prefix ext-list)
(let ((opening-file-name (concat file-name-prefix "." (car ext-list))))
(cond ((null (car ext-list)) nil)
((file-exists-p opening-file-name) opening-file-name)
(t (c-open-relational-file-get-opening-file-name file-name-prefix
(cdr ext-list))))))
(defun c-open-relational-file ()
"keeping in touch between header file and source file for C or C++"
(interactive)
(let* ((c-or-cpp-header-map (list "m" "mm" "mpp" "M" "c"
"cpp" "cxx" "cc" "c++" "C"))
(c-source-map (list "h" "s"))
(asm-source-map (list "c"))
(cpp-source-map (list "hpp" "h" "hxx" "h++" "hh" "H"))
(cpp-header-map (list "cpp" "cxx" "cc" "c++" "C"))
(ext-map (list
(cons "h" c-or-cpp-header-map)
(cons "m" c-source-map)
(cons "c" c-source-map)
(cons "s" asm-source-map)
(cons "C" cpp-source-map)
(cons "cc" cpp-source-map)
(cons "cpp" cpp-source-map)
(cons "cxx" cpp-source-map)
(cons "c++" cpp-source-map)
(cons "M" cpp-source-map)
(cons "H" cpp-header-map)
(cons "hh" cpp-header-map)
(cons "hpp" cpp-header-map)
(cons "hxx" cpp-header-map)
(cons "h++" cpp-header-map)))
(opened-file-name (buffer-file-name (window-buffer)))
(opened-file-name-prefix (file-name-sans-extension opened-file-name))
(opened-file-ext-type (file-name-extension opened-file-name))
(opening-file-ext-type-list (cdr (assoc opened-file-ext-type ext-map)))
(opening-file-name (c-open-relational-file-get-opening-file-name opened-file-name-prefix
opening-file-ext-type-list))
(opening-file-buffer (if (null opening-file-name)
nil
(find-file-noselect opening-file-name))))
(progn
;(print opened-file-name)
;(print opened-file-name-prefix)
;(print opened-file-ext-type)
;(print opening-file-name)
(if (null opening-file-buffer)
(message "not found relational file")
(switch-to-buffer opening-file-buffer)))))
(provide 'cOpenRelational)