I created a custom bash script inspired by Dmtri Popov's "snippy" script featured in Linux Magazine (2014). This script allows me to expand typed abbreviations into full text.
I keep all my snippets in separate text files in a dedicated directory, $HOME/.local/share/snippy. Each file is named according to the abbreviation I want to use to insert the snippet.
To insert a snippet, I simply type its abbreviation and press Ctrl+,. The script 1) identifies the abbreviation based on the word before the cursor; 2) locates the corresponding snippet file within the snippy directory, and 3) replaces the typed abbreviation with the full contents of the file.
This approach allows for quick and efficient insertion of frequently used text snippets while keeping them organized and easily accessible.
Setting it up
Step 1. Install the script snippy
a) Copy the following code into a text file called snippy.
#!/bin/bash
# Dependencies: wl-clipboard (Wayland) or xclip (x11); dotool (https://sr.ht/~geb/dotool/)
sleep_time=0.2
snippets_dir=$HOME/.local/share/snippy
f_saved_clipboard=$(mktemp)
flag_gnome_copied_files=0
if [ -z ${XDG_SESSION_TYPE+x} ] ; then
echo "XDG_SESSION_TYPE is not set. Please set to 'x11' or 'wayland'" ; exit
else
if [ "$XDG_SESSION_TYPE" = 'x11' ] ; then
copy_to_clip="xsel -bi"
paste_from_clip="xsel -bo"
else
copy_to_clip="wl-copy -n"
paste_from_clip="wl-paste -n"
fi
fi
Select word before cursor and read name of clip from primary clipboard
echo key ctrl+shift+left | dotoolc
sleep 0.1
selected_clip="$snippets_dir/$(wl-paste -n -p)"
Load and paste selected clip if it is valid
echo "$selected_clip" > ~/debug.txt
if [ -f "$selected_clip" ] ; then
# Save the current clipboard
if [[ $(wl-paste --list-types | grep x-special/gnome-copied-files) == "x-special/gnome-copied-files" ]] ; then
flag_gnome_copied_files=1
$paste_from_clip --type x-special/gnome-copied-files > "$f_saved_clipboard"
else
$paste_from_clip > "$f_saved_clipboard"
fi
# Load and paste the selected clip
$copy_to_clip < "$selected_clip"
sleep $sleep_time
echo key ctrl+v | dotoolc
# Restore the clipboard
sleep 0.4
if [ $flag_gnome_copied_files = "1" ] ; then
$copy_to_clip --type x-special/gnome-copied-files < "$f_saved_clipboard"
else
$copy_to_clip < "$f_saved_clipboard"
fi
rm $f_saved_clipboard
else
echo key ctrl+right | dotoolc
fi
b) Move the script to ~/.local/bin. Create the directory if it does not yet exist.
If you had to create the directory, then log out then back in to Ubuntu before continuing. That way, the newly created directory will be included in the PATH.
c) Make the script executable:
You can do that with the terminal: chmod +x ~/.local/bin/snippy. Else, locate the file in the file manager, right-click the file and select "Properties" and turn the checkmark "Executable as a program" on.
Step 2. Install a clipboard manipulation tool
Install wl-clipboard, a command line tool to manipulate the clipboard on wayland. If on Xorg, then install xclip instead.
sudo apt install wl-clipboard # If you run Wayland
sudo apt install xclip # If you run Xorg
Step 3. Install a keyboard automation tool
Install dotool. dotool (https://sr.ht/~geb/dotool/) unfortunately is not available in the Ubuntu software repository. However, it is easy to compile and install it, based on the instructions on the website.
a) Download the archive file with the source code: On the tab "Source" of the website https://sr.ht/~geb/dotool/, download the .tar.gz archive of the release version (currently 1.4, https://git.sr.ht/~geb/dotool/archive/1.4.tar.gz).
b) Extract the archive file. In the standard version of Ubuntu, you can do that by right-clicking the archive and selecting "Extract here". This creates a directory with the same name of the archive file, without the .tar.gz extension (currently: dotool-1.4).
c) Open a terminal in that directory. With "Files", you can right-click the directory created in step b) and select "Open in terminal". Alternatively, open the terminal and use the cd command to change to the created directory, for example cd ~/Downloads/dotool-1.4.
d) Install the requirements: go, libxkbcommon-dev and scdoc
sudo apt install golang-go
sudo apt install libxkbcommon-dev
sudo apt install scdoc
e) Compile and install:
./build.sh && sudo ./build.sh install
f) Trigger the udev rule
sudo udevadm control --reload && sudo udevadm trigger
Note: You could instead use ydotool. This tool can, in principle, be installed more easily because it is in the Ubuntu software repositories. However, the version shipping with Ubuntu 22.04 is old and outdated. A more recent version also must be compiled. Obviously, the dotoolc commands in the script then must be replaced by equivalent ydotool commands.
Step 4. Set up dotool
You now should have access to the manual: man dotool. It indicates you may need to add yourself to the group input. On Ubuntu, that is needed. Execute following commands to create the group (if it does not yet exist) and add your user to it.
sudo groupadd -f input
sudo usermod -a -G input $USER
Now reboot the system to make sure that the changes are properly implemented.
When logged back in, test whether dotool works. Open a terminal and execute
echo type hello | dotool
You succesfully installed dotool if you see the word hello typed at the terminal. Each time dotool runs, it needs to create a virtual keyboard. This causes some delay. To avoid such delay, we will autostart a daemon, dotoold, and use dotoolc to do keyboard automation using the daemon.
Step 5. Set up a systemd user service
a) Install the user service file
Run following code in the terminal to automatically install a user service file:
cat > ~/.config/systemd/user/dotool.service << EOF
[Unit]
Description=dotool keyboard automation daemon
[Service]
ExecStart=/usr/local/bin/dotoold
[Install]
WantedBy=default.target
EOF
b) Enable the service
systemctl --user enable dotool
Log out then back in (or instead just start the service manually: systemctl --user start dotool. Check whether the service is succesfully loaded with the command:
echo type hello | dotoolc
Note how we now used dotoolc instead of dotool. And note how much speedier hello was typed now.
Step 6. Set up a shortcut key
Set up a shortcut key that triggers the script using the facility of your desktop environment. In standard Ubuntu:
- head to "Settings" - "Keyboard".
- Under "Keyboard Shortcuts", click "View and customize shortcuts". The "Keyboard Shortcuts" dialog appears.
- Select "Custom shortcuts". The "Custom Shortcut" dialog appears.
- Click "+" and in the "Custom Shortcut" dialog, enter: Name: "Snippy", Command: "snippy" then click "Set shortcut". Now press the shortcut you want to use. I use Ctrl+,. Hit the green "Done" button and close the dialogs.
Step 7. Set up your snippets
Create a directory ~/.local/share/snippy. In that directory, store your text snippets, i.e., text files which you name according to the abbreviation name you want to use. For example, we create a text file named dt that contains the text:
"dotool reads actions from stdin and simulates keyboard/mouse input using Linux's uinput module. It works systemwide and supports keyboard layouts."
Step 8. Test
Open a text editor and type dt. Now hit the shortcut key. If the abbreviation is not correctly expanded, you may need to edit the script to increase sleep_time=0.2 to e.g 0.3 (0.3 seconds). However, you also may try reducing that time. On my system, I can set it at 0.
Unfortunately, on Wayland implementations different from wlroots, wl-clipboard needs to create a (transparent) window to gain access to the clipboard. This causes flickering. When using a dock, this causes application icons to be briefly created and displayed.