请尝试使用Doom Emacs 「Emacs+Vim双强联合」
美味的樱桃菌
2021年05月21日 09:32

这篇文章会与你一起安装Doom Emacs并进行基础的使用和定制,如果对你有帮助,请到Doom Emacs主页点个Star和三连。

DoomEmacs Github页面 : https://github.com/hlissner/doom-emacs

    众所周知,Emacs和Vim都是十分古老且强大的文本编辑器,其中Vim的特点是基于模式的编辑方式、高可自定义性、处理文本效率高、丰富的插件资源和丑陋的VimScript。而Emacs的特点则是具有超高可定制性、巨多插件资源、由充满魔法的Lisp语言构建和用户都得了腱消炎等。我们发现双方特点有一定重合,却又都存在一些问题。那么,有没有什么编辑器可以让两者结合使得双剑合璧,天下无敌(VSCode用户表示不服)呢?

   Doom Emacs就是一个Emacs+Vim的产物,其包含了Emacs和Vim的优点,还减少了用户折腾的时间,可以说它就是你用来上网、聊天、游戏、看电影、听音乐、写代码、做笔记、搞科研、学习的工具不二之选了。Doom Emacs是一个Emacs发行版本(配置集合)就像Linux内核和各大发行版的关系,都是在前者的基础上做了超多工作使得一个强大的工具变的更加强大大的超强义体集合。其大部分模块都提供了文档支持,且有上百个贡献者,1.5W Commits,10k+ Star,450+ issues  ,提供针对超过近60门编程语言的模块以及各种可提升使用体验的模块可选。下面让我们正式进入Doom Emacs的世界...


本文分为五个阶段,分别是:

  • 安装Doom Emacs

  • 介绍Doom Emacs使用方法

  • 开启Doom Emacs提供的模块

  • 自定义Doom Emacs模块

  • 进阶

提前说明: 请使用装有GNU/Linux或Mac系统的现代电脑进行尝试。


安装Doom Emacs

    为了能快速的将基础系统环境安装完毕,我使用由强大的Gnome Boxes虚拟机驱动的Archlinux。

    

ArchLinux installed.

安装完系统,先配置一下软件源,以便安装软件方便,这里我使用由上海交通大学提供的开源镜像源/软件源。

添加如下内容到 /etc/pacman.conf 以添加archlinuxcn软件源

代码块
Shell
自动换行
复制代码
[archlinuxcn]
Server = https://mirrors.sjtug.sjtu.edu.cn/archlinux-cn/$arch
复制成功

覆盖写入如下内容到 /etc/pacman.d/mirrorlist 以设置交大软件源

代码块
Shell
自动换行
复制代码
Server = https://mirrors.sjtug.sjtu.edu.cn/archlinux/$repo/os/$arch
复制成功

随后在终端输入如下命令 以刷新软件源并安装archlinuxcn软件源密钥

代码块
Shell
自动换行
复制代码
sudo pacman -Syy && sudo pacman -S archlinuxcn-keyring && sudo pacman -Syy
复制成功

随后下载几个必要的软件 以为后续的安装做准备

代码块
Shell
自动换行
复制代码
 sudo pacman -S qv2ray emacs git ripgrep fd libvterm librime v2ray
复制成功

上面的几个软件介绍如下:

  • qv2ray fq工具

  • v2ray fq工具

  • emacs 本期主角

  • git 版本控制工具, 用它来获取doom emacs

  • ripgrep 搜索文件内容的工具,好用得鸭批

  • fd 搜索文件的工具,好用得鸭批

  • libvterm vterm的库,后面启用Doom Emacs的vterm模块需要使用

  • librime rime的库,后面自定义Doom Emacs输入法需要使用

由于Doom Emacs的安装大部分都需要从github上获取资源,所以请保证你有一个稳定可访问github的网络资源(请自行必应搜索v2ray机场并配合qv2ray和v2ray来设置代理fq)。

假设你已经有了一个可用的v2ray链接且能正常使用,下面简单介绍下qv2ray的设置和让终端走代理的设置。

打开qv2ray的首选项的入站设置,将SOCKS5端口设置为1088,HTTP设置为8000。(这里可以自定义设置,上值仅为个人习惯)。

随后键入如下命令 以创建一个使得终端走代理的命令的别名:

代码块
Shell
自动换行
复制代码
alias ep='export https_proxy="127.0.0.1:8000" && export http_proxy="127.0.0.1:8000"'
复制成功

