Я экспериментировал с cedet и семантикой в моей разработке emacs c / c ++, и я вполне доволен этим, за исключением одной маленькой детали.
я использую ede-cpp-root-project
создать проект и дать корневой каталог моего проекта вместе с каталогами, в которых находятся включаемые файлы, как показано ниже:
(ede-cpp-root-project "My Project":name "My Project":file "/path/to/rootdir/AFILE":include-path '(
"/include2""/include1")
)
Это позволяет мне легко переходить к объявлениям функций с semantic-ia-fast-jump
но это не дает мне определения этих функций. Так что, похоже, он имеет дело только с заголовочными файлами и полностью игнорирует исходные файлы. Даже если я иду на объявление функции и триггера semantic-analyze-proto-impl-toggle
это скажет мне, что подходящая реализация не может быть найдена.
Если я вручную открою исходный файл, в котором находится реализация функции, то и только тогда он анализируется семантически, и все вышеупомянутые функции работают.
Поэтому мой вопрос заключается в том, чтобы вручную открыть все исходные файлы, включенные в корневой каталог моего проекта, или вручную включить их в ede-cpp-root-project
через :spp-files
Аргумент есть ли другой способ принудительного анализа всех исходных файлов в каталоге?
Спасибо!
После долгого игнорирования этой проблемы я подумал, что мне следует потратить некоторое время на чтение elisp и попытаться найти обходной путь. Это не самый красивый код elisp, так как я использую elisp только для своих нужд в emacs, но он делает то, что мне нужно.
(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)
Чтобы использовать его, либо вызовите функцию напрямую, например так: (my-semantic-parse-dir "path/to/dir/root/" ".*regex")
или нажмите M-x lk-parse-curdir-c
из буфера для рекурсивного сканирования всех файлов, связанных с c / c ++, из директории имени посетителя этого буфера.
Альтернативный и, возможно, предпочтительный способ вызова функции — это вызов lk-parse-dir-c
в интерактивном режиме, который, в свою очередь, предложит вам проанализировать каталог.
Если у какого-либо гуру-элиспа есть лучшее решение или предложения по улучшению кода, я бы хотел их услышать.
Я недавно реализовал это для Python. Это может быть принято для C / C ++ с небольшими изменениями.
(defvar python-extention-list (list "py"))
(defun semanticdb-rescan-directory (pathname)
(dolist (file (cddr (directory-files pathname t)))
(if (file-directory-p file)
(semanticdb-rescan-directory file)
(when (member (file-name-extension file) python-extention-list)
(message "Parsing %s file." file)
(ignore-errors
(semanticdb-file-table-object file))))))
(defun semantic-python-rescan-includes ()
(interactive)
(dolist (includes (semantic-python-get-system-include-path))
(message "Parsing %s" includes)
(semanticdb-rescan-directory includes)))
Попробуйте запустить команду «bovinate». Это можно сделать с помощью комбинации клавиш Meta + X, затем набрав «bovinate» и нажав клавишу «Enter». Клавиша «Meta» в Windows называется клавишей «Alt».