aboutsummaryrefslogtreecommitdiff
path: root/readline/doc/hstech.texinfo
diff options
context:
space:
mode:
Diffstat (limited to 'readline/doc/hstech.texinfo')
-rw-r--r--readline/doc/hstech.texinfo494
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
-
-
-