Emacs Practices

Table of Contents

1 简介

可能你已经听过 Emacs 被称为“神的编译器”,也有可能见过许多关于它和 “编译器之神” vim 之间的争论,我们不去管那些争论。我自己是一个实用主义者,什么东西好,我就直接拿来用,其实哪有什么东西是万能的,只有适合或者不适合。使用 Emacs 目的只有一个:效率!!

这篇文章主要根据GNU Emacs Manuals Online 以及所用到的插件的 manual 来介绍 Emacs 的安装和配置过程,可以说是.emacs.d 对应的一份说明书。当然查看这些 manual 更方便的方式是使用 Emacs 自带的 info 功能,而不是打开浏览器查看对应的 web 页面。

2 安装

2.1 Window

可以从官网下载编译的好的二进制 Emacs 包,但是官网是 32 位的,而且没有图片和 Gnutls 的 DLL 库,所以更推荐使用 ChrisZheng 编译的 64 位版本 emacs-w641,该版本进行自带了一切 windows 下一些要使用的 DLL,并且做了一些优化。

2.2 Linux

除了通过 apt 或者 yum 等包管理器安装外,还可以通过源码进行编译。

git clone git://git.savannah.gnu.org/emacs.git
cd emacs
# on ubuntu
sudo apt-get build-dep emacs24
# on centos

./autogen.sh
./configure						# 此处注意查看还缺少什么库
make && sudo make install && make clean

3 配置

小节主要讲解如何将 Emacs 配置成为一个强大的 IDE,内容包括项目工程管理、代码导航、代码编辑等。

3.1 项目管理(Project Management)

从项目层次对代码进行管理。

项目管理有很多工具,包括 ede,projectile 等工具,在尝试了几款插件之后,最合适我的还是 projectile。 正如 projectile 所言,它提供了一系列特性来支持工程管理,这些特性不依赖第三方,当然,有些情况下结合第三方工具能提供更好的性能。

projectile 中的工程概念十分简单:包含特殊文件的文件夹。目前 git, mercurial, darcs 和 bazaar 的容器都会默认为一个工程目录,lein, maven, sbt, scons, rebar and bundler 也同样如此。如果想手动指定文件夹为工程目录,只需要在其中新建一个名字为 .projectile 的空文件即可。

prjectile 通过和 helm 整合在一起(helm-projectile),可以在工程切换、文件路径补全方面得到更好的支持,如可以指定更多切换工程后的要执行的动作,补全可以为渐进补全等。helm-projectile 提供了一些 helm 版本的 projectile 命令,这些命令更加好用。参考 《Exploring large projects with Projectile and Helm Projectile》

3.1.1 切换项目

  • helm-projectile-switch-project (C-c p p)

3.1.2 保存当前工程所有打开文件

  • projectile-save-project-buffers (C-c p s)

3.1.3 关闭当前工程所有打开文件

  • projectile-kill-buffers (C-c p k)

3.1.4 浏览当前工程目录

  • helm-projectile-find-dire (C-c p d)
  • speedbar

    使用 cedet 包中的 speedbar 可以单独分出一个侧边栏,用来浏览整个工程,包括文件变量等。

  • neotree
  • direx

3.1.5 清除当前工程文件缓存

  • projectile-invalidate-cache (C-c p i)

3.1.6 定义工程项项目相关的变量

  • Emacs 自带的 dir-local 功能

3.1.7 文件操作(File in Project)

  • 在所有已知工程中查找文件

    helm-projectile-find-file-in-known-project (C-c p F)

  • 切换当前工程已打开文件

    helm-projectile-switch-to-buffer (C-c p b)

  • 当前工程中查找文件

    helm-projectile-find-file (C-c p f)

  • 当前工程指定目录中查找文件

    projectile-find-file-in-directory (C-c p l)

  • 打开当前光标下文件

    projectile-find-file-dwim(C-c p g)

  • 同名但不同类型文件切换,例如 .h <-> .c/.cpp, Gemfile <-> Gemfile.lock…

    helm-projectile-find-other-file (C-c p a)

  • 跳转到当前工程最近浏览文件(jump to recently visited files in the project)

    helm-projectile-recentf (C-c p e)

  • 添加文件到工程

    projectile-cache-current-file (C-c p z)

3.2 代码导航(Code Navigation)

首先,要明确以下几个概念:

  • tag:程序中的变量和函数名称定义叫做 tag。
  • rtag:程序中变量和函数的地方叫做 rtag。
  • symbol:程序中出现的单词称为 symbol。