随后我们仅需要在终端输入 ep 之后,终端的命令就会走HTTP的代理网络了,可以通过如下命令测试是否成功,若有返回HTML代码则证明成功。

代码块
Shell
自动换行
复制代码
curl google.com
复制成功

既然你有代理了,那么下面就需要使用git clone获取doom emacs了,键入如下命令:

代码块
Shell
自动换行
复制代码
git clone --depth 1 https://github.com/hlissner/doom-emacs ~/.emacs.d
复制成功

等待clone完成,键入如下命令进行doom emacs的安装:

如果安装失败,请多执行几次,确保不是网络的问题,通常来说不会有问题。

代码块
Shell
自动换行
复制代码
cd ~/.emacs.d/bin && ./doom install
复制成功

安装过程中可能会提示你下载 all-the-icons 字体,输入y即可:

all-the-icons prompt

安装程序的最后阶段会给一大堆提示,其告诉了我们几个重要的操作流程:

doom emacs installed prompt

  1. 在你修改了~/.doom.d/init.el~/.doom.d/packages.el后需要执行doom sync

  2. 如果有问题就运行 doom doctor

  3. 如果需要更新就运行 doom upgrade

  4. 可以在Emacs内通过 SPC h d h来查看文档

自此Doom Emacs就安装完成了,让我们启动Emacs吧!

Doom Emacs launch up

通过 M-x emacs-init-time ,左下角显示Doom Emacs配置的启动速度仅有0.3s,这个速度十分快了,这得益于Doom Emacs优秀的懒加载技术。


介绍Doom Emacs使用方法

经过简单的几步(除了安装系统那几步,提到仅为了拉人入Arch神教~),Doom Emacs便安装完成,下面介绍一下Doom Emacs的使用方法。

在我们使用 doom install 命令时,你可能会好奇这个doom是个玩意,是干啥用的?虽然前面提了一嘴但还远远不够解释清除,doom是个可执行文件是doom emacs配置独有的,它被放在~/.emacs.d/bin/下,你可以通过下面的命令将其链接到/usr/bin/下以方便在任何目录下使用:

代码块
Shell
自动换行
复制代码
sudo ln -s ~/.emacs.d/bin/doom /usr/bin/doom
复制成功

通过命令 doom help可以查看其作用,下面列举了所有命令及其解释:

  • doom sync 用于同步私有配置和Doom配置。意味着只要你修改了私有配置的包相关的内容,都需要运行此命令,例如你要为私有配置添加了新的包(插件),或升级/降级了某个包,doom sync会自动为你做好那些安装/降级/编译/链接操作。

  • doom upgrade 用于更新Doom配置或更新所有包时,如果你看到doom的最新更新正好解决了你提的issue便可使用此命令让Doom更新为最新版本,又如果你想要升级所有的包(插件)那么你也可以通过此命令进行升级。

  • doom doctor 此命令效果是尝试找到Doom出错的问题,通常只能监测出常见的问题,如果你有问题可以先试试这个命令,再去群或者翻issues。

  • doom env 基本不用使用,其作用是让doom 的环境变量和你的shell环境变量同步一下,除非你shell环境变量经常变动,否则是几乎不会用到这个功能的。

  • doom build 重新编译所有的包(把el文件编译成elc以提高运行速度)。

  • doom info 输出doom的相关信息,用来给doom提issue用的。如果你需要提issue,那么你需要将这个命令的输出也贴上去,用于判断是否是环境问题。

  • doom clean 这个命令会删除所有的elc文件,执行后你需要使用doom build重新编译它们。

  • doom run 从doom可执行文件的父级目录下启动Emacs。我猜测可能是为了解决一些路径问题。

  • doom compile 将私有配置和已开启的模块编译成字节码。提高运行效率的。

  • doom purge 删除那些已安装,但是没有使用的包,并将其压缩。你有时可能会通过 M-x package-install 来安装包,这样是不太好的,你应该通过后面我说的方法来安装,否则就会出现有些包已安装但却没有使用的情况。

