Skip to main content
~/sohanscript
$
fd8c7289b5de48be6a0d
·7 min read

Kanata as a Text Expander — Why I Stopped Installing Extra Tools

linux
kanata
hyprland
text-expander
expanso
3ef4f885272bc6323209

Sohan R. Emon

Developer, Learner, Tech Enthusiast

So I was typing my email address for what feels like the hundredth time this week. And yeah, that is not even an exaggeration. Forms, git configs, .env files, Slack messages, everywhere I go it is the same email, same phone number, same “thank you so much” reply. And every single time I type it out fully. Kind of ridiculous honestly.

At some point I stopped and thought, wait a minute, I already have Kanata running. Why am I not just using that?


First, What Is Text Expansion?

Text expansion is simple. You type something short like tysm and it turns into “thank you so much” automatically. It saves keystrokes, saves time, and stops you from messing up things like your own email address (which happens more than you’d expect).

It sounds basic, because it is. But the tool you pick actually matters quite a bit.


What Are the Alternatives?

Before getting into Kanata, it is fair to look at what people usually use for this.

Espanso (Cross-platform, open source)

Probably the most common one in the Linux world. You define triggers in YAML, map them to text, and it just works across Linux, Mac, and Windows. It is solid.

The downside is it runs as another background service. Another thing to maintain, another thing that can break after updates. It is not heavy, but it is still extra.

AutoKey (Linux only)

Python-based automation tool. You can do text expansion and also scripting, which is powerful.

But the UI feels dated and the setup is more than most people want just for expanding a few phrases.

AutoHotkey (Windows only)

Classic Windows tool. Extremely powerful, basically a scripting language for automation.

But obviously useless if you are not on Windows.

TextExpander (Mac/Windows, paid)

A polished commercial tool with subscription pricing. Great if you are in a team already using it.

For personal use though, paying monthly just for shortcuts feels unnecessary.

Raycast (Mac only)

A launcher app with snippets built in. Very smooth experience overall.

But it is Mac only, and it is doing a lot more than just text expansion, launcher, clipboard tools, snippets, everything in one place.

Built-in desktop features (GNOME, KDE)

Some desktops offer basic replacements or autocorrect features. They are fine for small stuff but very limited. Not something you build a workflow around.

xdotool / ydotool scripts

You can hack together shell scripts that type text for you.

It works, but it is manual and awkward. You still need hotkeys and glue code everywhere.


So Why Kanata?

Honestly, because it is already there.

I already use Kanata every day for keyboard remapping, home row mods, navigation layers, mouse control, all of that. It is always running when I log in, and I barely think about it anymore.

And Kanata has defseq, which is basically perfect for text expansion. You type a sequence of keys and it triggers an action, including macros that type text.

No new software, no new service, no new config system. Everything stays in one place.

There is also another nice part. Kanata runs at a low input level, so it feels instant. No delay, no lag. Some tools that do expansion at the app layer sometimes feel slightly delayed, especially in terminals. Kanata just feels like you typed it yourself.


How It Works

Install Kanata

sudo pacman -S kanata

There are three main pieces.

1. defvirtualkeys (the action)

This defines what actually gets executed when a sequence matches.

lisp
(defvirtualkeys tysm (macro bspc S-t h a n k spc y o u spc s o m u c h))

bspc deletes the trigger input first, then the rest just types out the expanded text.


2. defseq (the trigger)

This maps a key sequence to that virtual key.

lisp
(defseq tysm (t y s m d scln))

So when I type t y s m and then my leader combo, it fires.


3. A leader key

You need a way to enter sequence mode. I use S-scln which is basically :.

So the flow becomes: press :, type shortcut, get expansion.


The Template Pattern

Writing all of this manually gets annoying fast, so I wrap it in a template.

lisp
(deftemplate seq (name keys action)
  (defvirtualkeys $name $action)
  (defseq $name ($keys d scln))
  (defseq $name ($keys S-scln))
)

Now I can define a shortcut in one line.

lisp
(t! seq tysm (t y s m) (macro bspc S-t h a n k spc y o u spc s o m u c h))

Much cleaner, less repetition.


Real Examples From My Setup

A few actual snippets I use.

Identity shortcuts

lisp
(t! seq id-nn  (n n)  (macro bspc S-s o h a n))
(t! seq id-ns  (n s)  (macro bspc S-s o h a n spc S-e m o n))
(t! seq id-emo (e m o) (macro bspc s o h a n e m o n (unicode @) o u t l o o k . c o m))

So :nn gives my first name, :ns gives full name, :emo gives my email. I also keep phone shortcuts in the same style.

Emoji shortcuts

lisp
(t! seq em-smile (m s) (macro bspc (unicode 😄)))
(t! seq em-cry   (m c) (macro bspc (unicode 😂)))
(t! seq em-heart (m h) (macro bspc (unicode ❤)))

Typing :ms for 😄 is way faster than searching emoji menus.

Typography tweaks

lisp
(t! seq ty-dash (- -) (macro bspc (unicode —)))

Double dash becomes an em dash. Small improvement, but it makes writing look cleaner.


What Kanata Cannot Do

It is not perfect.

  • No dynamic values, so things like current date need external generation
  • Multi-line snippets get messy fast
  • No clipboard-aware expansions or interactive prompts
  • No GUI snippet search, you need to remember or check config

So if you want dynamic templates or a searchable snippet manager, Espanso or similar tools are better.

But for static stuff like emails, names, phrases, emoji, Kanata is more than enough.


Setting It Up

If you already use Kanata, this is the minimal setup.

Step 1

Create a file like composer.kbd:

lisp
(deftemplate seq (name keys action)
  (defvirtualkeys $name $action)
  (defseq $name ($keys S-scln))
)

(t! seq my-email (e m) (macro bspc y o u (unicode @) e x a m p l e . c o m))

Step 2

Include it:

lisp
(include composer.kbd)

Step 3

Enable sequence mode:

lisp
(defcfg
  sequence-timeout 1000
  sequence-input-mode visible-backspaced
)

Step 4

Reload:

bash
kanata --check --cfg ~/.config/kanata/kanata.kbd
systemctl --user restart kanata.service

Done.


Final Thoughts

Espanso is good. So are the other tools. I am not saying they are bad.

But every extra tool means more maintenance, more configs, more chances for something to break after updates.

Kanata is already running anyway. It already controls your keyboard. So letting it handle text expansion too just feels natural.

My email is now basically impossible to mistype, emoji are instant, and I did not install anything extra for it.

If you are already using Kanata, this is one of those things that just makes sense to try.

Found this useful? Share!