diff options
Diffstat (limited to 'readline/doc/hstech.texinfo')
-rw-r--r-- | readline/doc/hstech.texinfo | 494 |
1 files changed, 349 insertions, 145 deletions
diff --git a/readline/doc/hstech.texinfo b/readline/doc/hstech.texinfo index c3fe3f6..5410090 100644 --- a/readline/doc/hstech.texinfo +++ b/readline/doc/hstech.texinfo @@ -1,8 +1,8 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988, 1991 Free Software Foundation, Inc. -Authored by Brian Fox. +Copyright (C) 1988, 1991, 1994, 1996 Free Software Foundation, Inc. +Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on @@ -26,8 +26,9 @@ into another language, under the above conditions for modified versions. @node Programming with GNU History @chapter Programming with GNU History -This chapter describes how to interface the GNU History Library with -programs that you write. It should be considered a technical guide. +This chapter describes how to interface programs that you write +with the GNU History Library. +It should be considered a technical guide. For information on the interactive use of GNU History, @pxref{Using History Interactively}. @@ -42,32 +43,35 @@ History Interactively}. @node Introduction to History @section Introduction to History -Many programs read input from the user a line at a time. The GNU history +Many programs read input from the user a line at a time. The GNU History library is able to keep track of those lines, associate arbitrary data with -each line, and utilize information from previous lines in making up new +each line, and utilize information from previous lines in composing new ones. -The programmer using the History library has available to him functions -for remembering lines on a history stack, associating arbitrary data -with a line, removing lines from the stack, searching through the stack +The programmer using the History library has available functions +for remembering lines on a history list, associating arbitrary data +with a line, removing lines from the list, searching through the list for a line containing an arbitrary text string, and referencing any line -on the stack directly. In addition, a history @dfn{expansion} function -is available which provides for a consistent user interface across many +in the list directly. In addition, a history @dfn{expansion} function +is available which provides for a consistent user interface across different programs. -The end-user using programs written with the History library has the -benifit of a consistent user interface, with a set of well-known +The user using programs written with the History library has the +benefit of a consistent user interface with a set of well-known commands for manipulating the text of previous lines and using that text in new commands. The basic history manipulation commands are similar to -the history substitution used by @code{Csh}. +the history substitution provided by @code{csh}. If the programmer desires, he can use the Readline library, which includes some history manipulation by default, and has the added -advantage of Emacs style command line editing. +advantage of command line editing. @node History Storage @section History Storage +The history list is an array of history entries. A history entry is +declared as follows: + @example typedef struct _hist_entry @{ char *line; @@ -75,179 +79,378 @@ typedef struct _hist_entry @{ @} HIST_ENTRY; @end example +The history list itself might therefore be declared as + +@example +HIST_ENTRY **the_history_list; +@end example + +The state of the History library is encapsulated into a single structure: + +@example +/* A structure used to pass the current state of the history stuff around. */ +typedef struct _hist_state @{ + HIST_ENTRY **entries; /* Pointer to the entries themselves. */ + int offset; /* The location pointer within this array. */ + int length; /* Number of elements within this array. */ + int size; /* Number of slots allocated to this array. */ + int flags; +@} HISTORY_STATE; +@end example + +If the flags member includes @code{HS_STIFLED}, the history has been +stifled. + @node History Functions @section History Functions This section describes the calling sequence for the various functions present in GNU History. -@defun {void using_history} () +@menu +* Initializing History and State Management:: Functions to call when you + want to use history in a + program. +* History List Management:: Functions used to manage the list + of history entries. +* Information About the History List:: Functions returning information about + the history list. +* Moving Around the History List:: Functions used to change the position + in the history list. +* Searching the History List:: Functions to search the history list + for entries containing a string. +* Managing the History File:: Functions that read and write a file + containing the history list. +* History Expansion:: Functions to perform csh-like history + expansion. +@end menu + +@node Initializing History and State Management +@subsection Initializing History and State Management + +This section describes functions used to initialize and manage +the state of the History library when you want to use the history +functions in your program. + +@deftypefun void using_history () Begin a session in which the history functions might be used. This -just initializes the interactive variables. -@end defun +initializes the interactive variables. +@end deftypefun + +@deftypefun {HISTORY_STATE *} history_get_history_state () +Return a structure describing the current state of the input history. +@end deftypefun + +@deftypefun void history_set_history_state (HISTORY_STATE *state) +Set the state of the history list according to @var{state}. +@end deftypefun + +@node History List Management +@subsection History List Management -@defun {void add_history} (char *string) +These functions manage individual entries on the history list, or set +parameters managing the list itself. + +@deftypefun void add_history (char *string) Place @var{string} at the end of the history list. The associated data field (if any) is set to @code{NULL}. -@end defun - -@defun {int where_history} () -Returns the number which says what history element we are now looking -at. -@end defun - -@defun {int history_set_pos} (int pos) -Set the position in the history list to @var{pos}. -@end defun - -@defun {int history_search_pos} (char *string, int direction, int pos) -Search for @var{string} in the history list, starting at @var{pos}, an -absolute index into the list. @var{direction}, if negative, says to search -backwards from @var{pos}, else forwards. Returns the absolute index of -the history element where @var{string} was found, or -1 otherwise. -@end defun - -@defun {HIST_ENTRY *remove_history} (); -Remove history element @var{which} from the history. The removed -element is returned to you so you can free the line, data, +@end deftypefun + +@deftypefun {HIST_ENTRY *} remove_history (int which) +Remove history entry at offset @var{which} from the history. The +removed element is returned so you can free the line, data, and containing structure. -@end defun +@end deftypefun -@defun {void stifle_history} (int max) -Stifle the history list, remembering only @var{max} number of entries. -@end defun +@deftypefun {HIST_ENTRY *} replace_history_entry (int which, char *line, char *data) +Make the history entry at offset @var{which} have @var{line} and @var{data}. +This returns the old entry so you can dispose of the data. In the case +of an invalid @var{which}, a @code{NULL} pointer is returned. +@end deftypefun -@defun {int unstifle_history} (); +@deftypefun void clear_history () +Clear the history list by deleting all the entries. +@end deftypefun + +@deftypefun void stifle_history (int max) +Stifle the history list, remembering only the last @var{max} entries. +@end deftypefun + +@deftypefun int unstifle_history () Stop stifling the history. This returns the previous amount the -history was stifled by. The value is positive if the history was +history was stifled. The value is positive if the history was stifled, negative if it wasn't. -@end defun +@end deftypefun + +@deftypefun int history_is_stifled () +Returns non-zero if the history is stifled, zero if it is not. +@end deftypefun + +@node Information About the History List +@subsection Information About the History List -@defun {int read_history} (char *filename) +These functions return information about the entire history list or +individual list entries. + +@deftypefun {HIST_ENTRY **} history_list () +Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the +current input history. Element 0 of this list is the beginning of time. +If there is no history, return @code{NULL}. +@end deftypefun + +@deftypefun int where_history () +Returns the offset of the current history element. +@end deftypefun + +@deftypefun {HIST_ENTRY *} current_history () +Return the history entry at the current position, as determined by +@code{where_history ()}. If there is no entry there, return a @code{NULL} +pointer. +@end deftypefun + +@deftypefun {HIST_ENTRY *} history_get (int offset) +Return the history entry at position @var{offset}, starting from +@code{history_base}. If there is no entry there, or if @var{offset} +is greater than the history length, return a @code{NULL} pointer. +@end deftypefun + +@deftypefun int history_total_bytes () +Return the number of bytes that the primary history entries are using. +This function returns the sum of the lengths of all the lines in the +history. +@end deftypefun + +@node Moving Around the History List +@subsection Moving Around the History List + +These functions allow the current index into the history list to be +set or changed. + +@deftypefun int history_set_pos (int pos) +Set the position in the history list to @var{pos}, an absolute index +into the list. +@end deftypefun + +@deftypefun {HIST_ENTRY *} previous_history () +Back up the current history offset to the previous history entry, and +return a pointer to that entry. If there is no previous entry, return +a @code{NULL} pointer. +@end deftypefun + +@deftypefun {HIST_ENTRY *} next_history () +Move the current history offset forward to the next history entry, and +return the a pointer to that entry. If there is no next entry, return +a @code{NULL} pointer. +@end deftypefun + +@node Searching the History List +@subsection Searching the History List +@cindex History Searching + +These functions allow searching of the history list for entries containing +a specific string. Searching may be performed both forward and backward +from the current history position. The search may be @dfn{anchored}, +meaning that the string must match at the beginning of the history entry. +@cindex anchored search + +@deftypefun int history_search (char *string, int direction) +Search the history for @var{string}, starting at the current history +offset. If @var{direction} < 0, then the search is through previous entries, +else through subsequent. If @var{string} is found, then +the current history index is set to that history entry, and the value +returned is the offset in the line of the entry where +@var{string} was found. Otherwise, nothing is changed, and a -1 is +returned. +@end deftypefun + +@deftypefun int history_search_prefix (char *string, int direction) +Search the history for @var{string}, starting at the current history +offset. The search is anchored: matching lines must begin with +@var{string}. If @var{direction} < 0, then the search is through previous +entries, else through subsequent. If @var{string} is found, then the +current history index is set to that entry, and the return value is 0. +Otherwise, nothing is changed, and a -1 is returned. +@end deftypefun + +@deftypefun int history_search_pos (char *string, int direction, int pos) +Search for @var{string} in the history list, starting at @var{pos}, an +absolute index into the list. If @var{direction} is negative, the search +proceeds backward from @var{pos}, otherwise forward. Returns the absolute +index of the history element where @var{string} was found, or -1 otherwise. +@end deftypefun + +@node Managing the History File +@subsection Managing the History File + +The History library can read the history from and write it to a file. +This section documents the functions for managing a history file. + +@deftypefun int read_history (char *filename) Add the contents of @var{filename} to the history list, a line at a time. If @var{filename} is @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, or errno if not. -@end defun +@end deftypefun -@defun {int read_history_range} (char *filename, int from, int to) +@deftypefun int read_history_range (char *filename, int from, int to) Read a range of lines from @var{filename}, adding them to the history list. -Start reading at the @var{from}'th line and end at the @var{to}'th. If +Start reading at line @var{from} and end at @var{to}. If @var{from} is zero, start at the beginning. If @var{to} is less than @var{from}, then read until the end of the file. If @var{filename} is @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, or @code{errno} if not. -@end defun +@end deftypefun -@defun {int write_history} (char *filename) -Append the current history to @var{filename}. If @var{filename} is -@code{NULL}, then append the history list to @file{~/.history}. Values +@deftypefun int write_history (char *filename) +Write the current history to @var{filename}, overwriting @var{filename} +if necessary. If @var{filename} is +@code{NULL}, then write the history list to @file{~/.history}. Values returned are as in @code{read_history ()}. -@end defun +@end deftypefun -@defun {int append_history} (int nelements, char *filename) -Append @var{nelement} entries to @var{filename}. The entries appended -are from the end of the list minus @var{nelements} up to the end of the -list. -@end defun +@deftypefun int append_history (int nelements, char *filename) +Append the last @var{nelements} of the history list to @var{filename}. +@end deftypefun -@defun {HIST_ENTRY *replace_history_entry} () -Make the history entry at @var{which} have @var{line} and @var{data}. -This returns the old entry so you can dispose of the data. In the case -of an invalid @var{which}, a @code{NULL} pointer is returned. -@end defun - -@defun {HIST_ENTRY *current_history} () -Return the history entry at the current position, as determined by -@code{history_offset}. If there is no entry there, return a @code{NULL} -pointer. -@end defun - -@defun {HIST_ENTRY *previous_history} () -Back up @var{history_offset} to the previous history entry, and return a -pointer to that entry. If there is no previous entry, return a -@code{NULL} pointer. -@end defun +@deftypefun int history_truncate_file (char *filename, int nlines) +Truncate the history file @var{filename}, leaving only the last +@var{nlines} lines. +@end deftypefun -@defun {HIST_ENTRY *next_history} () -Move @code{history_offset} forward to the next history entry, and return -the a pointer to that entry. If there is no next entry, return a -@code{NULL} pointer. -@end defun - -@defun {HIST_ENTRY **history_list} () -Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the -current input history. Element 0 of this list is the beginning of time. -If there is no history, return @code{NULL}. -@end defun +@node History Expansion +@subsection History Expansion -@defun {int history_search} (char *string, int direction) -Search the history for @var{string}, starting at @code{history_offset}. -If @var{direction} < 0, then the search is through previous entries, -else through subsequent. If @var{string} is found, then -@code{current_history ()} is the history entry, and the value of this -function is the offset in the line of that history entry that the -@var{string} was found in. Otherwise, nothing is changed, and a -1 is -returned. -@end defun +These functions implement @code{csh}-like history expansion. -@defun {int history_expand} (char *string, char **output) +@deftypefun int history_expand (char *string, char **output) Expand @var{string}, placing the result into @var{output}, a pointer -to a string. Returns: +to a string (@pxref{History Interaction}). Returns: @table @code @item 0 If no expansions took place (or, if the only change in the text was the de-slashifying of the history expansion -character), +character); @item 1 -if expansions did take place, or +if expansions did take place; @item -1 -if there was an error in expansion. +if there was an error in expansion; +@item 2 +if the returned line should only be displayed, but not executed, +as with the @code{:p} modifier (@pxref{Modifiers}). @end table If an error ocurred in expansion, then @var{output} contains a descriptive error message. -@end defun +@end deftypefun -@defun {char *history_arg_extract} (int first, int last, char *string) +@deftypefun {char *} history_arg_extract (int first, int last, char *string) Extract a string segment consisting of the @var{first} through @var{last} -arguments present in @var{string}. Arguments are broken up as in -the GNU Bash shell. -@end defun - -@defun {int history_total_bytes} (); -Return the number of bytes that the primary history entries are using. -This just adds up the lengths of @code{the_history->lines}. -@end defun +arguments present in @var{string}. Arguments are broken up as in Bash. +@end deftypefun + +@deftypefun {char *} get_history_event (char *string, int *cindex, int qchar) +Returns the text of the history event beginning at @var{string} + +@var{*cindex}. @var{*cindex} is modified to point to after the event +specifier. At function entry, @var{cindex} points to the index into +@var{string} where the history event specification begins. @var{qchar} +is a character that is allowed to end the event specification in addition +to the ``normal'' terminating characters. +@end deftypefun + +@deftypefun {char **} history_tokenize (char *string) +Return an array of tokens parsed out of @var{string}, much as the +shell might. The tokens are split on white space and on the +characters @code{()<>;&|$}, and shell quoting conventions are +obeyed. +@end deftypefun @node History Variables @section History Variables -This section describes the variables in GNU History that are externally -visible. - -@defvar {int history_base} -For convenience only. You set this when interpreting history commands. -It is the logical offset of the first history element. -@end defvar +This section describes the externally visible variables exported by +the GNU History Library. + +@deftypevar int history_base +The logical offset of the first entry in the history list. +@end deftypevar + +@deftypevar int history_length +The number of entries currently stored in the history list. +@end deftypevar + +@deftypevar int max_input_history +The maximum number of history entries. This must be changed using +@code{stifle_history ()}. +@end deftypevar + +@deftypevar char history_expansion_char +The character that starts a history event. The default is @samp{!}. +@end deftypevar + +@deftypevar char history_subst_char +The character that invokes word substitution if found at the start of +a line. The default is @samp{^}. +@end deftypevar + +@deftypevar char history_comment_char +During tokenization, if this character is seen as the first character +of a word, then it and all subsequent characters up to a newline are +ignored, suppressing history expansion for the remainder of the line. +This is disabled by default. +@end deftypevar + +@deftypevar {char *} history_no_expand_chars +The list of characters which inhibit history expansion if found immediately +following @var{history_expansion_char}. The default is whitespace and +@samp{=}. +@end deftypevar + +@deftypevar {char *} history_search_delimiter_chars +The list of additional characters which can delimit a history search +string, in addition to whitespace, @samp{:} and @samp{?} in the case of +a substring search. The default is empty. +@end deftypevar + +@deftypevar int history_quotes_inhibit_expansion +If non-zero, single-quoted words are not scanned for the history expansion +character. The default value is 0. +@end deftypevar + +@deftypevar {Function *} history_inhibit_expansion_function +This should be set to the address of a function that takes two arguments: +a @code{char *} (@var{string}) and an integer index into that string (@var{i}). +It should return a non-zero value if the history expansion starting at +@var{string[i]} should not be performed; zero if the expansion should +be done. +It is intended for use by applications like Bash that use the history +expansion character for additional purposes. +By default, this variable is set to NULL. +@end deftypevar @node History Programming Example @section History Programming Example -The following snippet of code demonstrates simple use of the GNU History -Library. +The following program demonstrates simple use of the GNU History Library. @smallexample main () @{ char line[1024], *t; - int done = 0; + int len, done = 0; line[0] = 0; + using_history (); while (!done) @{ - fprintf (stdout, "history%% "); - t = gets (line); + printf ("history$ "); + fflush (stdout); + t = fgets (line, sizeof (line) - 1, stdin); + if (t && *t) + @{ + len = strlen (t); + if (t[len - 1] == '\n') + t[len - 1] = '\0'; + @} if (!t) strcpy (line, "quit"); @@ -257,37 +460,41 @@ main () char *expansion; int result; - using_history (); - result = history_expand (line, &expansion); - strcpy (line, expansion); - free (expansion); if (result) - fprintf (stderr, "%s\n", line); + fprintf (stderr, "%s\n", expansion); - if (result < 0) - continue; + if (result < 0 || result == 2) + @{ + free (expansion); + continue; + @} - add_history (line); + add_history (expansion); + strncpy (line, expansion, sizeof (line) - 1); + free (expansion); @} - if (strcmp (line, "quit") == 0) done = 1; - if (strcmp (line, "save") == 0) write_history (0); - if (strcmp (line, "read") == 0) read_history (0); - if (strcmp (line, "list") == 0) + if (strcmp (line, "quit") == 0) + done = 1; + else if (strcmp (line, "save") == 0) + write_history ("history_file"); + else if (strcmp (line, "read") == 0) + read_history ("history_file"); + else if (strcmp (line, "list") == 0) @{ - register HIST_ENTRY **the_list = history_list (); + register HIST_ENTRY **the_list; register int i; + the_list = history_list (); if (the_list) for (i = 0; the_list[i]; i++) - fprintf (stdout, "%d: %s\n", - i + history_base, the_list[i]->line); + printf ("%d: %s\n", i + history_base, the_list[i]->line); @} - if (strncmp (line, "delete", strlen ("delete")) == 0) + else if (strncmp (line, "delete", 6) == 0) @{ int which; - if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1) + if ((sscanf (line + 6, "%d", &which)) == 1) @{ HIST_ENTRY *entry = remove_history (which); if (!entry) @@ -306,6 +513,3 @@ main () @} @} @end smallexample - - - |