交代一下背景,笔者在接触emacs之前只写过C,只使用过芯片厂商提供的开发环境,没有真正使用过IDE(Integrated Development Environment),可以说是从零开始接触emacs。当然并不是一时的心血来潮,而是为了成为更好的程序猿,在不断接触linux、VIM、git过程中偶然接触了一门名为Lisp 的语言,其实也不算是偶然,而是买了一本名叫SICP的”编程入门书”,被Lisp的优(qi)雅(pa)语法深深吸引了,后来又听说emacs是用lisp一种方言作为拓展语言的,禁不住网上各种推销就去学习了被誉为神之编辑器的emacs。真是一步一坑,从此走上了一条不归路…这一系列文章被称作教程,不如说是个人学习emacs经历总结回顾。
你为什么需要一个编辑器而不是IDE?
这个问题显然又会引发无数口水,因为接触IDE的时间不多(后来试着使用过VS2015和pycharm一段时间),可能不具有太多的发言权。但结合我浅薄的经验和网上的各种说辞来看,一个集成开发环境的编辑器相比IDE有一下几点优势:
- 编程是输入活儿,编辑器可以做到双手不离键盘,所思即所得。
- 编辑器有灵活的拓展性,可以根据自己的需求个性定制添加插件,提高自动化程度,省去人工时间。
- 免费,大部分的编辑器都是开源的:VIM、Emacs、Atom;轻量级,打开速度快。这两点都是相对IDE而言的。
- 编辑器的操作和工作流一旦固定,可以继续在已有的基础上配置一门语言的开发环境,不用再为了学习一门语言去适应新的IDE。
- 成为更优秀程序猿,老一代的前辈总是告诫我们说IDE封装好太多东西了,自己用编辑器配置一个开发环境会学到很多,其实说来说去就是为了–装逼~
- 当然纯粹用编辑器编程也有很多的缺点,比如在大型工程上功能无力、对一些高级语言支持不够比如java、跳转不准确、对菜鸟不友好完全没图形界面来的方便、入门门槛太高,可能还要为此学习一门语言等等。就本人经验而言,你需要一颗生命不止折腾不休的心,期间会消耗大量的时间,需要持久的忍耐力,但是浪费的时间会有更高的回报,一旦修炼完成工作效率会成倍的提高,是一桩不会亏本的买卖。
为什么是emacs?
- 原因之一是Lisp,一门古老而有趣的语言,对当代语言有深远的影响,不管作为菜鸟还是大牛都应该找个时间了解一下它。emacs对所有Lisp系的语言的支持都非常好。而且Emacs Lisp作为一门语言完整而强大,极大增强了emacs的拓展性以至于emacs被戏称为一个操作系统。
- 第二Org-mode,它可以像Markdown一样为你的项目写文档,也能够以纯文本的格式进行GTD,进行时间管理和自我管理。这是很多人转向emacs的原因。
- 其三evil-mode,一个emacs上的VIM-simulation,很多人学会了VIM之后体会到了它在编辑上的高效,在各个地方都装上了VIM模拟器——浏览器、IDE的插件等等。evil-mode模拟VIM比其他任何一个都要完整,因为它可以自己制定命令,而且还有从VIM移植过来的插件evil-matchit、evil-nerd-commenter等。可以说emacs为人诟病的按键低效也被evil弥补了。
- 最后是magit,这是个人私心加上的,magit是emacs上git的一个插件。对于git因为其强大的功能在操作的时候显得过于繁琐,总是有各种各样的命令和选项记不住,通常做法是在命令行上自定义别名,但是别名增多又会遗忘。magit按键定义高效而清晰,又提供了”半图形”的界面,内容对比、日志查看等都可以在编辑器里完成。
作为一个普通的编辑器?
当初对编辑器的印象停留在notepad++ 上, 作为一个稍微高级一点的编辑器,基本上都具备以下功能:
- 能够使用一套自定义的快捷键来编辑文本,熟悉之后会行云流水。
- 有行号、可以缩进、注释、显示块级,可以展开或者折叠块级。
- 可以选择编辑的不同语言,比如C、python、JavaScript等。
- 语法高亮提示。
- 可以同时打开多个文件,以选项卡的形式陈列。
- 能够显示工程的文件树。
- 选择文件编码。
- 简单的自动完成。
- 搜索、替换、书签。
- 甚至能够运行程序。
- 添加插件、进行简单的主题变换等等。
- 启动速度极快。
所有”高级”编辑器都有以上的特性,包括一些概念也是通用的,我们暂且不讨论在终端下的编辑器,以下概念以图形界面的编辑器为主。
文件(file)和缓冲区(buffer)
当用一个编辑器打开一个文件时,这个文件就会变成一个buffer,顾名思义把打开文件的过程就是把它丢到内存里面,buffer是内存里文件形式。
窗口(window)和外框架(frame)
window是用来显示buffer的,一个window一次只能显示一个buffer,但是一个buffer可以在多个window中显示。buffer可以不显示出来,隐藏在window之外,隐藏在冰山之下,所以这两者并不是绝对联结在一起的,因为一个是可视的实物,一个只存在于深深的内存中。外框架(frame)就是用来管理window的,一个frame可以分割成不同的窗口。我们平常打开一个编辑器就是打开一个frame,通过管理window来管理不同的buffer,每个buffer又对应着不同的文件。一层一层来达到同时编辑多个文件的目的。
作为再高级的编辑器?
再高级一点,我们的目的就是能够配置成一个写程序的环境。
主模式(major-mode)和次模式(minor-mode)
emacs 是通过modes这种形式来配置不同语言环境的。mode中文翻译为模式,这和vim中的模式是完全不一样的概念。一个buffer可以分为major-mode(主模式)和minor-mode(次模式),比如当打开一个*.md
文件时主模式就变成了markdown-mode,再打开一个*.py
文件时主模式会自动切换成python-mode,一个buffer只会有个主模式。而次模式会有很多种,分别实现了一些通用的功能比如各个语言的缩进处理、拼写错误检查、语法错误检查、智能匹配成对的特殊符号等等。显然一个major-mode可以挂载无数多个minor-mode。
mode-line和minibuffer
上一节我们讲到了mode,为了显示当前主模式和次模式的信息,会在当前buffer 的下边多加一条显示栏,这就是所谓的mode-line,这和vim是一样的。不过mode-line已经被玩出各种花样不仅限于显示当前mode信息,可以显示buffer内容的进度,显示时间,显示一个倒计时,显示当前文档的git分支(如果该文档是用git进行版本管理的话)等。minibuffer在emacs的最底下,当执行一些命令时会跳出提示,比如保存一个buffer 的时候会显示保存的路径,搜索的时候minibuffer会等待你的输入,打开文件的时候会列出当前的路径下部分文件名等。总而言之就是用户与emacs交互的窗口,这种联系就如同shell跟操作系统的关系一样,除了编辑文件你大部分的时间都是在minibuffer里面和emacs交互。
一图胜千言
这张图概括了前面提到的所有概念
基本操作概念
emacs里面每个操作都对应着一个命令,一个命令意味需要一个或多个函数来支持,即使像最简单的向前移动一个字符,都是一个名叫forward-char的函数实现的。
按键说明
emacs因为其古老悠久的原因,许多按键说明没有跟上现代键盘的发展的脚步。以下会提到的和我们现在所用键盘按键的对应关系。
按键 | 名称 | 实际对应的实体键 |
---|---|---|
M | Meta | Alt |
A | Meta | Alt |
C | Control | Ctrl |
S | Shift | Shift |
SPC | Space | Space |
经常会看到C-x 其实同时按control键和x键,C-x C-s就是同时按control和s键后又同时按control和s键。其他同理。 一些常见按键前缀约定:
前缀按键(key) | 功能 |
---|---|
C-x |
触发系统默认的功能 |
C-c |
默认留给用户自定义 |
M-x | 触发minibuffer,等待用户输入需要运行的命令 |
C-g | 取消运行的命令(这个命令很有用) |
帮助
control + h 键是帮助命令前缀按键,前期对新手的帮助非常大。
按键 | 功能 |
---|---|
C-h a | 模糊搜索关键字帮助 |
C-h i | 阅读内置info帮助文档 |
C-h f | 查找一个函数信息 |
C-h v | 查找一个变量信息 |
C-h m | 查找一个模式信息 |
C-h b | 查找当前的buffer的按键绑定 |
C-h k | 查找一个按键的绑定信息 |
key、hook、map
这三个概念会不断的出现在定制emacs的过程当中,从上两节了解到key其实就是按键
,map中文意思是映射
,一个map就是一个按键与一个函数或者多个函数成关系映射。hook中文解释为钩子
,顾名思义,一般用在将某个minor-mode挂载到某个major-mode上面,也可以将某个函数挂载在某个mode上面。
emacs官方自带指南
接着安装emacs,网上都有在不同系统下的安装教程,这里略过不提。 知道了上面的这些就可以按C-h t 进入官方指南,按照指南操作emacs,大概在半个小时内操作一遍。VIM党可以跳过这一步。完成之后emacs算是基本入门了。