Last active
February 2, 2026 16:07
-
Star
(266)
You must be signed in to star a gist -
Fork
(51)
You must be signed in to fork a gist
-
-
Save sedm0784/4443120 to your computer and use it in GitHub Desktop.
AutoHotkey script to map Caps Lock to Escape when it's pressed on its own and Ctrl when used in combination with another key, à la Steve Losh. Adapted from one that does something similar with the Ctrl Key on the Vim Tips Wiki (http://vim.wikia.com/wiki/Map_caps_lock_to_escape_in_Windows?oldid=32281). (Plus contribs from @randy909 & @mmikeww.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| g_LastCtrlKeyDownTime := 0 | |
| g_AbortSendEsc := false | |
| g_ControlRepeatDetected := false | |
| *CapsLock:: | |
| if (g_ControlRepeatDetected) | |
| { | |
| return | |
| } | |
| send,{Ctrl down} | |
| g_LastCtrlKeyDownTime := A_TickCount | |
| g_AbortSendEsc := false | |
| g_ControlRepeatDetected := true | |
| return | |
| *CapsLock Up:: | |
| send,{Ctrl up} | |
| g_ControlRepeatDetected := false | |
| if (g_AbortSendEsc) | |
| { | |
| return | |
| } | |
| current_time := A_TickCount | |
| time_elapsed := current_time - g_LastCtrlKeyDownTime | |
| if (time_elapsed <= 250) | |
| { | |
| SendInput {Esc} | |
| } | |
| return | |
| ~*^a:: | |
| ~*^b:: | |
| ~*^c:: | |
| ~*^d:: | |
| ~*^e:: | |
| ~*^f:: | |
| ~*^g:: | |
| ~*^h:: | |
| ~*^i:: | |
| ~*^j:: | |
| ~*^k:: | |
| ~*^l:: | |
| ~*^m:: | |
| ~*^n:: | |
| ~*^o:: | |
| ~*^p:: | |
| ~*^q:: | |
| ~*^r:: | |
| ~*^s:: | |
| ~*^t:: | |
| ~*^u:: | |
| ~*^v:: | |
| ~*^w:: | |
| ~*^x:: | |
| ~*^y:: | |
| ~*^z:: | |
| ~*^1:: | |
| ~*^2:: | |
| ~*^3:: | |
| ~*^4:: | |
| ~*^5:: | |
| ~*^6:: | |
| ~*^7:: | |
| ~*^8:: | |
| ~*^9:: | |
| ~*^0:: | |
| ~*^Space:: | |
| ~*^Backspace:: | |
| ~*^Delete:: | |
| ~*^Insert:: | |
| ~*^Home:: | |
| ~*^End:: | |
| ~*^PgUp:: | |
| ~*^PgDn:: | |
| ~*^Tab:: | |
| ~*^Return:: | |
| ~*^,:: | |
| ~*^.:: | |
| ~*^/:: | |
| ~*^;:: | |
| ~*^':: | |
| ~*^[:: | |
| ~*^]:: | |
| ~*^\:: | |
| ~*^-:: | |
| ~*^=:: | |
| ~*^`:: | |
| ~*^F1:: | |
| ~*^F2:: | |
| ~*^F3:: | |
| ~*^F4:: | |
| ~*^F5:: | |
| ~*^F6:: | |
| ~*^F7:: | |
| ~*^F8:: | |
| ~*^F9:: | |
| ~*^F10:: | |
| ~*^F11:: | |
| ~*^F12:: | |
| g_AbortSendEsc := true | |
| return |
For authohotkey v2: https://gist.github.com/108anup/ecd891f21dc88ef107ff6c8ab0969700
Working wiki link at head (without needing to login) https://vim.fandom.com/wiki/Map_caps_lock_to_escape_in_Windows
Working wiki link at head (without needing to login) https://vim.fandom.com/wiki/Map_caps_lock_to_escape_in_Windows
Dual Key Remap is awesome.
For authohotkey v2: https://gist.github.com/108anup/ecd891f21dc88ef107ff6c8ab0969700
Thanks for the script but I found a bug that caused my Caps lock to get stuck on "ON". I added a way to toggle Caps Lock using RAlt. Here is the updated script :
#Requires AutoHotkey v2.0
#SingleInstance Force
OnExit(ExitHandler)
ExitHandler(*) {
Send "{Ctrl up}"
}
global g_LastCtrlKeyDownTime := 0
global g_AbortSendEsc := false
global g_CtrlIsDown := false
*CapsLock:: {
global g_LastCtrlKeyDownTime
global g_AbortSendEsc
global g_CtrlIsDown
if (g_CtrlIsDown)
return
g_CtrlIsDown := true
g_AbortSendEsc := false
g_LastCtrlKeyDownTime := A_TickCount
Send "{Ctrl down}"
}
*CapsLock Up:: {
global g_LastCtrlKeyDownTime
global g_AbortSendEsc
global g_CtrlIsDown
if (!g_CtrlIsDown)
return
Send "{Ctrl up}"
g_CtrlIsDown := false
elapsed := A_TickCount - g_LastCtrlKeyDownTime
if (!g_AbortSendEsc && elapsed <= 500)
Send "{Esc}"
}
AbortEsc() {
global g_AbortSendEsc := true
}
~*^a:: AbortEsc()
~*^b:: AbortEsc()
~*^c:: AbortEsc()
~*^d:: AbortEsc()
~*^e:: AbortEsc()
~*^f:: AbortEsc()
~*^g:: AbortEsc()
~*^h:: AbortEsc()
~*^i:: AbortEsc()
~*^j:: AbortEsc()
~*^k:: AbortEsc()
~*^l:: AbortEsc()
~*^m:: AbortEsc()
~*^n:: AbortEsc()
~*^o:: AbortEsc()
~*^p:: AbortEsc()
~*^q:: AbortEsc()
~*^r:: AbortEsc()
~*^s:: AbortEsc()
~*^t:: AbortEsc()
~*^u:: AbortEsc()
~*^v:: AbortEsc()
~*^w:: AbortEsc()
~*^x:: AbortEsc()
~*^y:: AbortEsc()
~*^z:: AbortEsc()
~*^1:: AbortEsc()
~*^2:: AbortEsc()
~*^3:: AbortEsc()
~*^4:: AbortEsc()
~*^5:: AbortEsc()
~*^6:: AbortEsc()
~*^7:: AbortEsc()
~*^8:: AbortEsc()
~*^9:: AbortEsc()
~*^0:: AbortEsc()
~*^Space:: AbortEsc()
~*^Backspace:: AbortEsc()
~*^Delete:: AbortEsc()
~*^Insert:: AbortEsc()
~*^Home:: AbortEsc()
~*^End:: AbortEsc()
~*^PgUp:: AbortEsc()
~*^PgDn:: AbortEsc()
~*^Tab:: AbortEsc()
~*^Enter:: AbortEsc()
~*^,:: AbortEsc()
~*^.:: AbortEsc()
~*^/:: AbortEsc()
~*^;:: AbortEsc()
~*^':: AbortEsc()
~*^[:: AbortEsc()
~*^]:: AbortEsc()
~*^\:: AbortEsc()
~*^-:: AbortEsc()
~*^=:: AbortEsc()
~*^`:: AbortEsc()
~*^F1:: AbortEsc()
~*^F2:: AbortEsc()
~*^F3:: AbortEsc()
~*^F4:: AbortEsc()
~*^F5:: AbortEsc()
~*^F6:: AbortEsc()
~*^F7:: AbortEsc()
~*^F8:: AbortEsc()
~*^F9:: AbortEsc()
~*^F10:: AbortEsc()
~*^F11:: AbortEsc()
~*^F12:: AbortEsc()
; ===============================
; RIGHT ALT → CAPS LOCK OFF
; ===============================
*RAlt:: {
SetCapsLockState "Off"
}
; ===============================
; MANUAL RECOVERY
; ===============================
F12:: {
Send "{Ctrl up}"
global g_CtrlIsDown := false
global g_AbortSendEsc := false
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you want to run this script, you should look into AutoHotKey. in this example, you need to install the correct version of the runtime, save the script as an .auk file, and run it using the runtime.