这里不得不提一下 doom dir local dir ,doom dir是指你的私有配置目录,local dir是指doom及你私有配置的包的缓存目录,它们都可以通过doom命令进行提前设置,启动时指定 --doomdir--localdir 参数即可。


    doom emacs默认是使用vim按键风格的,这是通过包 evil 实现的,也就是说在emacs内可以使用vim这种高效按键设计风格。doom emacs的启动页面叫做dashboard,也是emacs的一个插件,不过doom对其改造了一番,其默认展示了几个在emacs被启动时最有可能被使用的命令,十分的人性化。doom emacs也学习了Spacemacs的理念,大量键绑定都是基于空格键(SPC)定义的,相信使用过SpaceVim或Evan Emacs的同学都知道这个概念,优点是SPC这个键相比于C-c或C-x来说跟好按,且没有什么插件会针对这个键进行绑定,所以很少会出现按键被覆盖的问题。

    当你在normal模式下键入SPC后会弹出一个在底部的窗口,这个窗口展示了基于SPC按键下的所有键表,这个功能是由Emacs插件Which-key提供的,就像这样:

SPC Prompt

我们看到有两种颜色的可选按键,其中紫色的代表按下后还有一层按键可选,蓝色的代表按下后就会执行按键绑定的命令。

这里以M-x举例,其是一个蓝色按键提示,所以当我们按下  SPC : 后就会执行其绑定的命令,想要知道对应的命令可以通过命令 describe-key 进行查看,执行这个命令后你所按下的键会自动找到其对应的命令,再比如 SPC SPC 可以从当前Project中查找文件。

另一种紫色的按键提示意味着其是一个前缀键(Prefix-Key),就像 SPC 键一样包含了很多键,不过SPC键在doom中被称作 主键(leader-Key)。我们按下 f 可以查看和file相关的按键绑定,就像这样:

File Prompt

doom还有一种特殊的前缀键,叫做局部主键(localleader),其特殊之处在于,不同模式下局部主键的键表都是不同的,也存在某些模式下是没有这个局部主键的情况。我们可以通过按键 SPC m 查看当前所在模式的局部主键的所有键表,举例我打开了一个ELisp文件,那么Emacs当前的主模式应该就是 elisp-mode ,doom为这个模式定义了一些局部主键如下所示:

elisp mode prompt

doom 为elisp-mode根据功能划分提供了一些有用的按键绑定。

小总结:

  • doom的按键风格是vim风,此功能由evil包实现。

  • 显示按键提示的功能是由which-key包实现。

  • 通过which-key的提示。我们可以将按键提示分为两类,分别是前缀键和键绑定,前缀键可以包含多个键绑定,每个键绑定有对应的函数。

  • 前缀键可以分为三种类型,分别是普通(Prefix Key),主键(leader Key),局部主键(Local leader Key)


开启Doom Emacs提供的模块

默认情况下doom emacs根据功能类别共提供了150+个可选模块,我们可以按需增加想要的模块,下面会介绍如何开启一个模块。

如果需要修改模块相关的配置,需要打开 $doom-dir/init.el 文件,除非你指定了doom-dir的路径否则其默认路径应该是 ~/.doom.d/init.el

可以直接通过快捷键 SPC h d c 来跳转至私有配置文件,或通过 SPC f p 从私有配置目录内查找指定文件并打开。

打开init.el后,文件内容大致如下:

init.el

前面几行注释告诉我们可以通过键入SPC h d h来打开doom emacs的文档,随后找到 "Module Appendix&#​34; 链接(SPC m g g 可以跳转至指定标题),链接指向一个modules.org文件,里面列出了所有的模块以及对模块的简短介绍和模块可用Flag。

下面我们会举例如何配置一个python的开发环境,相信我速度很快,仅需要几步,一个完整,高速的Python环境就能搭建完成。

为了了解有关Python模块更多的内容,我们可以通过键入SPC h d m后键入Python来打开Python模块的文档,而不是通过modules.org内的简短信息。打开后文件内容大致如下:

python module readme

文档由org-mode驱动,得益于层级关系,我们很轻松的能看到此文档分为4节,分别是描述(Description)、依赖(Prerequisites)、特性(Features)、配置(Configuration),通常来说,我们仅需了解描述、依赖和特性就够了至于配置的话没有特殊的需求应该是不同理会的。

通过描述说明,我们了解到此模块提供了以下几个针对python的功能:

  1. 语法检查 由flycheck提供

  2. 代码片段

  3. 测试运行 由nose或pytest提供

  4. 自动格式化 由black提供 依赖于:editor format 模块

  5. LSP集成 (三个server可选 mspyls, pyls 或 pyright)

找到Module Flags标题,里面展示了此模块所支持的所有Flag,Flag你可以理解成针对这个模块的扩展,例如 LSP Flag就使得Python模块提供LSP支持,而pyright Flag就使得LSP服务器使用pyright实现。

再后面的Plugins标题说明了这个模块所有使用到的插件,并且还简单列出了关系:

