编程小贴士

给你的编程提供小点子


Emacs下 C/C++ 开发环境搭建指南

在这个指南中,我将帮助你搭建一个高效的C/C++开发环境。尽管看起来很长,但步骤清晰简短(主要是复制/粘贴Emacs Lisp代码到你的init.el文件中)。指南中的大部分操作都会有解释,并且强调其特点。遵循这个指南,你将能够很高效的在Emacs中浏览 Linux内核代码树,可以实现像跳转到光标处的定义或者引用,在跳转点之间前进或者后退,立刻找到某个文件,在.h文件和.c/.cpp文件之间跳转 等。

一些例子:
.h文件和.c/.cpp文件之间跳转

tips1000_2014-09-19_00-27-06

通过使用helm-semantic-or-imenu显示树型代码轮廓

tips1000_2014-09-19_00-27-05

符号引用
tips1000_2014-09-19_00-27-052

代码补全1
tips1000_2014-09-19_00-27-051

代码补全2
tips1000_2014-09-19_00-27-07

头文件补全
tips1000_2014-09-19_00-27-04

在底部显示函数接口
tips1000_2014-09-19_00-27-07

将光标处的函数置顶显示
tips1000_2014-09-19_00-27-11

编译支持
tips1000_2014-09-19_00-27-14

编译输出
tips1000_2014-09-19_00-27-141

花哨的GDB调试
tips1000_2014-09-19_00-27-15

得到光标处命令的手册
tips1000_2014-09-19_00-27-16

导航:
准备:
知道如何使用package.el和MELPA。如果你不清楚,阅读《如何使用Emacs扩展管理》

全局安装GNU,可以在这里下载,或者可以通过你的操作系统的软件管理程序下载。对于Windows用户,在这里下载。

安装ggtags,当从MELPA安装ggtags之后,用下面的代码配置ggtags以及按键绑定。

(require 'ggtags)
(add-hook 'c-mode-common-hook
(lambda ()
(when (derived-mode-p 'c-mode 'c++-mode 'java-mode 'asm-mode)
(ggtags-mode 1))))

(define-key ggtags-mode-map (kbd "C-c g s") 'ggtags-find-other-symbol)
(define-key ggtags-mode-map (kbd "C-c g h") 'ggtags-view-tag-history)
(define-key ggtags-mode-map (kbd "C-c g r") 'ggtags-find-reference)
(define-key ggtags-mode-map (kbd "C-c g f") 'ggtags-find-file)
(define-key ggtags-mode-map (kbd "C-c g c") 'ggtags-create-tags)
(define-key ggtags-mode-map (kbd "C-c g u") 'ggtags-update-tags)

(define-key ggtags-mode-map (kbd "M-,") 'pop-tag-mark)

或者,helm + helm-gtags 。 Helm很棒,如果你打算使用Helm,请阅读Helm指南,记得在使用helm-gtags之前安装Helm,你也可以使用这个默认配置。当将上面的文件添加到你的~/.emacs.d时,记得添加(require ‘setup-helm)到你的init.el

;; this variables must be set before load helm-gtags
;; you can change to any prefix key of your choice
(setq helm-gtags-prefix-key "\C-cg")

(require 'helm-gtags)

(setq
helm-gtags-ignore-case t
helm-gtags-auto-update t
helm-gtags-use-input-at-cursor t
helm-gtags-pulse-at-cursor t

helm-gtags-suggested-key-mapping t
)

;; Enable helm-gtags-mode in Dired so you can jump to any tag
;; when navigate project tree with Dired
(add-hook 'dired-mode-hook 'helm-gtags-mode)

;; Enable helm-gtags-mode in Eshell for the same reason as above
(add-hook 'eshell-mode-hook 'helm-gtags-mode)

;; Enable helm-gtags-mode in languages that GNU Global supports
(add-hook 'c-mode-hook 'helm-gtags-mode)
(add-hook 'c++-mode-hook 'helm-gtags-mode)
(add-hook 'java-mode-hook 'helm-gtags-mode)
(add-hook 'asm-mode-hook 'helm-gtags-mode)

;; key bindings
(define-key helm-gtags-mode-map (kbd "M-s") 'helm-gtags-select)
(define-key helm-gtags-mode-map (kbd "M-.") 'helm-gtags-dwim)
(define-key helm-gtags-mode-map (kbd "M-,") 'helm-gtags-pop-stack)
(define-key helm-gtags-mode-map (kbd "C-c ") 'helm-gtags-next-history)

在使用ggtags和helm-gtags之前,记得在你的项目root目录下执行gtags以创建GTAGS数据库。

$ cd /path/to/project/root
$ gtags

执行完成之后,下面几个文件会创建出来

$ ls G*
GPATH GRTAGS GTAGS

GTAGS: 定义数据库
GRTAGS: 引用数据库
GPATH: 路径名数据库

如果你使用ggtags,要使用ggtags-create-tags创建GTAGS数据库。这是推荐用法,以让它知道项目root在哪。

基本移动:
C-M-f执行forward-sexp,在呼应的符号之间向前移动,比如一对大括号:
tips1000_2014-09-19_00-27-151

C-M-b执行backward-sexp,与C-M-f相反:
tips1000_2014-09-19_00-27-201

C-M-k执行kill-sexp,删除呼应符号之间的内容,比如一对大括号之间的内容:
tips1000_2014-09-19_00-27-20

C-M-或者C-M-@执行mark-sexp,选中呼应符号之间的内容:
tips1000_2014-09-19_00-27-24

C-M-a执行beginning-of-defun,移动光标到函数的定义开头:
tips1000_2014-09-19_00-27-251

C-M-e执行end-of-defun,移动光标到函数的结尾:
tips1000_2014-09-19_00-27-252

C-M-h执行mark-defun,选中一个函数的全部内容:
tips1000_2014-09-19_00-27-25

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>