October 1, 2019
By: Kevin

emacs 第一部分:熟悉emacs

  1. 为什么emacs不仅仅是个编辑器
  2. emacs 安装
    1. osx
    2. Windows
    3. Linux
  3. emacs的UI
    1. buffer
    2. modeline
    3. mini buffer
  4. 生活自理必须掌握的快捷键
    1. 窗体操作
    2. 操作buffer和文件
    3. 移动光标(point)
    4. emacs中选择区域(region)
    5. 粘贴复制
    6. clojure-mode和cider
  5. emacs 的配置和文件结构

经验从来都是一张网,知识都是相互关联引用的。

而我们希望学习过程是一条线,先有基础,逐步递进,每个概念在遇到的时候都有前序概念的支撑。这个过程需要非常精细的组织和编排。

这种方式我们称之为上课,参照材料我们称其为课本。除了课本,我们还有老师、辅导书和周而复始的考试。十几年下来我们一定程度上适应了这种‘学习方式’。

人是要长大的,不总会在课堂里,而且真知不会来自于循序渐进的灌输。

自发的学习过程,从实践,从blog,甚至看书,总会有从消防栓喝水感觉。太多的概念,太多的未知铺面而来的感觉并不享受,很容易受挫,难以坚持。

多做准备,从教和学两个方面都是: 从教来说:尽量循序渐进,都是从三岁数过手指头过来的,回到初学者的心态。写作是一种很好的梳理方法,写作中思考的跳跃性会受约束,迫使自己的思路和传达更加逻辑。 从学来说:多做准备,子曰:“不愤不启,不悱不发”。有积累才有顿悟。开放心态,不要抱有成见,不为已知所累。

作为emacs系列的第一篇文章,我希望能够说清楚:

  1. 什么是emacs:emacs本身极大有别于我们传统认知中的编辑器。
  2. 开始使用emacs,了解基buffer、mode等基础概念
  3. 了解emacs的配置,从purcell的配置开始,了解配置文件的组织
  4. 熟悉emacs的包管理,自动/手动升级卸载扩展。

为什么emacs不仅仅是个编辑器

从emacs中,我找了效率和乐趣。

Emacs与其说是个编辑器,更是一个elisp(emacs lisp 语言)运行环境,极端一点,可以说它是个操作系统。

“I’m using Linux. A library that emacs uses to communicate with Intel hardware.” – Erwin, #emacs, Freenode.

几乎不会关闭emacs,很多任务都放到上面执行

  • 组织笔记:org-mode
  • 写markdown:markdown-mode
  • 各个工程的git客户端:magit
  • 文档/公式编辑:org-mode + latex
  • clojure/clojurescript 开发环境:cider
  • ...

通过M-x uptimes命令我可以看到最长42天都没有关闭过,比起操作系统。。。很多时候我更依赖emacs。

Last 200 uptimes

Boot                Endtime             Uptime       This emacs
=================== =================== ============ ==========
2019-09-29 13:37:08 2019-10-01 20:00:37   2.06:23:28 <--
2019-09-23 20:46:39 2019-09-29 11:34:39   5.14:47:59 
2019-08-12 08:31:38 2019-09-23 19:38:59  42.11:07:21 
2019-08-07 16:27:23 2019-08-11 21:48:30   4.05:21:07 
2019-08-04 23:44:06 2019-08-07 16:12:26   2.16:28:19 
2019-08-04 11:22:58 2019-08-04 21:29:52   0.10:06:54 

emacs 安装

虽然在各个系统有差异,我们推荐使用purcell配置,clojure开发依赖的clojure-mode, cider, paredit都含在其中了。是一个很赞的start kit。

osx

推荐使用brew,brew cask安装带UI的应用程序,比如emacs、mpv、wireshark。

#安装emacs26.3 带GUI
brew cask install emacs
#使用purcell start kit
git clone https://github.com/purcell/emacs.d.git ~/.emacs.d

Windows

#安装emacs26.3 带GUI
#安装步骤待补充
#使用purcell start kit
git clone https://github.com/purcell/emacs.d.git ~/.emacs.d

Linux

#安装emacs26.3 带GUI
#安装步骤待补充
#使用purcell start kit
git clone https://github.com/purcell/emacs.d.git ~/.emacs.d

emacs的UI

emacs

buffer

Emacs的界面元素中,主界面被称为frame,每一个可见的区域称为一个window,这个很反直觉(现在普遍的认知是windw最大,其他窗体元素比如frame都是window的子元素)。

Emacs有40余年的历史,它诞生大大早于现代GUI之前,那个时候frame,window和现代通常的GUI元素的涵义不同。