3.2.1 搜索符号(search symbol)

  • helm-projectile-grep (C-c p s g)
  • helm-projectile-ag (C-c p s s)

    工程内搜索,速度 ag>ack>grep,所以推荐使用搭配 ag(the silver search)进行工程内符号 (symbol) 的全局搜索,支持正在表达式搜索。

  • helm-occur(C-c h M-s o)

    在当前 buffer 中查找符号出现位置。

3.2.2 查找定义(find tag defination)

  • semantic-complete-jump-local(C-c j)

    跳转到定义在当前文档中的符号。

  • semantic-complete-jump

    只要符号定义的文件被 semantic 分析过,都能进行跳转(C-c J)。

  • helm-gtags-find-tag(C-c g t)

    查找 tag。

  • helm-semantic-or-imenu(C-c h i)

    列出当前 buffer 定义的 tag。

  • helm-gtags-select(C-c g A)

    列出当前函数总引用的 tag

  • helm-gtags-previous-history (C-c g p)

    跳回前一次查看的地方。

  • helm-gtags-nex-history (C-c g n)

    跳回到下一次查看的地方。

3.2.3 查找引用

  • helm-gtags-find-rtags(C-c g r)

    工程内查找该 tag 的引用。

3.2.4 代码折叠

  • hide-show-mode
  • semantic-tag-folding

3.2.5 代码高亮

  • auto-highlight-symbol

    高亮当前 buffer 中同名符号。

  • highlight-symbol-at-point(M-s h .)
  • highlight-regexp(M-s h r)
  • 高亮当前作用域中同名符号。

    multi-occur

  • M-x global-hl-line-mode(global-hl-line-mode)

    高亮当前行

  • highlight-changes-mode(global-highlight-changes-mode)

    高亮所做更改

3.3 代码编辑(Code Editor)

3.3.1 模板系统

  • yasnippet

    语言关键字模板,自定义模板。

  • header2

    自动添加文件头或者函数说明。

3.3.2 自动补全

  • completion-at-point(C-M-i)
  • semantic-complete-analyze-inline(C-c,SPC)

    显示当前 point 处符号可能的补全列表。

  • company
  • auto-complete

3.3.3 语法检查

编程语言语法检查,单词检查。

  • flycheck
  • pylint

3.3.4 文档提示

  • function-args

    函数原型提示。

  • eldoc

3.3.5 括号匹配

  • paredit-mode
  • show-paren-mode
  • electric-pair-mode

3.3.6 跳转标记

  • begin-of-defun(C-M-a)

    跳转到函数定义开始处。

  • end-of-defun(C-M-e)

    跳转到函数定义结束处。

  • mark-defun

    将函数定义标记为选区。

3.3.7 查找替换

  • projctile-replace (C-c p r)

    工程内替换符号。

  • replace-string
  • replace-rexp

    文件内替换

  • 选中当前平衡表达式
  • mark-defun(C-M-h)

    选中当前函数

  • narrow-to-defun(C-x n d)

    当前函数定义内操作。

3.3.8 代码风格

  • subword-mode

    可以将下划线‘_’连起来的单词当做一个符号。

  • superword-mode

    可以处理驼峰命名法的单词。

3.3.9 自动缩进

自带的缩进效果已经很好,但是要注意的一点是: 如果想要改变缩进时 TAB 键插入的空白符,需要修改 TabStopList,tab-width 只对已经存在的制表符的显示效果起作用 6

3.3.10 自动换行

  • electric-layout-mode

    可以在编程模式中 {,},;等符号之后自动换行。

3.3.11 语言主模式

  • python
    • pymacs
    • ropemacs
    • jedi

3.4 编译代码(Compiler)

自动化编译,一键编译

  • helm-projectile-compile-project

3.5 调试代码(Debug)

调试代码,直接跳转到测试文件,进行单元测试

  • jump to a test in project
    • projectile
  • toggle between code and its test
    • projectile

3.6 工程文档(Document)

  • 查看函数说明,生成函数、类的文档。
  • manual
    • info-lookup-symbol(C-h S)
    • M-x man

      在 man mode buffer 中还可以使用 C-h m 跳转到其他 man page。

    • M-x woman

      不支持 man 程序的操作系统(如 windows)上可以使用该命令显示 man page。

  • lua-mode

    可以使用 lua-search-documentation 查看 lua 库函数相关文档。

  • Doxygen
  • GraphViz
  • UML

3.6.1 版本控制(Version Control)

  • projectile helm-projectile-vc (C-c p v)
  • magit

3.6.2 持续集成

Footnotes:

Author: 刘尚亮

Created: 2017-08-30 三 16:06

Emacs 25.2.2 (Org mode 8.2.10)

Validate