趁着放假又好好折腾了一把 emacs ,添加了一些有用的小功能。

1. “随着日出日落”——白天黑夜不同主题

Emacs 几乎伴随着我的整个生产过程,这就意味着无论白天光线强烈的时候还是夜晚光线不足的时候,我都需要面对着屏幕上的 Emacs 敲东西,这对于眼睛来说无疑是一个负担。在不能关闭屏幕出去走走的情况下,一个好的主题配色对于眼睛的保护就显得尤为重要了。白天主题在夜晚会显得刺眼,夜晚主题在白天则有些看不清。在多番搜索后,找到了根据当地日出日落日间切换主题的包 circadian ,它可以直接根据指定好的经纬度计算好主题切换的时间,然后在日落时切换为黑夜主题,在日出时切换为白天主题:

1
2
3
4
5
6
7
8
(use-package circadian
  :ensure t
  :config
  (setq calendar-latitude 30.58)
  (setq calendar-longitude 114.27)
  (setq circadian-themes '((:sunrise . modus-operandi)
                           (:sunset  . atom-one-dark)))
  (circadian-setup))

效果如下:

2. “手动泛型”——多行编辑

在代码里有许多重复的 pattern ,为了节省时间通常会采用多行编辑的方法,这个功能在 Sublime 中比较出名, VS Code 里可以通过按住 Alt 键加上鼠标点击的方式添加多个光标。 Emacs 中虽然也有矩形编辑,但用起来有点不太顺手。顺带贴一份 矩形编辑 的快捷键加强记忆:

key function
C-x r k 剪切矩形
C-x r M-w 复制矩形
C-x r d 删除矩形
C-x r y 粘贴矩形
C-x r o 在矩形前插入相同的空白矩形
C-x r N 给矩形中每一行添加序号
C-x r c 用空白填充矩形
C-x r t 在矩形前插入字符(多行编辑)
C-x SPC 开启矩形选区模式

原生的矩形编辑毕竟是直接对矩形进行操作,不是严格意义上的多行编辑,而且每次做完一个操作都要重新按快捷键。包 multiple-cursors 很好地解决了这个问题,它直接插入光标,实现更加简单快捷的多行编辑:

1
2
3
4
5
6
7
(use-package multiple-cursors
  :ensure t
  :config
  (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
  (global-set-key (kbd "C->") 'mc/mark-next-like-this)
  (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
  (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this))

效果如下:

3. “符号之美”——异步渲染 Latex

在 Org-Mode 中记科学类笔记时常常会写一些数学公式,虽然 Org 本身支持 Latex 的预览,但每次都要通过 C-c C-x C-l 来调用生成预览,而且每次生成 Emacs 都会卡住。这里用著名的 xenops 包来解决这个问题:

1
2
3
(use-package xenops
  :ensure t
  :hook (org-mode . xenops-mode))

效果如下:

4. “M-x vscode”——使用 Emacs 写代码

比起很多现代的 IDE , Emacs 还是有点太古老了,但这并不代表它无法胜任写代码的工作。如果只是写一些简单的代码,那很多 IDE 就有点太重了,这时候 Emacs 轻量级的资源占用和快捷键系统就显现出了优势。 lsp-mode 提供了这种可能。使用 lsp-mode 联合 company-mode 可以实现简单的代码补全、查询、语法检查等功能。配置代码比较长不再贴上来。

效果如下:

5. “高铁论文伴侣”——本地词典

最近有一些需要离线使用 Emacs 的场景(比如在高铁里看论文记笔记),苦于没有网,不理解的英文单词不能直接搜索查询,很影响阅读体验。因此想着添加一个本地英文词典,这样在没网的情况下也能愉快地查词了。刚开始找到的是 sdcv ,它是 Stardict 的命令行版本,与 Emacs 结合效果也不错,但在 Windows 上无论如何都没办法编译出正常运行的版本。然后又发现在 GoldenDict 有一个现代版本 goldendict-ng ,支持很多种本地词典格式,遂下载下来一试。配合 Emacs China 中大佬的调用代码,可以直接在 Emacs 里调用查词:

1
2
3
4
5
6
(defun yuh/dict-word-at-point ()
  "Search word in goldendict"
  (interactive)
  (call-process-shell-command (concat "goldendict " (current-word) " &") nil 0)
  )
(global-set-key (kbd "C-c s g") 'yuh/dict-word-at-point)

效果如下:

6. “拼写大师”——英文单词补全

在写一些英文文本时,偶尔会出现单词不会拼的情况,如果这个时候去查词典就有点太影响效率了。好在上面提到的 company-mode 可以直接补全英文单词:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
;; 将词典加入 ispell 设置中
(setq ispell-alternate-dictionary "C:/Users/niall/OneDrive/scripts/words_alpha.txt")
;; 设置函数来开关补全单词功能
(defun toggle-company-ispell ()
  "Toggle company-ispell."
  (interactive)
  (cond
   ((memq 'company-ispell company-backends)
    (setq company-backends (delete 'company-ispell company-backends))
    (message "company-ispell disabled"))
   (t
    (setq company-backends (push 'company-ispell company-backends))
    (message "company-ispell enabled!"))))
(global-set-key (kbd "C-c t s") 'toggle-company-ispell)

效果如下:

7. “有个地方在等我”——文本跳跃

Emacs 快捷键系统带来的最大便利就是不用动鼠标,用按键就可以实现光标的上下左右移动,但如果想直接跳跃到文本中的指定位置,那就要借助别的包的实现。 avy 是一个能跳跃到文本中指定字符的包,在中文的跳跃中它应当与 ace-pinyin 配合使用,这样只需要中文的拼音首字母就能跳到想要的位置。配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
(use-package ace-pinyin
  :ensure t
  :config
  (ace-pinyin-global-mode +1))
(use-package avy
  :config
  (global-set-key (kbd "C-:") 'avy-goto-char)
  (global-set-key (kbd "C-\"") 'avy-goto-char-2)
  (global-set-key (kbd "M-g f") 'avy-goto-line)
  (global-set-key (kbd "M-g w") 'avy-goto-word-1)
  (global-set-key (kbd "M-g e") 'avy-goto-word-0))

效果如下:

写在最后

关于折腾的限度问题,实际上很难去回答。但我想至少有几个准则是可以参考的:

  1. 不必要的功能不折腾
  2. 太复杂的不折腾
  3. 工作时间不折腾

最终,所有的东西都是要为生产和效率服务,也应该在生产上时常用到。