惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
月光博客
月光博客
V
Visual Studio Blog
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
Jina AI
Jina AI
J
Java Code Geeks
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
Recorded Future
Recorded Future
C
Check Point Blog
腾讯CDC
N
Netflix TechBlog - Medium
aimingoo的专栏
aimingoo的专栏
罗磊的独立博客
Hacker News: Ask HN
Hacker News: Ask HN
SecWiki News
SecWiki News
博客园 - Franky
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
News | PayPal Newsroom
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security @ Cisco Blogs
W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
F
Full Disclosure
The Cloudflare Blog
Y
Y Combinator Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
S
Schneier on Security
Schneier on Security
Schneier on Security
Spread Privacy
Spread Privacy
L
LINUX DO - 热门话题
AI
AI
N
News and Events Feed by Topic
T
Tor Project blog
P
Palo Alto Networks Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More
G
Google Developers Blog

Computer – Ed_'s Blog

给 Debian 开了自动安全更新 – yywr's Blog 移动网络/高延迟网络下 ssh 的替代品 – yywr's Blog H3C NX30PRO 半砖救回记 – yywr's Blog OBS摄像头设置教程:画面形状与绿幕功能详解 – yywr's Blog 视频录制和推流直播工具OBS Studio 的使用 – 基础篇 – yywr's Blog UPower – 将笔记本电池当成UPS使用 – yywr's Blog 私有音乐服务 Navidrome:部署与Nginx 二级目录反代访问 – yywr's Blog 简单的私有云数据访问工具 – FileBrowser 部署记要 – yywr's Blog 又一个 Honkintosh – yywr's Blog Samba 服务基本用法 – yywr's Blog Crontab 使用笔记 – yywr's Blog 终于修了个梯子 – yywr's Blog 防火墙配置工具 UFW – yywr's Blog
macOS 下 xlr-spaceFN 键盘映射方案实现方案 v1 – yywr's Blog
yywr · 2026-06-11 · via Computer – Ed_'s Blog

macOS 用了差不多一年半,但是一直觉得不得劲,因为在Windows 下,我有一个基于 Autohotkey V1 的键盘映射方案 xlr-sapce 键盘映射方案  for Windows,让我在工作打字时更快的操作光标,移动、选择、编辑,以空格为修饰键,加字母区域的按键,手部不需要任何多余的移动,而在macOS 一直没办法实现

以前在使用 Linux 的时候也尝试实现这个映射方案,最接近的方案是使用 XModMap,但最终还差点,找资料实在太难了,而 AI 让我的想法更好的实现了,所以下面是在 macOS 下xlr-sapceFN 映射方案,虽然不够完美,但是也非常接近了

xlr-sapceFN 映射方案简介

xlr-spaceFN 映射方案与其它键盘映射方案最大的不同,以及最大的优点就是,使用空格作为修饰键,在Windows 下,Autohotkey让这个想法完美实现了,目前macOS 下虽然功能实现了,但还是有点遗憾

本配置将空格键改造为一个智能功能层激活键:

  • 轻点空格 → 正常输出空格(无延迟感,一般100-150毫秒内,自己调)
  • 按住空格 → 激活功能层,此时按下特定字母键可执行导航、编辑等快捷操作

快速参考卡片(按键位布局)

q
 
w
Bksp
e
r
Del
t
 
y
PgUp
u
Sel←
i
Sel↑
o
Sel→
p
Page Home
a
Home
s
d
f
g
End
h
←选词
j
←选择
k
↓选择
l
→选择
Enter
行尾 + 换行
 
z
Undo
x
Cut
c
Copy
v
Paste
b
PgDn
n
→选词
m
 
  
Page End
按住空格键时

macOS xlr-sapceFN 映射方案实现核心思路:如何实现“空格当修饰键”

实现方式:使用 Karabiner-Elements+ 配置文件的方式实现

Karabiner 的规则不能直接写 GetKeyState,但可以通过 to_if_held_downto_if_alone 组合实现:

  • 当按下空格并稍后释放(没有按其他键)→ 发送 space(单独空格)。
  • 当按下空格并按住不放时 → 进入“修饰键模式”,此时再按其他键触发自定义动作。

当前必须接受的缺点

Karabiner-Elements 无法实现和 AutoHotkey 完全一致的逻辑,这是两个平台键盘事件处理机制上的本质差异导致的:AutoHotkey 在 Windows 低层 (钩子) 驱动可以直接操控键盘状态,强制将其“角色”转换;而 Karabiner-Elements 在 macOS 受沙盒限制,只能通过“裁决”策略用延迟判断该输出字符还是激活功能,无法做到真正的零延迟使用方法

具体来说就是:在 macOS 下,必须为空格按下进程设置一个延迟时间,比如说 150 毫秒:

  • 在这个时间内:按下并释放空格则正常输出空格 >>> 理想状态
  • 在这个时间内:按下空格和其它键并释放,没有冲突的情况下,输出其它键 >>> 难受状态
  • 在这个时间之后:按下并释放空格没有任何反应 >>> 难受状态
  • 在这个时间之后:按下空格和设定的组合键,实现设定的映射 >>> 理想状态

