Expandables

DIY Text Expander

Article from Issue 162/2014
Author(s):

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

01 #!/bin/bash
02 # read the abbreviation
03 xdotool key ctrl+shift+Left
04 xdotool key ctrl+x
05 sleep 0.2s # to work reliably in Firefox
06 SELECTION=`xsel -b`
07 # read snippet file
08 xsel -b -i < ~/.snippy/${SELECTION}
09 # paste snippet
10 xdotool key ctrl+v
11 xdotool key BackSpace # delete the last blank line, so we stay inline

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 ifthenelif part of the script wraps the selection into the appropriate tags.

Listing 2

Bash Script with a Combo Box

01 #!/bin/bash
02 xdotool key --delay 0 ctrl+c
03 SELECTION=`xsel -b`
04 CHOICE=$(kdialog --combobox "Formatting option:" "Italics" "Bold")
05 if [ "${CHOICE}" = "Italics" ]
06         then
07                 echo ""${SELECTION}"" | xsel -b -i
08         elif [ "${CHOICE}" = "Bold" ]
09         then
10                 echo "<strong>"${SELECTION}"</strong>" | xsel -b -i
11 fi
12 xdotool key --delay 0 ctrl+v
13 xdotool key --delay 0 BackSpace

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

01 #!/bin/bash
02 xdotool key --delay 0 ctrl+c
03 SELECTION=`xsel -b`
04 CHOICE=$(kdialog --combobox "Formatting option:" "Italics" "Bold" "Hyperlink")
05 if [ "${CHOICE}" = "Italics" ]
06         then
07                 echo ""${SELECTION}"" | xsel -b -i
08         elif [ "${CHOICE}" = "Bold" ]
09         then
10                 echo "<strong>"${SELECTION}"</strong>" | xsel -b -i
11         elif [ "${CHOICE}" = "Hyperlink" ]
12         then
13                 URL=$(kdialog --title "Enter URL" --inputbox "URL")
14                 echo "<a href='"$URL"'>"${SELECTION}"</a>" | xsel -b -i
15 fi
16 xdotool key --delay 0 ctrl+v
17 xdotool key --delay 0 BackSpace

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):

Figure 1: Simple message box generated with easybashgui.
#!/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

01 #!/bin/bash
02 source easybashgui
03 xdotool key --delay 0 ctrl+c
04 SELECTION=`xsel -b`
05 menu "https://www.google.com/search?q=define:" "http://en.wikipedia.org/wiki/"
06 URL="$(0< "${dir_tmp}/${file_tmp}" )"
07 xdg-open $URL${SELECTION}
Figure 2: Easybashgui-based lookup script.

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.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus

Direct Download

Read full article as PDF:

Price $2.95

News

njobs Europe
What:
Where:
Country:
Njobs Netherlands Njobs Deutschland Njobs United Kingdom Njobs Italia Njobs France Njobs Espana Njobs Poland
Njobs Austria Njobs Denmark Njobs Belgium Njobs Czech Republic Njobs Mexico Njobs India Njobs Colombia