@ignore
This file documents the user interface to the GNU History library.

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
all copies.

Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore

@node Programming with GNU History
@chapter Programming with GNU History

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}.

@menu
* Introduction to History::	What is the GNU History library for?
* History Storage::		How information is stored.
* History Functions::		Functions that you can use.
* History Variables::		Variables that control behaviour.
* History Programming Example::	Example of using the GNU History Library.
@end menu

@node Introduction to History
@section Introduction to 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 composing new
ones.

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
in the list directly.  In addition, a history @dfn{expansion} function
is available which provides for a consistent user interface across
different programs.

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 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 command line editing.

Before declaring any functions using any functionality the History
library provides in other code, an application writer should include
the file @code{<readline/history.h>} in any file that uses the
History library's features.  It supplies extern declarations for all
of the library's public functions and variables, and declares all of
the public data structures.

@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;
  char *data;
@} 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.

@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
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

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 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 deftypefun

@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

@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.  The value is positive if the history was
stifled, negative if it wasn't.
@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

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 deftypefun

@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 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 deftypefun

@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 deftypefun

@deftypefun int append_history (int nelements, char *filename)
Append the last @var{nelements} of the history list to @var{filename}.
@end deftypefun

@deftypefun int history_truncate_file (char *filename, int nlines)
Truncate the history file @var{filename}, leaving only the last
@var{nlines} lines.
@end deftypefun

@node History Expansion
@subsection History Expansion

These functions implement @code{csh}-like history expansion.

@deftypefun int history_expand (char *string, char **output)
Expand @var{string}, placing the result into @var{output}, a pointer
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);
@item 1
if expansions did take place;
@item -1
if there was an error in expansion;
@item 2
if the returned line should 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 deftypefun

@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 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 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 program demonstrates simple use of the GNU History Library.

@smallexample
main ()
@{
  char line[1024], *t;
  int len, done = 0;

  line[0] = 0;

  using_history ();
  while (!done)
    @{
      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");

      if (line[0])
        @{
          char *expansion;
          int result;

          result = history_expand (line, &expansion);
          if (result)
            fprintf (stderr, "%s\n", expansion);

          if (result < 0 || result == 2)
            @{
              free (expansion);
              continue;
            @}

          add_history (expansion);
          strncpy (line, expansion, sizeof (line) - 1);
          free (expansion);
        @}

      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;
          register int i;

          the_list = history_list ();
          if (the_list)
            for (i = 0; the_list[i]; i++)
              printf ("%d: %s\n", i + history_base, the_list[i]->line);
        @}
      else if (strncmp (line, "delete", 6) == 0)
        @{
          int which;
          if ((sscanf (line + 6, "%d", &which)) == 1)
            @{
              HIST_ENTRY *entry = remove_history (which);
              if (!entry)
                fprintf (stderr, "No such entry %d\n", which);
              else
                @{
                  free (entry->line);
                  free (entry);
                @}
            @}
          else
            @{
              fprintf (stderr, "non-numeric arg given to `delete'\n");
            @}
        @}
    @}
@}
@end smallexample
