I have been experimenting with cedet and semantic in my emacs c/c++ development setup and I am quite satisfied with it except for one small detail.
I use ede-cpp-root-project
to create a project and give the root directory of my project along with the directories where include files reside like below:
(ede-cpp-root-project "My Project"
:name "My Project"
:file "/path/to/rootdir/AFILE"
:include-path '(
"/include2"
"/include1"
)
)
This allows me to easily jump to the declarations of functions with semantic-ia-fast-jump
but it does not get me to the definitions of those functions. So it seems to only be dealing with header files and totally ignore source files. Even if I go on the declaration of the function and trigger semantic-analyze-proto-impl-toggle
it will tell me that no suitable implementation could be found.
If I manually open the source file where the implementation of the function is located, then and only then it is parsed by semantic and all the above mentioned functions work.
So my question is, short of manually opening all source files included underneath my project's root directory or manually including them in ede-cpp-root-project
via the :spp-files
argument is there any other way to force parsing of all source files under a directory?
Thanks!
After ignoring this problem for a long time I thought I should spend some quality time reading on elisp and try to figure out a work-around. It is not the prettiest elisp code there is, since I use elisp only for my emacs needs but it does what I need.
(defvar c-files-regex ".*\\.\\(c\\|cpp\\|h\\|hpp\\)"
"A regular expression to match any c/c++ related files under a directory")
(defun my-semantic-parse-dir (root regex)
"
This function is an attempt of mine to force semantic to
parse all source files under a root directory. Arguments:
-- root: The full path to the root directory
-- regex: A regular expression against which to match all files in the directory
"
(let (
;;make sure that root has a trailing slash and is a dir
(root (file-name-as-directory root))
(files (directory-files root t ))
)
;; remove current dir and parent dir from list
(setq files (delete (format "%s." root) files))
(setq files (delete (format "%s.." root) files))
(while files
(setq file (pop files))
(if (not(file-accessible-directory-p file))
;;if it's a file that matches the regex we seek
(progn (when (string-match-p regex file)
(save-excursion
(semanticdb-file-table-object file))
))
;;else if it's a directory
(my-semantic-parse-dir file regex)
)
)
)
)
(defun my-semantic-parse-current-dir (regex)
"
Parses all files under the current directory matching regex
"
(my-semantic-parse-dir (file-name-directory(buffer-file-name)) regex)
)
(defun lk-parse-curdir-c ()
"
Parses all the c/c++ related files under the current directory
and inputs their data into semantic
"
(interactive)
(my-semantic-parse-current-dir c-files-regex)
)
(defun lk-parse-dir-c (dir)
"Prompts the user for a directory and parses all c/c++ related files
under the directory
"
(interactive (list (read-directory-name "Provide the directory to search in:")))
(my-semantic-parse-dir (expand-file-name dir) c-files-regex)
)
(provide 'lk-file-search)
To use it either call the function directly like so: (my-semantic-parse-dir "path/to/dir/root/" ".*regex")
or press M-x lk-parse-curdir-c
from a buffer to recursively scan all c/c++ related files from that buferr's visiting filename directory.
An alternate and perhaps preferrable way to call the function is by invoking lk-parse-dir-c
interactively which in turn will prompt you for a directory to parse.
If any elisp guru has a better solution or suggestions to improve the code I would love to hear them.