spacemacs使用semantic跳转代码
Posted csfreebird
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spacemacs使用semantic跳转代码相关的知识,希望对你有一定的参考价值。
semantic和CEDIT的关系
semantic是CEDIT的核心,支持语义理解的代码分析。
安装semantic layer
在~/.spacemacs中配置semantic layer名称,然后重启emacs即可
跳转到打开过的buffer
安装了semantic layer之后,只要在spacemacs中打开过某个文件,就会自动建立tag,
tag目录在~/.emacs.d/.cache/semanticdb/
比如这里就有个tag文件:
~/.emacs.d/.cache/semanticdb/!home!dean!work!gitlab!gitlab.com!mystudy!mongodb!code!simple!src!helper!semantic.cache
;; Object semanticdb-project-database-file
;; SEMANTICDB Tags save file
(semanticdb-project-database-file "semanticdb-project-database-file"
:tables
(list
(semanticdb-table "semanticdb-table"
:major-mode c++-mode
:tags
'( ("helper/logger.h" include nil nil [1 27])
("InitLog" function (:type "void") nil [29 1018]))
:file "logger.cc"
:pointmax 1019
:fsize 1018
:lastmodtime '(22645 60456 254615 422000)
:unmatched-syntax nil))
:file "!home!dean!work!gitlab!gitlab.com!mystudy!mongodb!code!simple!src!helper!semantic.cache"
:semantic-tag-version "2.0"
:semanticdb-version "2.2")
现在进入main.cc文件中,里面有一行调用InitLog函数的代码,将光标移动到上面,然后按下快捷键
C-c , J, 执行的是semantic-complete-jump函数。
在mini buffer中回车确认查找的是InitLog函数
然后就自动跳入源代码了。
设置变量
需要到.emacs.d/layers/+emacs/semantic/config.el中修改,比如
(setq semanticdb-find-default-throttle '(file local project unloaded system recursive))
这里加上了unloaded system recursive
不能跳入未打开buffer的问题
这是个大问题,经过了两天的探索,目前结局了第一个问题,如何跳转到有函数声明的头文件,当然如果头文件包含了内联的函数实现,就一并解决了。
答案是使用ede的帮助。
ede帮助跳入函数声明的头文件
下面是配置
(require 'mode-local)
(setq-mode-local c++-mode
semanticdb-find-default-throttle
'(project unloaded recursive))
(global-ede-mode t)
(ede-cpp-root-project "MongoDB"
:name "Simple Project"
:file "~/work/gitlab/gitlab.com/mystudy/mongodb/README.org"
:include-path '("/code/simple/include"
"/code/simple/include/error"
"/code/simple/include/helper"
"/code/simple/src"
"/code/simple/src/helper"
)
:spp-table '(("isUnix" . "")
("BOOST_TEST_DYN_LINK" . "")))
用命令查看,会发现项目中include的头文件都能够被找到, 不使用ede,仅依靠semanticdb-project-roots毫无用处。
M-x semanticdb-find-adebug-scanned-includes
*scanned helper/logger.h : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned my_app.h : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned boost/filesystem.hpp : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned iostream : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned sstream : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned stdexcept : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned string : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
*scanned vector : /home/dean/work/gitlab/gitlab.com/mystudy/mongodb/code/simple/src/main.cc
在main.cc中对调用代码InitLog运行命令
M-x semantic-ia-fast-jump, 跳到logger.h文件的函数声明。
现在来解决如何跳入源代码文件的问题
跳入函数定义文件(非头文件)
感觉关键是学会使用函数
semanticdb-file-table-object
下面的文章提供了解决思路
http://www.it1352.com/483633.html
在.spacemacs文件中的user-config函数中添加这么一段
(defvar c-files-regex ".*\\\\.\\\\(c\\\\|cpp\\\\|h\\\\|hpp\\\\|cc\\\\)"
"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)
然后重启emacs,打开main.cc文件,运行命令加载索引
M-x ls-parse-curdir-c
然后运行命令跳转
M-x semantic-ia-fast-jump, 可以跳入函数定义文件了。
注意,此时用semanticdb-find-adebug-scanned-includes 无法观察到已经被这段程序加载的cc文件。这是一个缺憾,等以后对semantic更理解了,再来解决。
以上是关于spacemacs使用semantic跳转代码的主要内容,如果未能解决你的问题,请参考以下文章