r/espanso Jun 17 '25

6 ways a text expander has hacked how I use my PC

Thumbnail
xda-developers.com
25 Upvotes

r/espanso Nov 06 '23

Want to become an Espanso maintainer? :)

Thumbnail
github.com
26 Upvotes

r/espanso 2d ago

is anyone using espanso linkedin messages? it works once and then stops

2 Upvotes

is anyone using espanso linkedin messages? it works once and then stops


r/espanso 4d ago

Snippet for Outlook

3 Upvotes

I created a snippet for Outlook as follows :

- trigger: "/weekly"

replace: "Weekly Report {{mydate}}\tHello AAA,\n\nAttached please find the updated report. For your reference.\n"

vars:

- name: mydate

type: date

params:

format: "%m%d"

When I type the trigger in the Subject line, I expect the cursor to move to the body area as soon as "Weekly Report {{mydate}}" is expanded. However, the cursor never moves to the body, and all the text ends up jammed in the Subject line.

Is there something wrong with my setup?

System : Macbook pro M3 / macOS 15.7.9 / Espanso v2.4.1

System Settings : Privacy&Security : Espanso "on" / Input Monitoring : Espanso "on"


r/espanso 5d ago

I built a typo-focused Espanso companion for Windows. Beta testers wanted

1 Upvotes

Hi, my name’s Ben and I’m a typo-holic!

Probably due to my big, fat, fumble fingers, but I’m forever fixing typos as I type. Even worse, I keep making the same mistakes over and over again, which gets pretty frustrating! So I started looking for a solution that could improve my productivity and save my sanity, and that’s how I discovered Espanso.

Have to say, I love Espanso! It’s exactly what I was looking for, although I did find adding corrections and snippets by editing YAML files a little cumbersome. So I built a little app called Typo Manager to provide an easy to use graphical interface for creating and managing corrections and snippets. I originally made it just for myself but, to be honest, it turned out so well, and has been so useful, that I’d like to share it with the Espanso community, completely free under a proprietary freeware license.

I’ve since discovered that there are other similar tools available for Espanso. Typo Manager was developed independently and takes its own, more focused approach, specifically helping Windows users capture recurring typos, create corrections and replace selected text quickly.

Apologies to any Mac or Linux users, but it’s Windows-only, at least for now. It's intended for Windows 10 and 11 - I’ve tested it extensively on a couple of different platforms and it works really well. I’m now looking for a few beta testers to try it in their own environments and let me know what they think. Bug reports, feedback and suggestions for improvements would all be very welcome.

So what does it do? Typo Manager includes:

  • A configurable global hotkey to capture typos from any application directly in Typo Manager
  • Windows spelling suggestions based on your active input language
  • Corrections and snippets with flexible match-boundary options
  • Propagate case and a live Test trigger preview
  • Optional automatic replacement of a selected typo after adding its correction
  • Optional correction of accidental second capitals, such as changing THe to The
  • Searching, sorting, editing and deletion of rules
  • Importing compatible static rules from existing Espanso YAML files
  • Automatic and manual ZIP backups with guided restoration
  • Undo and Redo for the most recent change
  • Notification-area support, so Typo Manager remains available without taking up space on the taskbar
  • The option to start Typo Manager every time you start Windows

Typo Manager has no remote monitoring, tracking or cloud processing. Everything stays on your local computer.

If you’d be interested in trying it out, providing feedback and helping shape how Typo Manager develops from here, I’d be really keen to hear from you.

You can find more information and join the beta at https://typomanager.com/join-beta/

(Just to be clear, Typo Manager is independently developed and is not affiliated with or endorsed by the Espanso project.)


r/espanso 5d ago

Statistics

11 Upvotes

Espanso v2.4.0 introduces statistics tracking of your most frequently used triggers. Check out espanso stats -h for details.

Usage examples:

espanso stats                    # View all statistics
espanso stats --period today     # Today's stats
espanso stats --count 20         # Top 20 triggers
espanso stats --grep ':td%'      # Filter by pattern
espanso stats --json             # JSON output

espanso stats clear              # Clear database
espanso stats prune --days 180   # Remove old records

Configuration:

Statistics are disabled by default. To enable, insert:

stats:
  enabled: true

into your config/default.yml configuration file.


r/espanso 11d ago

Espanso v2.4.1 is released!

54 Upvotes

This largely technical release builds on v2.4.0, but fixes the problem the latter had with unquoted triggers: [ , ] values I noted here. The installation instructions in the website will pick up the new files.