在上面几种情况中,日常使用其实还是非常容易触发难受状态的,整个工作流程会受到一点影响,相对来说来还是能够接受的 ,最难受的其实是使用删除的时候,很多时候删除操作非常快,但按太快容易进入难受状态,以后再想办法吧

操作指引

  1. 下载并安装Karabiner-Elements后打开,进入Setup ,将所有功能打开,尤其是 Driver Extension
  2. 将下面的 JSON 代码保存为 ~/.config/karabiner/assets/complex_modifications/xlr_spaceFN_modifier.json(如果目录不存在则手动创建)。
  3. 打开 Karabiner-Elements → Complex Modifications → Add predefined rule → xlr-SpaceFN → Enable All
  4. 如果某些快捷键与系统快捷键冲突(如 Ctrl+Space 切换输入法),可以在 Karabiner 的 Simple Modifications 或系统设置中关闭对应组合。
  5. [Base] Hold Spacebar to activate layer (required) 是必须启用的 ,其它的已经分成了移动、选择、编辑三块,按需要开启

方案代码

  1. 基础层(必需) – 按住空格激活功能层(设置变量)
  2. 光标移动层 – 方向键、行首行尾、翻页
  3. 文本选择层 – Shift + 方向、按词选择、选至行首尾
  4. 编辑操作层 – 删除、复制粘贴、撤销、行尾换行

基础层必须启用,其他层可以任意组合启用/禁用。
所有规则共用同一个变量 space_fn_layer,互不冲突。

将下面代码按指引中的第二步保存为 josn 文件

{
    "title": "xlr-SpaceFN-v2",
    "rules": [
        {
            "description": "[Base] Hold Spacebar to activate layer (required)",
            "manipulators": [
                {
                    "description": "Hold Spacebar for Layer (with delay)",
                    "from": {
                        "key_code": "spacebar",
                        "modifiers": { "optional": ["any"] }
                    },
                    "to_if_alone": [{ "key_code": "spacebar" }],
                    "to_if_held_down": [{ "set_variable": { "name": "space_fn_layer", "value": 1 } }],
                    "to_after_key_up": [{ "set_variable": { "name": "space_fn_layer", "value": 0 } }],
                    "parameters": {
                        "basic.to_if_alone_timeout_milliseconds": 110,
                        "basic.to_if_held_down_threshold_milliseconds": 111
                    },
                    "type": "basic"
                }
            ]
        },
        {
            "description": "[Block 1] Cursor Movement (e,s,d,f | a,g | y,b)",
            "manipulators": [
                {
                    "from": { "key_code": "e" },
                    "to": [{ "key_code": "up_arrow" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "s" },
                    "to": [{ "key_code": "left_arrow" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "d" },
                    "to": [{ "key_code": "down_arrow" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "f" },
                    "to": [{ "key_code": "right_arrow" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "a" },
                    "to": [{ "key_code": "left_arrow", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "g" },
                    "to": [{ "key_code": "right_arrow", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "y" },
                    "to": [{ "key_code": "page_up" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "b" },
                    "to": [{ "key_code": "page_down" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                }
            ]
        },
        {
            "description": "[Block 2] Text Selection (i,j,k,l | h,n | u,o)",
            "manipulators": [
                {
                    "from": { "key_code": "i" },
                    "to": [{ "key_code": "up_arrow", "modifiers": ["left_shift"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "j" },
                    "to": [{ "key_code": "left_arrow", "modifiers": ["left_shift"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "k" },
                    "to": [{ "key_code": "down_arrow", "modifiers": ["left_shift"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "l" },
                    "to": [{ "key_code": "right_arrow", "modifiers": ["left_shift"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "h" },
                    "to": [{ "key_code": "left_arrow", "modifiers": ["left_shift", "left_option"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "n" },
                    "to": [{ "key_code": "right_arrow", "modifiers": ["left_shift", "left_option"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "u" },
                    "to": [{ "key_code": "left_arrow", "modifiers": ["left_command", "left_shift"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "o" },
                    "to": [{ "key_code": "right_arrow", "modifiers": ["left_command", "left_shift"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                }
            ]
        },
        {
            "description": "[Block 3] Editing (w,r | c,x,v,z | p,/, Enter)",
            "manipulators": [
                {
                    "from": { "key_code": "w" },
                    "to": [{ "key_code": "delete_or_backspace" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "r" },
                    "to": [{ "key_code": "delete_forward" }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "c" },
                    "to": [{ "key_code": "c", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "x" },
                    "to": [{ "key_code": "x", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "v" },
                    "to": [{ "key_code": "v", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "z" },
                    "to": [{ "key_code": "z", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "p" },
                    "to": [{ "key_code": "up_arrow", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "slash" },
                    "to": [{ "key_code": "down_arrow", "modifiers": ["left_command"] }],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                },
                {
                    "from": { "key_code": "return_or_enter" },
                    "to": [
                        { "key_code": "right_arrow", "modifiers": ["left_command"] },
                        { "key_code": "return_or_enter" }
                    ],
                    "conditions": [{ "name": "space_fn_layer", "type": "variable_if", "value": 1 }],
                    "type": "basic"
                }
            ]
        }
    ]
}