Previous Section  < Day Day Up >  Next Section

2.7. readline

bash's command-line editing interface is readline. It is actually a library of software developed for the GNU project that can be used by applications requiring a text-based interface. It provides editing and text-manipulation features to make it easier for the user to enter and edit text. Just as importantly, it allows standardization, in terms of both key strokes and customization methods, across all applications that use it.

readline provides default editing in either of two modes: vi or emacs. Both modes provide a subset of the editing commands found in the full editors. We've already looked at the command sets of these modes in the previous sections of this chapter. We'll now look at how you can make your own command sets.

readline gives bash added flexibility compared to other shells because it can be customized through the use of key bindings, either from the command line or in a special startup file. You can also set readline variables. We'll see how you can set up readline using your own startup file now, and then go on to examine how the binding capability can be used from the command line.

2.7.1. The readline Startup File

The default startup file is called .inputrc and must exist in your home directory if you wish to customize readline. You can change the default filename by setting the environment variable INPUTRC (see Chapter 3 for further information on environment variables).

When bash starts up, it reads the startup file (if there is one) and any settings there come into effect. The startup file is just a sequence of lines that bind a keyname to a macro or readline function name. You can also place comments in the file by preceding any line with a #.

You can use either an English name or a key escape sequence for the keyname. For example, to bind CTRL-T to the movement command for moving to the end of the current line, you could place Control-t: end-of-line in your .inputrc. If you wanted to use a key escape sequence you could have put "\C-t<">: end-of-line. The \C- is the escape sequence prefix for Control. The advantage of the key sequence is that you can specify a sequence of keys for an action. In our example, once readline has read this line, typing a CTRL-T will cause the cursor to move to the end of the line.

The end-of-line in the previous example is a readline function. There are over 60 functions that allow you to control everything from cursor motions to changing text and command completion (for a complete list, see the bash manual page). All of the emacs and vi editing mode commands that we looked at in this chapter have associated functions. This allows you to customize the default modes or make up completely new ones using your own key sequences.

Besides the readline functions, you can also bind a macro to a key sequence. A macro is simply a sequence of keystrokes inside single or double quotes. Typing the key sequence causes the keys in the macro to be entered as though you had typed them. For example, we could bind some text to CTRL-T; "\C-t<">: <">Curiouser and curiouser!<">. Hitting CTRL-T would cause the phrase Curiouser and curiouser! to appear on the command line.

If you want to use single or double quotes in your macros or key sequence, you can escape them by using a backslash (\). Table 2-18 lists the common escape sequences.

Table 2-18. Escape sequences

Sequence

Description

\C-

Control key prefix

\M-

Meta (Escape) key prefix

\e

The escape character

\\

The backslash character (\)

\<">

