key-echo: 单按修饰键来触发Emacs命令

Emacs 本身的按键机制需要用户最少按一个组合键才能执行一个命令, 如果用户只按一个修饰键, 比如只按 Shift 时, Emacs 本身并不会触发一个 Shift 按键事件。

这样的机制在大部分 Emacs 场景都没有问题, 但是对于输入法场景就很不方便, 用户每次切换中英文都需要按一个组合键, 不能像传统输入法那样只需要按一次 Shift 键就可以快速切换输入法状态。

这半个月都在旅游自驾, 今天东北下大雨, 终于有时间写会儿代码来解决这个问题啦。

key-echo 是一个利用 XRecord 技术来实现的全局按键监听插件, 它可以监听一些特殊的单按键事件, 比如用户只是按了一下 Shift 辅助键而没有按其他字母按键时, 发送信号给 Emacs, 让 Emacs 执行一些 Elisp 代码, 比如切换输入法。

安装方法

  1. 安装 Emacs 28 及以上版本
  2. 安装 Python 依赖: epc, sexpdata, six, pynput: pip3 install epc sexpdata six pynput
  3. git clone 下载此仓库, 并替换下面配置中的 load-path 路径
  4. 把下面代码加入到你的配置文件 ~/.emacs 中:
(add-to-list 'load-path "<path-to-key-echo>")

(require 'key-echo)
(key-echo-enable)

(defun key-echo-shift-to-switch-input-method (key)
  (interactive)
  (when (string-equal key "Key.shift")
    (toggle-input-method)
    ))

(setq key-echo-single-key-trigger-func 'key-echo-shift-to-switch-input-method)

加上上面设置后, 按 Shift 可以自由切换输入法。

10 个赞

早上增强了一下, 单按Shift是用于切换输入法, 单按Left Alt是用于弹出 blink-search, 单按Right Alt是用于弹出popweb翻译

2 个赞

大佬终于出手解决这个困扰多年的老问题了,在中文输入环境下,shift键确实不像英文输入环境下那么有用,偏偏还做的那么大,占空间,完全可以拿shift来做点别的事情,蹭大佬的贴子,又把我对 shift的用法贴一下

1 个赞

用key-echo这个插件,我觉得对哪些evil模式切换用户最好用,shift按键很大很好按。

windows上我用autohot key处理 shif输入法的 :grinning:

1 个赞

非常棒的功能努力想用上

正在研究中,还没用上,按完不切换,message里是

Making input-method-function buffer-local while locally let-bound!

去掉eaf lsp meow 后终于让报错明确了些

Making input-method-function buffer-local while locally let-bound!
pyim 出现错误: (wrong-type-argument overlayp nil) , 开启 debug-on-error 后可以了解详细情况。

继续研究中

直接用 emacs-rime 吧, key-echo 配合 emacs-rime 和 toggle-input-method 没有问题。

好的,上次 emacs-rime 没搞成倒是 pyim 一下子就能用了,所以就留下来了,我再回去折腾下

大佬轻描淡写,这个不是下大雨吧, 是极罕见特大洪灾

1 个赞

不同地方情况不一样吧,哈尔滨附近就是大雨

BlindingDark
#Emacs-general

tg 群群友提供了另一个思路,就是用外部键盘映射工具,把 shift 映射到 f-num 区域,或者别的按键组合,这样 emacs 里就可以响应了。优点是依赖很少,配置也很少。

我实践了这个思路,ahk代码

#HotIf WinActive("ahk_class Emacs")
  Shift::send "{F12}"
#HotIf

emacs里面写 (global-set-key (kbd "<f12>") 'indent-for-tab-command), 与我的配置无冲突,shift开头的其它快捷键也不影响,单按shift的时候在emacs里等于按f12,这个思路完全可行,也确实是 依赖很少,配置也很少


0807更新:绑F12以后某些mode会自定义f12这个键,有冲突,然后我就写了个F13,这时才发现原来f-num 区域,指的不仅是键盘上那12个键, 而是F1到F24,emacs可以响应的预留键位有那么多,没有理由不用上

2 个赞

现在看新闻都不敢轻信了,不知道洪灾真实情况如何

加了一个 key-echo-keyboard-quit-key 选项, 默认绑定到 Right Alt.

这样通过 key-echo 可以实现常用功能加速:

  1. 按 Shift 来快速切换输入法
  2. 按 Right Alt 来发送 Ctrl + g 按键
  3. 按 Left Alt 来调用自定义命令, 比如 blink-search 来搜索
2 个赞

我一开始不行, 重启 emacs 就可以了.

很好用,赞呀

1 个赞

你们喜欢就好

请问我按照 README 中设置后 shift 并不能够起到切换输入法的作用,并没有反应,已经尝试过重启 emacs 了。

目前的配置如下

(add-to-list 'load-path "~/.emacs.d/straight/repos/key-echo/")
(require 'key-echo)
(setq key-echo-enable-log t)

(key-echo-enable)

(defun key-echo-shift-to-switch-input-method (key)
  (interactive)
  (when (string-equal key "Key.shift")
    (toggle-input-method)
    ))

(setq key-echo-single-key-trigger-func 'key-echo-shift-to-switch-input-method)

如果打开 log,会发现 key-echo 中没有任何输入

如果打开 debug,会发现 key-echo 会随着每次击键出现如下文本

[Thread 0x7fffed02f6c0 (LWP 17316) exited]
[New Thread 0x7fffed02f6c0 (LWP 17318)]
[Thread 0x7fffed02f6c0 (LWP 17318) exited]
[New Thread 0x7fffed02f6c0 (LWP 17320)]
[Thread 0x7fffed02f6c0 (LWP 17320) exited]
[New Thread 0x7fffed02f6c0 (LWP 17322)]
[Thread 0x7fffed02f6c0 (LWP 17322) exited]
[New Thread 0x7fffed02f6c0 (LWP 17325)]
[Thread 0x7fffed02f6c0 (LWP 17325) exited]
[New Thread 0x7fffed02f6c0 (LWP 17327)]
[Thread 0x7fffed02f6c0 (LWP 17327) exited]
[New Thread 0x7fffed02f6c0 (LWP 17329)]
[Thread 0x7fffed02f6c0 (LWP 17329) exited]
[New Thread 0x7fffed02f6c0 (LWP 17334)]
[Thread 0x7fffed02f6c0 (LWP 17334) exited]

我的系统是 manjaro,emacs 版本是 29.1,使用 emacs-rime。已经按照 README 用 pip 安装过相关依赖。

byte compile了吗?

我自己的配置文件没有。请问还有什么我可以提供的辅助 debug 的信息吗?这是我的配置。 配置 key-echo 的代码在 core/init-tmp.el 中,配置 emacs-rime 的代码在 core/init-input.el 中,rime 本身的配置在这里

(key-echo-enable)

这个放在相应配置的最后试试?