重回Emacs

2014.11.19/2016.12.03发布于笔记暂无评论/目录

念书的时候接触过Emacs,也自学了一段时间Elisp,工作之后就完全抛弃掉了。工作中单纯编辑文本文件直接用Vim,大一点的工程用过Visual Studio, Eclipse,目前主要在用Kdevelop,这几个都算是editor和IDE中的佼佼者了,不过用久了之后总觉得不够贴心。正好最近不怎么忙,所以就想重新再学一下Emacs。

特别声明,本文不是Emacs的推广软文,仅记录重拾Emacs后学到的若干知识而已。说实话,各种Editor和IDE都有自己的所长。Emacs也不是无所不能,至少在语法解析这方面,和专业的IDE还是差距较大,当然,也可能是我没有配置好 :(

我的Emacs配置

本配置以https://github.com/tuhdo/emacs-c-ide-demo为基础,并加入了我早年收集的若干配置而成。安装和使用的package主要有helm, projectile, cedet等,主要配置了C/C++,Golang和Python的开发环境,现已放在Github上。

安装

首先请备份你的~/.emacs.d目录,然后

git clone https://github.com/mawenbao/emacs.d ~/.emacs.d

初次启动需要安装各种package,需要等一会。

每次安装package后建议手动运行下sh tool/gen-package-list.sh,将已安装的package名称记录到packages.list里,以后迁移的时候即可自动安装。

依赖

当前配置仅适用于GNU/Linux操作系统,且需要Emacs24+。

  1. 为了支持go-mode下的自动补全,需要安装gocode

     go get -u github.com/nsf/gocode
    
  2. 为了启用jedi,需要手动安装jedi

     # jedi的版本可能有更新,目录名称里的时间可能不是这个
     cd ~/.emacs.d/elpa/jedi-20140321.1323
     sudo python setup.py install
    
  3. 为了使用helm-gtags,需要安装global,需要注意的是Debian/Ubuntu上的global包太过老旧,请自行下载安装global-6.2.3+版本。

目录结构说明

  • init.el 配置文件入口
  • elpa/ 从melpa下载的package包统一放置于此
  • save.d/ 各种package的本地存储统一放在该目录
  • my-config/ 未包含在仓库中,用于存储个人的配置
  • site-lisp/ 手动安装的第三方package
  • custom/
    • custom-funcs.el 自定义的function或macro
    • custom-save.el 保存emacs的界面选项(font, theme等)
    • setup-misc.el 各种emacs的配置
    • setup-packages.el 各种package的简单配置
    • package-config/ 该目录下存放一些比较复杂的package配置
    • setup-prog.el 编程和编辑方面的配置
    • setup-keys.el 快捷键方面的配置(部分package的快捷键配置位于package-config目录里面)
  • packages.list 记录已安装的package名称,由tool/gen-package-list.sh自动生成
  • tool/ 各种工具
    • gen-package-list.sh 更新已安装的package列表
    • install-emacs-registry.py 在Windows注册表中安装Emacs的相关信息

各种错误

  1. 安装时报错: Trying to parse HTTP response code in odd buffer

    解决方法是重启emacs

  2. helm-gtags-update-tags报错: Failed: update TAGS

    升级global至6.2.3+版本,然后运行 M-x helm-gtags-create-tags

Emacs入门

以下的说明都以上面的配置为基础。

包管理系统

Emacs 24+引入了全新的package管理系统,以后安装和更新package再也不用满大街的搜索了,虽然该系统还不是那么完美,但是已经非常有用了。使用 M-x list-packages 即可查看所有的package列表。

调试Elisp

Emacs自带了一个很方便的源码调试工具Edebug,使用 M-x edebug-defun 即可对当前函数进行调试。

自动补全

目前主流的补全package主要是company和auto-completion,感觉二者各有所长,对于Python和Golang这两种语言,感觉还是auto-completion更好用,详情见我的配置里的相关设置。

helm

helm是一个能改变Emacs使用习惯的package,这里有一个图文并茂的介绍,建议阅读一下。

常用快捷键:

  • C-c h C-c f 打开最近访问的文件
  • C-c h i 显示当前的文档结构
  • C-c h m 查看man page
  • (C-u) C-c h / 使用正则表达式查找(当前)目录下的文件
  • C-c h l locate一个文件
  • C-c h r 测试regexp
  • C-c h x 查看registers
  • (C-u) C-c h b 继续之前的helm命令
  • M-x helm-occur occur函数的helm接口
  • C-c s 类似occur的东东
  • 在Minibuf中(不同的命令可能有不同的快捷键绑定,具体请参考helm帮助 C-c ? )
    • C-c ? 显示帮助信息
    • C-o 在不同的候选源之间切换
    • C-p C-n 在候选项buffer里上下导航
    • C-v M-v 在候选项buffer里上下翻页
    • C-k 清空Minibuf中的内容
    • Tab 显示候选项内容
    • C-l 返回上一级
    • (C-u) C-s (递归)grep当前文档/目录
    • C-! 暂停/开始helm更新
    • C-c h 切换到文件名历史
    • M-p 切换到其他目录
    • C-c i 在当前位置插入匹配文件的路径
    • C-c C-k kill当前选项并退出Minibuf

projectile

projectile可以识别git等仓库,并以工程的方式进行管理,另外projectile还能配合tramp管理远程工程,非常方便。

快捷键:

  • C-c p o 对但前工程下的所有buffer调用occur函数
  • C-c p s g 对当前工程下的所有文件进行grep
  • C-c p b 当前工程的buffer列表
  • C-c p f 当前工程的文件列表
  • C-c p d 当前工程的目录列表
  • C-c p e 当前工程的最近访问文件列表
  • C-c p p 在多个工程之间切换
    • C-d 打开dired
    • M-e 在当前目录打开eshell
    • (C-u) C-s 在多个工程间(递归)grep
    • M-D 移除一个project记录

如果某个工程需要忽略些文件或目录,但又不想在全局配置里设置,比如不想projectile索引pyc文件,根目录下的.settings目录和所有的node_modules目录,可以在工程的根目录创建一个.projectile文件:

-*.pyc
-/.settings
-node_modules

C++开发

这里主要用到cedet, company这两个package,自动补全这里需要cedet里的ede, semantic和company-semantic互相配合来实现。在上面的配置中,单独在一个文件.emacs.d/my-config/my-ede-projects.el里配置C++项目。

(ede-cpp-root-project "my-test-project-name"
    :file "~/projects/my-test-project/src/Makefile"
    :include-path '("../include"
                    "../include2")
    )
  • my-test-project-name: 项目的名称
  • :file: 工程的Makefile文件位置,如果没有Makefile,也必须是一个实际存在的文件
  • :include-path: cedet的semantic在这些目录目录里搜索和分析头文件,这些路径是:file的相对路径

