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

Copyright (C) 1988-2020 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 @sc{gnu} History Library.
It should be considered a technical guide.
For information on the interactive use of @sc{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 @sc{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. 

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

The programmer can also 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 void *histdata_t;

typedef struct _hist_entry @{
  char *line;
  char *timestamp;
  histdata_t 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 around the current state of the history.
 */
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
exported by the @sc{gnu} History library.

@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 (void)
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 (void)
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 (const char *string)
Place @var{string} at the end of the history list.  The associated data
field (if any) is set to @code{NULL}.
If the maximum number of history entries has been set using
@code{stifle_history()}, and the new number of history entries would exceed
that maximum, the oldest history entry is removed.
@end deftypefun

@deftypefun void add_history_time (const char *string)
Change the time stamp associated with the most recent history entry to
@var{string}.
@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 {histdata_t} free_history_entry (HIST_ENTRY *histent)
Free the history entry @var{histent} and any history library private
data associated with it.  Returns the application-specific data
so the caller can dispose of it.
@end deftypefun

@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data)
Make the history entry at offset @var{which} have @var{line} and @var{data}.
This returns the old entry so the caller can dispose of any
application-specific data.  In the case
of an invalid @var{which}, a @code{NULL} pointer is returned.
@end deftypefun

@deftypefun void clear_history (void)
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.
The history list will contain only @var{max} entries at a time.
@end deftypefun

@deftypefun int unstifle_history (void)
Stop stifling the history.  This returns the previously-set
maximum number of history entries (as set by @code{stifle_history()}).
The value is positive if the history was
stifled, negative if it wasn't.
@end deftypefun

@deftypefun int history_is_stifled (void)
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 (void)
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 (void)
Returns the offset of the current history element.
@end deftypefun

@deftypefun {HIST_ENTRY *} current_history (void)
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}.
The range of valid
values of @var{offset} starts at @code{history_base} and ends at
@var{history_length} - 1 (@pxref{History Variables}).
If there is no entry there, or if @var{offset} is outside the valid
range, return a @code{NULL} pointer.
@end deftypefun

@deftypefun time_t history_get_time (HIST_ENTRY *entry)
Return the time stamp associated with the history entry @var{entry}.
If the timestamp is missing or invalid, return 0.
@end deftypefun

@deftypefun int history_total_bytes (void)
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 current history offset to @var{pos}, an absolute index
into the list.
Returns 1 on success, 0 if @var{pos} is less than zero or greater
than the number of history entries.
@end deftypefun

@deftypefun {HIST_ENTRY *} previous_history (void)
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 (void)
If the current history offset refers to a valid history entry,
increment the current history offset.
If the possibly-incremented history offset refers to a valid history
entry, return a pointer to that entry;
otherwise, return a @code{BNULL} 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 (const char *string, int direction)
Search the history for @var{string}, starting at the current history offset.
If @var{direction} is less than 0, then the search is through
previous entries, otherwise through subsequent entries.
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 (const 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} is less than 0, then the search is
through previous entries, otherwise through subsequent entries.
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 (const 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 (const 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 @code{errno} if not.
@end deftypefun

@deftypefun int read_history_range (const 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 (const 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}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun

@deftypefun int append_history (int nelements, const char *filename)
Append the last @var{nelements} of the history list to @var{filename}.
If @var{filename} is @code{NULL}, then append to @file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun

@deftypefun int history_truncate_file (const char *filename, int nlines)
Truncate the history file @var{filename}, leaving only the last
@var{nlines} lines.
If @var{filename} is @code{NULL}, then @file{~/.history} is truncated.
Returns 0 on success, or @code{errno} on failure.
@end deftypefun

@node History Expansion
@subsection History Expansion

These functions implement 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 removal of escape characters preceding 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 occurred in expansion, then @var{output} contains a descriptive
error message.
@end deftypefun

@deftypefun {char *} get_history_event (const 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 (const char *string)
Return an array of tokens parsed out of @var{string}, much as the
shell might.  The tokens are split on the characters in the
@var{history_word_delimiters} variable,
and shell quoting conventions are obeyed as described below.
@end deftypefun

@deftypefun {char *} history_arg_extract (int first, int last, const char *string)
Extract a string segment consisting of the @var{first} through @var{last}
arguments present in @var{string}.  Arguments are split using
@code{history_tokenize}.
@end deftypefun

@node History Variables
@section History Variables

This section describes the externally-visible variables exported by
the @sc{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 history_max_entries
The maximum number of history entries.  This must be changed using
@code{stifle_history()}.
@end deftypevar

@deftypevar int history_write_timestamps
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions.  The default value is 0, meaning that
timestamps are not saved.

The current timestamp format uses the value of @var{history_comment_char}
to delimit timestamp entries in the history file.  If that variable does
not have a value (the default), timestamps will not be written.
@end deftypevar

@deftypevar char history_expansion_char
The character that introduces a history event.  The default is @samp{!}.
Setting this to 0 inhibits history expansion.
@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_word_delimiters
The characters that separate tokens for @code{history_tokenize()}.
The default value is @code{" \t\n()<>;&|"}.
@end deftypevar

@deftypevar {char *} history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, TAB, @samp{:} and @samp{?} in the case of
a substring search.  The default is empty.
@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 space, tab, newline,
carriage return, and @samp{=}.
@end deftypevar

@deftypevar int history_quotes_inhibit_expansion
If non-zero, the history expansion code implements shell-like quoting:
single-quoted words are not scanned for the history expansion
character or the history comment character, and double-quoted words may
have history expansion performed, since single quotes are not special
within double quotes.
The default value is 0.
@end deftypevar

@deftypevar int history_quoting_state
An application may set this variable to indicate that the current line
being expanded is subject to existing quoting. If set to @samp{'}, the
history expansion function will assume that the line is single-quoted and
inhibit expansion until it reads an unquoted closing single quote; if set
to @samp{"}, history expansion will assume the line is double quoted until
it reads an unquoted closing double quote. If set to zero, the default,
the history expansion function will assume the line is not quoted and
treat quote characters within the line as described above.
This is only effective if @var{history_quotes_inhibit_expansion} is set.
@end deftypevar

@deftypevar {rl_linebuf_func_t *} 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 @code{int} 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 @code{NULL}.
@end deftypevar

@node History Programming Example
@section History Programming Example

The following program demonstrates simple use of the @sc{gnu} History Library.

@smallexample
#include <stdio.h>
#include <readline/history.h>

main (argc, argv)
     int argc;
     char **argv;
@{
  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
