diff options
Diffstat (limited to 'libtecla-1.4.1/html/gl_get_line.html')
-rw-r--r-- | libtecla-1.4.1/html/gl_get_line.html | 2295 |
1 files changed, 2295 insertions, 0 deletions
diff --git a/libtecla-1.4.1/html/gl_get_line.html b/libtecla-1.4.1/html/gl_get_line.html new file mode 100644 index 0000000..dcc45a0 --- /dev/null +++ b/libtecla-1.4.1/html/gl_get_line.html @@ -0,0 +1,2295 @@ +<head> +<title>Manual Page</title> +</head> +<body> +<pre> +</pre><h2>NAME</h2><pre> + gl_get_line, new_GetLine, del_GetLine, + gl_customize_completion, gl_change_terminal, + gl_configure_getline, gl_load_history, gl_save_history, + gl_group_history, gl_show_history, gl_watch_fd, + gl_terminal_size, gl_resize_history, gl_limit_history, + gl_clear_history, gl_toggle_history, gl_lookup_history, + gl_state_of_history, gl_range_of_history, + gl_size_of_history, gl_echo_mode, gl_replace_prompt, + gl_prompt_style, gl_ignore_signal, gl_trap_signal, + gl_last_signal - allow the user to compose an input line + +</pre><h2>SYNOPSIS</h2><pre> + #include <stdio.h> + #include <libtecla.h> + + GetLine *new_GetLine(size_t linelen, size_t histlen); + + GetLine *del_GetLine(GetLine *gl); + + char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos); + + int gl_customize_completion(GetLine *gl, void *data, + CplMatchFn *match_fn); + + int gl_change_terminal(GetLine *gl, FILE *input_fp, + FILE *output_fp, const char *term); + + int gl_configure_getline(GetLine *gl, + const char *app_string, + const char *app_file, + const char *user_file); + + int gl_save_history(GetLine *gl, const char *filename, + const char *comment, int max_lines); + + int gl_load_history(GetLine *gl, const char *filename, + const char *comment); + + int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); + + int gl_group_history(GetLine *gl, unsigned stream); + + int gl_show_history(GetLine *gl, FILE *fp, + const char *fmt, int all_groups, + int max_lines); + + int gl_resize_history(GetLine *gl, size_t bufsize); + + void gl_limit_history(GetLine *gl, int max_lines); + void gl_clear_history(GetLine *gl, int all_groups); + + void gl_toggle_history(GetLine *gl, int enable); + + GlTerminalSize gl_terminal_size(GetLine *gl, + int def_ncolumn, + int def_nline); + + int gl_lookup_history(GetLine *gl, unsigned long id, + GlHistoryLine *hline); + + void gl_state_of_history(GetLine *gl, + GlHistoryState *state); + + void gl_range_of_history(GetLine *gl, + GlHistoryRange *range); + + void gl_size_of_history(GetLine *gl, GlHistorySize *size); + + void gl_echo_mode(GetLine *gl, int enable); + + void gl_replace_prompt(GetLine *gl, const char *prompt); + + void gl_prompt_style(GetLine *gl, GlPromptStyle style); + + int gl_ignore_signal(GetLine *gl, int signo); + + int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); + + int gl_last_signal(const GetLine *gl); + + + +</pre><h2>DESCRIPTION</h2><pre> + The gl_get_line() function is part of the tecla library (see + the <a href="libtecla.html">libtecla(3)</a> man page). If the user is typing at a termi- + nal, it prompts them for an line of input, then provides + interactive editing facilities, similar to those of the unix + tcsh shell. In addition to simple command-line editing, it + supports recall of previously entered command lines, TAB + completion of file names, and in-line wild-card expansion of + filenames. + + +</pre><h2>AN EXAMPLE</h2><pre> + The following shows a complete example of how to use the + gl_get_line() function to get input from the user: + + #include <stdio.h> + #include <locale.h> + #include <libtecla.h> + int main(int argc, char *argv[]) + { + char *line; /* The line that the user typed */ + GetLine *gl; /* The gl_get_line() resource object */ + + setlocale(LC_CTYPE, ""); /* Adopt the user's choice */ + /* of character set. */ + + gl = new_GetLine(1024, 2048); + if(!gl) + return 1; + + while((line=gl_get_line(gl, "$ ", NULL, -1)) != NULL && + strcmp(line, "exit\n") != 0) + printf("You typed: %s\n", line); + + gl = del_GetLine(gl); + return 0; + } + + In the example, first the resources needed by the + gl_get_line() function are created by calling new_GetLine(). + This allocates the memory used in subsequent calls to the + gl_get_line() function, including the history buffer for + recording previously entered lines. Then one or more lines + are read from the user, until either an error occurs, or the + user types exit. Then finally the resources that were allo- + cated by new_GetLine(), are returned to the system by cal- + ling del_GetLine(). Note the use of the NULL return value of + del_GetLine() to make gl NULL. This is a safety precaution. + If the program subsequently attempts to pass gl to + gl_get_line(), said function will complain, and return an + error, instead of attempting to use the deleted resource + object. + + + +</pre><h2>THE FUNCTIONS USED IN THE EXAMPLE</h2><pre> + The descriptions of the functions used in the example are as + follows: + + GetLine *new_GetLine(size_t linelen, size_t histlen) + + This function creates the resources used by the + gl_get_line() function and returns an opaque pointer to the + object that contains them. The maximum length of an input + line is specified via the linelen argument, and the number + of bytes to allocate for storing history lines is set by the + histlen argument. History lines are stored back-to-back in a + single buffer of this size. Note that this means that the + number of history lines that can be stored at any given + time, depends on the lengths of the individual lines. If + you want to place an upper limit on the number of lines that + can be stored, see the gl_limit_history() function described + later. If you don't want history at all, specify histlen as + zero, and no history buffer will be allocated. + + On error, a message is printed to stderr and NULL is + returned. + + GetLine *del_GetLine(GetLine *gl) + + This function deletes the resources that were returned by a + previous call to new_GetLine(). It always returns NULL (ie a + deleted object). It does nothing if the gl argument is NULL. + + char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos); + + The gl_get_line() function can be called any number of times + to read input from the user. The gl argument must have been + previously returned by a call to new_GetLine(). The prompt + argument should be a normal NUL terminated string, specify- + ing the prompt to present the user with. By default prompts + are displayed literally, but if enabled with the + gl_prompt_style() function (see later), prompts can contain + directives to do underlining, switch to and from bold fonts, + or turn highlighting on and off. + + If you want to specify the initial contents of the line, for + the user to edit, pass the desired string via the start_line + argument. You can then specify which character of this line + the cursor is initially positioned over, using the start_pos + argument. This should be -1 if you want the cursor to follow + the last character of the start line. If you don't want to + preload the line in this manner, send start_line as NULL, + and set start_pos to -1. + + The gl_get_line() function returns a pointer to the line + entered by the user, or NULL on error or at the end of the + input. The returned pointer is part of the specified gl + resource object, and thus should not be free'd by the + caller, or assumed to be unchanging from one call to the + next. When reading from a user at a terminal, there will + always be a newline character at the end of the returned + line. When standard input is being taken from a pipe or a + file, there will similarly be a newline unless the input + line was too long to store in the internal buffer. In the + latter case you should call gl_get_line() again to read the + rest of the line. Note that this behavior makes + gl_get_line() similar to fgets(). In fact when stdin isn't + connected to a terminal,gl_get_line() just calls fgets(). + + +</pre><h2>OPTIONAL PROMPT FORMATTING</h2><pre> + Whereas by default the prompt string that you specify is + displayed literally, without any special interpretation of + the characters within it, the gl_prompt_style() function can + be used to enable optional formatting directives within the + prompt. + + void gl_prompt_style(GetLine *gl, GlPromptStyle style); + + The style argument, which specifies the formatting style, + can take any of the following values: + + GL_FORMAT_PROMPT - In this style, the formatting + directives described below, when + included in prompt strings, are + interpreted as follows: + + %B - Display subsequent + characters with a bold + font. + %b - Stop displaying characters + with the bold font. + %F - Make subsequent characters + flash. + %f - Turn off flashing + characters. + %U - Underline subsequent + characters. + %u - Stop underlining + characters. + %P - Switch to a pale (half + brightness) font. + %p - Stop using the pale font. + %S - Highlight subsequent + characters (also known as + standout mode). + %s - Stop highlighting + characters. + %V - Turn on reverse video. + %v - Turn off reverse video. + %% - Display a single % + character. + + For example, in this mode, a prompt + string like "%UOK%u$ " would + display the prompt "OK$ ", + but with the OK part + underlined. + + Note that although a pair of + characters that starts with a % + character, but doesn't match any of + the above directives is displayed + literally, if a new directive is + subsequently introduced which does + match, the displayed prompt will + change, so it is better to always + use %% to display a literal %. + + Also note that not all terminals + support all of these text + attributes, and that some substitute + a different attribute for missing + ones. + + GL_LITERAL_PROMPT - In this style, the prompt string is + printed literally. This is the + default style. + + + +</pre><h2>THE AVAILABLE KEY BINDING FUNCTIONS</h2><pre> + The gl_get_line() function provides a number of functions + which can be bound to key sequences. The names of these + functions, and what they do, are given below. + + user-interrupt - Send a SIGINT signal to the + parent process. + abort - Send a SIGABRT signal to the + parent process. + suspend - Suspend the parent process. + stop-output - Pause terminal output. + start-output - Resume paused terminal output. + literal-next - Arrange for the next character + to be treated as a normal + character. This allows control + characters to be entered. + cursor-right - Move the cursor one character + right. + cursor-left - Move the cursor one character + left. + insert-mode - Toggle between insert mode and + overwrite mode. + beginning-of-line - Move the cursor to the + beginning of the line. + end-of-line - Move the cursor to the end of + the line. + delete-line - Delete the contents of the + current line. + kill-line - Delete everything that follows + the cursor. + backward-kill-line - Delete all characters between + the cursor and the start of the + line. + forward-word - Move to the end of the word + which follows the cursor. + forward-to-word - Move the cursor to the start of + the word that follows the + cursor. + backward-word - Move to the start of the word + which precedes the cursor. + goto-column - Move the cursor to the + 1-relative column in the line + specified by any preceding + digit-argument sequences (see + ENTERING REPEAT COUNTS below). + find-parenthesis - If the cursor is currently + over a parenthesis character, + move it to the matching + parenthesis character. If not + over a parenthesis character + move right to the next close + parenthesis. + forward-delete-char - Delete the character under the + cursor. + backward-delete-char - Delete the character which + precedes the cursor. + list-or-eof - This is intended for binding + to ^D. When invoked when the + cursor is within the line it + displays all possible + completions then redisplays + the line unchanged. When + invoked on an empty line, it + signals end-of-input (EOF) to + the caller of gl_get_line(). + del-char-or-list-or-eof - This is intended for binding + to ^D. When invoked when the + cursor is within the line it + invokes forward-delete-char. + When invoked at the end of the + line it displays all possible + completions then redisplays + the line unchanged. When + invoked on an empty line, it + signals end-of-input (EOF) to + the caller of gl_get_line(). + forward-delete-word - Delete the word which follows + the cursor. + backward-delete-word - Delete the word which precedes + the cursor. + upcase-word - Convert all of the characters + of the word which follows the + cursor, to upper case. + downcase-word - Convert all of the characters + of the word which follows the + cursor, to lower case. + capitalize-word - Capitalize the word which + follows the cursor. + change-case - If the next character is upper + case, toggle it to lower case + and vice versa. + redisplay - Redisplay the line. + clear-screen - Clear the terminal, then + redisplay the current line. + transpose-chars - Swap the character under the + cursor with the character just + before the cursor. + set-mark - Set a mark at the position of + the cursor. + exchange-point-and-mark - Move the cursor to the last + mark that was set, and move + the mark to where the cursor + used to be. + kill-region - Delete the characters that lie + between the last mark that was + set, and the cursor. + copy-region-as-kill - Copy the text between the mark + and the cursor to the cut + buffer, without deleting the + original text. + yank - Insert the text that was last + deleted, just before the + current position of the cursor. + append-yank - Paste the current contents of + the cut buffer, after the + cursor. + up-history - Recall the next oldest line + that was entered. Note that + in vi mode you are left in + command mode. + down-history - Recall the next most recent + line that was entered. If no + history recall session is + currently active, the next + line from a previous recall + session is recalled. Note that + in vi mode you are left in + command mode. + history-search-backward - Recall the next oldest line + who's prefix matches the string + which currently precedes the + cursor (in vi command-mode the + character under the cursor is + also included in the search + string). Note that in vi mode + you are left in command mode. + history-search-forward - Recall the next newest line + who's prefix matches the string + which currently precedes the + cursor (in vi command-mode the + character under the cursor is + also included in the search + string). Note that in vi mode + you are left in command mode. + history-re-search-backward -Recall the next oldest line + who's prefix matches that + established by the last + invocation of either + history-search-forward or + history-search-backward. + history-re-search-forward - Recall the next newest line + who's prefix matches that + established by the last + invocation of either + history-search-forward or + history-search-backward. + complete-word - Attempt to complete the + incomplete word which + precedes the cursor. Unless + the host program has customized + word completion, filename + completion is attempted. In vi + commmand mode the character + under the cursor is also + included in the word being + completed, and you are left in + vi insert mode. + expand-filename - Within the command line, expand + wild cards, tilde expressions + and dollar expressions in the + filename which immediately + precedes the cursor. In vi + commmand mode the character + under the cursor is also + included in the filename being + expanded, and you are left in + vi insert mode. + list-glob - List any filenames which match + the wild-card, tilde and dollar + expressions in the filename + which immediately precedes the + cursor, then redraw the input + line unchanged. + list-history - Display the contents of the + history list for the current + history group. If a repeat + count of > 1 is specified, + only that many of the most + recent lines are displayed. + See the "ENTERING REPEAT + COUNTS" section. + read-from-file - Temporarily switch to reading + input from the file who's + name precedes the cursor. + read-init-files - Re-read teclarc configuration + files. + beginning-of-history - Move to the oldest line in the + history list. Note that in vi + mode you are left in command + mode. + end-of-history - Move to the newest line in the + history list (ie. the current + line). Note that in vi mode + this leaves you in command + mode. + digit-argument - Enter a repeat count for the + next key-binding function. + For details, see the ENTERING + REPEAT COUNTS section. + newline - Terminate and return the + current contents of the + line, after appending a + newline character. The newline + character is normally '\n', + but will be the first + character of the key-sequence + that invoked the newline + action, if this happens to be + a printable character. If the + action was invoked by the + '\n' newline character or the + '\r' carriage return + character, the line is + appended to the history + buffer. + repeat-history - Return the line that is being + edited, then arrange for the + next most recent entry in the + history buffer to be recalled + when gl_get_line() is + next called. Repeatedly + invoking this action causes + successive historical input + lines to be re-executed. Note + that this action is equivalent + to the 'Operate' action in + ksh. + ring-bell - Ring the terminal bell, unless + the bell has been silenced via + the nobeep configuration + option (see the THE TECLA + CONFIGURATION FILE section). + forward-copy-char - Copy the next character into + the cut buffer (NB. use repeat + counts to copy more than one). + backward-copy-char - Copy the previous character + into the cut buffer. + forward-copy-word - Copy the next word into the cut + buffer. + backward-copy-word - Copy the previous word into the + cut buffer. + forward-find-char - Move the cursor to the next + occurrence of the next + character that you type. + backward-find-char - Move the cursor to the last + occurrence of the next + character that you type. + forward-to-char - Move the cursor to the + character just before the next + occurrence of the next + character that the user types. + backward-to-char - Move the cursor to the + character just after the last + occurrence before the cursor + of the next character that the + user types. + repeat-find-char - Repeat the last + backward-find-char, + forward-find-char, + backward-to-char or + forward-to-char. + invert-refind-char - Repeat the last + backward-find-char, + forward-find-char, + backward-to-char, or + forward-to-char in the + opposite direction. + delete-to-column - Delete the characters from the + cursor up to the column that + is specified by the repeat + count. + delete-to-parenthesis - Delete the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis. + forward-delete-find - Delete the characters from the + cursor up to and including the + following occurence of the + next character typed. + backward-delete-find - Delete the characters from the + cursor up to and including the + preceding occurence of the + next character typed. + forward-delete-to - Delete the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed. + backward-delete-to - Delete the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed. + delete-refind - Repeat the last *-delete-find + or *-delete-to action. + delete-invert-refind - Repeat the last *-delete-find + or *-delete-to action, in the + opposite direction. + copy-to-column - Copy the characters from the + cursor up to the column that + is specified by the repeat + count, into the cut buffer. + copy-to-parenthesis - Copy the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis, into + the cut buffer. + forward-copy-find - Copy the characters from the + cursor up to and including the + following occurence of the + next character typed, into the + cut buffer. + backward-copy-find - Copy the characters from the + cursor up to and including the + preceding occurence of the + next character typed, into the + cut buffer. + forward-copy-to - Copy the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed, into the cut + buffer. + backward-copy-to - Copy the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed, into the cut + buffer. + copy-refind - Repeat the last *-copy-find + or *-copy-to action. + copy-invert-refind - Repeat the last *-copy-find + or *-copy-to action, in the + opposite direction. + vi-mode - Switch to vi mode from emacs + mode. + emacs-mode - Switch to emacs mode from vi + mode. + vi-insert - From vi command mode, switch to + insert mode. + vi-overwrite - From vi command mode, switch to + overwrite mode. + vi-insert-at-bol - From vi command mode, move the + cursor to the start of the line + and switch to insert mode. + vi-append-at-eol - From vi command mode, move the + cursor to the end of the line + and switch to append mode. + vi-append - From vi command mode, move the + cursor one position right, and + switch to insert mode. + vi-replace-char - From vi command mode, replace + the character under the cursor + with the the next character + entered. + vi-forward-change-char - From vi command mode, delete + the next character then enter + insert mode. + vi-backward-change-char - From vi command mode, delete + the preceding character then + enter insert mode. + vi-forward-change-word - From vi command mode, delete + the next word then enter + insert mode. + vi-backward-change-word - From vi command mode, delete + the preceding word then + enter insert mode. + vi-change-rest-of-line - From vi command mode, delete + from the cursor to the end of + the line, then enter insert + mode. + vi-change-line - From vi command mode, delete + the current line, then enter + insert mode. + vi-change-to-bol - From vi command mode, delete + all characters between the + cursor and the beginning of + the line, then enter insert + mode. + vi-change-to-column - From vi command mode, delete + the characters from the cursor + up to the column that is + specified by the repeat count, + then enter insert mode. + vi-change-to-parenthesis - Delete the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis, then + enter vi insert mode. + vi-forward-change-find - From vi command mode, delete + the characters from the + cursor up to and including the + following occurence of the + next character typed, then + enter insert mode. + vi-backward-change-find - From vi command mode, delete + the characters from the + cursor up to and including the + preceding occurence of the + next character typed, then + enter insert mode. + vi-forward-change-to - From vi command mode, delete + the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed, then enter + insert mode. + vi-backward-change-to - From vi command mode, delete + the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed, then enter + insert mode. + vi-change-refind - Repeat the last + vi-*-change-find or + vi-*-change-to action. + vi-change-invert-refind - Repeat the last + vi-*-change-find or + vi-*-change-to action, in the + opposite direction. + vi-undo - In vi mode, undo the last + editing operation. + vi-repeat-change - In vi command mode, repeat the + last command that modified the + line. + + +</pre><h2>DEFAULT KEY BINDINGS IN EMACS MODE</h2><pre> + The following default key bindings, which can be overriden + by the tecla configuration file, are designed to mimic most + of the bindings of the unix tcsh shell, when it is in emacs + editing mode. + + This is the default editing mode of the tecla library. + + Note that a key sequence like ^A or C-a means hold the + control-key down while pressing the letter A, and that where + you see \E or M- in a binding, this represents the escape + key or the Meta modifier key. Also note that to + gl_get_line(), pressing the escape key before a key is + equivalent to pressing the meta key at the same time as that + key. Thus the key sequence M-p can be typed in two ways, by + pressing the escape key, followed by pressing p, or by + pressing the Meta key at the same time as p. + + Under UNIX the terminal driver sets a number of special keys + for certain functions. The tecla library attempts to use the + same keybindings to maintain consistency. The key sequences + shown for the following 6 bindings are thus just examples of + what they will probably be set to. If you have used the stty + command to change these keys, then the default bindings + should match. + + ^C -> user-interrupt + ^\ -> abort + ^Z -> suspend + ^Q -> start-output + ^S -> stop-output + ^V -> literal-next + + The cursor keys are refered to by name, as follows. This is + necessary because different types of terminals generate dif- + ferent key sequences when their cursor keys are pressed. + + right -> cursor-right + left -> cursor-left + up -> up-history + down -> down-history + + The remaining bindings don't depend on the terminal sett- + tings. + + ^F -> cursor-right + ^B -> cursor-left + M-i -> insert-mode + ^A -> beginning-of-line + ^E -> end-of-line + ^U -> delete-line + ^K -> kill-line + M-f -> forward-word + M-b -> backward-word + ^D -> del-char-or-list-or-eof + ^H -> backward-delete-char + ^? -> backward-delete-char + M-d -> forward-delete-word + M-^H -> backward-delete-word + M-^? -> backward-delete-word + M-u -> upcase-word + M-l -> downcase-word + M-c -> capitalize-word + ^R -> redisplay + ^L -> clear-screen + ^T -> transpose-chars + ^@ -> set-mark + ^X^X -> exchange-point-and-mark + ^W -> kill-region + M-w -> copy-region-as-kill + ^Y -> yank + ^P -> up-history + ^N -> down-history + M-p -> history-search-backward + M-n -> history-search-forward + ^I -> complete-word + ^X* -> expand-filename + ^X^F -> read-from-file + ^X^R -> read-init-files + ^Xg -> list-glob + ^Xh -> list-history + M-< -> beginning-of-history + M-> -> end-of-history + \n -> newline + \r -> newline + M-o -> repeat-history + M-^V -> vi-mode + + M-0, M-1, ... M-9 -> digit-argument (see below) + + Note that ^I is what the TAB key generates, and that ^@ can + be generated not only by pressing the control key and the @ + key simultaneously, but also by pressing the control key and + the space bar at the same time. + + +</pre><h2>DEFAULT KEY BINDINGS IN VI MODE</h2><pre> + The following default key bindings are designed to mimic the + vi style of editing as closely as possible. This means that + very few editing functions are provided in the initial char- + acter input mode, editing functions instead being provided + by the vi command mode. Vi command mode is entered whenever + the escape character is pressed, or whenever a key-sequence + that starts with a meta character is entered. In addition to + mimicing vi, libtecla provides bindings for tab completion, + wild-card expansion of file names, and historical line + recall. + + To learn how to tell the tecla library to use vi mode + instead of the default emacs editing mode, see the section + entitled THE TECLA CONFIGURATION FILE. + + As already mentioned above in the emacs section, Note that a + key sequence like ^A or C-a means hold the control-key down + while pressing the letter A, and that where you see \E or M- + in a binding, this represents the escape key or the Meta + modifier key. Also note that to gl_get_line(), pressing the + escape key before a key is equivalent to pressing the meta + key at the same time as that key. Thus the key sequence M-p + can be typed in two ways, by pressing the escape key, fol- + lowed by pressing p, or by pressing the Meta key at the same + time as p. + + Under UNIX the terminal driver sets a number of special keys + for certain functions. The tecla library attempts to use the + same keybindings to maintain consistency, binding them both + in input mode and in command mode. The key sequences shown + for the following 6 bindings are thus just examples of what + they will probably be set to. If you have used the stty com- + mand to change these keys, then the default bindings should + match. + + ^C -> user-interrupt + ^\ -> abort + ^Z -> suspend + ^Q -> start-output + ^S -> stop-output + ^V -> literal-next + M-^C -> user-interrupt + M-^\ -> abort + M-^Z -> suspend + M-^Q -> start-output + M-^S -> stop-output + + Note that above, most of the bindings are defined twice, + once as a raw control code like ^C and then a second time as + a meta character like M-^C. The former is the binding for vi + input mode, whereas the latter is the binding for vi command + mode. Once in command mode all key-sequences that the user + types that they don't explicitly start with an escape or a + meta key, have their first key secretly converted to a meta + character before the key sequence is looked up in the key + binding table. Thus, once in command mode, when you type the + letter i, for example, the tecla library actually looks up + the binding for M-i. + + The cursor keys are refered to by name, as follows. This is + necessary because different types of terminals generate dif- + ferent key sequences when their cursor keys are pressed. + + right -> cursor-right + left -> cursor-left + up -> up-history + down -> down-history + + The cursor keys normally generate a keysequence that start + with an escape character, so beware that using the arrow + keys will put you into command mode (if you aren't already + in command mode). + + The following are the terminal-independent key bindings for + vi input mode. + + ^D -> list-or-eof + ^G -> list-glob + ^H -> backward-delete-char + ^I -> complete-word + \r -> newline + \n -> newline + ^L -> clear-screen + ^N -> down-history + ^P -> up-history + ^R -> redisplay + ^U -> backward-kill-line + ^W -> backward-delete-word + ^X* -> expand-filename + ^X^F -> read-from-file + ^X^R -> read-init-files + ^? -> backward-delete-char + + The following are the key bindings that are defined in vi + command mode, this being specified by them all starting with + a meta character. As mentioned above, once in command mode + the initial meta character is optional. For example, you + might enter command mode by typing Esc, and then press h + twice to move the cursor two positions to the left. Both h + characters get quietly converted to M-h before being com- + pared to the key-binding table, the first one because Escape + followed by a character is always converted to the + equivalent meta character, and the second because command + mode was already active. + + M-\ -> cursor-right (Meta-space) + M-$ -> end-of-line + M-* -> expand-filename + M-+ -> down-history + M-- -> up-history + M-< -> beginning-of-history + M-> -> end-of-history + M-^ -> beginning-of-line + M-; -> repeat-find-char + M-, -> invert-refind-char + M-| -> goto-column + M-~ -> change-case + M-. -> vi-repeat-change + M-% -> find-parenthesis + M-a -> vi-append + M-A -> vi-append-at-eol + M-b -> backward-word + M-B -> backward-word + M-C -> vi-change-rest-of-line + M-cb -> vi-backward-change-word + M-cB -> vi-backward-change-word + M-cc -> vi-change-line + M-ce -> vi-forward-change-word + M-cE -> vi-forward-change-word + M-cw -> vi-forward-change-word + M-cW -> vi-forward-change-word + M-cF -> vi-backward-change-find + M-cf -> vi-forward-change-find + M-cT -> vi-backward-change-to + M-ct -> vi-forward-change-to + M-c; -> vi-change-refind + M-c, -> vi-change-invert-refind + M-ch -> vi-backward-change-char + M-c^H -> vi-backward-change-char + M-c^? -> vi-backward-change-char + M-cl -> vi-forward-change-char + M-c\ -> vi-forward-change-char (Meta-c-space) + M-c^ -> vi-change-to-bol + M-c0 -> vi-change-to-bol + M-c$ -> vi-change-rest-of-line + M-c| -> vi-change-to-column + M-c% -> vi-change-to-parenthesis + M-dh -> backward-delete-char + M-d^H -> backward-delete-char + M-d^? -> backward-delete-char + M-dl -> forward-delete-char + M-d -> forward-delete-char (Meta-d-space) + M-dd -> delete-line + M-db -> backward-delete-word + M-dB -> backward-delete-word + M-de -> forward-delete-word + M-dE -> forward-delete-word + M-dw -> forward-delete-word + M-dW -> forward-delete-word + M-dF -> backward-delete-find + M-df -> forward-delete-find + M-dT -> backward-delete-to + M-dt -> forward-delete-to + M-d; -> delete-refind + M-d, -> delete-invert-refind + M-d^ -> backward-kill-line + M-d0 -> backward-kill-line + M-d$ -> kill-line + M-D -> kill-line + M-d| -> delete-to-column + M-d% -> delete-to-parenthesis + M-e -> forward-word + M-E -> forward-word + M-f -> forward-find-char + M-F -> backward-find-char + M-- -> up-history + M-h -> cursor-left + M-H -> beginning-of-history + M-i -> vi-insert + M-I -> vi-insert-at-bol + M-j -> down-history + M-J -> history-search-forward + M-k -> up-history + M-K -> history-search-backward + M-l -> cursor-right + M-L -> end-of-history + M-n -> history-re-search-forward + M-N -> history-re-search-backward + M-p -> append-yank + M-P -> yank + M-r -> vi-replace-char + M-R -> vi-overwrite + M-s -> vi-forward-change-char + M-S -> vi-change-line + M-t -> forward-to-char + M-T -> backward-to-char + M-u -> vi-undo + M-w -> forward-to-word + M-W -> forward-to-word + M-x -> forward-delete-char + M-X -> backward-delete-char + M-yh -> backward-copy-char + M-y^H -> backward-copy-char + M-y^? -> backward-copy-char + M-yl -> forward-copy-char + M-y\ -> forward-copy-char (Meta-y-space) + M-ye -> forward-copy-word + M-yE -> forward-copy-word + M-yw -> forward-copy-word + M-yW -> forward-copy-word + M-yb -> backward-copy-word + M-yB -> backward-copy-word + M-yf -> forward-copy-find + M-yF -> backward-copy-find + M-yt -> forward-copy-to + M-yT -> backward-copy-to + M-y; -> copy-refind + M-y, -> copy-invert-refind + M-y^ -> copy-to-bol + M-y0 -> copy-to-bol + M-y$ -> copy-rest-of-line + M-yy -> copy-line + M-Y -> copy-line + M-y| -> copy-to-column + M-y% -> copy-to-parenthesis + M-^E -> emacs-mode + M-^H -> cursor-left + M-^? -> cursor-left + M-^L -> clear-screen + M-^N -> down-history + M-^P -> up-history + M-^R -> redisplay + M-^D -> list-or-eof + M-^I -> complete-word + M-\r -> newline + M-\n -> newline + M-^X^R -> read-init-files + M-^Xh -> list-history + + M-0, M-1, ... M-9 -> digit-argument (see below) + + Note that ^I is what the TAB key generates. + + +</pre><h2>ENTERING REPEAT COUNTS</h2><pre> + Many of the key binding functions described previously, take + an optional count, typed in before the target keysequence. + This is interpreted as a repeat count by most bindings. A + notable exception is the goto-column binding, which inter- + prets the count as a column number. + + By default you can specify this count argument by pressing + the meta key while typing in the numeric count. This relies + on the digit-argument action being bound to Meta-0, Meta-1 + etc. Once any one of these bindings has been activated, you + can optionally take your finger off the meta key to type in + the rest of the number, since every numeric digit thereafter + is treated as part of the number, unless it is preceded by + the literal-next binding. As soon as a non-digit, or literal + digit key is pressed the repeat count is terminated and + either causes the just typed character to be added to the + line that many times, or causes the next key-binding func- + tion to be given that argument. + + For example, in emacs mode, typing: + + M-12a + + causes the letter 'a' to be added to the line 12 times, + whereas + + M-4M-c + + Capitalizes the next 4 words. + + In vi command mode the Meta modifier is automatically added + to all characters typed in, so to enter a count in vi + command-mode, just involves typing in the number, just as at + it does in the vi editor itself. So for example, in vi com- + mand mode, typing: + + 4w2x + + moves the cursor four words to the right, then deletes two + characters. + + You can also bind digit-argument to other key sequences. If + these end in a numeric digit, that digit gets appended to + the current repeat count. If it doesn't end in a numeric + digit, a new repeat count is started with a value of zero, + and can be completed by typing in the number, after letting + go of the key which triggered the digit-argument action. + + +</pre><h2>THE TECLA CONFIGURATION FILE</h2><pre> + By default, the first call to gl_get_line() looks for a file + called .teclarc in your home directory (ie. ~/.teclarc). If + it finds this file, it reads it, interpreting each line as + defining a new key binding or an editing configuration + option. Since the emacs keybindings are installed by + default, if you want to use the non-default vi editing mode, + the most important item to go in this file is the following + line: + + edit-mode vi + + This will re-configure the default bindings for vi-mode. The + complete set of arguments that this command accepts are: + + vi - Install key-bindings like those of the vi + editor. + emacs - Install key-bindings like those of the emacs + editor. This is the default. + none - Use just the native line editing facilities + provided by the terminal driver. + + To prevent the terminal bell from being rung, such as when + an unrecognized control-sequence is typed, place the follow- + ing line in the configuration file: + + nobeep + + An example of a key binding line in the configuration file + is the following. + + bind M-[2~ insert-mode + + On many keyboards, the above key sequence is generated when + one presses the insert key, so with this keybinding, one can + toggle between the emacs-mode insert and overwrite modes by + hitting one key. One could also do it by typing out the + above sequence of characters one by one. As explained above, + the M- part of this sequence can be typed either by pressing + the escape key before the following key, or by pressing the + Meta key at the same time as the following key. Thus if you + had set the above key binding, and the insert key on your + keyboard didn't generate the above key sequence, you could + still type it in either of the following 2 ways. + + 1. Hit the escape key momentarily, then press '[', then '2', then + finally '~'. + + 2. Press the meta key at the same time as pressing the '[' key, + then press '2', then '~'. + + If you set a keybinding for a key-sequence that is already + bound to a function, the new binding overrides the old one. + If in the new binding you omit the name of the new function + to bind to the key-sequence, the original binding becomes + undefined. + + Starting with versions of libtecla later than 1.3.3 it is + now possible to bind keysequences that begin with a print- + able character. Previously key-sequences were required to + start with a control or meta character. + + Note that the special keywords "up", "down", "left" and + "right" refer to the arrow keys, and are thus not treated as + keysequences. So, for example, to rebind the up and down + arrow keys to use the history search mechanism instead of + the simple history recall method, you could place the fol- + lowing in your configuration file: + + bind up history-search-backwards + bind down history-search-backwards + + To unbind an existing binding, you can do this with the bind + command by omitting to name any action to rebind the key + sequence to. For example, by not specifying an action func- + tion, the following command unbinds the default beginning- + of-line action from the ^A key sequence: + + bind ^A + + +</pre><h2>ALTERNATE CONFIGURATION SOURCES</h2><pre> + As mentioned above, by default users have the option of con- + figuring the behavior of gl_get_line() via a configuration + file called .teclarc in their home directories. The fact + that all applications share this same configuration file is + both an advantage and a disadvantage. In most cases it is + an advantage, since it encourages uniformity, and frees the + user from having to configure each application separately. + In some applications, however, this single means of confi- + guration is a problem. This is particularly true of embedded + software, where there's no filesystem to read a configura- + tion file from, and also in applications where a radically + different choice of keybindings is needed to emulate a + legacy keyboard interface. To cater for such cases, the + following function allows the application to control where + configuration information is read from. + + + int gl_configure_getline(GetLine *gl, + const char *app_string, + const char *app_file, + const char *user_file); + + + It allows the configuration commands that would normally be + read from a user's ~/.teclarc file, to be read from any or + none of, a string, an application specific configuration + file, and/or a user-specific configuration file. If this + function is called before the first call to gl_get_line(), + the default behavior of reading ~/.teclarc on the first call + to gl_get_line() is disabled, so all configuration must be + achieved using the configuration sources specified with this + function. + + If app_string != NULL, then it is interpreted as a string + containing one or more configuration commands, separated + from each other in the string by embedded newline charac- + ters. If app_file != NULL then it is interpreted as the full + pathname of an application-specific configuration file. If + user_file != NULL then it is interpreted as the full path- + name of a user-specific configuration file, such as + ~/.teclarc. For example, in the following call, + + gl_configure_getline(gl, "edit-mode vi \n nobeep", + "/usr/share/myapp/teclarc", + "~/.teclarc"); + + the app_string argument causes the calling application to + start in vi edit-mode, instead of the default emacs mode, + and turns off the use of the terminal bell by the library. + It then attempts to read system-wide configuration commands + from an optional file called /usr/share/myapp/teclarc, then + finally reads user-specific configuration commands from an + optional .teclarc file in the user's home directory. Note + that the arguments are listed in ascending order of prior- + ity, with the contents of app_string being potentially over- + riden by commands in app_file, and commands in app_file + potentially being overriden by commands in user_file. + You can call this function as many times as needed, the + results being cumulative, but note that copies of any + filenames specified via the app_file and user_file arguments + are recorded internally for subsequent use by the read- + init-files key-binding function, so if you plan to call this + function multiple times, be sure that the last call speci- + fies the filenames that you want re-read when the user + requests that the configuration files be re-read. + + +</pre><h2>FILENAME AND TILDE COMPLETION</h2><pre> + With the default key bindings, pressing the TAB key (aka. + ^I) results in gl_get_line() attempting to complete the + incomplete filename that precedes the cursor. gl_get_line() + searches backwards from the cursor, looking for the start of + the filename, stopping when it hits either a space or the + start of the line. If more than one file has the specified + prefix, gl_get_line() completes the filename up to the point + at which the ambiguous matches start to differ, then lists + the possible matches. + + In addition to literally written filenames, gl_get_line() + can complete files that start with ~/ and ~user/ expressions + and that contain $envvar expressions. In particular, if you + hit TAB within an incomplete ~user, expression, + gl_get_line() will attempt to complete the username, listing + any ambiguous matches. + + The completion binding is implemented using the + cpl_word_completions() function, which is also available + separately to users of this library. See the + cpl_word_completions(3) man page for more details. + + +</pre><h2>CUSTOMIZED WORD COMPLETION</h2><pre> + If in your application, you would like to have TAB comple- + tion complete other things in addition to or instead of + filenames, you can arrange this by registering an alternate + completion callback function, via a call to the + gl_customize_completion() function. + + int gl_customize_completion(GetLine *gl, void *data, + CplMatchFn *match_fn); + + The data argument provides a way for your application to + pass arbitrary, application-specific information to the + callback function. This is passed to the callback every time + that it is called. It might for example, point to the symbol + table from which possible completions are to be sought. The + match_fn argument specifies the callback function to be + called. The CplMatchFn function type is defined in + libtecla.h, as is a CPL_MATCH_FN() macro that you can use to + declare and prototype callback functions. The declaration + and responsibilities of callback functions are described in + depth in the <a href="cpl_complete_word.html">cpl_complete_word(3)</a> man page. + + In brief, the callback function is responsible for looking + backwards in the input line, back from the point at which + the user pressed TAB, to find the start of the word being + completed. It then must lookup possible completions of this + word, and record them one by one in the WordCompletion + object that is passed to it as an argument, by calling the + cpl_add_completion() function. If the callback function + wishes to provide filename completion in addition to its own + specific completions, it has the option of itself calling + the builtin file-name completion callback. This also, is + documented in the <a href="cpl_complete_word.html">cpl_complete_word(3)</a> man page. + + Note that if you would like gl_get_line() to return the + current input line when a successful completion is been + made, you can arrange this when you call + cpl_add_completion(), by making the last character of the + continuation suffix a newline character. If you do this, the + input line will be updated to display the completion, + together with any contiuation suffix up to the newline char- + acter, then gl_get_line() will return this input line. + + +</pre><h2>FILENAME EXPANSION</h2><pre> + With the default key bindings, pressing ^X* causes + gl_get_line() to expand the filename that precedes the cur- + sor, replacing ~/ and ~user/ expressions with the + corresponding home directories, and replacing $envvar + expressions with the value of the specified environment + variable, then if there are any wildcards, replacing the so + far expanded filename with a space-separated list of the + files which match the wild cards. + + The expansion binding is implemented using the + ef_expand_file() function. See the <a href="ef_expand_file.html">ef_expand_file(3)</a> man + page for more details. + + +</pre><h2>RECALLING PREVIOUSLY TYPED LINES</h2><pre> + Every time that a new line is entered by the user, it is + appended to a list of historical input lines maintained + within the GetLine resource object. You can traverse up and + down this list using the up and down arrow keys. Alterna- + tively, you can do the same with the ^P, and ^N keys, and in + vi command mode you can alternatively use the k and j char- + acters. Thus pressing up-arrow once, replaces the current + input line with the previously entered line. Pressing up- + arrow again, replaces this with the line that was entered + before it, etc.. Having gone back one or more lines into the + history list, one can return to newer lines by pressing + down-arrow one or more times. If you do this sufficient + times, you will return to the original line that you were + entering when you first hit up-arrow. + + Note that in vi mode, all of the history recall functions + switch the library into command mode. + + In emacs mode the M-p and M-n keys work just like the ^P and + ^N keys, except that they skip all but those historical + lines which share the prefix that precedes the cursor. In vi + command mode the upper case K and J characters do the same + thing, except that the string that they search for includes + the character under the cursor as well as what precedes it. + + Thus for example, suppose that you were in emacs mode, and + you had just entered the following list of commands in the + order shown: + + ls ~/tecla/ + cd ~/tecla + ls -l getline.c + emacs ~/tecla/getline.c + + If you next typed: + + ls + + and then hit M-p, then rather than returning the previously + typed emacs line, which doesn't start with "ls", + gl_get_line() would recall the "ls -l getline.c" line. + Pressing M-p again would recall the "ls ~/tecla/" line. + + +</pre><h2>HISTORY FILES</h2><pre> + To save the contents of the history buffer before quitting + your application, and subsequently restore them when you + next start the application, the following functions are pro- + vided. + + + int gl_save_history(GetLine *gl, const char *filename, + const char *comment, int max_lines); + int gl_load_history(GetLine *gl, const char *filename, + const char *comment); + + + The filename argument specifies the name to give the history + file when saving, or the name of an existing history file, + when loading. This may contain home-directory and environ- + ment variable expressions, such as "~/.myapp_history" or + "$HOME/.myapp_history". + Along with each history line, extra information about it, + such as when it was entered by the user, and what its nest- + ing level is, is recorded as a comment preceding the line in + the history file. Writing this as a comment allows the his- + tory file to double as a command file, just in case you wish + to replay a whole session using it. Since comment prefixes + differ in different languages, the comment argument is pro- + vided for specifying the comment prefix. For example, if + your application were a unix shell, such as the bourne + shell, you would specify "#" here. Whatever you choose for + the comment character, you must specify the same prefix to + gl_load_history() that you used when you called + gl_save_history() to write the history file. + + The max_lines must be either -1 to specify that all lines in + the history list be saved, or a positive number specifying a + ceiling on how many of the most recent lines should be + saved. + + Both fuctions return non-zero on error, after writing an + error message to stderr. Note that gl_load_history() does + not consider the non-existence of a file to be an error. + + +</pre><h2>MULTIPLE HISTORY LISTS</h2><pre> + If your application uses a single GetLine object for enter- + ing many different types of input lines, you may wish + gl_get_line() to distinguish the different types of lines in + the history list, and only recall lines that match the + current type of line. To support this requirement, + gl_get_line() marks lines being recorded in the history list + with an integer identifier chosen by the application. Ini- + tially this identifier is set to 0 by new_GetLine(), but it + can be changed subsequently by calling gl_group_history(). + + + int gl_group_history(GetLine *gl, unsigned id); + + + The integer identifier id can be any number chosen by the + application, but note that gl_save_history() and + gl_load_history() preserve the association between identif- + iers and historical input lines between program invokations, + so you should choose fixed identifiers for the different + types of input line used by your application. + + Whenever gl_get_line() appends a new input line to the his- + tory list, the current history identifier is recorded with + it, and when it is asked to recall a historical input line, + it only recalls lines that are marked with the current iden- + tifier. + +</pre><h2>DISPLAYING HISTORY</h2><pre> + The history list can be displayed by calling + gl_show_history(). + + + int gl_show_history(GetLine *gl, FILE *fp, + const char *fmt, + int all_groups, + int max_lines); + + + This displays the current contents of the history list to + the stdio output stream fp. If the max_lines argument is + greater than or equal to zero, then no more than this number + of the most recent lines will be displayed. If the + all_groups argument is non-zero, lines from all history + groups are displayed. Otherwise just those of the currently + selected history group are displayed. The format string + argument, fmt, determines how the line is displayed. This + can contain arbitrary characters which are written verbatim, + interleaved with any of the following format directives: + + %D - The date on which the line was originally + entered, formatted like 2001-11-20. + %T - The time of day when the line was entered, + formatted like 23:59:59. + %N - The sequential entry number of the line in + the history buffer. + %G - The number of the history group which the + line belongs to. + %% - A literal % character. + %H - The history line itself. + + Thus a format string like "%D %T %H0 would output something + like: + + 2001-11-20 10:23:34 Hello world + + Note the inclusion of an explicit newline character in the + format string. + + +</pre><h2>LOOKING UP HISTORY</h2><pre> + The gl_lookup_history() function allows the calling applica- + tion to look up lines in the history list. + + + typedef struct { + const char *line; /* The requested historical */ + /* line. */ + unsigned group; /* The history group to which */ + /* the line belongs. */ + time_t timestamp; /* The date and time at which */ + /* the line was originally */ + /* entered. */ + } GlHistoryLine; + + int gl_lookup_history(GetLine *gl, unsigned long id, + GlHistoryLine *hline); + + + The id argument indicates which line to look up, where the + first line that was entered in the history list after + new_GetLine() was called, is denoted by 0, and subsequently + entered lines are denoted with successively higher numbers. + Note that the range of lines currently preserved in the his- + tory list can be queried by calling the + gl_range_of_history() function, described later. If the + requested line is in the history list, the details of the + line are recorded in the variable pointed to by the hline + argument, and 1 is returned. Otherwise 0 is returned, and + the variable pointed to by hline is left unchanged. + + Beware that the string returned in hline->line is part of + the history buffer, so it must not be modified by the + caller, and will be recycled on the next call to any func- + tion that takes gl as its argument. Therefore you should + make a private copy of this string if you need to keep it + around. + + +</pre><h2>MISCELLANEOUS HISTORY CONFIGURATION</h2><pre> + If you wish to change the size of the history buffer that + was originally specified in the call to new_GetLine(), you + can do so with the gl_resize_history() function. + + + int gl_resize_history(GetLine *gl, size_t histlen); + + + The histlen argument specifies the new size in bytes, and if + you specify this as 0, the buffer will be deleted. + + As mentioned in the discussion of new_GetLine(), the number + of lines that can be stored in the history buffer, depends + on the lengths of the individual lines. For example, a 1000 + byte buffer could equally store 10 lines of average length + 100 bytes, or 2 lines of average length 50 bytes. Although + the buffer is never expanded when new lines are added, a + list of pointers into the buffer does get expanded when + needed to accomodate the number of lines currently stored in + the buffer. To place an upper limit on the number of lines + in the buffer, and thus a ceiling on the amount of memory + used in this list, you can call the gl_limit_history() + function. + + + void gl_limit_history(GetLine *gl, int max_lines); + + + The max_lines should either be a positive number >= 0, + specifying an upper limit on the number of lines in the + buffer, or be -1 to cancel any previously specified limit. + When a limit is in effect, only the max_lines most recently + appended lines are kept in the buffer. Older lines are dis- + carded. + + To discard lines from the history buffer, use the + gl_clear_history() function. + + void gl_clear_history(GetLine *gl, int all_groups); + + The all_groups argument tells the function whether to delete + just the lines associated with the current history group + (see gl_group_history()), or all historical lines in the + buffer. + + The gl_toggle_history() function allows you to toggle his- + tory on and off without losing the current contents of the + history list. + + + void gl_toggle_history(GetLine *gl, int enable); + + + Setting the enable argument to 0 turns off the history + mechanism, and setting it to 1 turns it back on. When his- + tory is turned off, no new lines will be added to the his- + tory list, and history lookup key-bindings will act as + though there is nothing in the history buffer. + + +</pre><h2>QUERYING HISTORY INFORMATION</h2><pre> + The configured state of the history list can be queried with + the gl_history_state() function. + + + typedef struct { + int enabled; /* True if history is enabled */ + unsigned group; /* The current history group */ + int max_lines; /* The current upper limit on the */ + /* number of lines in the history */ + /* list, or -1 if unlimited. */ + } GlHistoryState; + + void gl_state_of_history(GetLine *gl, + GlHistoryState *state); + + On return, the status information is recorded in the vari- + able pointed to by the state argument. + + The gl_range_of_history() function returns the number and + range of lines in the history list. + + + typedef struct { + unsigned long oldest; /* The sequential entry number */ + /* of the oldest line in the */ + /* history list. */ + unsigned long newest; /* The sequential entry number */ + /* of the newest line in the */ + /* history list. */ + int nlines; /* The number of lines in the */ + /* history list. */ + } GlHistoryRange; + + void gl_range_of_history(GetLine *gl, GlHistoryRange *range); + + The return values are recorded in the variable pointed to by + the range argument. If the nlines member of this structure + is greater than zero, then the oldest and newest members + report the range of lines in the list, and + newest=oldest+nlines-1. Otherwise they are both zero. + + The gl_size_of_history() function returns the total size of + the history buffer and the amount of the buffer that is + currently occupied. + + typedef struct { + size_t size; /* The size of the history buffer */ + /* (bytes). */ + size_t used; /* The number of bytes of the */ + /* history buffer that are */ + /* currently occupied. */ + } GlHistorySize; + + void gl_size_of_history(GetLine *gl, GlHistorySize *size); + + On return, the size information is recorded in the variable + pointed to by the size argument. + + +</pre><h2>CHANGING TERMINALS</h2><pre> + The new_GetLine() constructor function assumes that input is + to be read from stdin, and output written to stdout. The + following function allows you to switch to different input + and output streams. + + int gl_change_terminal(GetLine *gl, FILE *input_fp, + FILE *output_fp, const char *term); + + The gl argument is the object that was returned by + new_GetLine(). The input_fp argument specifies the stream + to read from, and output_fp specifies the stream to be writ- + ten to. Only if both of these refer to a terminal, will + interactive terminal input be enabled. Otherwise + gl_get_line() will simply call fgets() to read command + input. If both streams refer to a terminal, then they must + refer to the same terminal, and the type of this terminal + must be specified via the term argument. The value of the + term argument is looked up in the terminal information data- + base (terminfo or termcap), in order to determine which spe- + cial control sequences are needed to control various aspects + of the terminal. new_GetLine() for example, passes the + return value of getenv("TERM") in this argument. Note that + if one or both of input_fp and output_fp don't refer to a + terminal, then it is legal to pass NULL instead of a termi- + nal type. + + Note that if you want to pass file descriptors to + gl_change_terminal(), you can do this by creating stdio + stream wrappers using the POSIX fdopen() function. + + +</pre><h2>EXTERNAL EVENT HANDLING</h2><pre> + While gl_get_line() is waiting for keyboard input from the + user, you can ask it to also watch for activity on arbitrary + file descriptors, such as network sockets, pipes etc, and + have it call functions of your choosing when activity is + seen. This works on any system that has the select() system + call, which is most, if not all flavors of unix. Registering + a file descriptor to be watched by gl_get_line() involves + calling the gl_watch_fd() function. + + + int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); + + + If this returns non-zero, then it means that either your + arguments are invalid, or that this facility isn't supported + on the host system. + + The fd argument is the file descriptor to be watched. The + event argument specifies what type of activity is of + interest, chosen from the following enumerated values: + + + GLFD_READ - Watch for the arrival of data to be read. + GLFD_WRITE - Watch for the ability to write to the file + descriptor without blocking. + GLFD_URGENT - Watch for the arrival of urgent + out-of-band data on the file descriptor. + + + The callback argument is the function to call when the + selected activity is seen. It should be defined with the + following macro, which is defined in libtecla.h. + + + #define GL_FD_EVENT_FN(fn) GlFdStatus (fn)(GetLine *gl, \ + void *data, int fd, \ + GlFdEvent event) + + The data argument of the gl_watch_fd() function is passed to + the callback function for its own use, and can point to any- + thing you like, including NULL. The file descriptor and the + event argument are also passed to the callback function, and + this potentially allows the same callback function to be + registered to more than one type of event and/or more than + one file descriptor. The return value of the callback func- + tion should be one of the following values. + + + GLFD_ABORT - Tell gl_get_line() to abort with an + error (errno won't be set, so set it + appropriately yourself if you need it). + GLFD_REFRESH - Redraw the input line then continue + waiting for input. Return this if + your callback wrote to the terminal. + GLFD_CONTINUE - Continue to wait for input, without + redrawing the line. + + Note that before calling the callback, gl_get_line() blocks + most signals, and leaves its own signal handlers installed, + so if you need to catch a particular signal you will need to + both temporarily install your own signal handler, and + unblock the signal. Be sure to re-block the signal (if it + was originally blocked) and reinstate the original signal + handler, if any, before returning. + + Your callback shouldn't try to read from the terminal, which + is left in raw mode as far as input is concerned. You can + however write to the terminal as usual, since features like + conversion of newline to carriage-return/linefeed are re- + enabled while the callback is running. If your callback + function does write to the terminal, be sure to output a + newline first, and when your callback returns, tell + gl_get_line() that the input line needs to be redrawn, by + returning the GLFD_REFRESH status code. + + To remove a callback function that you previously registered + for a given file descriptor and event, simply call + gl_watch_fd() with the same file descriptor and event argu- + ments, but with a callback argument of 0. The data argument + is ignored in this case. + + +</pre><h2>SIGNAL HANDLING DEFAULTS</h2><pre> + By default, the gl_get_line() function intercepts a number + of signals. This is particularly important for signals which + would by default terminate the process, since the terminal + needs to be restored to a usable state before this happens. + In this section, the signals that are trapped by default, + and how gl_get_line() responds to them, is described. Chang- + ing these defaults is the topic of the following section. + + When the following subset of signals are caught, + gl_get_line() first restores the terminal settings and sig- + nal handling to how they were before gl_get_line() was + called, resends the signal, to allow the calling + application's signal handlers to handle it, then if the pro- + cess still exists, gl_get_line() returns NULL and sets errno + as specified below. + + + SIGINT - This signal is generated both by the keyboard + interrupt key (usually ^C), and the keyboard + break key. + + errno=EINTR + + SIGHUP - This signal is generated when the controlling + terminal exits. + + errno=ENOTTY + + SIGPIPE - This signal is generated when a program attempts + to write to a pipe who's remote end isn't being + read by any process. This can happen for example + if you have called gl_change_terminal() to + redirect output to a pipe hidden under a pseudo + terminal. + + errno=EPIPE + + SIGQUIT - This signal is generated by the keyboard quit + key (usually ^\). + + errno=EINTR + + SIGABRT - This signal is generated by the standard C, + abort() function. By default it both + terminates the process and generates a core + dump. + + errno=EINTR + + SIGTERM - This is the default signal that the UN*X + kill command sends to processes. + + errno=EINTR + + Note that in the case of all of the above signals, POSIX + mandates that by default the process is terminated, with the + addition of a core dump in the case of the SIGQUIT signal. + In other words, if the calling application doesn't override + the default handler by supplying its own signal handler, + receipt of the corresponding signal will terminate the + application before gl_get_line() returns. + + If gl_get_line() aborts with errno set to EINTR, you can + find out what signal caused it to abort, by calling the fol- + lowing function. + + int gl_last_signal(const GetLine *gl); + + This returns the numeric code (eg. SIGINT) of the last sig- + nal that was received during the most recent call to + gl_get_line(), or -1 if no signals were received. + + On systems that support it, when a SIGWINCH (window change) + signal is received, gl_get_line() queries the terminal to + find out its new size, redraws the current input line to + accomodate the new size, then returns to waiting for key- + board input from the user. Unlike other signals, this signal + isn't resent to the application. + + Finally, the following signals cause gl_get_line() to first + restore the terminal and signal environment to that which + prevailed before gl_get_line() was called, then resend the + signal to the application. If the process still exists after + the signal has been delivered, then gl_get_line() then re- + establishes its own signal handlers, switches the terminal + back to raw mode, redisplays the input line, and goes back + to awaiting terminal input from the user. + + SIGCONT - This signal is generated when a suspended + process is resumed. + + SIGPWR - This signal is generated when a power failure + occurs (presumably when the system is on a + UPS). + + SIGALRM - This signal is generated when a timer + expires. + SIGUSR1 - An application specific signal. + + SIGUSR2 - Another application specific signal. + + SIGVTALRM - This signal is generated when a virtual + timer expires (see man setitimer(2)). + + SIGXCPU - This signal is generated when a process + exceeds its soft CPU time limit. + + SIGTSTP - This signal is generated by the terminal + suspend key, which is usually ^Z, or the + delayed terminal suspend key, which is + usually ^Y. + + SIGTTIN - This signal is generated if the program + attempts to read from the terminal while the + program is running in the background. + + SIGTTOU - This signal is generated if the program + attempts to write to the terminal while the + program is running in the background. + + + Obviously not all of the above signals are supported on all + systems, so code to support them is conditionally compiled + into the tecla library. + + Note that if SIGKILL, which by definition can't be caught, + or any of the hardware generated exception signals, such as + SIGSEGV, SIGBUS and SIGFPE, are received and unhandled while + gl_get_line() has the terminal in raw mode, the program will + be terminated without the terminal having been restored to a + usable state. In practice, job-control shells usually reset + the terminal settings when a process relinquishes the con- + trolling terminal, so this is only a problem with older + shells. + + +</pre><h2>CUSTOMIZED SIGNAL HANDLING</h2><pre> + The previous section listed the signals that gl_get_line() + traps by default, and described how it responds to them. + This section describes how to both add and remove signals + from the list of trapped signals, and how to specify how + gl_get_line() should respond to a given signal. + + If you don't need gl_get_line() to do anything in response + to a signal that it normally traps, you can tell to + gl_get_line() to ignore that signal by calling + gl_ignore_signal(). + + int gl_ignore_signal(GetLine *gl, int signo); + The signo argument is the number of the signal (eg. SIGINT) + that you want to have ignored. If the specified signal isn't + currently one of those being trapped, this function does + nothing. + + The gl_trap_signal() function allows you to either add a new + signal to the list that gl_get_line() traps, or modify how + it responds to a signal that it already traps. + + int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); + + The signo argument is the number of the signal that you wish + to have trapped. The flags argument is a set of flags which + determine the environment in which the application's signal + handler is invoked, the after argument tells gl_get_line() + what to do after the application's signal handler returns, + and errno_value tells gl_get_line() what to set errno to if + told to abort. + + The flags argument is a bitwise OR of zero or more of the + following enumerators: + + GLS_RESTORE_SIG - Restore the caller's signal + environment while handling the + signal. + + GLS_RESTORE_TTY - Restore the caller's terminal settings + while handling the signal. + + GLS_RESTORE_LINE - Move the cursor to the start of the + line following the input line before + invoking the application's signal + handler. + + GLS_REDRAW_LINE - Redraw the input line when the + application's signal handler returns. + + GLS_UNBLOCK_SIG - Normally, if the calling program has + a signal blocked (man sigprocmask), + gl_get_line() does not trap that + signal. This flag tells gl_get_line() + to trap the signal and unblock it for + the duration of the call to + gl_get_line(). + + GLS_DONT_FORWARD - If this flag is included, the signal + will not be forwarded to the signal + handler of the calling program. + + Two commonly useful flag combinations are also enumerated as + follows: + GLS_RESTORE_ENV = GLS_RESTORE_SIG | GLS_RESTORE_TTY | + GLS_REDRAW_LINE + + GLS_SUSPEND_INPUT = GLS_RESTORE_ENV | GLS_RESTORE_LINE + + + If your signal handler, or the default system signal handler + for this signal, if you haven't overriden it, never either + writes to the terminal, nor suspends or terminates the cal- + ling program, then you can safely set the flags argument to + 0. + + If your signal handler always writes to the terminal, reads + from it, or suspends or terminates the program, you should + specify the flags argument as GL_SUSPEND_INPUT, so that: + + 1. The cursor doesn't get left in the middle of the input + line. + 2. So that the user can type in input and have it echoed. + 3. So that you don't need to end each output line with + \r\n, instead of just \n. + + The GL_RESTORE_ENV combination is the same as + GL_SUSPEND_INPUT, except that it doesn't move the cursor, + and if your signal handler doesn't read or write anything to + the terminal, the user won't see any visible indication that + a signal was caught. This can be useful if you have a signal + handler that only occasionally writes to the terminal, where + using GL_SUSPEND_LINE would cause the input line to be + unnecessarily duplicated when nothing had been written to + the terminal. Such a signal handler, when it does write to + the terminal, should be sure to start a new line at the + start of its first write, by writing a new line before + returning. If the signal arrives while the user is entering + a line that only occupies a signal terminal line, or if the + cursor is on the last terminal line of a longer input line, + this will have the same effect as GL_SUSPEND_INPUT. Other- + wise it will start writing on a line that already contains + part of the displayed input line. This doesn't do any harm, + but it looks a bit ugly, which is why the GL_SUSPEND_INPUT + combination is better if you know that you are always going + to be writting to the terminal. + + The after argument, which determines what gl_get_line() does + after the application's signal handler returns (if it + returns), can take any one of the following values: + + GLS_RETURN - Return the completed input line, just as + though the user had pressed the return + key. + + GLS_ABORT - Cause gl_get_line() to return NULL. + GLS_CONTINUE - Resume command line editing. + + The errno_value argument is intended to be combined with the + GLS_ABORT option, telling gl_get_line() what to set the + standard errno variable to before returning NULL to the cal- + ling program. It can also, however, be used with the + GL_RETURN option, in case you wish to have a way to distin- + guish between an input line that was entered using the + return key, and one that was entered by the receipt of a + signal. + + +</pre><h2>THE TERMINAL SIZE</h2><pre> + On most systems the combination of the TIOCGWINSZ ioctl and + the SIGWINCH signal is used to maintain an accurate idea of + the terminal size. The terminal size is newly queried every + time that gl_get_line() is called and whenever a SIGWINCH + signal is received. + + On the few systems where this mechanism isn't available, at + startup new_GetLine() first looks for the LINES and COLUMNS + environment variables. If these aren't found, or they con- + tain unusable values, then if a terminal information data- + base like terminfo or termcap is available, the default size + of the terminal is looked up in this database. If this too + fails to provide the terminal size, a default size of 80 + columns by 24 lines is used. If this default isn't appropri- + ate for your system, gl_terminal_size() can be used to sup- + ply a different fallback. + + The gl_terminal_size() function allows you to query the + current size of the terminal, and install an alternate fall- + back size for cases where the size isn't available. Beware + that the terminal size won't be available if reading from a + pipe or a file, so the default values can be important even + on systems that do support ways of finding out the terminal + size. + + typedef struct { + int nline; /* The terminal has nline lines */ + int ncolumn; /* The terminal has ncolumn columns */ + } GlTerminalSize; + + GlTerminalSize gl_terminal_size(GetLine *gl, + int def_ncolumn, + int def_nline); + + This function first updates gl_get_line()'s idea of the ter- + minal size, then records its findings in the return value. + + The def_ncolumn and def_nline specify the default number of + terminal columns and lines to use if the terminal size can't + be determined. + + +</pre><h2>HIDING WHAT YOU TYPE</h2><pre> + When entering sensitive information, such as passwords, it + is best not to have the text that you are entering echoed on + the terminal. Furthermore, such text should not be recorded + in the history list, since somebody finding your terminal + unattended could then recall it, or somebody snooping + through your directories could see it in your history file. + With this in mind, the gl_echo_mode() function allows you to + toggle on and off the display and archival of any text that + is subsequently entered in calls to gl_get_line(). + + + int gl_echo_mode(GetLine *gl, int enable); + + + The enable argument specifies whether entered text should be + visible or not. If it is 0, then subsequently entered lines + will not be visible on the terminal, and will not be + recorded in the history list. If it is 1, then subsequent + input lines will be displayed as they are entered, and pro- + vided that history hasn't been turned off via a call to + gl_toggle_history(), then they will also be archived in the + history list. Finally, if the enable argument is -1, then + the echoing mode is left unchanged, which allows you to + non-destructively query the current setting via the return + value. In all cases, the return value of the function is 0 + if echoing was disabled before the function was called, and + 1 if it was enabled. + + When echoing is turned off, note that although tab comple- + tion will invisibly complete your prefix as far as possible, + ambiguous completions will not be displayed. + + +</pre><h2>CALLBACK FUNCTION FACILITIES</h2><pre> + Unless otherwise stated, callback functions, such as tab + completion callbacks and event callbacks should not call any + functions in this module. The following functions, however, + are designed specifically to be used by callback functions. + + Calling the gl_replace_prompt() function from a callback + tells gl_get_line() to display a different prompt when the + callback returns. It has no effect if called when + gl_get_line() is not being called. + + void gl_replace_prompt(GetLine *gl, const char *prompt); + + + +</pre><h2>INTERNATIONAL CHARACTER SETS</h2><pre> + Since libtecla version 1.4.0, gl_get_line() has been 8-bit + clean. This means that all 8-bit characters that are print- + able in the user's current locale are now displayed verbatim + and included in the returned input line. Assuming that the + calling program correctly contains a call like the follow- + ing, + + setlocale(LC_CTYPE, ""); + + then the current locale is determined by the first of the + environment variables LC_CTYPE, LC_ALL, and LANG, that is + found to contain a valid locale name. If none of these vari- + ables are defined, or the program neglects to call setlo- + cale, then the default C locale is used, which is US 7-bit + ASCII. On most unix-like platforms, you can get a list of + valid locales by typing the command: + + locale -a + + at the shell prompt. + + +</pre><h2> Meta keys and locales</h2><pre> + Beware that in most locales other than the default C locale, + meta characters become printable, and they are then no + longer considered to match M-c style key bindings. This + allows international characters to be entered with the com- + pose key without unexpectedly triggering meta key bindings. + You can still invoke meta bindings, since there are actually + two ways to do this. For example the binding M-c can also be + invoked by pressing the escape key momentarily, then press- + ing the c key, and this will work regardless of locale. + Moreover, many modern terminal emulators, such as gnome's + gnome-terminal's and KDE's konsole terminals, already gen- + erate escape pairs like this when you use the meta key, + rather than a real meta character, and other emulators usu- + ally have a way to request this behavior, so you can con- + tinue to use the meta key on most systems. + + For example, although xterm terminal emulators generate real + 8-bit meta characters by default when you use the meta key, + they can be configured to output the equivalent escape pair + by setting their EightBitInput X resource to False. You can + either do this by placing a line like the following in your + ~/.Xdefaults file, + + XTerm*EightBitInput: False + + or by starting an xterm with an -xrm '*EightBitInput: False' + command-line argument. In recent versions of xterm you can + toggle this feature on and off with the "Meta Sends Escape" + option in the menu that is displayed when you press the left + mouse button and the control key within an xterm window. In + CDE, dtterms can be similarly coerced to generate escape + pairs in place of meta characters, by setting the + Dtterm*KshMode resource to True. + + +</pre><h2> Entering international characters</h2><pre> + If you don't have a keyboard that generates all of the + international characters that you need, there is usually a + compose key that will allow you to enter special characters, + or a way to create one. For example, under X windows on + unix-like systems, if your keyboard doesn't have a compose + key, you can designate a redundant key to serve this purpose + with the xmodmap command. For example, on many PC keyboards + there is a microsoft-windows key, which is otherwise useless + under Linux. On my PC the xev program reports that pressing + this key generates keycode 115, so to turn this key into a + compose key, I do the following: + + xmodmap -e 'keycode 115 = Multi_key' + + I can then enter an i with a umlaut over it by typing this + key, followed by ", followed by i. + + +</pre><h2>THREAD SAFETY</h2><pre> + In a multi-threaded program, you should use the libtecla_r.a + version of the library. This uses reentrant versions of sys- + tem functions, where available. Unfortunately neither ter- + minfo nor termcap were designed to be reentrant, so you + can't safely use the functions of the getline module in mul- + tiple threads (you can use the separate file-expansion and + word-completion modules in multiple threads, see the + corresponding man pages for details). However due to the use + of POSIX reentrant functions for looking up home directories + etc, it is safe to use this module from a single thread of a + multi-threaded program, provided that your other threads + don't use any termcap or terminfo functions. + + +</pre><h2>FILES</h2><pre> + libtecla.a - The tecla library + libtecla.h - The tecla header file. + ~/.teclarc - The personal tecla customization file. + + +</pre><h2>SEE ALSO</h2><pre> + <a href="libtecla.html">libtecla(3)</a>, <a href="ef_expand_file.html">ef_expand_file(3)</a>, <a href="cpl_complete_word.html">cpl_complete_word(3)</a>, + <a href="pca_lookup_file.html">pca_lookup_file(3)</a> + + +</pre><h2>AUTHOR</h2><pre> + Martin Shepherd (mcs@astro.caltech.edu) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +</pre> +</body> |