September 21, 2017 · linux python scripts software

Desktop Snippets

Fuzzy search snippets for the desktop.

The problem

During everyday computer use, there are several non-trivial things that must be
typed fairly often. Things like your email address or ¯\_(ツ)_/¯. Usually
this means typing it out in full, or navigating to somewhere like and copying emojis from there. In the spirit of
automating everything and efficiency, let's see if we can improve on this!

The idea

So, what if I could press a key sequence, fuzzy search for a "snippet" by name, and
instantly have it typed or copied to the clipboard?

The solution

After some fiddling around with bash and python scripts, I managed to work out
a solution that seems to work pretty well! Simply put, it does the following:

  1. Load in a yaml file containing name: snippet entries.
  2. Launch rofi with the snippet names for fuzzy search.
  3. Copy the corresponding snippet to the clipboard or use xdotool to type it out.

view of fuzzy searching snippets with rofi

The script can be called with python copy|type path/to/database.yml. This can be set up with a keybinding for launching, for
example in i3:

bindsym Mod4+z exec type ~/Documents/snippets.yml
bindsym Mod4+Shift+z exec copy ~/Documents/snippets.yml

Now the workflow becomes: press Mod4+z, type a couple of characters from the
snippet name, press Enter, and it gets instantly typed into the active
window! Alternatively, Mod4+Shift+z to copy the snippet to the clipboard.

The code

For reference, the code (current version) and an example snippets file is
below. Note: the code is also available on GitHub.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright © 2017 Samuel Walladge
# fuzzy search for text snippets to copy to clipboard
# depends on PyYaml, rofi, xsel, xdotool, and a yaml file containing key:snippet pairs

import yaml
import sys
import subprocess

COPY = 'copy'
TYPE = 'type'

if len(sys.argv) < 3:
    print('Usage: copy|type YAML_DB_FILENAME')

mode = sys.argv[1]
db_filename = sys.argv[2]

if mode not in (COPY, TYPE):
    print('Invalid mode! Must be either copy or type.')

    # { 'name': 'snippet' }
    db = yaml.load(open(db_filename))
except Exception as e:
    print('Failed to load database file ({!r})!'.format(db_filename))
    print('Ensure that it exists and is a valid yaml file.\n')

keys = '\n'.join(db.keys())
result =['rofi', '-dmenu', '-no-custom', '-p', 'snippet:', '-matching', 'fuzzy'],
        input=keys, stdout=subprocess.PIPE, encoding='utf-8')
if result.returncode != 0:

key = result.stdout.strip()
snippet = db.get(key, None)
if snippet is None:

# copy to primary and clipboard selection
if mode == COPY:['xsel', '-ip'], encoding='utf-8', input=str(snippet))['xsel', '-ib'], encoding='utf-8', input=str(snippet))
elif mode == TYPE:['xdotool', 'type', '--', snippet], encoding='utf-8')

Example snippets file. I chose yaml because it's simple and way more flexible that json for hand editing.

# snippets file for
# keys are snippet names (able to be fuzzy searched on)
# values are the snippets themselves - values can be multiline if required too

shrug: ¯\_(ツ)_/¯
koala emoji: ʕ•ᴥ•ʔ
disapproval emoji: ಠ_ಠ
table flip: (╯°□°)╯︵ ┻━┻

It's all pretty hacky and simple, but it works nicely. Hope this will be useful
to someone! Comments, feedback, or suggestions for improvement welcome!