设为首页 加入收藏

TOP

Emacs自动填充头文件(一)
2014-11-24 00:40:13 】 浏览:246
Tags:Emacs 自动 填充 文件
目标
1. 写 C/C++ 代码时候,可以根据自动补全头文件。注意,是补全,也就是说至少我们需要输入几个字符让它帮忙补全。
2. 如果头文件存放在搜索路径的子目录中,可以自动列出子目录中的文件,并将这些文件添加到用于补齐的候选名单中。
3. 补齐完成之后,可以自动判断到底应该使用 #include还是 #include “FILE” 。
方案
emacser.org 上有一篇文章,其中提到了这个解决方法,主要是利用了 abbrev-mode 和 skeleton-mode 来实现,通过这个方法,我们输入 inc, 然后按空格, 会提示输入文件名称。
代码如下:
View CodeLISP
;; 安装 abbrev
(mapc
(lambda (mode)
(define-abbrev-table mode '(
("inc" "" skeleton-include 1)
)))
'(c-mode-abbrev-table c++-mode-abbrev-table))

;; 输入 inc , 可以自动提示输入文件名称,可以自动补全.
(define-skeleton skeleton-include
"generate include<>" ""
> "#include <"
(completing-read "Include File:"
(mapcar #'(lambda (f) (list f ))
(apply 'append
(mapcar
#'(lambda (dir)
(directory-files dir))
(list "/usr/include"
"/usr/local/include"
"/usr/include/g++-3")))))
">")
该方法有若干局限性:
头文件的搜索路径是写死的,如果某个目录不存在,上面的代码会报错,不能补全。
无法补全搜索路径的子目录下的文件 ( 即前面的 AIM 2)。
没有判断在 #include 一个文件的时候,是应该使用符号 <> 还是符号 “” (即前面的 AIM 3)
解决方法并不复杂,对应如下:
通过某种方法来从系统中自动获取 include 的搜索路径。比如 CEDET 提供的: semantic-gcc-get-include-paths 函数。
重定义 minibuffer-mode 下的按键 “/”。将其绑定到一个用于搜索和展开某个目录,并更新 minibuffer-completion-table 的函数(minibuffer-completion-table 是 minibuffer-mode 中补全的候选 list)。
在 skeleton-include 中不使用 <> 或者 “。我们可以使用一个特殊的标记,然后在 skeleton-include 的结尾,根据头文件的路径判断到底应该使用什么符号。
整理以后的代码实现如下:
View CodeLISP
;; 输入 inc , 可以自动提示输入文件名称,可以自动补全.
;; Provided by yangyingchao@gmail.com
(mapc
(lambda (mode)
(define-abbrev-table mode '(
("inc" "" skeleton-include 1)
)))
'(c-mode-abbrev-table c++-mode-abbrev-table))

(defconst yc/inc-dir-list
(append (semantic-gcc-get-include-paths "c++") '("./")) "nil")
(defvar inc-minibuffer-compl-list nil "nil")

(defun yc/update-minibuffer-complete-table ( )
"Complete minibuffer"
(interactive)
(let ((prompt (minibuffer-prompt))
(comp-part (minibuffer-contents-no-properties)))
(when (and (string= "Include File:" prompt)
(> (length comp-part) 0))
(setq minibuffer-completion-table
(append minibuffer-completion-table
(let ((inc-files nil)
(dirname nil)
(tmp-name nil))
(mapc
(lambda (d)
(setq dirname (format "%s/%s" d comp-part))
(when (file-exists-p dirname)
(mapc
(lambda (x)
(when (not (or (string= "." x)
(string= ".." x)))
(setq tmp-name (format "%s/%s" comp-part x))
(add-to-list 'inc-files tmp-name)))
(directory-files dirname))))
yc/inc-dir-list)
inc-files)))))
(insert "/"))

(let ((map minibuffer-local-completion-map))
(define-key map "/" 'yc/update-minibuffer-complete-table))

(defun yc/update-inc-marks ( )
"description"
(let ((statement (buffer-substring-no-properties
(point-at-bol) (point-at-eol)))
(inc-file nil)
(to-begin nil)
(to-end nil)
(yc/re-include
(rx "#include" (+ ascii) "|XXX|" (group (+ ascii)) "|XXX|")))
(when (string-match yc/re-include statement)
(setq inc-file (match-
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇很酷的C语言技巧 下一篇switch case 疑点解析

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目