Your Cart
Loading

Productivity Boost With AutoHotKey—Automate Your Workflow

Someone asked me sarcastically:

“Why do you use curly apostrophes and quotes in your posts and straight ones in your comments? It’s a sign that you’re using AI.”

No, Karen, it’s a sign that I write my posts in Word, and my comments in a browser.

Copied from Word: “Don’t be ridiculous.”

Typed in browser: "Don't be ridiculous."

But that made me think: there has to be a way to use correct typography without remembering all the codes.

 

I’ve already gotten used to Alt + numpad codes, e.g. 0132/0148 for Polish quotes and 0151 for em dash (yes, I used em dash for years and won’t stop just because some ignorant person will think my writing is AI-generated).

Should I try to remember also 0146 for the apostrophe or is there a simpler solution?

 

Behold: AutoHotkey (AHK)—A small program running in your system tray with custom key mapping. Light, but powerful.

Install it, paste a command into Notepad and save it as .ahk file. When you run it, it replaces a key combination or a single key with your custom command.

 

For example:

'::Send("’")  → You just press the apostrophe key ' and get curly apostrophe

^!'::Send("“")  → Pressing Ctrl+Alt+' creates opening curly quote

^+'::Send("”")  → Pressing Ctrl+Shift+' creates closing curly quote

 

You can have a long list of shortcuts and automations in one file or in separate files, running at the same time silently in the system tray, waiting for you to trigger them. You can even create several files with different sets of hotkeys and run the one that you need depending on what you are doing.

 

What else you can do with AHK? Maybe you have a 5-button mouse, but you don’t really need Forward button and wish it was Refresh button instead. No problem:

XButton2::Send("{F5}")  → Now, Forward button refreshes pages in browsers and folders

 

Other useful commands:

• Create em dash with Alt + - or just by typing three hyphens ---

• Have multiple clipboards—store several copied texts and paste them with Alt + 1, 2, 3...

• Change ALL CAPS to lower case (and vice versa).

• Autocorrect and auto-fill (corect correct; thxx Thank you for your email; etc).

• Copy-paste into a form that doesn't have a paste capability.

• Convert units on the fly. Just type 106fff and watch it being replaced with 41°C.

• Shift + Scroll Wheel for Horizontal Scrolling.

• Use one hotkey to open multiple files (e.g. StyleGuide.pdf, SubtitleEdit.exe, KNP in Google Docs, and your work folder).

• And many, many more. See some ideas in this article.

 

I compiled quite a good list of nice hotkeys and ideas on how to use AHK. I tried them personally and they really help boost my productivity.

If you’re interested, take a look at it.


Table of Contents (non-clickable, sorry, Payhip doesn’t support it—you can Ctrl+F the section name)


Useful Tips

How To Find the Specific Key Code

Special Characters and Quotation Marks

Hotstrings & Autocorrect 

App Specific Hotkeys

Website Specific

Scripts

Switch casing of selected text

Character Counter

Search WordReference

Multiple clipboards 

Multiple clipboards v2 with context menu

Toggle “Always on Top”

Edit this script in Notepad

Unit Converters

Mouse Buttons

Files And URL Addresses

Mac Users

Final Considerations

 



 

Useful Tips

• Whatever is after ; in the line is ignored, so you can use it to describe what is this action for.

• If you use too much hot keys, you won’t remember them, so they won’t help you. Keeping a list of hot keys for reference (printed or electronic) may help.

• You can download this script to see all your hot keys in a convenient GUI: https://github.com/EpicKeyboardGuy/AHKV2-The-One-GUI-to-rule-them-all

• Take advantage of the keys you don’t use anyway. Depending on your usage, this can be Pause, Scroll Lock, Insert, ` (backtick), \, etc. Use them as one-key hotkeys instead of combinations.

• If you use your mouse a lot, you can set different hotkeys to combinations of buttons, like holding left and pressing right, holding middle and double-clicking left, holding right and scrolling, holding Ctrl and right click, etc. That gives you dozens of commands with the mouse.

• You can add your script to autostart to not launch it manually.

• To easily edit the script in Notepad, find the green H icon in system tray → right click → Edit the script.

• You can use a hotkey to open several files at once, for example, a style guide, KNP, and a CAT tool. You can have a different hotkey to each client or workflow.

 

• If your shortcut interferes with a hot key in one application you use, you don’t have to remove or change it. You can exclude this one application with the command below (e.g. WINWORD.EXE for Word):

#HotIf !WinActive("ahk_exe WINWORD.EXE")

 

If you want to exclude a website, use this command (whole page title or its main part that always stays the same for all projects, like memoQWeb):

#HotIf !WinActive("memoQWeb ahk_exe chrome.exe")

 

If you provide only part of the page title, always include this line at the top:

SetTitleMatchMode 2

 

Always put closing #HotIf after the relevant script section (both exclusive and excluding):

#HotIf

 



How To Find the Specific Key Code

If you have additional keys on your keyboard and you don’t know their name (like +/- Volume), you can check it here:

1.     Run any AutoHotkey script.

2.     Right-click the green "H" icon in your system tray (by the clock).

3.     Select Open.

4.     In the menu, go to View -> Key history and script info.

5.     Press the key you want to use.

6.     Press F5 to refresh the list.

7.     Look at the bottom of the list. You will see a column for VK and SC.

For example: Space key is SC039. You can use either key name or this code.

 

 



 

Special Characters and Quotation Marks

; Non-breaking space with Ctrl+Space

^Space::Send "{U+00A0}"

; Em-dash (—) with Alt+-

!-::Send "{U+2013}"

; Ellipsis (as single character …) with Alt + . (period)

!.::Send "{U+2026}"

; Multiplication sign (×) with Alt + x

!x::Send "{U+00D7}"

; Curled apostrophe by default for ' key

'::Send("’")

 

; Guillemets («) with Alt+[

![::Send "«"

; Guillemets (») with Alt+]

!]::Send "»"

; Lower curly quote with Ctrl+Alt+' (used e.g. in Polish)

^!'::Send("„")

; Opening curly quote with Ctrl+Alt+'

^!'::Send("“")

; Closing curly quote with Ctrl+Shift+'

^+'::Send("”")

; Opening single curly quote ‘ with Ctrl + Alt + `

^!`::Send "{U+2018}"

; Closing single curly quote ’ with Ctrl + Shift + `

^+`::Send "{U+2019}"

 

Instead of above quote pairs, you can make a smart script that recognizes whether you want to open the quote or close it. There is no combination, you just type it like usually, and it changes on its own like in Word.

If there is a space (or it's the start of a line), it sends the opening quote.

If there is a letter or number, it sends the closing quote.

If you need to type "simple" quotation marks, press it with Alt key.

 

; ‘Single quotes with backtick/tilde key `:

 

; --- Smart Single Curly Quotes ---

; Press the backtick key to trigger

$`::

{

   ; Step 1: Read the character to the left

   A_Clipboard := ""

   Send "+{Left}^c"

   if !ClipWait(0.1) ; If nothing is there (start of line)

   {

       Send "{Right}{U+2018}" ; Send opening ‘

       return

   }

   

   leftChar := A_Clipboard

   Send "{Right}" ; Put cursor back in place

 

   ; Step 2: Decide which quote to use

   ; If the character to the left is a space, tab, or newline, use opening quote

   if (leftChar = " " || leftChar = "`t" || leftChar = "`r" || leftChar = "`n")

   {

       Send "{U+2018}" ; Opening ‘

   }

   else

   {

       Send "{U+2019}" ; Closing ’

   }

}

 

; --- Manual Fallbacks ---

; Press Alt + ` to type a regular backtick if you ever need one

!`::Send "``"

 

 

; “Double” with quote key (Shift + apostrophe ’):

 

#HotIf !WinActive("ahk_exe WINWORD.EXE")

; HotIf with ! means it won’t be executed in Word, since Word can handle quotes on its own.

; --- Smart Double Curly Quotes ---

; Press the quote (Shift + ‘) to trigger

$+"::  ; Shift + '

{

  savedClipboard := A_Clipboard


  ; --- Detect start of line ---

  A_Clipboard := ""

  Send("+{Home}^c")

  ClipWait(0.1)

  lineLeft := A_Clipboard

  Send("{End}")


  if (lineLeft = "")

  {

    Send("{Text}“")

    A_Clipboard := savedClipboard

    return

  }


  ; --- Inspect previous character ---

  A_Clipboard := ""

  Send("+{Left}^c")

  ClipWait(0.1)

  leftChar := A_Clipboard

  Send("{Right}")


  if RegExMatch(leftChar, "[\s\(\[\{]")

    Send("{Text}“")

  else

    Send("{Text}”")


  A_Clipboard := savedClipboard

}


; Manual fallback

; Press Alt + Shift + ’ to type a regular dumb quotation mark if you need

!+"::Send('"')

 



 

Hotstrings & Autocorrect

This is the easiest to create, so feel free to make your own autocorrect, or import from a spell checker tool. Adding the * like in the second example makes it trigger immediately without the need to press space. It’s faster, but you will never able to write the abbreviation without it being expanded.

::btw::by the way ; (typing “btw” and then space/tab replaces it with “by the way”).

:*:fyi::for your information

::/sg:: According to the Style Guide

::--::–      ; Double hyphen becomes an En Dash

::_-::—    ; underscore and hyphen become an Em Dash

::...::…     ; Three dots become a single Ellipsis character

::(c)::©     ; Copyright symbol

::(r)::®     ; Registered trademark

::trasnlation::translation ; if you often mistype a word the same way

 



 

App Specific Hotkeys

You can use the same key combination for different outcomes in different apps.

Let’s say you want to make use of the Pause/Break key, but by hardwiring it globally to a rare combination, it will be useful only in one app. But it doesn’t have to be like this.

Example:

In Photoshop, you want Pause to replace Ctrl + Alt + Shift + L (Auto Contrast).

In Word, you want it to insert a 3x3 table.

In memoQ, you want it to replace Ctrl+Shift+S (Copy Source to Target).

You can have it all at once, using #IfWinActive directive.

 

 

; --- PHOTOSHOP CONTEXT ---

#HotIf WinActive("ahk_exe Photoshop.exe")

Pause::

{

   ; Replaces Ctrl + Alt + Shift + L

   Send "^!+l"

   Tooltip "Auto Contrast Applied"

   SetTimer () => Tooltip(), -1000

}

 

; --- MS WORD CONTEXT ---

#HotIf WinActive("ahk_exe WINWORD.EXE")

; Pause: Insert a 3x3 Table

#Requires AutoHotkey v2.0

 

#HotIf WinActive("ahk_exe WINWORD.EXE")

Pause:: {

   try {

       oWord := ComObjActive("Word.Application")

       ; Create the table

       oTable := oWord.ActiveDocument.Tables.Add(oWord.Selection.Range, 3, 3)

       oTable.Borders.Enable := 1

       oTable.Borders.LineWidth := 4

       oTable.AutoFitBehavior(2)

       Tooltip "Table with Manual Borders Created"

       SetTimer () => Tooltip(), -1000

 

   }

}

 

; --- MEMOQ CONTEXT ---

#HotIf WinActive("ahk_exe memoQ.exe")

Pause::

{

   ; Attempt to send the "Copy Source to Target" shortcut

   Send("^+s")

   

   ; Visual confirmation to see if the script even fired

   Tooltip "memoQ: Copying Source..."

   SetTimer () => Tooltip(), -1000

}

 

#HotIf ; Closes the context block




 

Website Specific

Likewise, you can use a hot key for a specific website. In the example below, the Pause/Break key:

• In Blend Workbench, inserts first item from the translation memory;

• In LinkedIn, opens your posts analytics;

• In Gmail, opens Labels settings.

Please note that this is for Chrome. For other browsers, you’ll need to adapt the code respectively.

 

#Requires AutoHotkey v2.0

SetTitleMatchMode 2

 

; --- 1) BLEND / XTM WORKBENCH ---

#HotIf !WinActive("One Hour Translation") and WinActive("ahk_exe chrome.exe")

Pause::

{

   Send "!i" ; Triggers Alt+I to insert first TM version

   Tooltip "XTM: Inserting TM"

   SetTimer () => Tooltip(), -1000

}

 

; --- 2) LINKEDIN ---

#HotIf WinActive("LinkedIn") and WinActive("ahk_exe chrome.exe")

Pause::

{

   ; Opens your specific analytics page in the current tab

   Run "https://www.linkedin.com/analytics/creator/content/?metricType=IMPRESSIONS&timeRange=past_7_days"

   Tooltip "Opening LinkedIn Analytics..."

   SetTimer () => Tooltip(), -1000

}

 

; --- 3) GMAIL ---

#HotIf WinActive("Gmail") and WinActive("ahk_exe chrome.exe")

Pause::

{

   ; 1. Grab the current URL

   bak := ClipboardAll() ; Save your current clipboard

   A_Clipboard := ""

   Send "^l^c"

   if !ClipWait(1)

       return

 

   ; 2. Find the position of the first "#"

   ; We only want the part BEFORE the hash (e.g., https://mail.google.com/mail/u/2/)

   pos := InStr(A_Clipboard, "#")

   

   if (pos > 0) {

       ; Strip the old hash and everything after it

       baseUrl := SubStr(A_Clipboard, 1, pos - 1)

       newUrl := baseUrl . "#settings/labels"

   } else {

       ; If there's no hash at all, ensure there's a trailing slash and add the path

       baseUrl := RTrim(A_Clipboard, "/")

       newUrl := baseUrl . "/#settings/labels"

   }

 

   ; 3. Navigate

   Send "^l"

   Sleep 50

   A_Clipboard := newUrl

   Send "^v{Enter}"

   

   ; Restore original clipboard after a short delay

   SetTimer () => (A_Clipboard := bak), -500

   

   Tooltip "Opening Labels for Profile " . (RegExMatch(newUrl, "/u/(\d+)/", &m) ? m[1] : "?")

   SetTimer () => Tooltip(), -1500

}

#HotIf

 



 

Scripts

 

; Press Alt+C to switch casing of selected text

!c::

{

   A_Clipboard := ""

   Send "^c"

   ClipWait(2)

   static mode := 0

   if (mode = 0) {

       A_Clipboard := StrUpper(A_Clipboard)

       mode := 1

   } else if (mode = 1) {

       A_Clipboard := StrLower(A_Clipboard)

       mode := 2

   } else {

       A_Clipboard := StrTitle(A_Clipboard)

       mode := 0

   }

   Send "^v"

}



; Character Counter

; Usage: mark a text and press Ctrl + Shift + / (the physical key for ?)

; It shows a small label (tooltip) for 4 seconds with chars with spaces and chars without spaces

^+/::

{

  savedClip := ClipboardAll()

  A_Clipboard := ""

  Send("^c")

   

  if !ClipWait(0.4)

  {

    ToolTip("No text selected!")

  }

  else

  {

    ; Count characters with spaces

    fullCount := StrLen(A_Clipboard)

     

    ; Count without spaces for reference

    noSpaceCount := StrLen(StrReplace(A_Clipboard, " ", ""))

     

    ToolTip("Chars (with spaces): " fullCount "`nChars (no spaces): " noSpaceCount)

  }

   

  ; Hide tooltip after 4 seconds

  SetTimer(() => ToolTip(), -4000)

   

  ; Restore original clipboard content

  A_Clipboard := savedClip

}

 



; Highlight text and press Ctrl+Shift+S to search WordReference

^+s::

{

   A_Clipboard := "" ; Clear clipboard

   Send "^c" ; Copy selected text

   if ClipWait(2)

   {

       Run "https://www.wordreference.com/enpl/" . A_Clipboard ; Change 'enpl' to your language pair

   }

}

 



; Multiple clipboards

; It remembers multiple copied phrases WITHOUT AFFECTING YOUR REGULAR CLIPBOARD

; Use the number row, not num pad

 

SetTitleMatchMode 2

 

; Initialize an empty Map (Dictionary) to store your snippets

clips := Map()

 

; --- HOTKEYS TO SAVE (Ctrl + 1, 2, 3...) ---

^1::SaveToVar(1)

^2::SaveToVar(2)

^3::SaveToVar(3)

; add more if you need

 

; --- HOTKEYS TO PASTE (Alt + 1, 2, 3...) ---

!1::PasteFromVar(1)

!2::PasteFromVar(2)

!3::PasteFromVar(3)

 

SaveToVar(index) {

   global clips

   oldClip := A_Clipboard       ; Backup current clipboard

   A_Clipboard := ""            ; Clear clipboard

   Send "^c"                    ; Copy selection

   if ClipWait(1) {

       clips[index] := A_Clipboard ; Store selection in our Map

   }

   A_Clipboard := oldClip       ; Restore original clipboard

}

 

PasteFromVar(index) {

   global clips

   if clips.Has(index) {

       ; Using {Text} mode prevents symbols from breaking the script

       Send "{Text}" . clips[index]

   }

}



; Multiple clipboards v2 with context menu

; Initialize our Map

clips := Map()


; --- HOTKEYS TO SAVE (Ctrl + 1, 2, 3...) ---

^1::SaveToVar(1)

^2::SaveToVar(2)

^3::SaveToVar(3)

^4::SaveToVar(4)

^5::SaveToVar(5)

^6::SaveToVar(6)

^7::SaveToVar(7)

^8::SaveToVar(8)

^9::SaveToVar(9)

^0::SaveToVar(0)


; --- VISUAL PASTE (Ctrl + Middle Mouse/Wheel Click) ---

^MButton::ShowClipboardMenu()


SaveToVar(index) {

  global clips

  oldClip := ClipboardAll()

  A_Clipboard := ""

  Send("^c")

  if ClipWait(0.6) {

    clips[index] := A_Clipboard

    ToolTip("Saved to Slot " index)

    SetTimer(() => ToolTip(), -1000)

  }

  A_Clipboard := oldClip

}


ShowClipboardMenu() {

  global clips

  MyMenu := Menu()

   

  ; If map is empty, show a single disabled info line

  if clips.Count = 0 {

    MyMenu.Add("(No slots filled)", (*) => "")

    MyMenu.Disable("(No slots filled)")

  } else {

    for index, content in clips {

      ; Create preview: limit to 50 chars and remove newlines

      preview := StrReplace(SubStr(content, 1, 50), "`n", " ")

      itemLabel := "Slot " index ": " preview ""

       

      MyMenu.Add(itemLabel, MenuHandler.Bind(index))

    }

  }

   

  MyMenu.Show()

}


MenuHandler(index, *) {

  if clips.Has(index) {

    Send("{Text}" . clips[index])

  }

}

 



 

; Press Ctrl+Alt+A to toggle “Always on Top” for the active window

; This prevents a window to disappear every time you click. Use this to pin any window.

^!a:: WinSetAlwaysOnTop -1, "A"

 



; Press Ctrl + Alt + 0 to edit this script in Notepad (it’s ready like this, you don’t need to provide the path)

^!0::

{

   Run "notepad.exe `"" . A_ScriptFullPath . "`""

}

 

 



; Paste (type) into applications and forms that don't have a paste capability.

 

; ----------------------

; Paste clipboard content (fast)

; ----------------------

 

; Alt + V

!v::

{

   if (A_Clipboard != "")

   {

       SendInput "{Text}" . A_Clipboard

   }

}

 



; ----------------------

; Type clipboard content (slow, if the first one fails)

; ----------------------

   ; Typing at speed of 30 ms/character

   ; With a warning about long text and an emergency kill switch

 

; Alt + V

!v::

{

   clipText := A_Clipboard

   charCount := StrLen(clipText)

 

   if (charCount = 0)

       return

 

   estimatedSeconds := Round((charCount * 30) / 1000, 1)

 

   ; Warning for passages longer than 300 characters

   if (charCount > 300) {

       msgText := "Warning: Long text detected.`n`n"

                . "Characters: " . charCount . "`n"

                . "Estimated time: " . estimatedSeconds . " seconds.`n`n"

                . "Do you want to proceed?"

       

       if (MsgBox(msgText, "Long Paste Warning", "Icon! 4") = "No")

           return

   }

 

   Tooltip "Typing... (Press Ctrl+Esc to ABORT)"

   

   ; Change "SendEvent" to "SendInput" to paste it immediately instead of typing

   Loop Parse, clipText

   {

       SendEvent "{Text}" . A_LoopField

   }

   

   Tooltip "Done!"

   SetTimer () => Tooltip(), -1000

}

 

; THE EMERGENCY ABORT BUTTON

^Esc::

{

   Reload()

}

 

 



Unit Converters

 

; =================================

; Fahrenheit to Celsius Converter (F > C)

; =================================

; Usage: Type a number followed by 'fff' (e.g., 32fff) and hit space

; Works only with whole numbers! No decimal points! 32fff, not 32.5fff

 

:?:fff::

{

   ; 1. Copy the number to the left

   A_Clipboard := ""

   Send("^+{Left}^c")

   if !ClipWait(0.5)

       return

 

   num := A_Clipboard

   

   ; 2. Check if it's actually a number

   if IsNumber(num)

   {

       ; Formula: (F - 32) * 5/9

       celsius := Round((Number(num) - 32) * 5 / 9)

       Send("{Text}" . celsius . "°C")

   }

   else

   {

       ; If not a number, just put the text back

       Send("{Right}ff")

   }

}


; =================================

; Miles to Kilometers Converter (mi > km)

; =================================

; Usage: Type a number followed by 'mi' (e.g., 50mi) and hit space

; Works only with whole numbers! No decimal points! 50mi, not 50.5mi

 

:?:mi::

{

   A_Clipboard := ""

   Send("^+{Left}^c")

   if !ClipWait(0.5)

       return

 

   num := A_Clipboard

   if IsNumber(num)

   {

       ; Formula: Miles * 1.609

       km := Round(Number(num) * 1.609, 1)

       Send("{Text}" . km . " km")

   }

   else

   {

       Send("{Right}mi")

   }

}

 

; =================================

; USD to EUR converter with today’s rates

; =================================

; Usage: Type a number followed by 'usd>' (e.g., 510usd>) and hit space

; The rate is from open.er-api.com (updated daily)

; Duplicate and adjust the code to use other currencies

; Works only with whole numbers! No decimal points! 5usd>, not 5.10usd>

 

global CurrentEurRate := 0

global LastFetchTime := 0

 

:?:usd>::

{

   global CurrentEurRate, LastFetchTime

   

   ; 1. Grab the number to the left

   savedClipboard := A_Clipboard ; Backup current clipboard

   A_Clipboard := ""

   Send("^+{Left}^c")

   if !ClipWait(0.5) {

       A_Clipboard := savedClipboard

       return

   }

   

   valUSD := A_Clipboard

   if !IsNumber(valUSD) {

       Send("{Right}usd>")

       A_Clipboard := savedClipboard

       return

   }

 

   ; 2. Fetch the rate (Open ER API)

   currentTime := A_TickCount

   if (CurrentEurRate = 0 || (currentTime - LastFetchTime > 3600000)) {

       try {

           whr := ComObject("WinHttp.WinHttpRequest.5.1")

           whr.Open("GET", "https://open.er-api.com/v6/latest/USD", true)

           whr.Send()

           whr.WaitForResponse()

           

           if (whr.Status == 200 && RegExMatch(whr.ResponseText, '"EUR":(\d+\.\d+)', &match)) {

               CurrentEurRate := Float(match[1])

               LastFetchTime := currentTime

           } else {

               throw Error("API Error")

           }

       } catch {

           CurrentEurRate := 0

           Send("{Text}ERROR")

           A_Clipboard := savedClipboard

           return

       }

   }

 

   ; 3. Calculate and Format

   resEUR := Round(Number(valUSD) * CurrentEurRate, 2)

   ; Ensure we always have two decimal places (e.g., 10,50 instead of 10,5)

   formattedRes := Format("{:0.2f}", resEUR)

   formattedRes := StrReplace(formattedRes, ".", ",") . " €"

   

   ; 4. Stable Delivery

   A_Clipboard := formattedRes

   Sleep 50 ; Tiny pause to let the clipboard settle

   Send "^v"

   

   ; Restore original clipboard after a short delay

   SetTimer () => (A_Clipboard := savedClipboard), -500

   

   Tooltip "Rate: 1 USD = " . CurrentEurRate . " EUR"

   SetTimer () => Tooltip(), -2000

}

 

 



 

Mouse Buttons

 

; ---------------------------------------------------------

; Forward button refreshes pages in browsers and folders

; ---------------------------------------------------------

XButton2::Send("{F5}")

 



; ---------------------------------------------------------

; Switch tabs in browsers and folders

; ---------------------------------------------------------

; Hold one mouse button and tap the other to cycle through tabs to left or to right

RButton & LButton::Send('^+{Tab}')

~LButton & RButton::Send('^{Tab}')

RButton::Click "Right"


              

; ---------------------------------------------------------

; Switch between 2 program windows

; Hold middle mouse button and click left button

; to switch two windows without displaying thumbnails

; ---------------------------------------------------------

 

MButton & LButton::

{

   ; Get all windows

   ids := WinGetList()

   activeID := WinExist("A")

   

   foundActive := false

   

   for thisID in ids {

       ; 1. Find the current active window in the list

       if (thisID == activeID) {

           foundActive := true

           continue ; Skip the current window

       }

       

       ; 2. Once we've skipped the active one, check the NEXT ones for:

       if (foundActive) {

           style := WinGetStyle("ahk_id " thisID)

           title := WinGetTitle("ahk_id " thisID)

           

           ; 0x10000000 is WS_VISIBLE. We also check if it has a title

           ; and isn't a "hidden" system window.

           if (style & 0x10000000) && (title != "") {

               

               if WinGetMinMax("ahk_id " thisID) = -1

                   WinRestore("ahk_id " thisID)

               

               WinActivate("ahk_id " thisID)

               

               Tooltip "Switched to: " . title

               SetTimer () => Tooltip(), -1000

               return ; Stop once we found the first valid background window

           }

       }

   }

}

 

; Standard Right Click behavior

RButton::

{

   if !KeyWait("RButton", "T0.2")

       return

   Click "Right"

}

 

 



; ----------------------

; Shift + Scroll Wheel for Horizontal Scrolling

; ----------------------

 

+WheelUp::

{

   Loop 1 ; Increase this number for faster scrolling

       Send "{WheelLeft}"

}

 

+WheelDown::

{

   Loop 1 ; Increase this number for faster scrolling

       Send "{WheelRight}"

}

 




Files And URL Addresses

 

; --- NETFLIX POLISH STYLE GUIDE ---

; Alt + Insert

!Insert::

{

   Run "https://partnerhelp.netflixstudios.com/hc/en-us/articles/216787928-Polish-Timed-Text-Style-Guide"

   Tooltip "Opening Netflix Polish Guide..."

   SetTimer () => Tooltip(), -1500

}

 



 

; --- OPEN YOUR WORKFLOW FOR SUBTITLES ---

; Alt + Scroll Lock opens multiple files

!ScrollLock::

{

   ; 1. Path Definitions (Edit these for your real setup)

   styleGuide := "D:\Clients\Disney\StyleGuide.pdf"

   subtitleExe := "C:\Program Files\Subtitle Edit\SubtitleEdit.exe"

   knpDocUrl := "https://docs.google.com/document/d/1A2b3C4d5E6f7G8h9I0j/edit"

   workFolder := "D:\Clients\Disney\ActiveProjects"

 

   ; --- EXECUTION ---

 

   ; Open Style Guide PDF

   if FileExist(styleGuide)

       Run(styleGuide)

   else

       msg .= "PDF missing, "

 

   ; Open Subtitle Edit

   if FileExist(subtitleExe)

       Run(subtitleExe)

   else

       msg .= "Subtitle Edit missing, "

 

   ; Open Folder

   if DirExist(workFolder)

       Run(workFolder)

   else

       msg .= "Folder missing, "

 

   ; Open Google Doc (Launches in default browser)

   Run(knpDocUrl)

 

   ; --- FEEDBACK ---

   if IsSet(msg) {

       Tooltip "Workflow started with warnings: " . msg

   } else {

       Tooltip "Full Workflow Loaded!"

   }

   

   SetTimer () => Tooltip(), -4000

}

 

 


 

 

Mac Users

Okay, but all this is for Windows only.

If you use macOS, you may take a look at these customization options:

 

https://karabiner-elements.pqrs.org/

https://verityj.github.io/2023/06/17/eject.html

https://github.com/LakshmanTurlapati/ProKeys

 



 

Final Considerations

 

• Mind the existing hot keys, custom combinations can cause conflicts.

• You can use Gemini or ChatGPT to create scripts for you. Describe what you want to do with what keys, and ask it to write a script for AKH v2. If it won’t work like intended, describe the results or error, and your LLM should be able to make corrections to fit your needs (not always).

• If you use the script to turn ' and " into ‘ ’ and “ ”, you may want to turn it off whenever you have to modify or write HTML (or other) code, including the scripts.

• If you use scripts from the internet, they could potentially log what you copy (passwords, private data) and send it to somebody else. So always inspect before use.

• If you use your computer for gaming, you could get banned from a game just for having the script running in the background, because it can potentially give you unfair advantage in the game.

• Avoid remapping standard Windows shortcuts like Ctrl+C, Ctrl+V, or Alt+Tab unless you are adding a very specific #HotIf wrapper.

 


Do you like sharing useful tips? I do!

That’s why I spent a year crafting my ebooks that can make a big change in your work as a translator.

Check them out! 👇

About Me

I’m Konrad Jaworski, a freelance translator specializing in subtitling, audiovisual localization, and language quality assurance. With over 13 years of experience—full of trials, errors, successes, and a few worn-out keyboards—I’ve reached a point where I can confidently help others build their dream careers. And yes, that includes you!