让你的Emacs像VS一样方便
来源:互联网 发布:java访问redis数据库 编辑:程序博客网 时间:2024/05/13 19:42
Emacs是强大的文本编辑器之一,尤其是进行程序设计,人们常说:“程序员可以分为三种:使用Emacs的,使用Vim的,以及其他”,可见Emacs在程序员中间的地位。不多废话,直接进入正题。本文介绍了在Ubuntu环境下使用Emacs进行C/C++进行开发的配置方法,通过两天的折腾,配置了一些基本的功能:代码提示/补齐、代码折叠、代码缩进和代码跳转等功能,后续的配置还会继续更新本文章,但仅此三项已经大大提高了开发效率。
配置方法
本文配置是基于Emacs24进行配置的,但配置原理上也支持Emacs23。配置主要用到两个Emacs扩展:CEDET和Auto-Complete。CEDET用于向Auto-Complete提供语义分析,从而向auto-complete提供代码提示支撑。配置方法如下:
基本概念:
Emacs在启动的时候会默认加载home目录下的.emacs配置文件,此文件是隐藏文件,如果不存在可手动建立(命令:touch .emacs),建立此文件之后可以使用gedit进行编辑(gedit .emacs)。然后配置信息都写在此文件内。开启CEDET
首先需要开启CEDET,配置如下:;;set the mode enabled(setq semantic-default-submodes '(global-semanticdb-minor-mode global-semantic-idle-scheduler-mode global-semantic-idle-summary-mode global-semantic-idle-completions-mode global-semantic-decoration-mode global-semantic-highlight-func-mode global-semantic-stickyfunc-mode global-semantic-mru-bookmark-mode global-semantic-tag-folding-mode));;enable cedet(semantic-mode 1)
在CEDET1.1及以后版本中,通过设置默认语义子模式(semantic-default-submodes)来配置需要开启的模式,然后只需要(semantic-mode 1)一句话即可开启CEDET。CEDET支持的模式包括:CEDET模式列表 模式名称 模式作用 global-semanticdb-minor-mode开启Semanticdb支持。Semanticdb用于存储已经分析出的语义结果global-semantic-mru-bookmark-mode开启自动书签存储,从而可以使用代码跳转global-cedet-m3-minor-mode激活CEDET右键菜单(还没发先有啥用)global-semantic-highlight-func-mode高亮方法、类等的第一行global-semantic-stickyfunc-mode当前编辑的方法上滚到可视区域外时,将方法名显示在最顶端global-semantic-decoration-mode激活样式global-semantic-idle-local-symbol-highlight-mode高亮所有当前选中变量使用的位置global-semantic-idle-scheduler-mode空闲的时候对源码自动进行语义分析global-semantic-idle-completions-mode在空闲的时候显示可能的命名补全(CEDET自己的命名补全显示在已输入部分后面,显示为淡灰色)global-semantic-idle-summary-mode在空闲时显示当前位置的信息global-semantic-show-unmatched-syntax-mode显示当前没有进行语义处理的元素global-semantic-show-parser-state-mode显示当前语义处理器的状态global-semantic-highlight-edits-mode高亮还没有进行语义处理的元素配置代码提示/补齐
代码提示需要配合auto-complete进行,虽然CEDET也有代码提示功能(参见CEDET配置参考文章),但CEDET官方推荐的是使用auto-complete进行代码提示和补齐。
使用代码提示首先要开启CEDET代码补齐功能:;;开启代码补齐功能(require 'semantic/ia);;添加C++头文件(require 'semantic/bovine/gcc)
然后,将CEDET语义分析添加到ac-sources变量中,这是由于auto-complete使用ac-sources进行代码提示和补齐,配置如下:;;添加ac-sources(defun my-c-mode-cedet-hook () (add-to-list 'ac-sources 'ac-source-gtags) (add-to-list 'ac-sources 'ac-source-semantic))(add-hook 'c-mode-common-hook 'my-c-mode-cedet-hook)
最后,需要配置auto-complete。由于auto-complete不是Emacs标准的一部分,因此需要手动下载而配置。首先去auto-complete官网Auto Complete Mode下载最新版本的auto-complete(本文是基于1.3.1),然后解压放在~/home/.emacs.d文件夹下(.emacs.d如果不存在则手动建立),并将文件夹名称改为"auto-complete"(如果不是)。然后配置加载auto-complete如下:(add-to-list 'load-path "~/.emacs.d/auto-complete")(require 'auto-complete-config)(add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/dict")(ac-config-default);;ignore case(setq ac-ignore-case t)
最后一行配置了auto-complete代码提示忽略大小写,还有其他一些配置,例如设置提示框颜色等等,可以参考auto-complete配置参考文章。最后一行配置了忽略大小写
代码跳转
代码跳转时程序设计中很常用的一个功能,CEDET可以通过配置支持代码跳转功能。配置如下:(global-set-key [f2] 'semantic-ia-fast-jump);;jump(global-set-key [S-f2];;jump back:shift+f2 (lambda () (interactive) (if (ring-empty-p (oref semantic-mru-bookmark-ring ring)) (error "Semantic Bookmark ring is currently empty")) (let* ((ring (oref semantic-mru-bookmark-ring ring)) (alist (semantic-mrub-ring-to-assoc-list ring)) (first (cdr (car alist)))) (if (semantic-equivalent-tag-p (oref first tag) (semantic-current-tag)) (setq first (cdr (car (cdr alist))))) (semantic-mrub-switch-tags first))))
上面代码配置了使用f2进行代码跳转,然后使用shift+f2进行代码跳回(默认是使用\C-x B),另外需要注意的是使用代码跳转需要开启模式。此外如果代码无法跳回可在跳转配置前加入如下配置(参考点击打开链接):(defadvice push-mark (around semantic-mru-bookmark activate) "Push a mark at LOCATION with NOMSG and ACTIVATE passed to `push-mark'.If `semantic-mru-bookmark-mode' is active, also push a tag ontothe mru bookmark stack." (semantic-mrub-push semantic-mru-bookmark-ring (point) 'mark) ad-do-it)
代码缩进
代码缩进功能没有深入研究,就参考了GNU Emacs官方文档上的示例代码设置了一下(参见点击打开链接),代码如下:;;-------------indent setting start ;; Make a non-standard key binding. We can put this in;; c-mode-base-map because c-mode-map, c++-mode-map, and so on,;; inherit from it.(defun my-c-initialization-hook () (define-key c-mode-base-map "\C-m" 'c-context-line-break))(add-hook 'c-initialization-hook 'my-c-initialization-hook);; offset customizations not in my-c-style;; This will take precedence over any setting of the syntactic symbol;; made by a style.(setq c-offsets-alist '((member-init-intro . ++)));; Create my personal style.(defconst my-c-style '((c-tab-always-indent . t) (c-comment-only-line-offset . 4) (c-hanging-braces-alist . ((substatement-open after) (brace-list-open))) (c-hanging-colons-alist . ((member-init-intro before) (inher-intro) (case-label after) (label after) (access-label after))) (c-cleanup-list . (scope-operator empty-defun-braces defun-close-semi)) (c-offsets-alist . ((arglist-close . c-lineup-arglist) (substatement-open . 0) (case-label . 4) (block-open . 0) (knr-argdecl-intro . -))) (c-echo-syntactic-information-p . t)) "My C Programming Style")(c-add-style "PERSONAL" my-c-style);; Customizations for all modes in CC Mode.(defun my-c-mode-common-hook () ;; set my personal style for the current buffer (c-set-style "PERSONAL") ;; other customizations (setq tab-width 8 ;; this will make sure spaces are used instead of tabs indent-tabs-mode nil);; we like auto-newline, but not hungry-delete (c-toggle-auto-newline 1))(add-hook 'c-mode-common-hook 'my-c-mode-common-hook);;----------indent setting end
代码折叠
代码折叠功能使用了Emacs自带的hs-minor-mode,但是由于默认快捷键使用起来太不方便,所以进行了自定义为C-c ?快捷键,配置代码如下;;universal code folding(defun toggle-selective-display (column) (interactive "P") (set-selective-display (or column (unless selective-display (1+ (current-column))))))(defun toggle-hiding (column) (interactive "P") (if hs-minor-mode (if (condition-case nil (hs-toggle-hiding) (error t)) (hs-show-all)) (toggle-selective-display column)))(load-library "hideshow")(global-set-key (kbd "C-?") 'toggle-hiding)(global-set-key (kbd "C-`") 'toggle-selective-display)(add-hook 'c-mode-common-hook 'hs-minor-mode) (add-hook 'emacs-lisp-mode-hook 'hs-minor-mode) (add-hook 'java-mode-hook 'hs-minor-mode) (add-hook 'lisp-mode-hook 'hs-minor-mode) (add-hook 'perl-mode-hook 'hs-minor-mode) (add-hook 'sh-mode-hook 'hs-minor-mode);;display overlay content in echo area or tooltip(defun display-code-line-counts (ov) (when (eq 'code (overlay-get ov 'hs)) (overlay-put ov 'help-echo (buffer-substring (overlay-start ov) (overlay-end ov))))) (setq hs-set-up-overlay 'display-code-line-counts)
其他设置
除了上述设置,还有一些其他有趣的设置,包括:
其他快捷键
其他快捷键设置除了代码跳转外,还可以定义其他快捷键,包括:(defun my-c-mode-cedet-key() (local-set-key "\C-cd" 'semantic-ia-show-doc);;显示方法、类等的文档 (local-set-key "\C-cs" 'semantic-ia-show-summary);;显示方法、类等的概述 (local-set-key "\C-cc" 'semantic-ia-describe-class);;列举类的方法变量等 (local-set-key "\C-ct" 'semantic-analyze-proto-impl-toggle);;在.h和.cpp文件之间进行跳转切换 (local-set-key "\C-ci" 'semantic-decoration-include-visit);;进入include中的文件)(add-hook 'c-mode-common-hook 'my-c-mode-cedet-key)
显示行号
(global-linum-mode 1)
Emacs24及以上版本主题设置
M-x list-faces-display
隐藏工具栏
(tool-bar-mode -1)
Yasnippe代码模板
yasnippe提供了代码模板功能,但我个人习惯了自己写书写,而且配置很麻烦,所以就没有深入弄,基本配置代码如下:(add-to-list 'load-path "~/.emacs.d/yasnippet-0.6.1c/")(require 'yasnippet)(yas/initialize)(yas/load-directory "~/.emacs.d/yasnippet-0.6.1c/snippets")
需要注意的是,yasnnipe需要自己下载安装,与auto-complete方法一致,放在对应路径下就行,本文放在了~/.emacs.d/yasnippet-0.6.1c下。具体配置方法参见yasnippet配置参考文章。
配置完成后的效果如下图:
全部配置:
;;=====================================================================;;Emacs settings begin;;=====================================================================;;newline and indent(setq c-newline-and-indent 'newline-and-indent);;hide tool bar(tool-bar-mode -1);; display column-number-mode(global-linum-mode 1);;-------------indent setting start http://www.gnu.org/software/emacs/manual/html_mono/ccmode.html#Sample-_002eemacs-File;; Make a non-standard key binding. We can put this in;; c-mode-base-map because c-mode-map, c++-mode-map, and so on,;; inherit from it.(defun my-c-initialization-hook () (define-key c-mode-base-map "\C-m" 'c-context-line-break))(add-hook 'c-initialization-hook 'my-c-initialization-hook);; offset customizations not in my-c-style;; This will take precedence over any setting of the syntactic symbol;; made by a style.(setq c-offsets-alist '((member-init-intro . ++)));; Create my personal style.(defconst my-c-style '((c-tab-always-indent . t) (c-comment-only-line-offset . 4) (c-hanging-braces-alist . ((substatement-open after) (brace-list-open))) (c-hanging-colons-alist . ((member-init-intro before) (inher-intro) (case-label after) (label after) (access-label after))) (c-cleanup-list . (scope-operator empty-defun-braces defun-close-semi)) (c-offsets-alist . ((arglist-close . c-lineup-arglist) (substatement-open . 0) (case-label . 4) (block-open . 0) (knr-argdecl-intro . -))) (c-echo-syntactic-information-p . t)) "My C Programming Style")(c-add-style "PERSONAL" my-c-style);; Customizations for all modes in CC Mode.(defun my-c-mode-common-hook () ;; set my personal style for the current buffer (c-set-style "PERSONAL") ;; other customizations (setq tab-width 8 ;; this will make sure spaces are used instead of tabs indent-tabs-mode nil) ;; we like auto-newline, but not hungry-delete (c-toggle-auto-newline 1))(add-hook 'c-mode-common-hook 'my-c-mode-common-hook);;----------indent setting end;;=====================================================================;;emacs setting end;;=====================================================================;;=====================================================================;;cedet begin;;cedet(1.1) setting based on method descripted at;;http://alexott.net/en/writings/emacs-devenv/EmacsCedet.html;;=====================================================================;;set the mode enabled(setq semantic-default-submodes '(global-semanticdb-minor-mode global-semantic-idle-scheduler-mode global-semantic-idle-summary-mode global-semantic-idle-completions-mode global-semantic-decoration-mode global-semantic-highlight-func-mode global-semantic-stickyfunc-mode global-semantic-mru-bookmark-mode global-semantic-tag-folding-mode));;enable cedet(semantic-mode 1);;enable advanced functionality for name completion(require 'semantic/ia);;include standard C/C++ headers(require 'semantic/bovine/gcc);;add ac-souces, ac-sources is used by auto-complete(defun my-c-mode-cedet-hook () (add-to-list 'ac-sources 'ac-source-gtags) (add-to-list 'ac-sources 'ac-source-semantic))(add-hook 'c-mode-common-hook 'my-c-mode-cedet-hook);;solve the problem can not jump back according to http://blog.163.com/vic_kk/blog/static/494705242010726297405/#sec-3_4(defadvice push-mark (around semantic-mru-bookmark activate) "Push a mark at LOCATION with NOMSG and ACTIVATE passed to `push-mark'.If `semantic-mru-bookmark-mode' is active, also push a tag ontothe mru bookmark stack." (semantic-mrub-push semantic-mru-bookmark-ring (point) 'mark) ad-do-it);;add c-mode key set(global-set-key [f1] 'speedbar)(global-set-key [f2] 'semantic-ia-fast-jump);;jump(global-set-key [S-f2];;jump back:shift+f2 (lambda () (interactive) (if (ring-empty-p (oref semantic-mru-bookmark-ring ring)) (error "Semantic Bookmark ring is currently empty")) (let* ((ring (oref semantic-mru-bookmark-ring ring)) (alist (semantic-mrub-ring-to-assoc-list ring)) (first (cdr (car alist)))) (if (semantic-equivalent-tag-p (oref first tag) (semantic-current-tag)) (setq first (cdr (car (cdr alist))))) (semantic-mrub-switch-tags first))))(defun my-c-mode-cedet-key() (local-set-key "\C-cd" 'semantic-ia-show-doc) (local-set-key "\C-cs" 'semantic-ia-show-summary) (local-set-key "\C-cc" 'semantic-ia-describe-class) (local-set-key "\C-ct" 'semantic-analyze-proto-impl-toggle) (local-set-key "\C-ci" 'semantic-decoration-include-visit))(add-hook 'c-mode-common-hook 'my-c-mode-cedet-key);;;=====================================================================;;cedet end;;=====================================================================;;=====================================================================;;auto-complete begin;;auto-complete(1.3.1) setting based on method descripted at;;http://cx4a.org/software/auto-complete/manual.html;;=====================================================================(add-to-list 'load-path "~/.emacs.d/auto-complete")(require 'auto-complete-config)(add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/dict")(ac-config-default);;ignore case(setq ac-ignore-case t);;=====================================================================;;auto-complete end;;=====================================================================;;=====================================================================;;yasnippet begin;;yasnippet(0.6.1c) setting based on method descripted at;;http://capitaomorte.github.io/yasnippet/#id3;;=====================================================================(add-to-list 'load-path "~/.emacs.d/yasnippet-0.6.1c/")(require 'yasnippet)(yas/initialize)(yas/load-directory "~/.emacs.d/yasnippet-0.6.1c/snippets");;=====================================================================;;yasnippet end;;=====================================================================;;=====================================================================;;hs-minor-mode setting according to http://www.emacswiki.org/emacs/HideShow;;=====================================================================;;universal code folding(defun toggle-selective-display (column) (interactive "P") (set-selective-display (or column (unless selective-display (1+ (current-column))))))(defun toggle-hiding (column) (interactive "P") (if hs-minor-mode (if (condition-case nil (hs-toggle-hiding) (error t)) (hs-show-all)) (toggle-selective-display column)))(load-library "hideshow")(global-set-key (kbd "C-?") 'toggle-hiding)(global-set-key (kbd "C-`") 'toggle-selective-display)(add-hook 'c-mode-common-hook 'hs-minor-mode) (add-hook 'emacs-lisp-mode-hook 'hs-minor-mode) (add-hook 'java-mode-hook 'hs-minor-mode) (add-hook 'lisp-mode-hook 'hs-minor-mode) (add-hook 'perl-mode-hook 'hs-minor-mode) (add-hook 'sh-mode-hook 'hs-minor-mode);;display overlay content in echo area or tooltip(defun display-code-line-counts (ov) (when (eq 'code (overlay-get ov 'hs)) (overlay-put ov 'help-echo (buffer-substring (overlay-start ov) (overlay-end ov))))) (setq hs-set-up-overlay 'display-code-line-counts);;=====================================================================;;hs-minor-mode end;;=====================================================================
有用的链接
CEDET配置参考文章
auto-complete配置参考文章
yasnippet配置参考文章
代码折叠配置参考文章
EmacsWiki
配置CEDET浏览和编辑C++
GNU Emacs官方文档
- 让你的Emacs像VS一样方便
- 让你的Emacs像vi一样高亮 “#if 0 ... #endif"
- 像Excel一样冻结HTML表格的表头-博计报表让你更方便
- 让DropDownlist像GridView一样方便的显示ToolTip
- 让Source Insight像EMACS一样工作
- 如何让Eclipse的智能提示像VS一样霸气
- 让你的程序像office一样有位小助手.
- 让你的程序像系统命令一样运行
- 让你的PDF像百度文库一样在线预览
- Emacs快捷键列表 让我怎么不喜欢你,神一样的emacs
- 暴强的Javarebel——让JavaEE开发像ROR一样方便
- 暴强的Javarebel--让JavaEE开发像ROR一样方便
- 如何让你的eclipse的像vs2008一样具有强大的代码提示功能
- face2,让你的网站拥有像Google一样的智能提示
- Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来
- Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来
- 让你的MyEclipse像Visual Studio 2008一样拥有强大功能智能感知功能
- Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来
- 软件绿化之注册表右键菜单三
- 程序员需要心沉下来和仔细再仔细
- 【Linux基础】Linux系统的安装之Redhat
- ASP进行网络打印功能
- JAVA开发者最常去的25个英文网站
- 让你的Emacs像VS一样方便
- ExtJs4入门之九: 补充Grid组件杂项
- When is a Leak not a Leak? Using Heapshot Analysis to Find Undesirable Memory Growth
- php array中foreach的语法
- Visual C++ 2012 入门经典(第6版)
- 重构
- Lucene例子
- wordpress 分页
- Schema的优化和索引 - 选择最佳的数据类型