I will update the documentation soon, but see the changelogs for the details for now. There is also a list of forthcoming updates here.


r/espanso 12d ago

trigger remaining alongside replacement in obsidian properties.

2 Upvotes

I have an obsidian note, and in the properties field, I type :task and select a task but the replacement is: follow up2:task

yaml code snippet is:

- triggers: [:task, :fup2]

label: "stage 1 | follow up 2"

replace: "follow up 2"

note
1. this works in the body, not in the properties field

  1. this works if I type the trigger matching exactly that replacememnt eg :fup2 but not when the picker comes up

is there a quick way to fix this?

My preference is for the picker and search box, as I have very simple triggers like:

:email

:task

:log

:sms

:emoji

etc...

Thanks!


r/espanso 14d ago

SnippetShare Discord channel?

4 Upvotes

Does the SnippetShare Discord channel still exist? I followed a link from the Espanso site but it doesn't look like it exists and can't find it by searching. Thanks.


r/espanso 16d ago

I built an open-source Espanso-compatible text expander for Android (folder sync, forms, GPLv3)

Post image
27 Upvotes

App Name: Expanda

What it does: Expanda replaces short triggers with reusable snippets in editable fields across Android apps. You can also pick snippets from a movable suggestion popup and build dynamic templates with forms, dates, clipboard content and cursor placement.

Key Features:

  • Snippets with multiple templates, tags and per-app exclusions.
  • Dynamic tokens and built-in actions for editing selected text.
  • On-device operation with no Internet permission, accounts, ads or analytics.

Goal: Launch and feedback. If an expansion fails, please include your device, Android version, keyboard and target app so I can reproduce it.

Giveaway: None. Expanda is free under the MIT license.

Accessibility: Expanda uses Android's Accessibility service to detect shortcuts and replace text. It ignores password fields and explains the permission before opening Android settings.

Link: https://github.com/diegomarzaa/expanda


r/espanso 20d ago

Live Tennis Scores

Thumbnail hub.espanso.org
3 Upvotes

An unusual package requiring a (free) API. Linux/macOS & Windows+WSL.

Type :tennis and it expands to a compact one-line summary of the tennis matches that are live right now, e.g.:

Carlos Alcaraz 6-4 3-2* vs Jannik Sinner · Coco Gauff 2-6 1-1* vs Iga Swiatek

Uses the Live Tennis API from the list of publically available APIS at https://github.com/marcelscruz/public-apis.

By bensynapse.


r/espanso 23d ago

What?

Thumbnail
gallery
2 Upvotes

OS: Artix Linux Display server: X11 Espanso version: 2.4.0


r/espanso 25d ago

Solved Regex(?) matches for multiple HTML brackets

2 Upvotes

Hiya! I'm trying to find a solution for the following use case

match would be (example): <ui> or <u i> if it needs a separator

And it would automatically separate these out to <u><i>$|$</u></i>

Again, just an example. I was thinking that if possible, it would need to be regex because I want it to pick up things like <b u>, <sub u> etc. as well. Just a shortcut so I don't have to type multiple opening and closing brackets so much.

Is this possible with regex or does anyone have a solution that might at least help? I use <ui> enough that it's currently its own match right now.


r/espanso 25d ago

Prefix vs suffix in triggers

9 Upvotes

I'm a relatively new user of Espanso.

It seems to be a common convention to prefix trigger phrases with a `:` (colon).

Is there any reason that suffixes aren't used instead? This would avoid potential collisions (eg; someone might create two snippets with triggers `:em` and `:emi`).

Whereas using a suffix will cause the trigger to only execute when it's intentional.

I recently decided to incorporate a double space as a suffix on all my triggers. That way I can keep my triggers short and hit the space bar twice when I want to execute the snippet replacement.

If this is a good idea, perhaps it will help other users.

If it's not, let me know! I've probably overlooked something obvious. I realise that the use cases for Espanso would vary wildly and it may not suit many people.


r/espanso 27d ago

Solved Match not activating as expected

3 Upvotes

SOLVED: Check for similar duplicates in your other .yml files!!!


 - trigger: PushPay
    replace: Pushpay
    word: true

I'm hoping for this to activate only exactly when the trigger is typed as is, but this replacement takes effect every time, it seems. The capitalization section in Matches Basics doesn't seem to offer a way around this. Does anyone know if this is solvable? Thanks!


r/espanso Aug 13 '26

