AutoHotkey v1 script for Claude, ChatGPT using Firefox and Chrome

I've been using Claude and ChatGPT a lot the past few months, but it's always irked me that ENTER means "send" and not "newline", whereas SHIFT-ENTER means "newline". My muscle memory from years of other apps just doesn't like that.

So I got both sites to help write a script for AutoHotkey v1.x that reverses that set of keystrokes, limited to Firefox and Chrome, and limited to their specific web pages. Both AI engines had a difficult time figuring out those limitations and so they parse the URL of the page you are on in a browser to determine if ENTER and SHIFT-ENTER should be swapped. I realize that this is a very narrow issue and totally depends on user preference, but I thought I might save someone some effort.

Below are the Firefox and Chrome macros and a helper function.

;===================================================================
; Macros Specific to Firefox and Chrome
;===================================================================
#NoEnv
SendMode Input
#SingleInstance force

; --- Cache vars ---
global __url_lastCheckTick := 0
global __url_lastResult := ""
global __url_cacheMs := 5000

; --- Firefox hotkeys ---
#IfWinActive ahk_exe firefox.exe
Enter::
    url := GetCurrentURL()
    if (RegExMatch(url, "i)(claude\.ai|chatgpt\.com|chat\.openai\.com)"))
        SendInput, +{Enter}
    else
        SendInput, {Enter}
return

+Enter::
    url := GetCurrentURL()
    if (RegExMatch(url, "i)(claude\.ai|chatgpt\.com|chat\.openai\.com)"))
        SendInput, {Enter}
    else
        SendInput, +{Enter}
return
#IfWinActive

; --- Chrome hotkeys ---
#IfWinActive ahk_exe chrome.exe
Enter::
    url := GetCurrentURL()
    if (RegExMatch(url, "i)(claude\.ai|chatgpt\.com|chat\.openai\.com)"))
        SendInput, +{Enter}
    else
        SendInput, {Enter}
return

+Enter::
    url := GetCurrentURL()
    if (RegExMatch(url, "i)(claude\.ai|chatgpt\.com|chat\.openai\.com)"))
        SendInput, {Enter}
    else
        SendInput, +{Enter}
return
#IfWinActive

GetCurrentURL() {
    global __url_lastCheckTick, __url_lastResult, __url_cacheMs
    now := A_TickCount
    
    if (now - __url_lastCheckTick < __url_cacheMs)
        return __url_lastResult
    
    __url_lastCheckTick := now
    ClipSaved := ClipboardAll
    Clipboard := ""
    SendInput, ^l
    Sleep, 80
    SendInput, ^c
    ClipWait, 0.8
    url := Clipboard
    SendInput, {Esc}
    Sleep, 15
    Clipboard := ClipSaved
    
    __url_lastResult := Trim(url, " `t`r`n")
    return __url_lastResult
}