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

Copyright (C) 1988-2011 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. 

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 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}.
@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.
@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}, starting from
@code{history_base} (@pxref{History Variables}).
If there is no entry there, or if @var{offset}
is greater than the history length, 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}.
@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)
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 (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 ocurred 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.
@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, single-quoted words are not scanned for the history expansion
character.  The default value is 0.
@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