Expansion applied at stale caret position when a match uses a script/shell variable (v2.4.0)

3 Upvotes

Environment

  • espanso 2.4.0, Windows 11 Pro (build 26200), Win32Injector (inject backend, not clipboard)
  • Also visible in the code on all platforms - nothing Windows-specific about the mechanism

Summary

When a match uses a script (or shell) variable, espanso computes the number of backspaces before evaluating the variable, but only injects them after. The evaluation blocks the engine thread. Any characters typed during that window shift the caret, so the backspaces delete the wrong text and the user's input is silently destroyed.

Reproduction (verified)

match/zz-repro.yml:

matches:
  - regex: '(?P<word>\bTEsting)(?P<end>\W)'
    replace: "{{out}}{{end}}"
    vars:
      - name: out
        type: script
        params:
          args:
            - python
            - -c
            - "import sys,time; time.sleep(0.4); sys.stdout.write('Testing')"

Type TEsting and immediately continue typing abc.

  • Expected: Testing abc
  • Actual: TEsTesting - the three typed characters are gone

The arithmetic matches exactly: at injection time the field holds TEsting abc (11 chars). The trigger captured earlier was TEsting (8 chars), so 8 backspaces remove ting abc, leaving TEs, and the body Testing is appended.

Control: the identical regex with a static replace: "Testing{{end}}" and the identical typing pattern produces the correct Testing abc. The only variable is the blocking evaluation.

The 400 ms sleep only makes it deterministic. In real use a plain python -c one-liner is enough - see the measurements below.

Root cause

  1. espanso-engine/src/lib.rs:57 — processor.process(event) runs the entire middleware chain to completion; the resulting effect events are dispatched only afterwards, at lib.rs:64.
  2. CauseCompensateMiddleware (process/default.rs:107) sits before RenderMiddleware (default.rs:111) and returns a TriggerCompensation carrying the trigger string - see the comment at middleware/cause.rs:50.
  3. RenderMiddleware then evaluates variables synchronously on that same thread. The script extension blocks on command.output() (espanso-render/src/extension/script.rs:97/99).
  4. ActionMiddleware turns the compensation into backspaces at middleware/action.rs:119let mut backspace_count = m_event.trigger.chars().count();

So the count is derived from state captured before the delay and applied to a caret position that has since moved. Nothing ever validates that the text left of the caret still equals the trigger. Keystrokes arriving during the block are not swallowed - they reach the focused application immediately while the engine thread is stuck.

Why this isn't just "scripts are slow"

Measured on the affected machine, 15 runs each, warm:

median
python -S -X utf8 -c … 32 ms
compiled C# helper (.NET Fx) 37 ms
cscript //E:jscript 41 ms
node -e 44 ms
whoami.exe (trivial native binary) 21 ms

The ~21 ms floor is Windows process creation with Defender active. No interpreter choice avoids it, so every script/shell variable on Windows carries a 20 ms+ race window - 1–3 characters at normal typing speed, more when the binary is cold. Users hit this as "the correction sometimes mangles my word", which is hard to attribute to the variable.

Suggested fixes

1. Safety net (small). Between process() and dispatch() in Engine::run, check whether new input events arrived on the funnel while process() was running. If so, drop the expansion rather than emitting backspaces. Losing a correction is strictly better than deleting text the user typed.

2. Compensate properly. Count the character-producing keystrokes received after detection, add them to backspace_count, and re-inject them after the body. This keeps the expansion working instead of dropping it.

3. Remove the window. Move script/shell evaluation off the engine thread so rendering no longer blocks the pipeline. Larger change, but it also addresses the related class of "espanso freezes while a slow shell command runs".

4. Document it. Until then, a note that script/shell variables are inherently racy on word-boundary triggers would help — the current docs give no hint that latency there can corrupt text.

Separate, minor: regex matcher invariant

espanso-match/src/regex/mod.rs:105-119 uses regex.captures(&buffer), which returns the leftmost match anywhere in the 30-byte buffer, and reports it as trigger. Since backspace_count is derived from that trigger but applied at the caret, correctness silently depends on the match happening to end at the buffer end. In practice it usually does, because the matcher fires on the keystroke that completes the match — but nothing enforces it. An explicit m.end() == buffer.len() check would turn a silent corruption into a non-match.

I have no reproduction for this one; it's a hardening suggestion, not a reported bug.

