在前面的几篇,我们完成了Emacs的vim模拟器、中文输入、多行编辑以及基本的补全功能的添加。这一篇没有具体的提升哪一方面的能力,这一篇我想整合我在其他教程中看到的我认为对我比较有用的用法和插件,算是对前期功能的一个总结。
让Emacs记住一些信息
一般的编辑器都会在下次打开时记住上次的一些信息,例如记住之前打开过的文件,执行过的命令,或者记住上次的窗口布局。
记住上次执行的命令
我们每次使用 M-x
执行命令时,minibuffer中显示的提示都是一样的,那些常用命令要么不在上面要么太靠下了,我们希望能记住某些命令,以便能快速找到它。
记住上次执行的命令可以使用 savehist
插件。它是一个Emacs自带的插件,默认是关闭的状态,我们可以通过将 use-package
来加载它,但是因为是自带的,不需要从镜像中下载所以它的 :ensure
项应该设置为 nil
(use-package savehist
:ensure nil
:hook (after-init . savehist-mode)
:custom
(savehist-file (locate-user-emacs-file "custom/savehist")) ;; 设置保存文件的位置
(savehist-additional-variables '(kill-rings shell-command-history)) ;; 额外保存剪切板和shell命令行历史
(savehist-ignored-variables '(message-history)) ;; 不保存消息历史
(history-delete-duplicates t) ;; 自动去重
(history-length 1000) ;; 保存历史数据条目
)
在执行一些操作关掉Emacs之后,我们会发现它在 ~/.emacs.d/custom
生成了一个名为 savehist
的文件,它记录了之前在minibuffer中执行的命令。为了保持git工程的干净,我打算将这种历史文件排除在git管理之外,所以单独将它放到custom目录,并忽略它
其实该插件不光可以保留执行的命令,minibuffer中的许多信息它都可以保存和持久化。
- minibuffer-history (所有 minibuffer 输入历史)
- command-history (执行过的命令)
- search-ring (搜索历史)
- regexp-search-ring (正则搜索历史)
- extended-command-history (M-x 命令历史)
- file-name-history (文件路径历史)
记住上次打开的文件
一般的编辑器都可以记录上次打开的文件,并列出来。Emacs也有一个类似的内置插件—— recentf
(use-package recentf
:ensure nil
:hook (after-init . recentf-mode)
:custom
(recentf-max-menu-item 10) ;; 最多只记录10条历史记录
(recentf-save-file (locate-user-emacs-file "custom/.recentf")) ;; 定义保存历史记录的临时文件路径
)
搜索功能的增强
实现全局搜索我们可以依赖Linux上的命令行工具 grep
和最近(也不算近了)的 ripgrep
。之前在介绍vim的时候,vim内部集成了 grep
。但是我们使用更为强大的 ripgrep
。在Emacs中可以配合插件 consult
和 ripgrep
,调用 consult-ripgrep
来进行全局搜索。它会自动搜索当前项目下的所有目录。
我们对之前 consult
插件的配置代码进行一些修改,并添加 ripgrep
的配置
(use-package consult
:ensure t)
(use-package ripgrep
:ensure t
:after consult
:bind
(("C-s" . consult-ripgrep))
)
这里我们将 C-s
绑定的快捷键修改为 consult-ripgrep
。
神奇的是,配合之前安装的orderless,我们只需要按照一个模糊的记忆来匹配想要的内容。
同时它也能支持输入中文
批量替换
批量替换这个功能,根据我找到的教程,它需要依赖 embark
、consult
、和 wgrep
这么三个插件。其中 consult
用来进行搜索,而 embark
可以为不同场景下的文本/候选项(如搜索结果、补全列表、文件路径等)提供动态的快捷操作菜单。简化了minibuffer上的一些操作。而 wgrep
则是其中的核心插件,用来批量修改内容并保存
(use-package embark
:ensure t
:after consult
:bind
(("C-e" . embark-export)))
(use-package embark-consult
:ensure t
:after embark)
(use-package wgrep
:ensure t
:custom
(wgrep-auto-save-buffer t) ;; 自动保存修改
)
这里我们使用 :after
来保证插件的加载顺序依次为 consult
、embark
、embark-consult
,特别是 embark-consult
,它依赖 consult
和 embark
,一定要将它放到后面加载。
下面来演示如何进行批量替换,这里我们将配置中所有 use-package
修改为 package-install
,修改之前记得使用git等版本管理工具进行备份
- 首先,使用
C-s
搜索use-package
关键字
- 接着使用
C-e
, 也就是上面绑定的快捷键来将结果从minibuffer
导出到buffer
- 然后使用
C-c C-p
调用wgrep-change-to-wgrep-mode
将 buffer 的mode由grep-mode
修改为wgrep-mode
- 接着使用
M-%
调用query-replace
进行替换,这个时候它需要输入被替换的字符和替换后的字符 - 确定后,对于每个待替换的位置使用 y 或者 n 来表示替换或者不替换。也可以使用
!
替换所有 - 最后使用
C-c C-c
调用wgrep-finish-edit
来结束编辑,配置之前设置的自动保存,此时修改内容已经被保存了 - 修改之后如何不满意,可以使用
C-c C-k
撤销修改
小节
这应该是最后一篇关于Emacs自身编辑功能的增强了,在这一块我没有使用太多的Emacs经验。倒是在vim上有点经验,所以很多东西我不自觉地就往vim上面靠,总想着vim在编辑上有些功能Emacs上还没有,该如何进行添加,这几篇就显得比较分散,总是想到什么功能就往上面堆。为此造成各位读者阅读体验不佳,我表示道歉。谢谢各位读者的支持和鼓励!