再往后看到 依赖(Prerequisites) 标题,这里说明了需要安装哪些外部工具:

这个例子中,我们仅为Python模块开启LSP和pyright Flag 所以我们仅需要处理关于 格式化(format)和pyimport(自动导入包用)和py-isort(处理python包的导入顺序)以及LSP相关的支持,

下面我们需要打开 :editor 下的 format模块,并且打开LSP模块和python模块,并且为python模块添加LSP和pyright Flag,下图演示了具体操作过程。

操作完成后,init.el文件内容如下:

format

LSP

python

现在我们以及修改了init.el文件,下面回到Python模块的文档,将我们所需的依赖安装完成。

执行如下命令进行安装:

由于我是ArchLinux,所以python的包尽量使用pacman来安装。

代码块
Shell
自动换行
复制代码
sudo pacman -S python-pytest python-nose python-black python-pyflakes python-isort
复制成功

使用npm来安装pyright

代码块
Shell
自动换行
复制代码
sudo npm install -g pyright
复制成功

将所有依赖都安装完毕后,你便可以执行doom sync,其会自动安装新增模块所需的包,并启用。

此时我们重启Emacs,即可体验Doom Emacs提供的Python模块了。

下图终端为VTerm,需要开启对应的模块。

Doom Emacs


自定义Doom Emacs模块

虽说Doom Emacs默认提供的模块已经很强大了,但我相信你总是会有自己的私有配置的,下面这个例子,我将会演示如何自定义一个Doom Emacs模块,实现在Emacs中使用Rime输入法。

Doom Emacs的私有配置是被放在--doom-dir下的,默认值为~/.doom.d/,所以你需要将私有配置存放在这里面。

下面是我Doom Emacs私有配置的目录结构:

下面对其一一讲解:

  • packages.el 存放安装包的代码

  • config.el 存放配置包的代码

  • init.el doom emacs的模块设置和启动入口

  • modules/ 私有模块都放在这个下面

  • rime/ 一个名为rime的模块

  • rime/config.el 针对这个模块的配置

  • rime/packages.el 针对这个模块要安装的包

其实并不是所有配置都需要已模块化的方式管理,只是既然有模块,就尽量按模块的方式来写配置。例如doom emacs默认的补全延迟是0.5,你就可以直接在~/.doom.d/config.el里添加如下代码让其补全延迟为0.1:

代码块
R
自动换行
复制代码
(setq company-idle-delay 0.1)
复制成功

注意,这里仅为了演示将此次私有模块名称定为rime,其实你可以叫其他名字,并且一个模块是可以做任意配置的。

我们所有的私有模块都得放在modules/下并且存放在单独的目录下,并且每个模块都必须包含

config.el和packages.el (注意packages有个s),packages.el用来放安装包的代码,基本上是调用一下package!宏,config.el里面就是针对这个模块要写的配置啦,通常是利用use-package!宏来对每个包进行管理和配置。

下面是具体配置内容:

config.el

rime/config.el

packages.el

rime/packages.el

    这个例子中,我们使用package!宏让doom在执行doom sync后安装这个包,并且在config.el中对这个包进行了配置,主要是配置了设置默认的输入法为rime,以及rime的输入框显示方法。

    编写好私有模块后还需在 init.el 内将其开启,添加如下内容至最后一个括号的前面:

    最后我们仅需执行doom sync,那么就会自动下载包并且安装啦!可以立刻重启Emacs体验一下属于你的配置吧!


进阶

Emacs可以让你随心所欲的操控,不过需要借助Emacs Lisp。所以如果你需要从随心所欲操控她,那么请学习Emacs Lisp,下面是我推荐的几个教程:

  • https://github.com/EvanMeek/elisp-guide 有中文翻译 ——By 作者和B站用户JimMoen

  • https://github.com/EvanMeek/Emacs-Elisp-Programming 就像CookBook一样——By caiorss

  • http://ergoemacs.org/ 实用的ELisp教程——By Xah Lee

  • https://www.gnu.org/software/emacs/documentation.html 官方文档,支持在Emacs内查看 C-h i

  • http://smacs.github.io/elisp/ 水木清华社区的简明Elisp教程——By 叶文彬

下面是推荐的几个经验交流之地:

  • https://emacs-china.org/ 世界上最大的中文Emacs论坛

  • t.me/emacs_zh 世界上最大的中文EmacsTG群组

  • QQ群466898428 GNU/Linux技术分享 群主等诸位群员都是Emacs用户