Skip to content

Instantly share code, notes, and snippets.

@volks73
Created September 26, 2017 14:47
Show Gist options
  • Select an option

  • Save volks73/1e889e01ad0a736159a5d56268a300a8 to your computer and use it in GitHub Desktop.

Select an option

Save volks73/1e889e01ad0a736159a5d56268a300a8 to your computer and use it in GitHub Desktop.
AutoHotkey script to change Caps Lock to Control on hold and Escape on press and release
; Change Caps Lock to Control when held down; otherwise, Escape
;
; Originally based on the answer provided in
; [this](https://superuser.com/questions/581692/remap-caps-lock-in-windows-escape-and-control)
; StackExchange SuperUser question.
;
; A shortcut should be created for this script and placed in the Windows 10
; user's startup folder to automatically enable the feature on boot/startup.
; The user's startup folder can be found using the following steps:
;
; 1. Windows Key+R. The _Run_ dialog will appear.
; 2. Enter the following: `%appdata%\Microsoft\Windows\Start Menu\Programs\Startup`
; 3. Press Enter key. A file explorer dialog will appear.
;
; Obviously, [AutoHotkey](https://autohotkey.com/) must be installed for this to work.
*CapsLock::
Send {Blind}{Ctrl Down}
cDown := A_TickCount
Return
*CapsLock up::
If ((A_TickCount-cDown)<400) ; Modify press time as needed (milliseconds)
Send {Blind}{Ctrl Up}{Esc}
Else
Send {Blind}{Ctrl Up}
Return
@KevinNitroG
Copy link

That is for capslock and control not control and escape.

yes, I said that in the first place 🫣

@abzalmyrzash
Copy link

abzalmyrzash commented Dec 19, 2025

For some people like me, the above scripts may not work, because it seems that Caps Lock gets repeated when it is held, therefore the timer gets reset every 50 milliseconds or so. So I wrote this:

capsLockTime := 0
capsLockIsDown := false

*CapsLock::
{
	global capsLockIsDown
	global capsLockTime
	Send "{Blind}{LControl down}"
	if (!capsLockIsDown) {
		capsLockTime := A_TickCount
		capsLockIsDown := true
	}
}

*CapsLock up::
{
	global capsLockIsDown
	if (capsLockIsDown) {
    	Send "{Blind}{LControl Up}"
		global capsLockTime
		if (A_TickCount - capsLockTime < 200) { ; modify time here
			Suspend "1"
			Send "{Esc}"
			Suspend "0"
		}
		capsLockIsDown := false
	}
}

Maybe someone could make it shorter or something (I am new to AHK myself), but it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment