1. 53

  2. 11

    I also love AutoHotKey. I feel it’s what the Windows Scripting Host should have been. It’s one of those languages, like Perl, that you can use to create anything from a simple one-line command to an advanced graphical application. For example, here is a graphical screen resolution manager I’ve built using only AutoHotKey.

    1. 4

      Direct link to that program’s source code, so you can see what advanced AutoHotkey code is like: drm.ahk v1.4.2

      1. 1

        I realized I forgot to mention one of the best things about AutoHotKey: the included documentation is phenomenal. For anyone wanting to get started, it’s available online here: https://www.autohotkey.com/docs/AutoHotkey.htm

      2. 9

        This is essentially the same argument that Tom Scott made in his video ‘The Art of the Bodge’ [1]. I remain sceptical that better solutions could not be achieved in Linux, but at the end of the day it’s about what tools work for you.

        [1] https://www.youtube.com/watch?v=lIFE7h3m40U

        1. 2

          That was a fantastic listen and you should submit it as an actual article.

          1. 2

            It was a great video. I can relate to the why’s and benefits of bodging.

            Although, I have to say that bodging the safety-critical situation they did the way they did was the most opposite of all high-assurance principles I’ve seen in production in a while. Glad it worked out. I’d have probably drawn the bodging line there switching to cheap and lazy approaches that were extra careful.

            1. 3

              one of my more.. dubious of bodgings with durden went something like this:

              /global/settings/timers/periodic/add=yeah:1=/global/display/region/ocr=0,0,300,100 /global/settings/timers/periodic/add=dont:60=/windows/group/remote/clipboard/paste

              now, hypothetically, there might have been an RSA SecureID token hanging in front of a webcam ..

          2. 2

            I expect the lack of a standard GUI API on Linux would make something like AutoHotKey more difficult to achieve. AHK relies a lot on low level aspects of the Windows API to select windows, activate them, send them messages, send keys, read the clipboard, etc. I would think that would be more complex to do in Linux.

          3. 4

            Yeah, AutoHotkey was great when I was using Windows.

            On macOS, I have managed to set up equivalents to many of AutoHotkey’s features. Here are the programs I used to do it, and how I could use them to solve your use-cases:

            AutoHotkey equivalent

            The closest equivalent to AutoHotkey in general is Keyboard Maestro (currently $36), a proprietary app. In Keyboard Maestro, you define macros using a drag-and-drop scripting language. You can also embed shell scripts or AppleScript. Each macro can have a number of triggers, most commonly Hot Key triggers.

            (Keyboard and) mouse shortcuts

            Keyboard Maestro’s triggers can associate custom shortcuts with your macros. Most of my macros have Hot Key triggers, which capture to keyboard shortcuts. For example, Shift+Ctrl+S triggers a macro that puts my laptop screen to sleep.

            However, to respond to a mouse input like Scroll Wheel Left, you would have to use a Device Key trigger. A Device Key trigger responds to a single device input, but sadly, it doesn’t block the input from being passed to the OS. In this example, whatever your cursor is over would scroll left in addition to the macro being activated.

            To replicate the Send, {NumpadAdd} part of your script, you would add a Type a Keystroke block to your macro. One nice thing about KeyboardMaestro is it can record the keystroke, so you don’t have to remember names like “NumpadAdd”.

            If you don’t want to buy Keyboard Maestro, macOS’s built-in Automator (free) can be used in some cases. For examples, compare these three solutions for working around bad default ⌘C behavior in Books: my simple Keyboard Maestro solution, someone’s straightforward Automator solution, and my shorter, situation-specific Automator solution.

            Hotstrings for math

            I used to use TextExpander (currently $40/year) for something like this. I had ddate mapped to the current date, and solang marked to a block of markup I used on Stack Overflow. TextExpander implements the direct equivalent to AutoHotkey hotstrings, and is probably the best way to implement short hotstrings like ;a.

            However, for my purposes, I realized that I could insert pieces of text more simply by using another program I was already using: LaunchBar (currently $30). While its most obvious feature is launching applications, one of its many other features is inserting text snippets. You define text snippets by putting text files in a certain folder. Your defined snippets are then added to your global list of searcheable items, alongside applications you can open and so on.

            To insert a snippet such as the current date using LaunchBar, I open a LaunchBar window with Command-Space, type date to find the “Current Date (ISO format)” snippet, and press Return to insert it.

            Also note that macOS makes typing special characters easier in general. All macOS keyboard layouts let you access an alternate layer of characters by holding Option. For example, Option-8 types ‘•’. If you would rather Option-A typed ‘∀’ instead of ‘å’, you could set that up by defining a custom math-focused keyboard layout with Ukelele (free). I have used Ukelele to define my own keyboard layout “U.S. – Rory custom” that makes smart quotes and apostrophes (“”‘’) easier to type.

            Markdown links

            You could do this with Keyboard Maestro. It has actions for reading from and writing to the clipboard, and for appending to, prepending to, and searching and replacing in text variables.

            Just a few days ago I implemented a Vim editor mapping to do a similar thing: turn the selected text into a link with the clipboard used as the URL. Of course, it only works in Vim. Here’s the source:

            " create Markdown link from selected text using URL in clipboard
            " uses vim-surround, so can’t be vnoremap
            vmap <Leader>ml s]%a()<Esc>"*Pl
            Fast Window Switching

            I used to have something set up for this. I used Karabiner (formerly KeyRemap4MacBook) to map my fn key to the combination of Shift-Control-Option-Command. Then, with Keyboard Maestro, I mapped ⇧⌃⌥⌘F to open the Finder and so on. That let me type fn+F to switch directly to the Finder.

            Karabiner was forced to be rewritten as Karabiner-Elements (free and open source) because of changes in macOS, and it lost some features in the process. I haven’t checked if mapping of fn is one of them. I don’t use Karabiner-Elements because I rarely used my fn mappings and my current model of laptop doesn’t have real function keys to remap.

            As for window groups to switch within, Keyboard Maestro doesn’t have a built-in concept like that. I think you could implement it, though – “if” statements can check the app of the current window.

            Remapping the calculator button

            This would be a straightforward application of Keyboard Maestro.


            Same as above.

            That covers everything in your article as much as macOS software is capable of. You may also be interested in…

            Features I use without equivalents in this article

            Keyboard Maestro lets you define a Quick Macro – a sequence of keypresses and clicks. I can press Ctrl-F1 to start recording, execute a sequence, then press Ctrl-F1 to stop recording. After that, Option-F1 will run the sequence. I use this, for example, in my browser to scroll many adjacent newly-opened tabs down to the start of the content, by recording and replaying the sequence Ctrl-Tab, Down, Down, Down, etc.

            Keyboard Maestro also supports image recognition for clicking on the screenshotted GUI element or waiting for something to appear on the screen. I’ve used this to make a macro that uses the System Preferences GUI to toggle a setting – it decides whether to move the selection up or down by recognizing the image of the currently-selected preference. I’ve also used it to abort a macro if I don’t see the expected window open after a certain step (which could happen if the GUI was in a certain state), to avoid executing further keypresses in the wrong window.

            LaunchBar comes with a built-in clipboard history manager. I use this to copy, for example, both a title and URL in one window, knowing they will be saved. Then, after switching to another window, I use the clipboard history to paste both of them where they need to go.

            1. 1

              Thank you for this! I basically use OS-X in anger (provided corporate fully “all sliders to the right” 16” Macbook Pro) but after a lot of work, have only gotten it to be – “painful” instead of “incredibly painful” compared to using my Linux rig.

              I soon will explore more of the tools you linked, a lot of tools to do what I used to be able to do with just autohotkey, but beggars and choosers.

            2. 4

              On linux I tend to use a lot of xdotool and xclip with window manager bindings to get similar results.

              1. 1

                I use Linux as my daily driver, and I have a few xdotool scripts that sort of work, but none of them feel great. They feel extremely poor compared to what I do with Autohotkey on windows. An example of one that was very easy on windows that I got … sort of working is sending a mute command (m) to slack video/audio meetings, but I can’t prove this isn’t differences in how the app works on Linux… doesn’t seem to accept the “m” unless focused.

                But, all in all, I have yet to come anywhere near the quality of life improvements I got from Autohotkey on Linux.

                1. 1

                  I see, thanks for the example. I guess windows provides greater introspection into UI controls.

              2. 4

                I love AHK too.

                To me, this is part and parcel of the larger problem of providing really deep end user application scripting for the desktop.

                Apple has gone a long way towards this (Though it appears they may have given up the ghost recently), and so has MIcrosoft (although they’ve been hampered by several different mechanisms).

                Ultimately, I really love the idea of both operating system and applications exposing various blobs of functionality as verbs which can be invoked by scripts to create custom workflows.

                The problem is that this requires a great deal of work by application developers, and a lot of app devs simply aren’t willing to do the heavy lifting for the 1% of the end user base like us who cares :)

                1. 2

                  I have this script for writing all accented characters in Spanish, French and German to my heart’s content, after being annoyed by standard international layouts https://gist.github.com/danidiaz/583824e50e3667ab50963cc30c7df0ec#file-acentos-ahk

                  I also use AutoHotKey to switch Ctrl and CapsLock in a work laptip for which I don’t have administrator rights.

                  1. 2

                    I use Linux but have something similar setup:

                    • this script

                      • switches to window if another program is focused;
                      • creates a new process if program is not running and switches to that;
                      • switches to the next open window of the same program if program is already focused

                      bound to F5 for

                      ./this-script Gnome-terminal gnome-terminal

                      and F2 for Firefox, F3 for IDEA etc..

                    • another script bound to F4 that, when Firefox is focused, launches a menu like this: https://imgur.com/a/wuoXYRj (it also offers “subscribe to feed” when there’s a RSS/atom feed in the page’s source (hint @pushcx there aren’t links to feeds on the story page). This has been a time sink, just as @hwayne writes, about delaying some time here and there, but it allows me to add feeds to my feeds.org file and bookmarks in a custom format to another org file.

                    • a variant of the first script bound to F1 that opens/focuses emacs, but makes sure the window is maximized

                    All in all, I think the commit rate for my dotfiles repo has went down a ton, since switching to stock Ubuntu after years of fiddling with i3 and awesomewm. This article by Xah Lee made me try out the “bind function keys to applications instead of using workspaces”, and I really like it so far:

                    1. 2

                      I also use a similar setup, but with https://github.com/mkropat/jumpapp instead of manually written scripts.

                      1. 1

                        This is great, I used AutoHotkey to do the exact same thing on windows, and haven’t bothered to setup an equivalent on Linux.

                      2. 1

                        Xah Lee is… impenetrable (and about that section: F-keys intrudes on terminal emulation for programs I require, so), so I’ll just throw out that people were fed up of tiling window management in the 1980s with things like GEM 2 (when Apple sued them) and Windows 1.0, and wanted floating windows. Feels like an amusing regression, eh? (I remember Nathan Lineback’s GUI site made frequent commentary about that…)

                        1. 2

                          Xah Lee is… impenetrable

                          That’s an extremely charitable way to describe the uninformed, egocentric vitriol he puts on his site!

                          1. 2

                            I don’t know, I think it’s just his opinions. I always appreciate reading them.

                            1. 1

                              The entire mechanical keyboard community is like that though. I have stories about that…

                              1. 1

                                I don’t think everyone is. What counts as “the community”? I’m a huge fan of mechanical keyboards and tiling window managers both, and I put a fair bit of effort into trying to be decent to folks – even those who use rubber domes and enjoy the clicky approach to user interfaces. I know lots of people who are the same. I suppose on that basis we’re not notorious though, like Xah Lee or the authors of certain window managers.

                                1. 1

                                  More the cult of personality and drama the administrator of the Reddit group has created over the years there and on other keyboard sites, but I’ll restrain from going too deep about that.

                                  1. 1

                                    Fair enough. There are certainly lots of toxic subreddits and comparative fora!

                            2. 1

                              I’ll just throw out that people were fed up of tiling window management in the 1980s with things like GEM 2 (when Apple sued them) and Windows 1.0, and wanted floating windows.

                              We’re seeing that today too on iPadOS - people have been begging for floating windows since day one.

                              1. 2

                                I’ll just throw out that people were fed up of tiling window management in the 1980s with things like GEM 2 (when Apple sued them) and Windows 1.0, and wanted floating windows.

                                We’re seeing that today too on iPadOS - people have been begging for floating windows since day one.

                                It seems to be different sets of people. If I have paper on my desk, it is always spread out everywhere and I use spatial memory to find things. This gets progressively worse after about 20 things and eventually I can’t find anything at all. I use my computer in a similar way. I have a lot of overlapping windows open, typically 2-3 that I’m referring to at any given time and switching between things by pulling windows out from behind others.

                                Most other people that I’ve seen; however, run one window maximised. Then they switch to another. Occasionally, they’ll have two windows tiled side-by-side. I find that I move to this workflow when the screen is small. I have a 13” and a 15” laptop and use maximised windows most of the time on the 13” screen, sometimes on the 15” screen, and rarely on the 40” display on my work desktop.

                                I suspect tiling window managers appeal to people who are more tidy than me…

                              2. 1

                                F-keys are not a necessity IMO, it’s just the pattern of having a single-ish (hwayne’s post mentions “pressing rightalt+1 will immediately switch to Firefox”) shortcut for an application (or the “mini FSM” of “if the application is already running, but not focused…”) that I find really useful. It would have killed the need for alt+tab like navigation years ago if I’d thought out about it earlier.

                                edit: I think “pressing keys to focus an application” and “tiling (vs floating?) WM” are orthogonal items and my post did not wish to emphasize that at all. One could very well like a tiling WM without using “application hotkeys” (I did for a long time). Sorry about linking to Xah Lee, I guess.

                                1. 2

                                  In my case, F-Keys won’t work because:

                                  F3=Exit   F4=Prompt   F9=Retrieve   F12=Cancel   F13=Information Assistant
                                  F23=Set initial menu                                                      

                                  That’s why I prefer “system has a modifier to itself” - usually Super.

                            3. 2

                              Wow, I’m reading a lot of mac equivalents for the features afforded by AutoHotKey but I’m surprised no one has mentioned Alfred (£25).

                              The downside of Alfred is that its drag-and-drop-blocks automation feature, Alfred Workflows, relies on integration with other apps. This means you need BetterTouchTool to bind your mouse/trackpad/remote, and you need to know bash/zsh/ruby/python/anything to actually get things done.

                              The upside of Alfred is that it’s really easy to pick up. In short, you write scripts that take in argv and spit out stdout. Then you have Alfred handle the rest, i.e. passing outputs to inputs and binding hotkeys.

                              Yea there’s a whole library of cool blocks, but (since I prefer bash) pretty much all of my workflows look like

                              [hotkey block] --> [bash script block]

                              You don’t need to learn another language for automation. I’m only drawing from bash knowledge, but that’s enough to bind these bash one-liners with minimal learning and effort:

                              • a hotkey to draw a Graphviz or mermaid.js graph from highlighted code. [Hotkey block] sends currently highlighted text to [bash block], which saves it to /tmp, pipes through dot or mermaid.js, and opens the results in your favorite image viewer
                              • a hotkey to compile and run code you’ve highlighted. [Hotkey block] sends currently highlighted text to [bash block], which saves it to /tmp, pipes through gcc, runs, and opens the results in your favorite text editor.
                              • a hotkey to run OCR on the clipboard and paste the result. [Hotkey block] sends current clipboard contents to [bash block], which pipes the clipboard image through your favorite OCR command to stdout, and sends that to a [clipboard paste block].

                              The key in “handling the rest” that I couldn’t find in any other automation software, is offering lots of control over inputs and outputs between blocks. Instead of argv, you can pass data into a block via straight up text replacement into the bash script block, controlling what characters get escaped. Or store it in a variable, or log it to a nice debug console, or pass it to another workflow… I find this level of control in “handling the rest” to be incredibly important, since the last thing I want to learn is how to stop my automator from escaping backslashes or utf-8-garbaging my outputs.

                              tl;dr as far as automation software goes, I’ve found Alfred Workflows to be dead easy to pick up since it leverages your existing knowledge and offers the least surprise

                              1. 1

                                I use alfred… although, i must with some embarrassment admit that I mostly use it just so I can type this: ¯\_(ツ)_/¯

                              2. 2

                                When the author mentioned playing with the clipboard when making Markdown links, I was reminded of a program I wrote years ago under Linux. If I highlighted a portion of a webpage in Firefox, I would use the X selection protocol to query for the text/html target of the selection (which returns the HTML of the highlighted portion of the page) and then for the text/x-moz-url-priv target to get the URL of the page. The X selection mechanism is probably more powerful than people realize.

                                1. 1

                                  Yes, the X11 primary selection is very useful, and I always miss it on Windows, where there really is no great way of getting the currently selected text, except sending Ctrl+C/Insert and checking the clipboard.

                                2. 2

                                  Thanks for the article. I like the markdown link shortcut in particular. I should adapt that for myself.

                                  I’ve started to do similar things on macOS using Hammerspoon. So far I’ve set it up to let me:

                                  1. Use shift when pasting something to simulate typing in the text instead, getting around websites that block pasting.

                                  2. Use “;” as a hyper key. By holding it down and pressing another key, I can switch between specific programs without cycling. I can also use hjkl as arrow keys.

                                  3. Automatically switch audio input and output devices according to my specified priority order. Because macOS would frequently get it wrong.

                                  4. Make control act as escape when tapped. I use this in conjunction with remapping caps lock to control in macOS system preferences. I previously used Karabiner Elements for making caps lock work as escape when tapped and control when held, but I was able to uninstall Karabiner because Hammerspoon was sufficient.

                                  5. Disable the insert key because I’ve never wanted its functionality, but I would sometimes hit it accidentally.

                                  1. 2

                                    From what I can tell, I get all of the value of AHK and more by living inside Emacs and using EXWM as my window manager. EXWM lets you set up simulation keys to send keys directly to applications, and is fully programmable with Emacs Lisp.

                                    1. 2

                                      I agree that AutoHotKey is amazing, but everything mentioned in the article can be done easily on macOS with Keyboard Maestro. You could even argue it’s easier, because it’s all in a GUI.

                                      1. 1

                                        There’s also Hammerspoon, which is free and lua-based. I haven’t tried either and can’t compare them to AutoHotKey, though. Worth mentioning that these are just a few of the simpler AHK scripts I have, and they can get significantly more complex.

                                        1. 2

                                          Yeah I’m using Hammerspoon + Keyboard Maestro + Amethyst (basically XMonad for macOS) + BetterTouchTool (easy mouse button and trackpad gesture remapping).

                                          I think the Mac tools are generally easier to work with, but AutoHotKey has a much higher ceiling on what you can do with it.

                                      2. 1

                                        @hwayne, I love your article. I have two recommendations for you:

                                        1. If you’re ever on Linux again and you’re looking for intuitive unicode input, look into XCompose. It makes typing unicode characters dramatically better.
                                        2. If you found the above really tempting, I have great news! Someone effectively made a compatibility layer between AHK and Compose. So you can use the same Compose configuration for Windows as you might use for linux, and have the same style of phenomenally-intuitive input!

                                        AHK is incredibly powerful. And being able to use Compose on Windows makes it dramatically more bearable. :)

                                        Tangentially related: I love all of your work, particularly on formal methods. If you ever take a look at frama-c, I would love to chat with someone about it!

                                        All the best,


                                        1. 1

                                          This seems all very nice indeed, but every time I embark on some customization journey I eventually give up, for one reason: reproducibility.

                                          Do you use more than one computer? Now you have to replicate all of that in all of them. Do you use more than one OS? Same. Reinstall/update the OS? Either do everything again or have to fix it because the update broke it. Need to do something in someone else’s computer? It’s gonna be a pain because your muscle memory will be all over the place.

                                          None of this is unsolvable, or even arguably that hard. But I don’t usually have the patience to do it, so, I tend to stick to vanilla as much as possible. If something is really annoying I might change a config or add a program to help (clipboard manager is a thing I can’t live without, for instance).

                                          1. 1

                                            Isn’t this what applescript was supposed to be?

                                            (I’ve never used applescript, but that’s my impression from the snippets I’ve seen and what people have said about it.)

                                            1. 5

                                              AppleScript works on a higher level - instead of “send key A to Program” it’s more like “tell Program to save file in window 4” - actually working with exposed commands and objects instead of blind fire based on assumption.