载入这些配置后,semantic即可正常的进行源码分析,然后company根据semantic的分析结果即可进行自动补全。

一些常用快捷键:

  • C-Tab 调用company-semantic弹出自动补全框
  • M-n M-p 在自动补全框中上下移动
  • F1 在自动补全框里查看对应项的文档
  • C-w 在自动补全框里查看对应项的源码
  • C-c C-j 跳转到当前符号的声明或定义的位置
  • C-c C-s 查看当前符号的声明或定义

GNU Global

Global和ctags类似,可以为源码中的Symbol建立索引(tag),方便检索。上面的配置里自带两个global相关的package:

默认启用的是helm-gtags,如果需要,可以修改.emacs.d/custom/setup-packages.el,启用ggtags:

;; (require 'setup-helm-gtags')
(require 'setup-ggtags')

一些常用的快捷键和函数(以helm-gtags为例):

  • M-. 查找当前符号的定义和引用等
  • M-, 使用 M-. 跳转之后,返回之前的位置
  • M-x helm-gtags-create-tags 对某个目录(默认当前目录)创建tags文件

编辑远程文件

Emacs自带的Tramp可以用于编辑远程文件,使用方式很简单,C-x C-f 打开文件时,按照如下格式即可:

/method:user@host#port:filename

其中:

  • 常用的method有
    • ssh: /ssh:test@example.org#1234:/path/to/file
    • sudo/su: /sudo::/path/to/file

另外,在远程文件的buffer里执行 M-x shellM-x eshell 都可以在远程服务器上开启一个shell会话。

远程的buffer都会在状态栏有个@符号。

不常用函数和快捷键

emacs-summary.txt

各种零散的技巧

  • shell-mode中输入密码的时候,使用M-x send-invisible即可在Minibuf中密文输入密码。

Emacs学习资源

  • 王垠Emacs笔记 我是看这个入门的。。。(怀旧一下,里面的内容应该比较古老了)
  • EmacsWiki Emacs的官方Wiki
  • Emacs Mini Manual 一个比较好的教程,着重讲了些Elisp基础,helm和CEDET等内容
  • Emacs中文网 挺不错的Emacs中文站,只是已经两年多没更新了

参考资料

#emacs

评论