In-line editing provides the ability to edit the current or previous commands before executing them. There are three in-line editing modes available: emacs, gmacs, and vi. The in-line editing mode is specified by setting the EDITOR or VISUAL variables, but if neither variable is set, the default is /bin/ed. The in-line editing mode can also be specified with the set o command like this: $ set o option where option can be emacs, gmacs, or vi. This is usually specified in your $HOME/.profile file. The size of the editing window is specified by the COLUMNS variable. The default is 80, unless COLUMNS is set. Some systems use the window size as the default. The size of your command prompt also affects the width of the editing window. In the examples in the following sections, the Before column shows what was displayed at the prompt, the Command column lists the edit mode command, and the After column displays the result. The underbar character (_) represents the cursor. Control characters are given as Ctl followed by the character in bold face. For example, Ctl-h specifies Control-h and is entered by pressing the h key while holding down the Control key. Vi Edit Mode If you know the Unix vi text editor, then learning how to use the vi inline editor is relatively easy. The vi in-line editor is a subset of the vi editor program, so most of the commands are the same. In vi edit mode, there are two operating modes: input and command. Operating in and out of input mode is virtually the same. Commands are entered and executed just as if you were not using the in-line editor. As soon as you press the <Escape> key, you are put in command mode. This is where you can enter your vi commands to access and edit commands from the history file, or current command line. Input Mode Once the vi edit mode is set, you are placed in input mode. If the vi mode is set in your .profile file, then you are automatically in input mode whenever the Korn shell starts up. As stated in the previous section, operating in and out of vi input mode is virtually the same. The next example shows some of the basic vi input mode commands. We start with 'print Hi again world'. The Ctl-w commands delete the strings world, and again, then the Ctl-h command deletes i. The @ command kills the entire line, and we get a new command prompt. Table 4.1. Vi Input Mode Commands Ctl-h, #, <Backspace> | delete the previous character (system dependent) | Ctl-d | terminate the shell | Ctl-x, @ | kill the entire line (system dependent) | <Return> | execute the current line | \ | escape the next Erase or Kill character | Ctl-v | escape the next character | Ctl-w | delete the previous word | Before | Command | After |
---|
$ print Hi again world_ | Ctl-w | $ print Hi again _ | $ print Hi again _ | Ctl-w | $ print Hi _ | $ print Hi _ | Ctl-h | $ print Hi_ | $ print Hi_ | Ctl-h | $ print H_ | $ print H_ | Ctl-h | $ print _ | $ print _ | @ | $ _ | The Erase and Kill characters can be set with the stty command. Command Mode When you press the <Escape> key in vi input mode, you are put in command mode. This is where the vi commands can be given to edit a single command from the history file. Editing commands can be given until the <Return> key is pressed, then the result is executed. To cancel current editing, press the <Escape> key again. If you enter an invalid command, or a search command fails, the Korn shell will cause your terminal to beep or flash. Table 4.2 lists the basic commands available in command mode. A complete listing of the commands can be found in Appendix E. Moving Around the History File In this example, we navigate through the command history file using some basic vi edit mode commands. Assume that these are the last two commands that were executed: $ history ? 339 pwd 340 date 341 history ? At the command prompt, the <Escape> key is pressed to enter command mode, then a series of k commands are given to successively retrieve the previous command. The j command is given to retrieve the next commands, until we get to the date command. After the <Return> key is pressed, date is executed. Before | Command | After |
---|
$ _ | <Escape>k | $ history -2 | $ history -2 k | $ date | | $ date | k | $ pwd | $ pwd | j | $ date | $ date | <Return> | | Of course, a more efficient way to retrieve the date command would be with a single backward search command, <Escape>/da<Return>. Notice that da is used to match date. Before | Command | After |
---|
$ _ | <Escape>/da<Return> | $ date | $ date | <Return> | | Editing Previous Commands In the next example, we want to change the word Hello to Goodbye in the print command. The <Escape> key is pressed to enter command mode. Then the k command retrieves the last command, and the h command moves the cursor left one character. The b command is given to move the cursor back one word, to the beginning of world. Another b command is given, and the cursor is at the beginning of Hello. Now the cw command is used to change the word Hello, and we can type over the new word Goodbye. When we are finished typing, the <Return> is pressed, and the result is executed. Before | Command | After |
---|
$ print Hello world_ | <Escape> | $ print Hello world | $ print Hello world | h | $ print Hello world | $ print Hello world | b | $ print Hello world | $ print Hello world | b | $ print Hello world | $ print Hello world | cwGoodbye | $ print Goodbye world | $ print Goodbye world | <Return> | | There are a number of ways that the same results could have been achieved. The cursor could have been moved back to Hello using FH (move left to character H), and then deleted using dw (delete word). Goodbye could have then been inserted using the i (insert) command. Table 4.2. Some Vi Command Mode Commands h, <Backspace> | move left one character | l, <Space> | move right one character | b | move left one word | B | move left one word; ignore punctuation | w | move right one word | W | move right one word; ignore punctuation | e | move to the end of the next word | E | move to end of next word; ignore punctuation | ^ | move to beginning of the line | $ | move to end of line | fc | move right to character c | Fc | move left to character c | a | add text after the current character | A | append text to end of the current line | i | insert text left of the current character | rc | replace current character with c | x | delete the current character | u | undo the last text modification command | k | get previous command from history file | j | get next command from history file | /string | search backward in the history file for command that matches string | ?string | search forward in the history file for command that matches string | . | repeat the last text modification command | ~ | toggle the case of the current character | Let's say we want to just add an exclamation point to the print Hello world command. Instead of typing it all over again, we enter <Escape> for command mode and k to get the last command. Then the $ command moves the cursor to the end of the line, and the a! command appends the ! character. After the <Return> key is pressed, print Hello world! is displayed. Before | Command | After |
---|
$ _ | <Escape>k | $ print Goodbye world | $ print Hello world | $ | $ print Hello world | $ print Hello worl d | a! | $ print Hello world! _ | $ print Hello world! _ | <Return> | | Here, a typo is spotted in the chmod command. Instead of backspacing fourteen times to make the correction, or killing the entire line and typing over, we enter command mode by pressing <Escape>. The ^ command moves the cursor to the beginning of the line, and e (end of word) moves it to the s character, where we want to make the correction. The rd command (replace current character with d) is given, followed by <Return> to execute. Before | Command | After |
---|
$ chmos 777 /tmp/foo_ | <Escape> | $ chmos 777 /tmp/foo | $ chmos 777 /tmp/foo | ^ | $ chmos 777 /tmp/foo | $ chmos 777 /tmp/foo | e | $ chmos 777 /tmp/foo | $ chmos 777 /tmp/foo | rd | $ chmod 777 /tmp/foo | $ chmod 777 /tmp/foo | <Return> | | Displaying Long Command Lines For lines longer than the window width, a mark is displayed at the end of the line to indicate the position. Only part of the command is displayed. The text position markers can be: > | line extends to the right of the edit window | < | line extends to the left of the edit window | * | line extends on both sides of the edit window | Moving around the command line makes different parts of the command line visible. If the cursor is moved past the last character, the line is redisplayed with the cursor in the middle of the screen. The COLUMNS variable setting, and the size of your command prompt also affect the width of the editing window. Emacs/Gmacs Edit Modes Like the vi in-line editor, the emacs/gmacs in-line editor is also basically a subset of the same text editors. However, there are a few commands in the emacs/gmacs in-line editors that are not in the regular program. This only difference between the emacs and gmacs editors is the way Ctl-t is handled. In emacs mode, Ctl-t transposes the current and next character. In gmacs mode, Ctl-t transposes the previous two characters. Table 4.3 lists the basic commands available in emacs/gmacs edit mode. Appendix E contains a complete listing of the commands. Editing Commands in Emacs/Gmacs Mode Before we look at some emacs/gmacs in-line editor command examples, here are the last three commands from the history file: $ history r n ? history r n ? grep ksh /etc/passwd print $PATH cd /usr/etc/yp In the following example, the Ctl-n and Ctl-p commands are used to get the next and previous commands from the history file. Assuming that history r n ? just completed execution, the Ctl-p command brings it back, and another Ctl-p goes back to grep. To get back to the cd command, the Ctl-r command is given. The <Return> key is pressed, and the current directory is changed to /usr/etc/yp. Before | Command | After |
---|
$ _ | Ctl-p | $ history -n -3_ | $ history -n -3_ | Ctl-p | $ grep x /etc/passwd_ | $ grep x /etc/passwd_ | Ctl-rcd | $ cd /usr/etc/yp_ | $ cd /usr/etc/yp_ | <Return> | | In the next example, we want to make a correction to the current command line. The Ctl-b commands moves the cursor one character left, then Esc-b moves the cursor one word left. The Ctl-d command deletes character C, and Ctl-]E moves forward to the next E character. The <Return> key is pressed, and the result is executed. Table 4.3. Some Emacs/Gmacs In-Line Edit Commands Ctl-b | move left one character | Ctl-f | move right one character | Esc-b | move left one word | Esc-f | move right one word | Ctl-a | move to beginning of line | Ctl-e | move to end of line | Ctl-]c | move right to character c | Ctl-h | delete preceding character | Ctl-x, @ | kill the entire line | Ctl-k | delete from cursor to end of line | Ctl-d | delete current character | Esc-d | delete current word | Ctl-w | delete from cursor to mark | Ctl-y | undo last delete (w/Esc-p) | Ctl-p | get previous command from history file | Ctl-n | get next command from history file | Ctl-rstring | search backward in history file for command that contains string | Ctl-c | change current character to upper case | Esc-l | change current character to lower case | Esc-p | save to buffer from cursor to mark | Esc-<Space> | mark current location | Ctl-l | redisplay current line | Before | Command | After |
---|
$ print AB CD EF_ | Ctl-b | $ print AB CD EF | $ print AB CD EF | Esc-b | $ print AB CD EF | $ print AB CD EF | Ctl-d | $ print AB D EF | $ print AB D EF | ^E | $ print AB D EF | $ print AB D EF | <Return> | | What about inserting text? To add characters to the command line, in emacs/gmacs mode, you just type them in. Characters are inserted before the cursor. Here we get the last command using Ctl-p. Then we move to the beginning of the line using Ctl-a, and to the next word with Esc-f. Ctl-k deletes to the end of the line, and we insert hello by typing it in. To display hello, we just press <Return>. Before | Command | After |
---|
$ _ | Ctl-p | $ print AB D EF_ | $ print AB D EF_ | Ctl-a | $ print AB D EF | $ print AB D EF | Esc-f | $ print_AB D EF | $ print AB D EF | Ctl-k | $ print_ | $ print_ | hello | $ print hello_ | $ print hello_ | <Return> | | This example shows another way in which a command can be edited using emacs/gmacs mode. The Ctl-a command moves the cursor to the beginning of the line, and ^]s moves to the s character. The Ctl-d command deletes s, then d is typed in. The <Return> key is pressed, and the command is run. Before | Command | After |
---|
$ chmos 777 /tm/foo_ | Ctl-a | $ chmos 777 /tmp/foo | $ chmos 777 /tm/foo | ^]s | $ chmos 777 /tmp/foo | $ chmos 777 /tm/foo | Ctl-d | $ chmo_777 /tmp/foo | $ chmo_777 /tm/foo | d | $ chmod 777 /tmp/foo | $ chmod 777 /tmp/foo | <Return> | | |