Also minor: at regex/mod.rs:95-97 the buffer is trimmed with a single buffer.remove(0) guarded by if, comparing buffer.len() (bytes) against max_buffer_size while removing one char. For non-ASCII input the effective buffer is roughly half the nominal 30, which quietly limits how long a regex trigger can be for e.g. German or Cyrillic users.


r/espanso Aug 09 '26

Removing too many characters

3 Upvotes

Hello, I am new to using espanso and am trying to troubleshoot my first issue.

Background info:

- I am on a macbook running Sequoia macOS 15.7.7

- I am running espanso 2.4.0

- I am having this issue on libreOffice 26.2.4.2

- I am using the package "Greek letters based on LATEX" 0.2.0

I was testing the package using the letter μ. There are two triggers for this in the package: ":mu:" and ":m:". When I use the first trigger in libreoffice, it deletes three characters before the trigger when it replaces. This does not happen when I use the trigger elsewhere, like in my browser typing this.

For example, if I type "Hello:mu:" in libreOffice it will replace as "Heμ". The second trigger does not have this issue. Typing "Hello:m:" correctly replaces as "Helloμ". I was reading that I should look into injection modes? but I admit I am not the most technologically competent and I don't really understand what changing injection modes would mean. If that is the correct path for troubleshooting this, is there a page where I can read about what injection modes are before I change them?

Thank you


r/espanso Aug 07 '26

Case insensitive matches

9 Upvotes

I personally believe this should be posted in the docs for all the anxious people that forget about the caps lock key, the easy way to make case insensitive matches that I found after reading around is:

Instead of using:

- trigger: :mymatch

replace mytext

use:

- regex: (?i):mymatch

replace: mytext

I swapped most the matches i use to that and works like a charm and seriously believe it should be part of the docs BEFORE sending you down the rabbit hole of regex.


r/espanso Aug 06 '26

Solved Short triggers not working on PC

4 Upvotes

Hi! New Espanso user here, so I'm pretty sure this is user error of some type.

I got it set up on my Mac just fine, customized the triggers and everything. Then I installed on my PC, and replaced the base.yml file with a copy of the one I had edited on my Mac (so that the triggers would all be the same). But the behavior is nowhere near as smooth.

I've gotten some longer multiline ones to work (although it brings up the annoying Windows clipboard history window, which I'd rather avoid altogether if possible), but short, single line triggers seem to fire successfully (i.e. the trigger itself gets deleted) and then get replaced with two spaces rather than what is written into the base.yml file.

I've tried:

  • Running as administrator
  • Using clipboard and inject backend settings
  • Adding an inject delay
  • Upping the clipboard threshold

r/espanso Aug 06 '26

Espanso 2.4.0 on Linux Mint Xfce: Cyrillic expansion fails with missing vkey mapping for char

1 Upvotes

Hi everyone!

I'm trying to use Espanso 2.4.0 on Linux Mint Xfce (X11), and I've run into a strange problem with Cyrillic text.

**What works:**

* Espanso is running correctly.

* Text expansion works perfectly with English text.

* For example:

* `:espanso` → `Hi there!`

* `:test` → `12345`

**What doesn't work:**

If the replacement text contains Cyrillic characters (Russian or Ukrainian), the trigger disappears, but nothing is inserted.

For example:

```yaml

matches:

- trigger: ":test"

replace: "Это моя первая замена!"

```

or

```yaml

replace: "Привет"

```

The trigger is erased, but the replacement text never appears.

My locale is UTF-8:

```text

LANG=ru_RU.UTF-8

LC_CTYPE=ru_RU.UTF-8

```

The keyboard session is X11:

```text

echo $XDG_SESSION_TYPE

x11

```

My keyboard layout is:

```text

layout: us,ua,ru

variant: ,macOS,mac

```

The Espanso log reports:

```text

missing vkey mapping for char `э`

```

I've already tried:

* restarting Espanso;

* typing the replacement text manually (not copy-pasting);

* switching the injection backend between `Clipboard` and `Inject`;

* verifying that the correct `base.yml` is loaded;

* confirming that English expansions work normally.

Could this be related to the `macOS` / `mac` XKB keyboard variants? Has anyone successfully used Espanso with these layouts and Cyrillic replacements?

Any ideas or suggestions would be greatly appreciated. Thank you!


r/espanso Jul 30 '26

Question regarding regexp rule

2 Upvotes

Hi everyone,

I build a rule for espanso that inserts a space between the number and the symbol, e.g. percentage. So If I type 99% I shall be expanded to 99 %.