个人建议Window和Frame放到一边,着眼于buffer。 emacs支持同时打开多个buffer,buffer不一定对应文件。 比如emacs打开时候的默认的*scratch*buffer

有特殊用途的一般都是*开始*结束,基本不对应具体文件。 buffer首先是个数据结构,星号buffer很多使用用来做I/O,比如:

  • *scratch*:emacs的草稿buffer
  • *Message*:emacs的用户交互历史信息
  • *Help*:emacs的帮助buffer
  • *eshell*:eshell模型开始后的交互buffer

emacs可以非常灵活的组织buffer,在一个大屏幕上(哪个程序员没有大屏幕),这种方式尤其方便。

modeline

emacs通过modeline来和用户沟通当前buffer的状态,一个典型的modeline类似下面:

U:--- buffer-name (major-mode minor-mode1 minor-mode2 ...)

第一个U代表编码:当前的bufferUnicode

U:后面的代表当前buffer的文件状态:

  • ** – 有未保存的修改
  • -- – 所有修改已经保存
  • %* – 只读,但是有修改
  • %% – 只读,没有修改

接下来是buffer的名字,对应文件的buffer名就是文件名。

再往后就是各种mode,每个buffer都只有一个major-mode(主模式)和至少一个minor-mode(辅模式)。

major-mode根据文件的后缀和文件属性自动判定,minor-mode挂在major-mode上。也可以手动开启和关闭。

emacs是高度可定制的,并不是一个编辑器,或者换个说法,编辑器的功能也是抽象为多个模式,比如行号这种基础的功能,对于emacs来说都是一个辅模式。

如果我们希望素有的clojure代码打开的时候都显示行号,我们可以在elisp中添加:

(add-hook 'clojure-mode-hook (lambda () (linmu-mode 1)))

主模式和辅模式的对应关系在配置文件中维护, 参见官方文档

现在正在编辑的.md文件的major-modeMarkdown,自动启动的minor-modeFlyC projectile Undo-Tree ElDoc

如果我需要编辑其中嵌入的clojure代码,我会通过(M-x clojure-mode RET)切换为clojure-mode, 代码编辑完成后,再切换为markdown-mode

mini buffer

emacs的minibuffer是用户输入命令,emacs也会通过这个区域做用户提醒(学名echo area), 每次M-x以后输入的命令(以后你会知道命令都是elisp的函数名)都是在此区域。

生活自理必须掌握的快捷键

emacs中常用的几个组合按键中:

  • C: Control键
  • M: Meta键,可以映射为option或者command
  • S: Shift
  • C-x: Control和x一起按下
  • C-x C-f: Control和x按下,再Control和f一起按下,打开一个文件,如果这个文件不存在,就创建一个新的。
  • C-c p f: Control和c按下,按p,按f,查找当前project的某个文件。

窗体操作

  • C-x o 不同窗体之间切换
  • C-x 1 干掉其他所有窗体,注意窗体和buffer是两个概念,不影响任何buffer和文件。
  • C-x 2 打开第二个窗体,上下排列
  • C-x 3 打开第二个窗体,左右排列
  • C-x 0 关闭当前窗体

操作buffer和文件

  • 切换buffer, C-x b 输入buffer 名称
  • 创建新buffer, C-x b 输入buffer名称,是的切换和创建是同一个命令
  • 打开某个文件, C-x C-f 打开某个文件,如果文件不存在,就创建个新的
  • 保存buffer到文件 C-x C-s

移动光标(point)

一闪一闪的称为point。

  • C-a 移动到行首
  • M-m 移动到行第一个非空白字符
  • C-e 移动到行尾
  • C-f 前移一个字符
  • C-b 后移一个字符
  • M-f 前移一个词
  • M-b 后移一个词
  • C-s 正则查找匹配,继续按查找下一个处匹配
  • C-r 返乡正则查找
  • M-< 跳到buffer头
  • M-> 跳到buffer尾
  • M-g g 跳转到某行

emacs中选择区域(region)

mark是一个标记,c-@打一个标记,然后移动point。x 光标(point)和标记(mark)之间的区域称为一个region。

在创建一个region之后, 可以在这个region中,进行复制、剪切。

粘贴复制

  • C-w 剪切
  • M-w 拷贝
  • C-y 粘贴

clojure-mode和cider

在一个clojure工程中,需要启动cider来启动REPL。

  • M-x cider-jack-in-clj: 启动一个clj的repl
  • M-x cider-jack-in-cljs: 启动一个cljs的repl

emacs 的配置和文件结构

Tags: emacs