介绍 #
KMonad 是一个改键器,能够在 windows , macos 以及 linux 上使用,可以将主行键位 ASDFJKL;键映射为修饰键(其实可以修改任意键位),最近因为在学习 emacs,无论是使用原始键位还是 evil 都大量涉及到使用功能键例如 ctrl , alt , meta 等,为了更加高效的编辑,但是又没有 QMK 键盘,所以尝试使用改键方案。
安装 #
macos 上的安装 #
由于官方没有编译可执行的文件,所以需要自己从源码进行编译,本人系统为 macOS 14,macOS13(不含)之前的版本安装方式有所不同,请参考官方教程kmonad/doc/installation.md at master · kmonad/kmonad · GitHub。
首先克隆仓库到本地并安装驱动
# 安装编译依赖
brew install haskell-stack
# 拉取仓库
git clone --recursive https://github.com/kmonad/kmonad.git
# 切换至kmonad文件夹
cd kmonad/
# 安装驱动程序
open c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/dist/Karabiner-DriverKit-VirtualHIDDevice-3.1.0.pkg
# 激活驱动 !!!注意此步会弹出权限提示,需要点击进入设置将权限打开,如果这一步点击了ok,后续需要在设置-通用-登录项与扩展中最下面的扩展找到驱动程序扩展,打开karabiner的权限
/Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate
# 此步确认是否在kmonad文件夹中,如果不是的话需要回到kmonad文件夹
stack install --flag kmonad:dext
安装完成后,kmonad 的可执行文件在 ~/.local/bin
中,记得要给 kmonad 执行权限 chmod +x kmonad
,在终端中检查执行 kmonad
是否有输出,如果提示找不到执行路径之类的报错,需要将 ~/.local/bin
添加到路径。新建 kmonad 使用的配置文件 keys.kbd
,文件名没有要求,但是后缀需要是 .kbd
,通过终端运行 kmonad 的形式是 kmonad keys.kbd
,kbd 配置文件内容见下一部分。
根据官方文档描述,运行 kmonad
时需要使用 sudo
权限,并且需要将可执行程序添加到 隐私与安全性➡️输入监控
中,因为需要 sudo
权限,所以一般的开机脚本执行类的方式比较麻烦,可以使用系统权限执行的 launchd
的方式,编写 plist 放在 /Library/LaunchDaemons
中,plist 如下,请根据自身路径修改其中 kmonad
的路径及配置文件路径
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.kmonad</string>
<key>ProgramArguments</key>
<array>
<string>/Users/zzzzz/.local/bin/kmonad</string>
<string>/Users/zzzzz/.local/bin/keys.kbd</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/kmonad.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/kmonad.stderr</string>
</dict>
</plist>
需要将 plist 文件(例:local.kmonad.plist)更改权限, sudo chown root:wheel local.kmonad.plist
如果开机运行失败,请检查:
- kmonad 二进制程序的可执行权限
- kmonad 二进制程序添加至 隐私与安全性➡️输入监控
local.kmonad.plist
的用户和组- 通用-登录项与扩展-扩展 中驱动程序扩展
karabiner
的权限是否打开
windows 系统下的安装 #
windows 系统下的安装比较简单,我尝试使用官方的编译方法,但是可能因为环境问题一直编译失败,现在官方最新版本是 0.43,在 Releases 里有编译好的 0.41 的版本,我用了目前没什么问题,用终端启动 kmonad 和配置文件测试后没有问题就可以尝试开机自启动了,在 windows 的配置文件中,注意 defcfg
块中调用的驱动与 mac 不同,需要修改,见后一部分配置文件的说明。
在 windows 系统上目前没有找到好的后台启动方式,如果直接用 sh 脚本或者创建快捷方式的形式开机启动,会有一个终端的弹窗出现,不能做到静默启动,目前是用 powershell 套娃 git bash 的形式达到静默启动,其中 git bash 的安装本教程不再赘述,powershell 脚本如下:
Start-Process "C:\Program Files\Git\bin\bash.exe" -ArgumentList "/c/Users/zzzzz/bin/start.sh" -WindowStyle Hidden
其中 start-process
指向 git bash 执行程序,后面指向需要执行的 sh 脚本,sh 脚本中写入 ~/bin/kmonad-0.4.1-win.exe ~/bin/keys.kbd
,kmonad 执行程序和配置文件根据自己的路径进行调整,然后利用 windows 自带的任务计划程序新建任务,常规和触发器按需调整,操作中新增启动程序,路径填入 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
,添加参数填入 -ExecutionPolicy Bypass -File "C:\Users\zzzzz\bin\run.ps1"
,这个参数后面的 ps1 路径需要根据前面新建的 powershell 脚本的路径修改。
配置文件说明 #
(defcfg
input (iokit-name)
output (kext)
;; Comment this if you want unhandled events not to be emitted
fallthrough true
;; Set this to false to disable any command-execution in KMonad
allow-cmd true
)
(defsrc
a s d f g h j k l ;
)
(defalias
met_a (tap-hold-next-release 200 a lsft)
alt_s (tap-hold-next-release 200 s lalt)
ctl_d (tap-hold-next-release 200 d lmet)
sft_f (tap-hold-next-release 200 f lctl)
sft_j (tap-hold-next-release 200 j rctl)
ctl_k (tap-hold-next-release 200 k rmet)
alt_l (tap-hold-next-release 200 l lalt)
met_; (tap-hold-next-release 200 ; rsft)
)
(deflayer homerowmods
@met_a @alt_s @ctl_d @sft_f g h @sft_j @ctl_k @alt_l @met_;
)
其中 defcfg
部分是调用驱动,mac 中 input 部分使用 iokit-name
可以识别所有输出不用修改,windows 将 input 和 output 替换为:
(defcfg
;; For Windows
input (low-level-hook)
output (send-event-sink)
;; This option tells KMonad to let non-configured keys act normal
fallthrough true
)
defalias
部分定义按键功能,kmonad 中 tap-hold-next-release
功能表示按下 200 毫秒后开始调用修饰键,这个值 200 是比较合适的,也可以根据自身需求修改,如果调得太短,容易造成正常按键无法触发,太长的话组合键比较难按出来,后面的 a lsft
对应的是 A 键修改为 lsft
左 shift 键,配置其余部分不需要修改。
在 macbook 上使用时,由于系统层的键盘发送的是 F1-F12 按键,由 mac 系统处理对应 Fn 键的功能转换,由于 kmonad 在系统层对按键进行拦截,所以 Fn 键对应的“将 F1,F2 用作标准功能键”的设置将会失效,需要进行特殊处理,官方教程:kmonad/keymap/template/apple.kbd,参考官方教程新建一个键盘层用作 Fn 功能键的切换层,配置如下:
(defcfg
input (iokit-name)
output (kext)
;; Comment this if you want unhandled events not to be emitted
fallthrough true
;; Set this to false to disable any command-execution in KMonad
;; allow-cmd true
)
(defsrc
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
grv 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \
caps a s d f g h j k l ; ' ret
lsft z x c v b n m , . / rsft up
fn lctl lalt lmet spc rmet ralt left down rght
)
(defalias
met_a (tap-hold-next-release 200 a lsft)
alt_s (tap-hold-next-release 200 s lalt)
ctl_d (tap-hold-next-release 200 d lmet)
sft_f (tap-hold-next-release 200 f lctl)
sft_j (tap-hold-next-release 200 j rctl)
ctl_k (tap-hold-next-release 200 k rmet)
alt_l (tap-hold-next-release 200 l lalt)
met_; (tap-hold-next-release 200 ; rsft)
fn (around (layer-toggle homerow) fn)
)
(deflayer default
_ f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ @met_a @alt_s @ctl_d @sft_f g h @sft_j @ctl_k @alt_l @met_; _ _
_ _ _ _ _ _ _ _ _ _ _ _ _
@fn _ _ _ _ _ _ _ _ _
)
(deflayer homerow
_ brdn brup lp mctl bldn blup prev pp next mute vold volu
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ @met_a @alt_s @ctl_d @sft_f g h @sft_j @ctl_k @alt_l @met_; _ _
_ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _
)
其中 fn (around (layer-toggle homerow) fn)
的意思是 Fn 键按下之后调用 homerow 这个图层,这个图层中设置了 F1-F12 对应的 mac 系统上的功能键,如果不按 Fn 则是标准功能键,如果要想实现不按 Fn 键直接使用 mac 系统的功能键,则将两个图层中第一行对换即可。