natpen.net
Adventures, Sustainability, and Technology


Word definiton popups with Arch and Sway

sway // wayland // technology

Posted on

Reading time: ~4 min

Table of Contents

One thing I really like on OSX, but miss on Linux, is the thing where you three-finger tap a word to look up its definition. It's really nice to be able to get the definition so easily, without having to context switch, open up a new tab, or anything. So I set out to try and replicate the functionality myself!

It got me thinking about how to do something similar in Linux. I didn't really want to start messing with touchpad stuff, so I thought I would try the ever-so-slightly-less-elegant workflow of double tapping to select a word on screen, ctrl+c to copy into the clipboard, then meta+c to get the definition as a OS popup notification. The magic, of course, lies in the meta+c step, which is what I set out to find or build.

I found this project on GitHub, which is essentially what I just described, and looks like a nice little Golang project. I thought I would create an alternative because that one is A) hardcoded to use xclip, and I wanted to use wl-clip, and B) I thought I could replicate the entire project with a couple lines of bash.

I had to spend a few minutes finally learning how to use jq, but after that it was relatively simple and I'm pleased with the end result. As long as you don't go over 10k requests per month, the twinword API is free to use, and now you can get definitions easily!

#!/usr/bin/env bash

WORD=$(wl-paste)

curl -d "entry=$WORD" 'https://www.twinword.com/api/v4/word/definition/' | jq '.meaning | map_values(select(length > 0)) | join("\n")' | xargs notify-send --expire-time=10000 "$WORD"
  (menu-bar-mode -1)

Jan 2020 Update

I've updated this script very slightly, to now rely on a dictionary I have installed locally. The UX is still the same at the end of the day, but I no longer require an internet connection for this setup to function.

#!/usr/bin/env bash

WORD=$(wl-paste)

DEFINITION=$(dict -d wn "$WORD")

notify-send --expire-time=20000 "$WORD" "$DEFINITION"

Pretty simple, but now it requires having installed dict, which, although great in practice, had a bit of a learning curve to get started. I was slightly put off initially by the fact that it necessitated a systemd service, but once I got over that mental hurdle it turned out to be pretty easy to get going.

I installed dict with pacman (sudo pacman -S dict), since it was available in the default Arch package repositories, but then I also installed some dictionaries for it from the AUR:

As you can see my short script, I generally just rely on the WordNet dictionary, but the others are installed locally, so if I want to use them they're just a simple call to dict away!

And lastly, as a slight addendum to the addendum, there's also a pretty cool Emacs-based integration with dict. Getting that to work only required adding the following snippet to my Emacs config.

(use-package dictionary
  :ensure t
  :bind (("C-c d" . dictionary-lookup-definition))
  :config (setq dictionary-server "localhost"))

Comments