目录

把 Caps Lock 键当作修饰键使用

CapsLock 在键盘上占据了一个非常方便顺手的位置(甚至比左手的 Ctrl 更加顺手),但它本身并不是一个常用的键。有人选择长按把它变成 Ctrl, 短按时则变成 Esc, 这当然是一种巧妙的优化。不过笔者选择把 CapsLock 键当作一个新的修饰键使用,用它来实现快速按下较为复杂的组合键。用 AutoHotKey 脚本可以很轻松实现这一构想。

AHK 脚本实现

我们直接展示最终的 AutoHotKey (AHK v2) 脚本如下,之后再解释其实现思路和细节。

#NoTrayIcon
#SingleInstance Force

!CapsLock::Send "{Blind}{Delete}"

CapsLock:: {
	KeyWait("CapsLock") ; 等待按键释放
	
	if (A_PriorKey != "CapsLock") {
		; 组合键
		Return
	} else if (A_TimeSinceThisHotkey > 200) {
		; 长按
		Return
    } else if (A_PriorHotkey = A_ThisHotkey && A_TimeSincePriorHotkey < 400) {
		; 双击
        SetTimer(SendEsc, 0)
        SetCapsLockState !GetKeyState("CapsLock", "T")
    } else {
		; 单击
        SetTimer(SendEsc, -450)
    }
}

SendEsc() {
	Send "{Esc}"
}

#HotIf GetKeyState("CapsLock", "P")
	Space::Send "{Media_Play_Pause}"    ; 播放/暂停
	a::Send "{Media_Prev}"              ; 上一曲
	d::Send "{Media_Next}"              ; 下一曲
	s::Send "{Volume_Down}"             ; 音量降低
	w::Send "{Volume_Up}"               ; 音量提高
	m::Send "{Volume_Mute}"             ; 静音

	q::Send "^#{Left}"                  ; 切换到左边的虚拟桌面
	e::Send "^#{Right}"                 ; 切换到右边的虚拟桌面
	r::Send "^#d"                       ; 新建虚拟桌面
	f::Send "^#{F4}"                    ; 关闭当前虚拟桌面

	x::Send "!{F4}"                     ; 关闭当前窗口

	h::Send "{Left}"          			; 左
	j::Send "{Down}"          			; 下
	k::Send "{Up}"            			; 上
	l::Send "{Right}"         			; 右
	b::Send "^{Left}"         			; 上一个单词
	n::Send "^{Right}"        			; 下一个单词
	0::Send "{Home}"          			; 行首 (0)
	6::Send "{Home}"          			; 行首 (^)
	4::Send "{End}"           			; 行尾 ($)

	~g:: {
		if (A_PriorHotkey = A_ThisHotkey and A_TimeSincePriorHotkey < 400)
			Send "^{Home}"				; 文档开头 (gg)
	}
	+g::Send "^{End}"         			; 文档结尾 (G)

	+T::Send "^+{Esc}"					; 任务管理器
#HotIf

; 为日语输入法的切换保留
#HotIf IsJapaneseIME()
	^CapsLock::Send "{Ctrl Down}{CapsLock}{Ctrl Up}"     ; Ctrl + CapsLock
	+CapsLock::Send "{Shift Down}{CapsLock}{Shift Up}"   ; Shift + CapsLock
	!CapsLock::Send "{Alt Down}{CapsLock}{Alt Up}"       ; Alt + CapsLock
#HotIf

IsJapaneseIME() {
	hwnd := WinActive("A")
	if !hwnd
		return false

	threadId := DllCall("GetWindowThreadProcessId", "Ptr", hwnd, "Ptr", 0)
	hkl := DllCall("GetKeyboardLayout", "UInt", threadId, "Ptr")

	; HKL 的低16位是语言ID。日语的语言ID是 0x411。
	langId := hkl & 0xFFFF
	return langId = 0x411
}

具体的自定义思路如下:

  • 智能单击/双击:使用 KeyWait 函数实现单击和双击的区分。单击时发送 Esc 键,双击时切换 CapsLock 状态,保留其原始用途。
  • 快捷键绑定:用 CapsLock 作为修饰键,绑定了一系列常用的快捷键:
    • 媒体控制:将 WASD 和空格键用于媒体播放控制。
    • 窗口管理:使: QERF 快速管理 Windows 虚拟桌面,用 X 关闭窗口。
    • Vim 导航:将 HJKL 等键映射为 Vim 风格的方向键和文本导航键。
  • Alt+Tab 增强:在按住 Alt 时,按下 CapsLock 会发送 Delete 键,这使得在 Alt + Tab 中可以用左手来关闭窗口。
  • 输入法兼容:日语输入法需要 Ctrl + CapsLock, Shift + CapsLockAlt + CapsLock 的组合键来切换平假/片假/英文输入,因此脚本中保留了这些组合键的功能。

快捷键的设计,是根据右手的位置来决定功能的划分。左手区主要是在日常使用中的常用功能(此时右手一般在鼠标上),而右手区则是文本编辑相关的按键(此时右手一般在键盘上)。

Alt+F4 和文本导航的按键绑定到 CapsLock 键上,主要是因为笔者的笔记本键盘上 F 区和 Home/End/PgUP/PgDn 重合(需要用 Fn 键切换),所以用 Vim 风格的按键来代替它们。

使用方法

为了能让脚本全局启用,我们需要使用任务计划程序,以最高权限运行它(否则在以管理员身份运行的程序中它将不起作用)。

Win+R, 输入 taskschd.msc 打开任务计划程序,创建一个新的任务,设置如下:

  • 常规:设置任务名称和描述,勾选“只在用户登录时运行”和“使用最高权限运行”。
  • 触发器:新建一个触发器,选择“在登录时”。
  • 操作:新建一个操作,选择“启动程序”,在“程序或脚本”中输入 C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe(替换为你的 AHK V2 的安装路径),在“添加参数”中输入你的脚本文件路径,例如 C:\path\to\your\script.ahk
  • 条件:可以根据需要调整,例如取消“仅在计算机使用交流电源时才开始任务”的勾选。
  • 设置:这里的默认设置通常是合适的。