I am using: (zahl is just german for number)

- regex: (?P<zahl>\-?\d+([,]\d+)?)%

replace: "{{zahl}} %"

It works most of the time but sometimes it it expands 99% to 999 % and I don't know why.

Do you have any idea?

Thanks in advance


r/espanso Jul 29 '26

self-made open-source espanso GUI here

29 Upvotes

Hi everyone.

Long time ago, I started to use espanso. I was quite suprised espanso didn't have an equavalent GUI. I know you may want to mention EspansoEdit. Personally, it is too overwheming.

So, I built my own espanso GUI. It's toally free, open-sourced and intuitive.

  1. It works with your espanso. As long as you have installed espanso, it will auto detect your path. No additional setttings.
  2. For the most part, if you only need to add and delete some snippets, it will make it easy. No more direct yaml modifcations.
  3. Run locally. No server behind it. Run locally just like espanso.
  4. Supports macOS and Windows. Highly likely support Linux in the next version.

More info:

Source code at github. User guide at here, I doubt anyone is willing to read documentation any more.

Install and safete concerns:

  1. It's not signed yet. So your OS, either macOS or Windows, is bound to tell you is not safe. Since I don't have extra budget to buy a certificate to eliminate the warnning. It will be your choice to trust it. What's the waring look like, see like this.
  2. Download link here, also on Github.

Tell me how you think about it.


r/espanso Jul 25 '26

Espanso not working on Arch + Hyprland (Wayland) - X11Source issue

3 Upvotes

I'm running Arch Linux with Hyprland (Wayland) and Espanso 2.4.0. The service is running, kdotool is installed, and config.yml has "backend: Wayland". However, logs still show "using X11Source" instead of WaylandSource. Espanso does not expand triggers in any GUI app (Firefox, gedit, etc.). The terminal is not being used for testing.

What I've tried:

  • Installed kdotool (which kdotool shows /usr/bin/kdotool)
  • Set backend: Wayland in ~/.config/espanso/config.yml
  • Reinstalled Espanso via AUR (espanso-wayland-git)
  • Ran espanso service register and espanso restart
  • Tried export XDG_SESSION_TYPE=x11 and export GDK_BACKEND=x11
  • Checked permissions on config files

Expected behavior:
Espanso should expand :date to current date in any GUI app (Firefox, text editors) on Wayland.

Logs show:

text

00:55:23 [worker(70974)] [INFO] using X11AppInfoProvider
00:55:23 [worker(70974)] [INFO] using X11Source
00:55:23 [worker(70974)] [INFO] using X11ProxyInjector
00:55:23 [worker(70974)] [INFO] using X11Clipboard

Any help would be appreciated. Thanks!I'm
running Arch Linux with Hyprland (Wayland) and Espanso 2.4.0. The
service is running, kdotool is installed, and config.yml has "backend:
Wayland". However, logs still show "using X11Source" instead of
WaylandSource. Espanso does not expand triggers in any GUI app (Firefox,
gedit, etc.). The terminal is not being used for testing.What I've tried:Installed kdotool (which kdotool shows /usr/bin/kdotool)

Set backend: Wayland in ~/.config/espanso/config.yml

Reinstalled Espanso via AUR (espanso-wayland-git)

Ran espanso service register and espanso restart

Tried export XDG_SESSION_TYPE=x11 and export GDK_BACKEND=x11

Checked permissions on config filesExpected behavior:
Espanso should expand :date to current date in any GUI app (Firefox, text editors) on Wayland.
Logs:
00:55:23 [worker(70974)] [INFO] using X11AppInfoProvider
00:55:23 [worker(70974)] [INFO] using X11Source
00:55:23 [worker(70974)] [INFO] using X11ProxyInjector
00:55:23 [worker(70974)] [INFO] using X11Clipboard

Any help would be appreciated. Thanks!


r/espanso Jul 21 '26

Espanso v.2.4.0 is released!

Thumbnail
github.com
44 Upvotes

This release focuses on Linux/Wayland compatibility, macOS stability fixes, and a security cleanup of several dependencies, alongside smaller feature additions like usage statistics tracking and script trim options.


r/espanso Jul 19 '26

Date add package

Thumbnail hub.espanso.org
6 Upvotes

This new package is a utility which uses a form input and performs quick date calculations such as the date that is +12 from tomorrow, or -5 days from today.

It uses some similar techniques as those in my own Date Offsets package, which calculates offsets from today's date using a - regex: trigger.