The double quote character (<">)

\'

The single quote character (')


readline also allows simple conditionals in the .inputrc. There are three directives: $if, $else, and $endif. The conditional of the $if can be an editing mode, a terminal type, or an application-specific condition.

To test for an editing mode, you can use the form mode= and test for either vi or emacs. For instance, to set up readline so that setting CTRL-T will take place only in emacs mode, you could put the following in your .inputrc:

$if mode=emacs

"\C-t": "Curiouser and curiouser!"

$endif

Likewise, to test for a terminal type, you can use the form term=. You must provide the full terminal name on the right-hand side of the test. This is useful when you need a terminal-specific key binding. You may, for instance, want to bind the function keys of a particular terminal type to key sequences.

If you have other applications that use readline, you might like to keep your bash-specific bindings separate. You can do this with the last of the conditionals. Each application that uses readline sets its own variable, which you can test for. To test for bash specifics, you could put $if bash into your .inputrc.

2.7.1.1 readline variables

readline has its own set of variables that you can set from within your .inputrc. Table 2-19 lists them.[10]

[10] The variables disable-completion, enable-keypad, input-meta, mark-directories, and visible-stats are not available in versions of bash prior to 2.0.

Table 2-19. readline variables

Variable

Description

bell-style

If set to none, readline never rings the bell (beeps). If set to visible, readline will attempt to use a visible bell. If set to audible, it will attempt to ring the bell. The default is audible.

comment-begin

The string to insert when the readline insert-comment command is executed. The default is a #.

completion-query-items

Determines when the user is asked to see further completions if the number of completions is greater than that given. The default is 100.

convert-meta

If set to On, converts characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prepending an escape character. The default is On.

disable-completion

If set to On, inhibits word completion. Completion characters will be inserted into the line as if they had been mapped to self-insert. The default is Off.

editing-mode

Sets the editing mode to vi or emacs.

enable-keypad

If set to On, readline tries to enable the keyboard's application keypad when it is called. Some systems need this to enable the arrow keys. The default is Off.

expand-tilde

If set to On, tilde expansion is attempted when readline attempts word completion. The default is Off.

horizontal-scroll-mode

Set to On means that lines will scroll horizontally if you type beyond the right-hand side of the screen. The default is Off, which wraps the line onto a new screen line.

input-meta

If set to On, eight-bit input will be accepted. The default is Off. This is synonymous with meta-flag.

keymap

Sets readline's current keymap for bindings. Acceptable names are emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command and vi-insert. The default is emacs. Note that the value of editing-mode also affects the keymap.

mark-directories

If set to On, completed directory names have a slash appended.

mark-modified-lines

If set to On, displays an asterisk at the start of history lines that have been modified. The default is Off.

meta-flag

If set to On, eight-bit input will be accepted. The default is Off.

output-meta

If set to On, displays characters with the eighth bit set directly. The default is Off.

show-all-if-ambiguous

If set to On, words with more than one possible completion are listed instead of ringing the bell. The default is Off.

visible-stats

If set to On, a character denoting a file's type as reported by the stat system call is appended to the filename when listing possible completions. The default is Off.


To set any of the variables, you can use the set command in your .inputrc. For example, to set vi-mode when you start up, you could place the line set editing-mode vi in your .inputrc. Every time bash starts it would change to vi-mode.

2.7.2. Key Bindings Using bind

If you want to try out key bindings or you want to see what the current settings are, you can do it from the bash command line by using the bind command. The binding syntax is the same as that of the .inputrc file, but you have to surround each binding in quotes so that it is taken as one argument.

To bind a string to CTRL-T, we could type bind `"\C-t<">: <">Curiouser and curiouser!"'. This would bind the given string to CTRL-T just as in the .inputrc, except that the binding will apply only to the current shell and will cease once you log out.

bind also allows you to print out the bindings currently in effect by typing bind -P.[11] If you do so, you'll see things like:

[11] Versions of bash prior to 2.0 use -d instead of -p, and -v instead of -P. Also, the -r, -V, -S, -s, -u, and the new -v and -x options are not available in these older versions.

abort can be found on "\C-g", "\C-x\C-g", "\e\C-g".

accept-line can be found on "\C-j", "\C-m".

alias-expand-line is not bound to any keys

arrow-key-prefix is not bound to any keys

backward-char can be found on "\C-b", "\eOD", "\e[D".

...

If you just want to see the names of the readline functions, you can use bind -l.

You can also unbind a function by using bind -u along with the name of the function; all keys for that function will then be unbound. Unbinding a key sequence can be done with bind -r followed by the sequence.

bind -x is useful if you want to bind a shell command to a key sequence. For example, bind -x `"\C-l":ls' binds CTRL-L to the ls command. Hitting CTRL-L would then give a directory listing.

Another option you might find useful is -p. This prints out the bindings to standard output in a format that can be re-read by bind, or used as a .inputrc file. So, to create a complete .inputrc file that you can then edit, you could type bind -p > .inputrc.

To read the file back in again you can use another option, -f. This option takes a filename as its argument and reads the key bindings from that file. You can also use it to update the key bindings if you've just modified your .inputrc.

    Previous Section  < Day Day Up >  Next Section