Emacs 在 Windows 下的CUA操作与其他程序配合的割裂感,一直是个头疼的问题,每次使用Emacs要有一种特别的仪式感,把自己调整到Emacs模式才能顺畅用起来,以至于平常记事本都比Emacs用的次数多。
如果能保持与 Windows 其他应用一致的 CUA 操作,比如在 vscode 下面执行 Ctrl+C ,然后到 Emacs 中执行 Ctrl+V,小拇指不移动,对我来说才是最适合的。
这两天看子龙山人老师的 2022 版 《21天学会 Emacs》,第一节改键就讲了他把 Left Window 键改成 Left Alt 键,Left Alt 键改成 App 键,大小写键改成 Ctrl 键的方案,兼容了 Windows 和 Mac 操作的一致性。这个改 Super 键的思路,给了我灵感。如果将左Ctrl键改为Super,CapsLock 键改为左 Ctrl 键,并且仅在 Emacs 窗口激活时生效,再配合子龙山人的改键配置,即可实现目标。
于是下午摸鱼撸了个小工具,代替 ShapsKey 改键,使改键方案只在Emacs窗口获得焦点时启用。
核心代码如下:
// Hook 回调处理函数
static UINT ModifyCallBack(UINT code, UINT mode)
{
HWND hWndFore = ::GetForegroundWindow();
HWND hWndEmacs = ::FindWindow(_T("Emacs"), NULL);
// 判断 Emacs 是否激活 仅在激活时生效
if (hWndFore != hWndEmacs) {
return code;
}
// 按键重映射
if (code == 0xA2) { // 左Ctrl 映射为 APP键
return 0x5D;
}
if (code == 0x14) { // CapsLock 映射为 右Ctrl
return 0xA3;
}
if (code == 0xA3) { // 右Ctrl键 映射为 CapsLock
return 0x14;
}
return code;
}
Emacs改键如下:
(setq w32-apps-modifier 'super) ; 通过SharpKeys改成了 Application
(global-set-key (kbd "s-a") 'mark-whole-buffer) ; 对应Windows上面的Ctrl-a 全选
(global-set-key (kbd "s-c") 'kill-ring-save) ; 对应Windows上面的Ctrl-c 复制
(global-set-key (kbd "s-s") 'save-buffer) ; 对应Windows上面的Ctrl-s 保存
(global-set-key (kbd "s-v") 'yank) ; 对应Windows上面的Ctrl-v 粘贴
(global-set-key (kbd "s-z") 'undo) ; 对应Windows上面的Ctrol-z 撤销
(global-set-key (kbd "s-x") 'kill-region) ; 对应Windows上面的Ctrol-x 剪
最后附上小工具链接。工具采用安装动态库钩子方案实现,可能会报毒,但保证无毒无后门,也没有在其他电脑上测试,不确定兼容性如何,我自己是 Windows 10 系统,感兴趣的朋友先试试再说吧,后续如有必要我将源码整理后放出来。
链接:腾讯微云 密码:xfihsj
5月21更新
今天早上用实际用了一下,发现两个Bug:
- Emacs下执行
c-z
最小化操作后,right ctrl
键弹不起来,必须要手动按两下right ctrl
键才能恢复; -
CapsLock
和right ctrl
键的改键消息会形成死循环,导致windows消息队列混乱;
一下午没解决,整不会了,再想想办法