Boost Your Productivity with AutoHotkey and Espanso
Amateurs sit and wait for inspiration; the rest of us just get up and go to work, Stephen King.
Give me six hours to chop down a tree, and I will spend the first four sharpening the axe, Abraham Lincoln.
AutoHotkey
AutoHotkey is a free, open source macro-creation and automation software utility for Windows that allows users to automate repetitive tasks.
- Installation. Go to the AutoHotkey Homepage, click Download, and run the installer (no reboot required).
- Launch it, click on New Script and name it, e.g., myshortcuts.ahk. It must end with .ahk (extension). Alternatively, right-click desktop/any directory, New, AutoHotkey Script.
- Edit the file with your favorite text or code editor: Right-click, Edit Script.
#Requires AutoHotkey v2.0 ; Ensures script runs only under v2.
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory. All relative paths start here.
; ^ = CTRL, # = Win, ! = Alt, + = SHIFT
/* ---------- HOTKEYS ---------- */
^g::Run "chrome" ; This defines a hotkey that triggers when Ctrl+g is pressed and launches Google Chrome browser.
#+d::Shutdown(9) ; Win + Shift + D shuts down and powers off the system
#+q::WinKill "A" ; Win + Shift + q closes the active window
-
Double-click the .ahk file to run it, a green “H” icon appears in the notification area.
-
Press Windows + Shift + D to immediately shut down your system, Ctrl+g to launch Google Chrome, etc.
-
Right-click on the green H F icon (AutoHotkey), Reload Script to reload the script after making any changes (avoids a full restart), Pause/Resume, and Exit.
Flow Launcher is a quick file search and app launcher for Windows with community-made plugins. Everything helps you locate files and folders by name instantly. Everything can integrate with Flow Launcher.
Espanso
Espanso is an open source, cross-platform text Expander.
You can quickly open the Espanso search bar on macOS by pressing Option + Space (Alt + Space).
Installation on Windows/macOS.
Let’s install it on Windows. Download and run the installer. You may experience a warning from Windows Smartscreen. Windows protected your PC. Click on More info and then on Run anyway.
# Ubuntu
# Download the "deb" package, https://espanso.org/, Install on Linux
wget ···.deb
# Install the package:
sudo apt install ./espanso-debian-x11-amd64.deb
# Register Espanso as a systemd service:
espanso service register
# Start Espanso
espanso start
# Install Emojis
espanso install actually-all-emojis
# MacOS, brew install espanso
# Configuring Espanso in a dotfile directory and managing via stow
# Structure (stow dir ~/macOS, package Espanso)
~/macOS/
└── Espanso/
└── Library/
└── Application Support/
└── espanso/
├── config/
│ └── default.yml
└── match/
├── base.yml
├── hugo.yml
└── packages/
# Stop the service
espanso stop
# Create Espanso structure
mkdir -p ~/macOS/Espanso/Library/Application\ Support
# Move the existing config into the package
mv ~/Library/Application\ Support/espanso ~/macOS/Espanso/Library/Application\ Support/espanso
# Stow it
cd ~/macOS
stow --no-folding -t ~ Espanso
# Verify
❯ ls -la ~/Library/Application\ Support/espanso
lrwxr-xr-x 1 nmaximo7 staff 55 7 Oct 06:35 /Users/nmaximo7/Library/Application Support/espanso -> ../../macOS/Espanso/Library/Application Support/espanso
- You are ready to use espanso. Open any application and type:
:espanso
NixOS
Edit configuration.nix. configuration.nix (system-level) turns espanso on and picks which build of it to install. The Wayland variant matters because GNOME on Wayland needs a different input-injection method than X11 — using the wrong package means triggers silently stop working.
services.espanso = {
# It creates and starts the systemd user service that keeps espanso running in the background.
enable = true;
# Use the Wayland package variant for GNOME
# On X11 you'd use plain pkgs.espanso; mixing them up is a common cause of "espanso runs but nothing types" on GNOME/Wayland.
package = pkgs.espanso-wayland;
};
Edit home-manager.nix ((user-level) manages your dotfiles):
# It symlink file Y from my dotfiles repo to path X in my home directory.
# The left side, ".config/espanso/match/NAME.yml", is the destination path relative to your home directory
# — so this becomes ~/.config/espanso/match/NAME.yml.
# This is the exact folder espanso watches; every .yml file inside it is auto-loaded, no registration needed elsewhere.
# The right side, .source = "/home/${username}/dotfiles/Espanso/NAME.yml", is the real file
# living in your dotfiles repo (so it's version-controlled and synced across machines).
home.file.".config/espanso/match/base.yml".source = "/home/${username}/dotfiles/Espanso/base.yml";
home.file.".config/espanso/match/bookmarks.yml".source = "/home/${username}/dotfiles/Espanso/bookmarks.yml";
home.file.".config/espanso/match/hugo.yml".source = "/home/${username}/dotfiles/Espanso/hugo.yml";
home.file.".config/espanso/match/maths.yml".source = "/home/${username}/dotfiles/Espanso/maths.yml";
home.file.".config/espanso/match/emojis.yml".source = "/home/${username}/dotfiles/Espanso/emojis.yml";
home.file.".config/espanso/match/prompts.yml".source = "/home/${username}/dotfiles/Espanso/prompts.yml";
Making shortcuts easy to remember
I’d suggest to use one consistent prefix per file, so the trigger itself tells you which “device” made it and your muscle memory only has to learn one pattern per category:
;m+ word → maths/LaTeX (e.g.;msqrt,;mpi,;mforall);h+ word → Hugo/markdown (e.g.;hlink,;hcode);b+ word → bookmarks (e.g.;bgoogle,;bgemini);e+ word → emoji/reactions (e.g.;ehug,;eshrug);p+ word → prompts (e.g.;pclarify)- plain
:wordstays for base/personal info
# bookmark.yml
matches:
- trigger: ";bsite"
replace: "https://justtothepoint.com/"
- trigger: ";bsitefull"
replace: "https://justtothepoint.com/, Free resources, bilingual e-books and videos to help
your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun."
- trigger: ";blocal"
replace: "http://localhost:1313/"
- trigger: ";bgemini"
replace: "https://gemini.google.com/app"
[...]
# base.yml
# Personal information (Fake Name Generator)
matches:
- trigger: ":name"
replace: "Cameron S. Phillips"
- trigger: ":dni"
replace: "31661375N"
- trigger: ":phone"
replace: "688 254 376"
[...]
# hugo.yml, markdown/HTML snippets
- trigger: ";hpara"
replace: '<p>$|$</p>'
- trigger: ";himage"
replace: ''
[...]
# math.yml, Greek letters + set theory/logic symbol
# LaTeX snippets: fractions, integrals, limits, matrices
- trigger: ";mforall"
replace: '∀ $\forall$'
- trigger: ";mint"
replace: '\int $|$(x)dx'
- trigger: ";mintdef"
replace: '\int_{a}^{b} $|$(x)dx'
[...]
# emojis.yml: reactions, kaomoji, love notes...
matches:
- trigger: ";egm"
replace: "Good morning. I hope your morning is as bright and gorgeous as your smile."
- trigger: ";ehappy"
replace: "(✿´‿`)"
- trigger: ";eha"
replace: "Just sayin'… :-)"
[...]
# prompts.yml: your AI prompt templates, expanded with a few more useful ones if you want.
matches:
# --- Writing & editing ---
- trigger: ";pclarify"
replace: "Could you please clarify, proofread, explain, and expand the explanation as much as possible to make it more comprehensive and accessible. Please be precise, verbose, avoid hallucinations, and do not worry about time, but precision. Thank you very much for your aid and support, I do appreciate it."
- trigger: ";pexplain"
replace: "Please explain the following concept as simply as possible, as if to someone with no background in the topic, then add a second, more technical explanation for someone with intermediate knowledge: $|$"
- trigger: ";psummarize"
replace: "Please summarize the following text into its key points, using short bullet points, without losing any critical detail: $|$"
[...]
Arch & other distributions
If you’re using any other Linux distributions, you can use Espanso’s AppImage to get the program up and running on your computer. To install the Espanso’s AppImage, just open a terminal and follow these steps:
- Create the $HOME/opt destination folder: mkdir -p ~/opt Install fuse2: sudo pacman -Syu fuse2
- Download the AppImage inside this folder: wget -O ~/opt/Espanso.AppImage ‘URL_GITHUB.COM/Espanso.AppImage’
- Make the AppImage executable: chmod u+x ~/opt/Espanso.AppImage
- Create the “espanso” command alias: sudo ~/opt/Espanso.AppImage env-path register
- Register espanso as a systemd service (systemd is a “system and service manager”): espanso service register
- Start espanso: espanso start
You are ready to use espanso. Open any application and type:
:espanso
Configuration
Espanso uses a file-based configuration approach, type: espanso path to find the path of your configuration folder. Typically: Windows (C:\Users\userName\AppData\Roaming\espanso), macOS (/Users/userName/Library/Preferences/espanso) or Linux (/home/userName/.config/espanso).
There are two folder: config and match. The files contained in the match directory define WHAT Espanso should do (base.yml), i.e., all your snippets and actions. The files contained in the config directory (default.yml) define HOW Espanso should perform its expansions.
-
To enable some emojis, instal some packages:: espanso install all-emojis or espanso install actually-all-emojis, and try :lol, :happy, :cry.
-
After every configuration change, espanso must be restarted: espanso restart.
-
Configuration. gedit /home/user/.config/espanso/default.yml or base.yml (depending on Espanso version)
keyboard_layout: layout: "un" # Sets the keyboard layout to 'un' (universal), which is generally compatible with various layouts. backspace_delay: 50 # Delay in milliseconds after each backspace. This allows for smoother text editing, preventing accidental interference with typing. backend: Clipboard # It specifies that the backend used for pasting text is the system clipboard.This is useful for ensuring compatibility with applications like VS Code.
pre_paste_delay: 100 # Delay in milliseconds before pasting text. \ # This allows any necessary processing time before the text is pasted. post_paste_delay: 100 # Delay in milliseconds after pasting text. # This ensures that the pasted content is properly registered before any further actions occur. paste_shortcut_event_delay: 100 # Delay in milliseconds after a paste shortcut event before processing the next action. # This helps prevent conflicts with the application's input handling. key_delay: 20 # Delay in milliseconds between individual keystrokes when typing out expanded text. # This mimics natural typing speed and can help prevent issues with applications that may not handle rapid input well. matches: # Personal Information matches: - trigger: ":name" replace: "Your Name" - trigger: ":address" replace: "Your Address" - trigger: ":telephone" replace: "Your Phone" - trigger: ":email" replace: "Your Email" - trigger: ":website" replace: "https://justtothepoint.com/, Free resources, bilingual e-books and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun." - trigger: ":social" replace: "Twitter: @justtothepoint.\nFacebook: https://www.facebook.com/nmaximo7.\nLinkedIn: https://www.linkedin.com/in/justtothepoint" - trigger: ":signature" replace: | '¯\\_(ツ)_/¯' Your Name. https://justtothepoint.com/, Free resources, bilingual e-books and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. # Love & affection - trigger: ":gm" replace: "Good morning. I hope your morning is as bright and gorgeous as your smile." - trigger: ":lv" replace: "Trust me, I get lost in your smile because I see something more beautiful than the stars." - trigger: ":lv2" replace: "(◕‿◕✿) Never let me go, hold me tight till it hurts so badly that I can never forget how much I love you." - trigger: ":lv3" replace: "Yᵒᵘ Oᶰˡʸ Lᶤᵛᵉ Oᶰᶜᵉ" # Reactions & emotions - trigger: ":dunno" replace: "¯(ツ)/¯ ¯\\_(ツ)_/¯ What do you mean? ◔̯◔" - trigger: ":happy" replace: "(✿´‿`)" - trigger: ":ha" replace: "Just saying'… :-)" - trigger: ":sc" replace: "" - trigger: ":thank" replace: "Sometimes the simplest things mean the most. Thank you very much for your like and love." # Additional useful snippets - trigger: ":shrug" replace: "¯\\_(ツ)_/¯" - trigger: ":flip" replace: "(╯°□°)╯︵ ┻━┻" - trigger: ":hug" replace: "(づ。◕‿‿◕。)づ" - trigger: ":kiss" replace: "(づ ̄ ³ ̄)づ" - trigger: ":wave" replace: "( ͡° ͜ʖ ͡°)ノ⌐■-■" - trigger: ":table" replace: "┬─┬ ノ( ゜-゜ノ)" - trigger: ":lenny" replace: "( ͡° ͜ʖ ͡°)" - trigger: ":heart" replace: "❤️" - trigger: ":lol" replace: "😂" # Date, Time, and Weather - trigger: ":date" replace: "{{mydate}}" vars: - name: mydate type: date params: format: "%d/%m/%y" - trigger: :time replace: "{{time}}" vars: - name: time type: date params: format: "%H:%M" - trigger: ":now" replace: "It's {{mytime}}" vars: - name: mytime type: date params: format: "%H.%M" - trigger: ":weather" replace: "{{output}}" vars: - name: output type: shell params: cmd: "curl 'http://wttr.in/?format=3'" # Inserts common HTML and Markdown elements - trigger: :hr replace: '<hr />' - trigger: :br replace: '<br />' - trigger: :div replace: '<div>$|$</div>' - trigger: :span replace: '<span>$|$</span>' - trigger: :h1 replace: '<h1>$|$</h1>' - trigger: :h2 replace: '<h2>$|$</h2>' - trigger: :h3 replace: '<h3>$|$</h3>' - trigger: :para replace: '<p>$|$</p>' - trigger: :sup replace: '<sup>$|$</sup>' - trigger: :sub replace: '<sub>$|$</sub>' - trigger: :fraction replace: '<sup>$|$</sup>⁄<sub></sub>' - trigger: "link" replace: "[$|$]()" vars: - name: "clipboard" type: "clipboard" - trigger: ":md-link" replace: "[$|$]({{clipboard}})" vars: - name: "clipboard" type: "clipboard" - trigger: ":html-link" replace: "<a href=\"{{clipboard}}\" />$|$</a>" vars: - name: "clipboard" type: "clipboard" # Inserts a markdown code block - trigger: :code replace: "```\n$|$\n```" # More shell commands - trigger: ":ip" replace: "{{output}}" vars: - name: output type: shell params: cmd: "curl 'https://api.ipify.org'" - trigger: ":edit" replace: "{{output}}" vars: - name: output type: shell params: cmd: "gedit ~/.config/espanso/match/base.yml" - trigger: ":quote" replace: "{{output}}" vars: - name: output type: shell params: cmd: "fortune" # Quick search - trigger: ":duckduckgo" replace: "https://duckduckgo.com/?q=" - trigger: ":wiki" replace: "https://en.wikipedia.org/w/?search=" - trigger: ":youtube" replace: "https://youtube.com/results?q=v" - trigger: ":google" replace: "https://google.com/search?q=" - trigger: "emojis" replace: ':heart: :sparkles: :woman shrugging: :fire: :cross mark: :calendar: :pencil: :check mark: :right arrow: :robot: :speaker: :bulb: :performing arts:' - trigger: ":proof" -
Synchronization.
-
Move espanso configuration folder to the Dropbox folder (mv ~/.config/espanso/ ~/Dropbox/).
-
Create a symbolic link: ln -s ~/Dropbox/espanso ~/.config/espanso/
-
Synchronization MacOS: rm -rf $HOME/Library/Preferences/espanso/, ln -s "$HOME/Dropbox/espanso" “/$HOME/Library/Preferences/espanso", espanso restart. We are assuming that $ESPANSO = /$HOME/Library/Preferences/espanso.
- Bibliography:
- Alicia’s Notes, Using Espanso to boost Efficiency.
- Espanso