The power of GNU Readline - part 2 (HPR Show 2453)

Dave Morriss

Table of Contents

Recap of Keys and Notation

(Feel free to skip this if you are up to speed with the keys and notation we used before.)

In the last episode we saw that most of the features in GNU Readline are invoked by multi-key sequences. These involve the Control key and the so-called Meta key. The Control key is usually marked Ctrl on the keyboard. The Meta key is the key marked Alt.

The notation used in the GNU Readline manual is C-k for ‘Control-k’, meaning the character produced when the k key is pressed while the Control key is being held down.

For the Meta key the notation M-k (Meta-k) means the character produced when the k key is pressed while the Meta key is being held down.

If your keyboard does not have a Meta key then the same result can be obtained for M-k by pressing the Esc key, releasing it, then pressing the k key.

In some instances both the Control and the Meta key might be used, so M-C-k would mean the character produced when the k key is pressed while the Meta and Control keys are being held down.

Note that in the last episode we looked at C-d as a way of deleting the character under the cursor (the same as the Del key, at least in my case). This key sequence has another meaning which we didn’t cover. If the input line is empty and the cursor is on the beginning of the line, C-d sends an ‘end of file signal’. This can stop a script or program waiting for input or kill the terminal emulator amongst other effects.

Key sequences and the desktop

Depending on which desktop you use you might find that some of the key sequences used by GNU Readline do not work the way they are documented.

One of the areas of confusion is with the Backspace and Delete keys. In my experience of using various flavours of Unix over the years (SunOS, Solaris, DomainOS, HP-UX, Ultrix, OSF/1, TRU64 Unix), the behaviour of these keys was the cause of much confusion.

As explained in the initial part of this article the original was in the context of paper tape. The Backspace key would move the tape backwards one place and the Delete key would then overpunch the position with all 1’s, a bit like the way typists used to cancel out an individual character on a typewriter.

The behaviour of using the Backspace key for deleting characters backward, and the Delete key for deleting the character under the cursor did not really settle down until the late 1990’s.

Going in for the kill

The term kill is used in the GNU manual to mean deleting text while saving it away for later. There you will also find the term yank meaning to re-insert deleted text back again. This is a bit confusing (not consistent with sed or vim for example) so I will not be using these terms (though I’ll refer to them in the notes for completeness).

As they point out, the more modern terminology for these actions is cut and paste.

Deleted (cut or killed) text is stored in a place called the kill-ring and can be restored. Consecutive kills cause the text to be accumulated into one unit which can be yanked (pasted) all at once. Commands which do not kill text separate the chunks of text on the kill ring.

C-k (Control-k)
Delete (Kill) the text from the current cursor position to the end of the line. Deletes everything to the right.
M-d (Meta-d)
Delete (Kill) forward from the cursor to the end of the current word, or, if between words, to the end of the next word. Word boundaries are the same as those used by M-f (move forward a word).
The space after the word is not deleted and the space before it is only deleted if the cursor is there.
M-DEL (M-Backspace) (Meta-DEL or Meta-Backspace)
Delete (Kill) backward from the cursor to the start of the current word, or, if between words, to the start of the previous word. Word boundaries are the same as those used by M-b (move backward a word).

Note: I find that this functionality is available as M-Backspace on my workstation, not as M-DEL.

This feature is very useful for deleting a filename component for example. We’ll look at this in the Examples section below.
C-w (Control-w)
Delete (Kill) backwards from the cursor to the previous whitespace. This is different from M-DEL because the word boundaries differ.
C-y (Control-y)
Paste (Yank) the most recently killed text back into the buffer at the cursor.
M-y (Meta-y)
Rotate the kill-ring, and paste (yank) the new top. You can only do this if the prior command is C-y or M-y.


Example 1

Type the following on the command line and position the cursor to the ‘m’ of miles (Hint: you can use the M-b command repeatedly for this). The circumflex (‘^’) below the line shows the cursor position:

$ echo How many miles to Babylon

Press C-k, that is, hold the Control key and press k. The text from the cursor to the end of the line is deleted. Move the cursor to the start of the string over the ‘H’ of How (you could press M-b twice):

$ echo How many

Press C-y to paste (yank) back the text we deleted (killed):

$ echo miles to BabylonHow many
miles to BabylonHow many

Not particularly useful, but you get the idea.

Example 2

As root you want to check various log files. First the mosquitto log:

$ tail /var/log/mosquitto/mosquitto.log

Of course, you will have created this line in the first place by typing:

$ tail /var/log/mos

then pressing the Tab key to get:

$ tail /var/log/mosquitto/

Then pressing Tab again fills in the rest (assuming your /var/log/mosquitto/ directory only contains files starting with mosquitto.log).

Now you might want to check the system log in case it holds any clues to the problem you’re investigating, so you recall the last line:

$ tail /var/log/mosquitto/mosquitto.log

You press M-Backspace three times to delete the last three elements and get:

$ tail /var/log/

You can then type syslog to get the command:

$ tail /var/log/syslog

As one last demonstration: if you were to remove the syslog you just typed using M-Backspace you would be able to restore it with C-y, then if you typed M-y you’d see syslog replaced by mosquitto/mosquitto.log.

This is because the ‘kill ring’ contained the syslog text after it had been deleted, but it also contained the earlier deletion. After typing Ctrl-y to restore the last deletion the key sequence M-y rotated the ring and restored the original deletion. You can repeat M-y to repeat this process with the kill ring.

Hopefully you can see the power of GNU Readline to do some useful stuff when creating and editing a command.