Changelog:
- 2020-08-22 增加了
winner-undo
与transient-map
搭配的例子 - 2020-08-22 增加了
strokes-mode
的介绍 - 2020-08-25 增加了
webjump
的介绍 - 2020-08-30 增加了
transient-map
的小技巧
winner-mode
winner-mode
是一个全局的minor mode
,它的主要功能是记录窗体的变动。例如当前有
2 个窗口,然后你关了一个,这时可以通过winner-undo
来恢复。还可以再winner-redo
来撤销刚才的undo
.
它默认按键绑定为:
C-c Left winner-undo
C-c Right winner-redo
如果不想它绑定在C-c前缀按键上,可以通过
(setq winner-dont-bind-my-keys nil)
来禁止。
建议配置:
(use-package winner-mode
:ensure nil
:hook (after-init . winner-mode))
同时,它也可以应用在ediff
上,恢复由ediff
导致的窗体变动。
(use-package ediff
:ensure nil
:hook (ediff-quit . winner-undo)
winner-undo 搭配 transient-map
如果平常有注意观察text-scale-adjust
(C-x C-=) 的行为,会发现只需要
按全一次C-x C-=,之后可以只按+
、-
或者0
来缩放字体。而如果触发了
其他按钮则会退出这个状态,它背后主要依赖transient-map
机制。
我们可以仿照着写一个transient-winner-undo
的版本,在需要连续执行winner-undo
的
时候只需要按一个u
就好了。
(defun transient-winner-undo ()
"Transient version of `winner-undo'."
(interactive)
(let ((echo-keystrokes nil))
(winner-undo)
(message "Winner: [u]ndo [r]edo")
(set-transient-map
(let ((map (make-sparse-keymap)))
(define-key map [?u] #'winner-undo)
(define-key map [?r] #'winner-redo)
map)
t)))
着实方便许多!
strokes
如果你想用鼠标来控制Emacs
的行为,有点像现在浏览器上的鼠标手势。不过它只能识别
鼠标移动轨迹所描绘的形状,不能判断它的方向。
- 执行
strokes-mode
打开minor-mode
- 执行
strokes-global-set-stroke
在弹出的buffer
内使用Shift
+鼠标左键(也可以用中键) 绘出想作为快捷操作的大致形状,假设是一个 C 的形状,然后鼠标右键结束绘制。稍后 会提示输入与stroke
对应的命令,假设是strokes-help
- 移动鼠标,使得它的轨迹是个 C 的形状
-
Shift
+鼠标中键以执行与这个stroke
对应的命令,也就是strokes-help
想要更详细的信息?请M-x strokes-help
.
webjump
你想在Emacs
里快速调用搜索引擎搜索吗?原来这个功能早已经内置了!
由于webjump-sites
早已有默认值了,如果想急着体验一下可以立即M-x webjump
。其原
理也是相当简单,通过用户选择它想要用的搜索引擎+查询内容构造出实际url
,然后通过
browse-url
调用托管给浏览器。
我的配置是这样的:
(use-package webjump
:ensure nil
:bind ("C-c /" . webjump)
:custom
(webjump-sites '(
;; Emacs.
("Emacs Home Page" .
"www.gnu.org/software/emacs/emacs.html")
("Savannah Emacs page" .
"savannah.gnu.org/projects/emacs")
;; Internet search engines.
("DuckDuckGo" .
[simple-query "duckduckgo.com"
"duckduckgo.com/?q=" ""])
("Google" .
[simple-query "www.google.com"
"www.google.com/search?q=" ""])
("Google Groups" .
[simple-query "groups.google.com"
"groups.google.com/groups?q=" ""])
("Wikipedia" .
[simple-query "wikipedia.org" "wikipedia.org/wiki/" ""]))))
如果只是想要简单的查询,那么可以作为 engine-mode的内置替换方案了。
当然,还可以配置多级查询选项,可参考webjump-to-iwin
的实现。
transient-map 小技巧
因为transient-map
的优先级比其他keymap
都要高,所以可以将它当作菜单来使用。
如果嫌set-transient-map
用起来不方便,可以使用hydra代替。
编辑时拷贝 (配合 avy)
如果在编辑文字时发现要拷贝一个url
,但是当前窗口内有多个url
,类似的场景如下:
/// url1: https://www.google.com
/// url2: https://www.baidu.com
/// url3: https://duckduckgo.com
int foo(int x) {
const char* url = "";
}
想要为url
赋值为注释内的 3 个 url 之一。
- 首先将光标移动到想复制的
url
处 - 再将这个
url
复制到kill-ring
当中 - 再回到原来的位置
- 再粘贴
(defhydra hydra-copy (:color blue)
"Copy"
("w" copy-word-at-point "word")
("u" copy-url-at-point "url")
("q" nil "cancel"))
(defun copy-url-at-point ()
"Copy url at point."
(interactive)
(save-excursion
(avy-goto-word-or-subword-1)
(kill-new (thing-at-point 'url))))
这里使用hydra
来偷懒一下。
效果图: