515 lines
18 KiB
Text
515 lines
18 KiB
Text
|
Info file history.info, produced by Makeinfo, -*- Text -*- from input
|
|||
|
file hist.texinfo.
|
|||
|
|
|||
|
This document describes the GNU History library, a programming tool
|
|||
|
that provides a consistent user interface for recalling lines of
|
|||
|
previously typed input.
|
|||
|
|
|||
|
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
|
|||
|
|
|||
|
Permission is granted to make and distribute verbatim copies of
|
|||
|
this manual provided the copyright notice and this permission notice
|
|||
|
pare preserved on all copies.
|
|||
|
|
|||
|
Permission is granted to copy and distribute modified versions of
|
|||
|
this manual under the conditions for verbatim copying, 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, except that this permission notice may be stated in a
|
|||
|
translation approved by the Foundation.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR)
|
|||
|
|
|||
|
GNU History Library
|
|||
|
*******************
|
|||
|
|
|||
|
This document describes the GNU History library, a programming tool
|
|||
|
that provides a consistent user interface for recalling lines of
|
|||
|
previously typed input.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Using History Interactively:: GNU History User's Manual.
|
|||
|
* Programming with GNU History:: GNU History Programmer's Manual.
|
|||
|
* Concept Index:: Index of concepts described in this manual.
|
|||
|
* Function and Variable Index:: Index of externally visible functions
|
|||
|
and variables.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top
|
|||
|
|
|||
|
Using History Interactively
|
|||
|
***************************
|
|||
|
|
|||
|
This chapter describes how to use the GNU History Library
|
|||
|
interactively, from a user's standpoint. It should be considered a
|
|||
|
user's guide. For information on using the GNU History Library in
|
|||
|
your own programs, *note Programming with GNU History::..
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* History Interaction:: What it feels like using History as a user.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: History Interaction, Up: Using History Interactively
|
|||
|
|
|||
|
History Interaction
|
|||
|
===================
|
|||
|
|
|||
|
The History library provides a history expansion feature that is
|
|||
|
similar to the history expansion in Csh. The following text describes
|
|||
|
the sytax that you use to manipulate the history information.
|
|||
|
|
|||
|
History expansion takes place in two parts. The first is to
|
|||
|
determine which line from the previous history should be used during
|
|||
|
substitution. The second is to select portions of that line for
|
|||
|
inclusion into the current one. The line selected from the previous
|
|||
|
history is called the "event", and the portions of that line that are
|
|||
|
acted upon are called "words". The line is broken into words in the
|
|||
|
same fashion that the Bash shell does, so that several English (or
|
|||
|
Unix) words surrounded by quotes are considered as one word.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Event Designators:: How to specify which history line to use.
|
|||
|
* Word Designators:: Specifying which words are of interest.
|
|||
|
* Modifiers:: Modifying the results of susbstitution.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction
|
|||
|
|
|||
|
Event Designators
|
|||
|
-----------------
|
|||
|
|
|||
|
An event designator is a reference to a command line entry in the
|
|||
|
history list.
|
|||
|
|
|||
|
`!'
|
|||
|
Start a history subsititution, except when followed by a space,
|
|||
|
tab, or the end of the line... = or (.
|
|||
|
|
|||
|
`!!'
|
|||
|
Refer to the previous command. This is a synonym for `!-1'.
|
|||
|
|
|||
|
`!n'
|
|||
|
Refer to command line N.
|
|||
|
|
|||
|
`!-n'
|
|||
|
Refer to the command line N lines back.
|
|||
|
|
|||
|
`!string'
|
|||
|
Refer to the most recent command starting with STRING.
|
|||
|
|
|||
|
`!?string'[`?']
|
|||
|
Refer to the most recent command containing STRING.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction
|
|||
|
|
|||
|
Word Designators
|
|||
|
----------------
|
|||
|
|
|||
|
A : separates the event specification from the word designator. It
|
|||
|
can be omitted if the word designator begins with a ^, $, * or %.
|
|||
|
Words are numbered from the beginning of the line, with the first word
|
|||
|
being denoted by a 0 (zero).
|
|||
|
|
|||
|
`0 (zero)'
|
|||
|
The zero'th word. For many applications, this is the command
|
|||
|
word.
|
|||
|
|
|||
|
`n'
|
|||
|
The N'th word.
|
|||
|
|
|||
|
`^'
|
|||
|
The first argument. that is, word 1.
|
|||
|
|
|||
|
`$'
|
|||
|
The last argument.
|
|||
|
|
|||
|
`%'
|
|||
|
The word matched by the most recent `?string?' search.
|
|||
|
|
|||
|
`x-y'
|
|||
|
A range of words; `-Y' Abbreviates `0-Y'.
|
|||
|
|
|||
|
`*'
|
|||
|
All of the words, excepting the zero'th. This is a synonym for
|
|||
|
`1-$'. It is not an error to use * if there is just one word in
|
|||
|
the event. The empty string is returned in that case.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction
|
|||
|
|
|||
|
Modifiers
|
|||
|
---------
|
|||
|
|
|||
|
After the optional word designator, you can add a sequence of one
|
|||
|
or more of the following modifiers, each preceded by a :.
|
|||
|
|
|||
|
`#'
|
|||
|
The entire command line typed so far. This means the current
|
|||
|
command, not the previous command, so it really isn't a word
|
|||
|
designator, and doesn't belong in this section.
|
|||
|
|
|||
|
`h'
|
|||
|
Remove a trailing pathname component, leaving only the head.
|
|||
|
|
|||
|
`r'
|
|||
|
Remove a trailing suffix of the form `.'SUFFIX, leaving the
|
|||
|
basename.
|
|||
|
|
|||
|
`e'
|
|||
|
Remove all but the suffix.
|
|||
|
|
|||
|
`t'
|
|||
|
Remove all leading pathname components, leaving the tail.
|
|||
|
|
|||
|
`p'
|
|||
|
Print the new command but do not execute it.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top
|
|||
|
|
|||
|
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.
|
|||
|
For information on the interactive use of GNU History, *note 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.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History
|
|||
|
|
|||
|
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 making up 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 for a line containing an arbitrary text string, and
|
|||
|
referencing any line on the stack directly. In addition, a history
|
|||
|
"expansion" function is available which provides for a consistent user
|
|||
|
interface across many 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
|
|||
|
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 `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.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History
|
|||
|
|
|||
|
History Storage
|
|||
|
===============
|
|||
|
|
|||
|
typedef struct _hist_entry {
|
|||
|
char *line;
|
|||
|
char *data;
|
|||
|
} HIST_ENTRY;
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History
|
|||
|
|
|||
|
History Functions
|
|||
|
=================
|
|||
|
|
|||
|
This section describes the calling sequence for the various
|
|||
|
functions present in GNU History.
|
|||
|
|
|||
|
* Function: void using_history ()
|
|||
|
Begin a session in which the history functions might be used.
|
|||
|
This just initializes the interactive variables.
|
|||
|
|
|||
|
* Function: void add_history (CHAR *STRING)
|
|||
|
Place STRING at the end of the history list. The associated data
|
|||
|
field (if any) is set to `NULL'.
|
|||
|
|
|||
|
* Function: int where_history ()
|
|||
|
Returns the number which says what history element we are now
|
|||
|
looking at.
|
|||
|
|
|||
|
* Function: int history_set_pos (INT POS)
|
|||
|
Set the position in the history list to POS.
|
|||
|
|
|||
|
* Function: int history_search_pos (CHAR *STRING, INT DIRECTION, INT
|
|||
|
POS)
|
|||
|
Search for STRING in the history list, starting at POS, an
|
|||
|
absolute index into the list. DIRECTION, if negative, says to
|
|||
|
search backwards from POS, else forwards. Returns the absolute
|
|||
|
index of the history element where STRING was found, or -1
|
|||
|
otherwise.
|
|||
|
|
|||
|
* Function: HIST_ENTRY *remove_history ();
|
|||
|
Remove history element WHICH from the history. The removed
|
|||
|
element is returned to you so you can free the line, data, and
|
|||
|
containing structure.
|
|||
|
|
|||
|
* Function: void stifle_history (INT MAX)
|
|||
|
Stifle the history list, remembering only MAX number of entries.
|
|||
|
|
|||
|
* Function: 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
|
|||
|
stifled, negative if it wasn't.
|
|||
|
|
|||
|
* Function: int read_history (CHAR *FILENAME)
|
|||
|
Add the contents of FILENAME to the history list, a line at a
|
|||
|
time. If FILENAME is `NULL', then read from `~/.history'.
|
|||
|
Returns 0 if successful, or errno if not.
|
|||
|
|
|||
|
* Function: int read_history_range (CHAR *FILENAME, INT FROM, INT TO)
|
|||
|
Read a range of lines from FILENAME, adding them to the history
|
|||
|
list. Start reading at the FROM'th line and end at the TO'th. If
|
|||
|
FROM is zero, start at the beginning. If TO is less than FROM,
|
|||
|
then read until the end of the file. If FILENAME is `NULL', then
|
|||
|
read from `~/.history'. Returns 0 if successful, or `errno' if
|
|||
|
not.
|
|||
|
|
|||
|
* Function: int write_history (CHAR *FILENAME)
|
|||
|
Append the current history to FILENAME. If FILENAME is `NULL',
|
|||
|
then append the history list to `~/.history'. Values returned
|
|||
|
are as in `read_history ()'.
|
|||
|
|
|||
|
* Function: int append_history (INT NELEMENTS, CHAR *FILENAME)
|
|||
|
Append NELEMENT entries to FILENAME. The entries appended are
|
|||
|
from the end of the list minus NELEMENTS up to the end of the
|
|||
|
list.
|
|||
|
|
|||
|
* Function: HIST_ENTRY *replace_history_entry ()
|
|||
|
Make the history entry at WHICH have LINE and DATA. This returns
|
|||
|
the old entry so you can dispose of the data. In the case of an
|
|||
|
invalid WHICH, a `NULL' pointer is returned.
|
|||
|
|
|||
|
* Function: HIST_ENTRY *current_history ()
|
|||
|
Return the history entry at the current position, as determined by
|
|||
|
`history_offset'. If there is no entry there, return a `NULL'
|
|||
|
pointer.
|
|||
|
|
|||
|
* Function: HIST_ENTRY *previous_history ()
|
|||
|
Back up HISTORY_OFFSET to the previous history entry, and return a
|
|||
|
pointer to that entry. If there is no previous entry, return a
|
|||
|
`NULL' pointer.
|
|||
|
|
|||
|
* Function: HIST_ENTRY *next_history ()
|
|||
|
Move `history_offset' forward to the next history entry, and
|
|||
|
return the a pointer to that entry. If there is no next entry,
|
|||
|
return a `NULL' pointer.
|
|||
|
|
|||
|
* Function: HIST_ENTRY **history_list ()
|
|||
|
Return a `NULL' terminated array of `HIST_ENTRY' which is the
|
|||
|
current input history. Element 0 of this list is the beginning
|
|||
|
of time. If there is no history, return `NULL'.
|
|||
|
|
|||
|
* Function: int history_search (CHAR *STRING, INT DIRECTION)
|
|||
|
Search the history for STRING, starting at `history_offset'. If
|
|||
|
DIRECTION < 0, then the search is through previous entries, else
|
|||
|
through subsequent. If STRING is found, then `current_history
|
|||
|
()' is the history entry, and the value of this function is the
|
|||
|
offset in the line of that history entry that the STRING was
|
|||
|
found in. Otherwise, nothing is changed, and a -1 is returned.
|
|||
|
|
|||
|
* Function: int history_expand (CHAR *STRING, CHAR **OUTPUT)
|
|||
|
Expand STRING, placing the result into OUTPUT, a pointer to a
|
|||
|
string. Returns:
|
|||
|
|
|||
|
`0'
|
|||
|
If no expansions took place (or, if the only change in the
|
|||
|
text was the de-slashifying of the history expansion
|
|||
|
character),
|
|||
|
|
|||
|
`1'
|
|||
|
if expansions did take place, or
|
|||
|
|
|||
|
`-1'
|
|||
|
if there was an error in expansion.
|
|||
|
|
|||
|
If an error ocurred in expansion, then OUTPUT contains a
|
|||
|
descriptive error message.
|
|||
|
|
|||
|
* Function: char *history_arg_extract (INT FIRST, INT LAST, CHAR
|
|||
|
*STRING)
|
|||
|
Extract a string segment consisting of the FIRST through LAST
|
|||
|
arguments present in STRING. Arguments are broken up as in the
|
|||
|
GNU Bash shell.
|
|||
|
|
|||
|
* Function: int history_total_bytes ();
|
|||
|
Return the number of bytes that the primary history entries are
|
|||
|
using. This just adds up the lengths of `the_history->lines'.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History
|
|||
|
|
|||
|
History Variables
|
|||
|
=================
|
|||
|
|
|||
|
This section describes the variables in GNU History that are
|
|||
|
externally visible.
|
|||
|
|
|||
|
* Variable: int history_base
|
|||
|
For convenience only. You set this when interpreting history
|
|||
|
commands. It is the logical offset of the first history element.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History
|
|||
|
|
|||
|
History Programming Example
|
|||
|
===========================
|
|||
|
|
|||
|
The following snippet of code demonstrates simple use of the GNU
|
|||
|
History Library.
|
|||
|
|
|||
|
main ()
|
|||
|
{
|
|||
|
char line[1024], *t;
|
|||
|
int done = 0;
|
|||
|
|
|||
|
line[0] = 0;
|
|||
|
|
|||
|
while (!done)
|
|||
|
{
|
|||
|
fprintf (stdout, "history%% ");
|
|||
|
t = gets (line);
|
|||
|
|
|||
|
if (!t)
|
|||
|
strcpy (line, "quit");
|
|||
|
|
|||
|
if (line[0])
|
|||
|
{
|
|||
|
char *expansion;
|
|||
|
int result;
|
|||
|
|
|||
|
using_history ();
|
|||
|
|
|||
|
result = history_expand (line, &expansion);
|
|||
|
strcpy (line, expansion);
|
|||
|
free (expansion);
|
|||
|
if (result)
|
|||
|
fprintf (stderr, "%s\n", line);
|
|||
|
|
|||
|
if (result < 0)
|
|||
|
continue;
|
|||
|
|
|||
|
add_history (line);
|
|||
|
}
|
|||
|
|
|||
|
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)
|
|||
|
{
|
|||
|
register HIST_ENTRY **the_list = history_list ();
|
|||
|
register int i;
|
|||
|
|
|||
|
if (the_list)
|
|||
|
for (i = 0; the_list[i]; i++)
|
|||
|
fprintf (stdout, "%d: %s\n",
|
|||
|
i + history_base, the_list[i]->line);
|
|||
|
}
|
|||
|
if (strncmp (line, "delete", strlen ("delete")) == 0)
|
|||
|
{
|
|||
|
int which;
|
|||
|
if ((sscanf (line + strlen ("delete"), "%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");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top
|
|||
|
|
|||
|
Concept Index
|
|||
|
*************
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* event designators: Event Designators.
|
|||
|
* expansion: History Interaction.
|
|||
|
|
|||
|
|
|||
|
File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top
|
|||
|
|
|||
|
Function and Variable Index
|
|||
|
***************************
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* HIST_ENTRY **history_list: History Functions.
|
|||
|
* HIST_ENTRY *current_history: History Functions.
|
|||
|
* HIST_ENTRY *next_history: History Functions.
|
|||
|
* HIST_ENTRY *previous_history: History Functions.
|
|||
|
* HIST_ENTRY *remove_history: History Functions.
|
|||
|
* HIST_ENTRY *replace_history_entry: History Functions.
|
|||
|
* char *history_arg_extract: History Functions.
|
|||
|
* int append_history: History Functions.
|
|||
|
* int history_base: History Variables.
|
|||
|
* int history_expand: History Functions.
|
|||
|
* int history_search: History Functions.
|
|||
|
* int history_search_pos: History Functions.
|
|||
|
* int history_set_pos: History Functions.
|
|||
|
* int history_total_bytes: History Functions.
|
|||
|
* int read_history: History Functions.
|
|||
|
* int read_history_range: History Functions.
|
|||
|
* int unstifle_history: History Functions.
|
|||
|
* int where_history: History Functions.
|
|||
|
* int write_history: History Functions.
|
|||
|
* void add_history: History Functions.
|
|||
|
* void stifle_history: History Functions.
|
|||
|
* void using_history: History Functions.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Tag Table:
|
|||
|
Node: Top973
|
|||
|
Node: Using History Interactively1567
|
|||
|
Node: History Interaction2075
|
|||
|
Node: Event Designators3127
|
|||
|
Node: Word Designators3770
|
|||
|
Node: Modifiers4676
|
|||
|
Node: Programming with GNU History5425
|
|||
|
Node: Introduction to History6152
|
|||
|
Node: History Storage7502
|
|||
|
Node: History Functions7766
|
|||
|
Node: History Variables13063
|
|||
|
Node: History Programming Example13499
|
|||
|
Node: Concept Index15744
|
|||
|
Node: Function and Variable Index16030
|
|||
|
|
|||
|
End Tag Table
|