Expandables
DIY Text Expander
![](/var/linux_magazin/storage/images/issues/2014/162/workspace-text-expander/popov_dimitri.png/613653-1-eng-US/Popov_Dimitri.png_medium.png)
A couple of utilities and a dash of Bash scripting are all you need to roll out a simple yet flexible text expander.
A tool that can expand abbreviations and insert ready-made text snippets can come in handy in many situations. With a bit of Bash scripting and a couple of existing utilities, you can easily build your own text expander and learn a few clever techniques in the process.
The starting point of this project is a simple Bash script published on the Arch Linux forum [1]. This nifty script uses a combination of the XSel [2] and xdotool [3] tools to replace an abbreviation with the related text snippet (Listing 1). The xdotool, which simulates keyboard input and mouse activity, is used to select and cut the abbreviation text (by simulating the Ctrl+Shift+Left Arrow and Ctrl+X keyboard shortcuts).
Listing 1
The Original Snippy Bash Script
The cut abbreviation is then set as the X selection with the XSel tool. The script then fetches the appropriate text file and copies its contents as the X selection. Finally, the xdotool pastes the copied contents by simulating the Ctrl+V keyboard shortcut. So, when you type foo
and run the script, it replaces the abbreviation with the contents of the ~/.snippy/foo
text file.
With a bit of creative tweaking, this script can be adapted for other text-expansion tasks, too. Before you start tweaking the script, however, you need to install the required packages. XSel and xdotool are available in the software repositories of most mainstream Linux distributions, so you can install both utilities using your distro's package manager. On Debian and Ubuntu, this can be done by running the apt-get install xsel xdotool
command as root. To do the same on openSUSE, run the zypper install xsel xdotool
command as root.
Next, create the .snippy
directory and populate it with files containing text snippets. Create a new script file, paste the contents of Listing 1 in it, and save as the snippy.sh
file. Make the script executable using the chmod +x snippy.sh
command, and then test the script to make sure it works. If the script doesn't behave properly, the most likely cause is the default 12ms delay that xdotool inserts between keystrokes. This problem is easy to fix by adding the --delay 0
parameter to all xdotool key
commands, for example:
xdotool key --delay 0 ctrl+shift+Left
The original Snippy Bash script is essentially a one-trick pony: Expanding abbreviations is all it can do. The good news is that you can easily repurpose the script for other uses. Suppose you often work on articles containing light HTML markup, such as <em></em>
for italics, <strong></strong>
for bold, and so on. Instead of adding these tags manually, you can create a simple Bash script that inserts the tags around the currently selected text fragment:
#!/bin/bash xdotool key --delay 0 ctrl+x SELECTION=`xsel -b` echo ""${SELECTION}"" | xsel -b -i xdotool key --delay 0 ctrl+v xdotool key --delay 0 BackSpace
The script cuts the selected text fragment and sets it as the X selection. The echo "<em>"${SELECTION}"</em>"
command wraps the selection into the specified tags (<em></em>
in this case) and passes the wrapped string to the X selection. Then, xdotool inserts the selection into the text file. Obviously, running the script manually every time you need to insert tags is not very practical, so you might want to assign a keyboard shortcut to it. To do this on KDE, select Configure Desktop from the Kicker and switch to Shortcuts and Gestures. You can then assign a new global command/URL shortcut to the script.
Of course, if you want to add other formatting options like italics or underlining, you have to create a separate script for each markup tag pair and assign a keyboard shortcut to the script. Alternatively, you can opt for a more practical approach that combines all formatting options in one script. One way to do this is by adding a dialog box to the script, which prompts the user to select the desired formatting option.
On KDE, you can use the kdialog software to add a simple combo box containing a drop-down list as shown in Listing 2. In this example, the kdialog --combobox "Text style:" "Italics" "Bold"
command generates a combo box with two entries: Italics and Bold. The return value (i.e., the selected item) is assigned to the CHOICE
variable, and the if
… then
… elif
part of the script wraps the selection into the appropriate tags.
Listing 2
Bash Script with a Combo Box
Adding kdialog to the mix lets you extend the formatting script even further. For example, you can repurpose the script for looking up selected words in online references:
#!/bin/bash xdotool key --delay 0 ctrl+c SELECTION=`xsel -b` URL=$(kdialog --combobox "Reference:" \ "https://www.google.com/search?q=define:" \ "http://en.wikipedia.org/wiki/") xdg-open $URL${SELECTION}
The script prompts the user to select the URL of the desired online reference and then uses the xdg-open
command to open a query link in the default browser.
You can also tweak the script to add a hyperlink to a text selection (e.g., <a href="http://linux-magazine.com">Linux Magazine</a>
):
#!/bin/bash xdotool key --delay 0 ctrl+x SELECTION=`xsel -b` URL=$(kdialog --title "Enter URL" --inputbox "URL") echo "<a href='"$URL"'> "${SELECTION}"</a>" | xsel -b -i xdotool key --delay 0 ctrl+v xdotool key --delay 0 BackSpace
Instead of creating a separate script, you can integrate this code into the formatting script as shown in Listing 3.
Listing 3
Extended Version of Formatting Script
In Gnome, you can use the Zenity software to add graphical dialogs and input boxes, but what if you use both Gnome and KDE on different machines? Enter easybashgui [4].
Introducing easybashgui
Zenity, Gtkdialog, kdialog – plenty of libraries are available to add graphical elements to your scripts. The problem is that each of these libraries is tied to a specific platform: kdialog works on KDE, whereas Zenity is designed for use with Gnome and GTK-based desktop environments. This restriction makes it tricky to write scripts that work on different graphical desktops without tweaking. Easybashgui provides a clever solution to this problem. This toolkit offers GUI functions that use any of the supported libraries, including yad, gtkdialog, kdialog, Zenity, Xdialog, Whiptail, and Bash built-ins. This approach lets you add graphical elements using the same set of functions on any desktop environment, as long as one of the supported libraries is installed on it.
Although easybashgui is distributed only as source code, compiling and deploying it on any Linux distribution is not particularly difficult. To begin, you need to install tools for building software from source code. To do this on Debian and Ubuntu, run the apt-get install build-essential
command as root. On openSUSE, you can use the zypper install --type pattern devel_basis
to do the same. Next, grab the latest release of easybashgui from the project's website and extract the downloaded tarball. In the terminal, switch to the resulting directory and run the make install
command as root.
Using easybashgui is equally easy. First, you need to include the easybashgui library into the Bash script using the source easybashgui
statement and then use one of the available functions to add graphical elements. Here is a simple example that displays the "Hello world!" message (Figure 1):
![](/var/linux_magazin/storage/images/issues/2014/162/workspace-text-expander/figure-1/613656-1-eng-US/Figure-1_large.png)
#!/bin/bash source easybashgui message "Hello world!"
Adapting the scripts described previously for use with easybashgui requires only a few minor changes. For example, the lookup script that uses the easybashgui menu
function (Figure 2) to display a list of options is shown in Listing 4.
Listing 4
Lookup Script
![](/var/linux_magazin/storage/images/issues/2014/162/workspace-text-expander/figure-2/613659-1-eng-US/Figure-2_large.png)
The only notable change in the listing is the URL="$(0< "${dir_tmp}/${file_tmp}")"
line. Easybashgui stores output in the {dir_tmp}/${file_tmp}
temporary file, so to retrieve the stored values, you need to use the 0< "${dir_tmp}/${file_tmp}"
command.
Easybashgui offers functions for adding key graphical elements and can view a complete list of all available functions along with their descriptions on the project's website [5].
Final Word
Of course, the described Bash scripts won't replace a powerful and versatile tool like Autokey, but they do have some advantages. The scripts have only a few dependencies, and they are light on resources. That means the scripts are easy to deploy on practically any Linux distribution, and they are suitable for use on older machines. Additionally, thanks to easybashgui, the scripts will work fine on any graphical desktop.
Dmitri Popov
Dmitri Popov has been writing exclusively about Linux and open source software for many years, and his articles have appeared in Danish, British, US, German, Spanish, and Russian magazines and websites. Dmitri is an amateur photographer, and he writes about open source photography tools on his Scribbles and Snaps blog at http://scribblesandsnaps.com.
Infos
- Snippy thread: http://bbs.archlinux.org/viewtopic.php?id=71938
- XSel: http://www.vergenet.net/~conrad/software/xsel/
- Xdotool: http://www.semicomplete.com/projects/xdotool
- Easybashgui: http://sites.google.com/site/easybashgui
- Easybashgui functions: http://sites.google.com/site/easybashgui/easy-bash-functions
Buy this article as PDF
(incl. VAT)