mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 04:25:10 +08:00
Initial revision
This commit is contained in:
parent
b6666a5d67
commit
be9485d5f5
36
readline/doc/Makefile
Normal file
36
readline/doc/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
# This makefile for Readline library documentation is in -*- text -*- mode.
|
||||
# Emacs likes it that way.
|
||||
|
||||
DVIOBJ = readline.dvi history.dvi
|
||||
INFOBJ = readline.info history.info
|
||||
|
||||
all: $(DVIOBJ) $(INFOBJ)
|
||||
|
||||
readline.dvi: texindex rlman.texinfo rluser.texinfo rltech.texinfo
|
||||
tex rlman.texinfo
|
||||
./texindex rlman.??
|
||||
tex rlman.texinfo
|
||||
mv rlman.dvi readline.dvi
|
||||
|
||||
history.dvi: texindex hist.texinfo hsuser.texinfo hstech.texinfo
|
||||
tex hist.texinfo
|
||||
tex hist.texinfo
|
||||
mv hist.dvi history.dvi
|
||||
|
||||
readline.info: rlman.texinfo rluser.texinfo rltech.texinfo
|
||||
makeinfo rlman.texinfo
|
||||
|
||||
history.info: hist.texinfo hsuser.texinfo hstech.texinfo
|
||||
makeinfo hist.texinfo
|
||||
|
||||
texindex: texindex.o
|
||||
$(CC) -o $@ $(LDFLAGS) $(CFLAGS) $?
|
||||
texindex.o: texindex.c
|
||||
|
||||
clean:
|
||||
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
|
||||
*.fns *.kys *.tps *.vrs *.o core texindex
|
||||
|
||||
squeaky-clean:
|
||||
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
|
||||
*.dvi *.info *.info-* *.fns *.kys *.tps *.vrs *.o core texindex
|
106
readline/doc/hist.texinfo
Normal file
106
readline/doc/hist.texinfo
Normal file
@ -0,0 +1,106 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename history.info
|
||||
@settitle GNU Readline Library
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@synindex vr fn
|
||||
@setchapternewpage odd
|
||||
|
||||
@ifinfo
|
||||
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.
|
||||
|
||||
@ignore
|
||||
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).
|
||||
@end ignore
|
||||
|
||||
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.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@sp 10
|
||||
@center @titlefont{GNU History Library}
|
||||
@center Brian Fox
|
||||
@center Free Software Foundation
|
||||
@center Version 1.1
|
||||
@center April 1991
|
||||
|
||||
@c Include the Distribution inside the titlepage environment so
|
||||
@c that headings are turned off.
|
||||
|
||||
@page
|
||||
|
||||
This document describes the GNU History library, a programming tool that
|
||||
provides a consistent user interface for recalling lines of previously
|
||||
typed input.
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
675 Massachusetts Avenue, @*
|
||||
Cambridge, MA 02139 USA
|
||||
|
||||
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 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.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top
|
||||
@top 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.
|
||||
@end menu
|
||||
@end ifinfo
|
||||
|
||||
@include hsuser.texinfo
|
||||
@include hstech.texinfo
|
||||
|
||||
@node Concept Index
|
||||
@appendix Concept Index
|
||||
@printindex cp
|
||||
|
||||
@node Function and Variable Index
|
||||
@appendix Function and Variable Index
|
||||
@printindex vr
|
||||
@contents
|
||||
|
||||
@bye
|
514
readline/doc/history.info
Normal file
514
readline/doc/history.info
Normal file
@ -0,0 +1,514 @@
|
||||
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
|
311
readline/doc/hstech.texinfo
Normal file
311
readline/doc/hstech.texinfo
Normal file
@ -0,0 +1,311 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox.
|
||||
|
||||
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 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, @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 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 @dfn{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 @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.
|
||||
|
||||
@node History Storage
|
||||
@section History Storage
|
||||
|
||||
@example
|
||||
typedef struct _hist_entry @{
|
||||
char *line;
|
||||
char *data;
|
||||
@} HIST_ENTRY;
|
||||
@end example
|
||||
|
||||
@node History Functions
|
||||
@section History Functions
|
||||
|
||||
This section describes the calling sequence for the various functions
|
||||
present in GNU History.
|
||||
|
||||
@defun {void using_history} ()
|
||||
Begin a session in which the history functions might be used. This
|
||||
just initializes the interactive variables.
|
||||
@end defun
|
||||
|
||||
@defun {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,
|
||||
and containing structure.
|
||||
@end defun
|
||||
|
||||
@defun {void stifle_history} (int max)
|
||||
Stifle the history list, remembering only @var{max} number of entries.
|
||||
@end defun
|
||||
|
||||
@defun {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.
|
||||
@end defun
|
||||
|
||||
@defun {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
|
||||
|
||||
@defun {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
|
||||
@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
|
||||
|
||||
@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
|
||||
returned are as in @code{read_history ()}.
|
||||
@end defun
|
||||
|
||||
@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
|
||||
|
||||
@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
|
||||
|
||||
@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
|
||||
|
||||
@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
|
||||
|
||||
@defun {int history_expand} (char *string, char **output)
|
||||
Expand @var{string}, placing the result into @var{output}, a pointer
|
||||
to a string. 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, or
|
||||
@item -1
|
||||
if there was an error in expansion.
|
||||
@end table
|
||||
|
||||
If an error ocurred in expansion, then @var{output} contains a descriptive
|
||||
error message.
|
||||
@end defun
|
||||
|
||||
@defun {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
|
||||
|
||||
@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
|
||||
|
||||
@node History Programming Example
|
||||
@section History Programming Example
|
||||
|
||||
The following snippet of code demonstrates simple use of the GNU History
|
||||
Library.
|
||||
|
||||
@smallexample
|
||||
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");
|
||||
@}
|
||||
@}
|
||||
@}
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
|
||||
|
153
readline/doc/hsuser.texinfo
Normal file
153
readline/doc/hsuser.texinfo
Normal file
@ -0,0 +1,153 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox.
|
||||
|
||||
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 Using History Interactively
|
||||
@chapter 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,
|
||||
@pxref{Programming with GNU History}.
|
||||
|
||||
@menu
|
||||
* History Interaction:: What it feels like using History as a user.
|
||||
@end menu
|
||||
|
||||
@node History Interaction
|
||||
@section History Interaction
|
||||
@cindex expansion
|
||||
|
||||
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
|
||||
@dfn{event}, and the portions of that line that are acted upon are
|
||||
called @dfn{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.
|
||||
@end menu
|
||||
|
||||
@node Event Designators
|
||||
@subsection Event Designators
|
||||
@cindex event designators
|
||||
|
||||
An event designator is a reference to a command line entry in the
|
||||
history list.
|
||||
|
||||
@table @asis
|
||||
|
||||
@item @code{!}
|
||||
Start a history subsititution, except when followed by a space, tab, or
|
||||
the end of the line... @key{=} or @key{(}.
|
||||
|
||||
@item @code{!!}
|
||||
Refer to the previous command. This is a synonym for @code{!-1}.
|
||||
|
||||
@item @code{!n}
|
||||
Refer to command line @var{n}.
|
||||
|
||||
@item @code{!-n}
|
||||
Refer to the command line @var{n} lines back.
|
||||
|
||||
@item @code{!string}
|
||||
Refer to the most recent command starting with @var{string}.
|
||||
|
||||
@item @code{!?string}[@code{?}]
|
||||
Refer to the most recent command containing @var{string}.
|
||||
|
||||
@end table
|
||||
|
||||
@node Word Designators
|
||||
@subsection Word Designators
|
||||
|
||||
A @key{:} separates the event specification from the word designator. It
|
||||
can be omitted if the word designator begins with a @key{^}, @key{$},
|
||||
@key{*} or @key{%}. Words are numbered from the beginning of the line,
|
||||
with the first word being denoted by a 0 (zero).
|
||||
|
||||
@table @code
|
||||
|
||||
@item 0 (zero)
|
||||
The zero'th word. For many applications, this is the command word.
|
||||
|
||||
@item n
|
||||
The @var{n}'th word.
|
||||
|
||||
@item ^
|
||||
The first argument. that is, word 1.
|
||||
|
||||
@item $
|
||||
The last argument.
|
||||
|
||||
@item %
|
||||
The word matched by the most recent @code{?string?} search.
|
||||
|
||||
@item x-y
|
||||
A range of words; @code{-@var{y}} Abbreviates @code{0-@var{y}}.
|
||||
|
||||
@item *
|
||||
All of the words, excepting the zero'th. This is a synonym for @code{1-$}.
|
||||
It is not an error to use @key{*} if there is just one word in the event.
|
||||
The empty string is returned in that case.
|
||||
|
||||
@end table
|
||||
|
||||
@node Modifiers
|
||||
@subsection Modifiers
|
||||
|
||||
After the optional word designator, you can add a sequence of one or more
|
||||
of the following modifiers, each preceded by a @key{:}.
|
||||
|
||||
@table @code
|
||||
|
||||
@item #
|
||||
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.
|
||||
|
||||
@item h
|
||||
Remove a trailing pathname component, leaving only the head.
|
||||
|
||||
@item r
|
||||
Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename.
|
||||
|
||||
@item e
|
||||
Remove all but the suffix.
|
||||
|
||||
@item t
|
||||
Remove all leading pathname components, leaving the tail.
|
||||
|
||||
@item p
|
||||
Print the new command but do not execute it.
|
||||
@end table
|
1720
readline/doc/readline.info
Normal file
1720
readline/doc/readline.info
Normal file
File diff suppressed because it is too large
Load Diff
103
readline/doc/rlman.texinfo
Normal file
103
readline/doc/rlman.texinfo
Normal file
@ -0,0 +1,103 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename readline.info
|
||||
@settitle GNU Readline Library
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@synindex vr fn
|
||||
@setchapternewpage odd
|
||||
|
||||
@ifinfo
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
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.
|
||||
|
||||
@ignore
|
||||
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).
|
||||
@end ignore
|
||||
|
||||
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.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@sp 10
|
||||
@center @titlefont{GNU Readline Library}
|
||||
@center Brian Fox
|
||||
@center Free Software Foundation
|
||||
@center Version 1.1
|
||||
@center April 1991
|
||||
|
||||
@page
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
675 Massachusetts Avenue, @*
|
||||
Cambridge, MA 02139 USA
|
||||
|
||||
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 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.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top
|
||||
@top GNU Readline Library
|
||||
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
@menu
|
||||
* Command Line Editing:: GNU Readline User's Manual.
|
||||
* Programming with GNU Readline:: GNU Readline Programmer's Manual.
|
||||
* Concept Index:: Index of concepts described in this manual.
|
||||
* Function and Variable Index:: Index of externally visible functions
|
||||
and variables.
|
||||
@end menu
|
||||
@end ifinfo
|
||||
|
||||
@include rluser.texinfo
|
||||
@include rltech.texinfo
|
||||
|
||||
@node Concept Index
|
||||
@unnumbered Concept Index
|
||||
@printindex cp
|
||||
|
||||
@node Function and Variable Index
|
||||
@unnumbered Function and Variable Index
|
||||
@printindex fn
|
||||
|
||||
@contents
|
||||
@bye
|
||||
|
1012
readline/doc/rltech.texinfo
Normal file
1012
readline/doc/rltech.texinfo
Normal file
File diff suppressed because it is too large
Load Diff
559
readline/doc/rluser.texinfo
Normal file
559
readline/doc/rluser.texinfo
Normal file
@ -0,0 +1,559 @@
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename rluser.info
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@setchapternewpage odd
|
||||
|
||||
@ignore
|
||||
This file documents the end user interface to the GNU command line
|
||||
editing feautres. It is to be an appendix to manuals for programs which
|
||||
use these features. There is a document entitled "readline.texinfo"
|
||||
which contains both end-user and programmer documentation for the GNU
|
||||
Readline Library.
|
||||
|
||||
Copyright (C) 1988 Free Software Foundation, Inc.
|
||||
|
||||
Authored by Brian Fox.
|
||||
|
||||
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 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 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 Command Line Editing
|
||||
@chapter Command Line Editing
|
||||
|
||||
This text describes GNU's command line editing interface.
|
||||
|
||||
@menu
|
||||
* Introduction and Notation:: Notation used in this text.
|
||||
* Readline Interaction:: The minimum set of commands for editing a line.
|
||||
* Readline Init File:: Customizing Readline from a user's view.
|
||||
@end menu
|
||||
|
||||
@node Introduction and Notation
|
||||
@section Introduction to Line Editing
|
||||
|
||||
The following paragraphs describe the notation we use to represent
|
||||
keystrokes.
|
||||
|
||||
The text @key{C-k} is read as `Control-K' and describes the character
|
||||
produced when the Control key is depressed and the @key{k} key is struck.
|
||||
|
||||
The text @key{M-k} is read as `Meta-K' and describes the character
|
||||
produced when the meta key (if you have one) is depressed, and the @key{k}
|
||||
key is struck. If you do not have a meta key, the identical keystroke
|
||||
can be generated by typing @key{ESC} @i{first}, and then typing @key{k}.
|
||||
Either process is known as @dfn{metafying} the @key{k} key.
|
||||
|
||||
The text @key{M-C-k} is read as `Meta-Control-k' and describes the
|
||||
character produced by @dfn{metafying} @key{C-k}.
|
||||
|
||||
In addition, several keys have their own names. Specifically,
|
||||
@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all
|
||||
stand for themselves when seen in this text, or in an init file
|
||||
(@pxref{Readline Init File}, for more info).
|
||||
|
||||
@node Readline Interaction
|
||||
@section Readline Interaction
|
||||
@cindex interaction, readline
|
||||
|
||||
Often during an interactive session you type in a long line of text,
|
||||
only to notice that the first word on the line is misspelled. The
|
||||
Readline library gives you a set of commands for manipulating the text
|
||||
as you type it in, allowing you to just fix your typo, and not forcing
|
||||
you to retype the majority of the line. Using these editing commands,
|
||||
you move the cursor to the place that needs correction, and delete or
|
||||
insert the text of the corrections. Then, when you are satisfied with
|
||||
the line, you simply press @key{RETURN}. You do not have to be at the
|
||||
end of the line to press @key{RETURN}; the entire line is accepted
|
||||
regardless of the location of the cursor within the line.
|
||||
|
||||
@menu
|
||||
* Readline Bare Essentials:: The least you need to know about Readline.
|
||||
* Readline Movement Commands:: Moving about the input line.
|
||||
* Readline Killing Commands:: How to delete text, and how to get it back!
|
||||
* Readline Arguments:: Giving numeric arguments to commands.
|
||||
@end menu
|
||||
|
||||
@node Readline Bare Essentials
|
||||
@subsection Readline Bare Essentials
|
||||
|
||||
In order to enter characters into the line, simply type them. The typed
|
||||
character appears where the cursor was, and then the cursor moves one
|
||||
space to the right. If you mistype a character, you can use @key{DEL} to
|
||||
back up, and delete the mistyped character.
|
||||
|
||||
Sometimes you may miss typing a character that you wanted to type, and
|
||||
not notice your error until you have typed several other characters. In
|
||||
that case, you can type @key{C-b} to move the cursor to the left, and then
|
||||
correct your mistake. Aftwerwards, you can move the cursor to the right
|
||||
with @key{C-f}.
|
||||
|
||||
When you add text in the middle of a line, you will notice that characters
|
||||
to the right of the cursor get `pushed over' to make room for the text
|
||||
that you have inserted. Likewise, when you delete text behind the cursor,
|
||||
characters to the right of the cursor get `pulled back' to fill in the
|
||||
blank space created by the removal of the text. A list of the basic bare
|
||||
essentials for editing the text of an input line follows.
|
||||
|
||||
@table @asis
|
||||
@item @key{C-b}
|
||||
Move back one character.
|
||||
@item @key{C-f}
|
||||
Move forward one character.
|
||||
@item @key{DEL}
|
||||
Delete the character to the left of the cursor.
|
||||
@item @key{C-d}
|
||||
Delete the character underneath the cursor.
|
||||
@item @w{Printing characters}
|
||||
Insert itself into the line at the cursor.
|
||||
@item @key{C-_}
|
||||
Undo the last thing that you did. You can undo all the way back to an
|
||||
empty line.
|
||||
@end table
|
||||
|
||||
@node Readline Movement Commands
|
||||
@subsection Readline Movement Commands
|
||||
|
||||
|
||||
The above table describes the most basic possible keystrokes that you need
|
||||
in order to do editing of the input line. For your convenience, many
|
||||
other commands have been added in addition to @key{C-b}, @key{C-f},
|
||||
@key{C-d}, and @key{DEL}. Here are some commands for moving more rapidly
|
||||
about the line.
|
||||
|
||||
@table @key
|
||||
@item C-a
|
||||
Move to the start of the line.
|
||||
@item C-e
|
||||
Move to the end of the line.
|
||||
@item M-f
|
||||
Move forward a word.
|
||||
@item M-b
|
||||
Move backward a word.
|
||||
@item C-l
|
||||
Clear the screen, reprinting the current line at the top.
|
||||
@end table
|
||||
|
||||
Notice how @key{C-f} moves forward a character, while @key{M-f} moves
|
||||
forward a word. It is a loose convention that control keystrokes
|
||||
operate on characters while meta keystrokes operate on words.
|
||||
|
||||
@node Readline Killing Commands
|
||||
@subsection Readline Killing Commands
|
||||
|
||||
The act of @dfn{cutting} text means to delete the text from the line, and
|
||||
to save away the deleted text for later use, just as if you had cut the
|
||||
text out of the line with a pair of scissors. There is a
|
||||
|
||||
@dfn{Killing} text means to delete the text from the line, but to save
|
||||
it away for later use, usually by @dfn{yanking} it back into the line.
|
||||
If the description for a command says that it `kills' text, then you can
|
||||
be sure that you can get the text back in a different (or the same)
|
||||
place later.
|
||||
|
||||
Here is the list of commands for killing text.
|
||||
|
||||
@table @key
|
||||
@item C-k
|
||||
Kill the text from the current cursor position to the end of the line.
|
||||
|
||||
@item M-d
|
||||
Kill from the cursor to the end of the current word, or if between
|
||||
words, to the end of the next word.
|
||||
|
||||
@item M-DEL
|
||||
Kill fromthe cursor the start of the previous word, or if between words, to the start of the previous word.
|
||||
|
||||
@item C-w
|
||||
Kill from the cursor to the previous whitespace. This is different than
|
||||
@key{M-DEL} because the word boundaries differ.
|
||||
|
||||
@end table
|
||||
|
||||
And, here is how to @dfn{yank} the text back into the line. Yanking
|
||||
is
|
||||
|
||||
@table @key
|
||||
@item C-y
|
||||
Yank the most recently killed text back into the buffer at the cursor.
|
||||
|
||||
@item M-y
|
||||
Rotate the kill-ring, and yank the new top. You can only do this if
|
||||
the prior command is @key{C-y} or @key{M-y}.
|
||||
@end table
|
||||
|
||||
When you use a kill command, the text is saved in a @dfn{kill-ring}.
|
||||
Any number of consecutive kills save all of the killed text together, so
|
||||
that when you yank it back, you get it in one clean sweep. The kill
|
||||
ring is not line specific; the text that you killed on a previously
|
||||
typed line is available to be yanked back later, when you are typing
|
||||
another line.
|
||||
|
||||
@node Readline Arguments
|
||||
@subsection Readline Arguments
|
||||
|
||||
You can pass numeric arguments to Readline commands. Sometimes the
|
||||
argument acts as a repeat count, other times it is the @i{sign} of the
|
||||
argument that is significant. If you pass a negative argument to a
|
||||
command which normally acts in a forward direction, that command will
|
||||
act in a backward direction. For example, to kill text back to the
|
||||
start of the line, you might type @key{M--} @key{C-k}.
|
||||
|
||||
The general way to pass numeric arguments to a command is to type meta
|
||||
digits before the command. If the first `digit' you type is a minus
|
||||
sign (@key{-}), then the sign of the argument will be negative. Once
|
||||
you have typed one meta digit to get the argument started, you can type
|
||||
the remainder of the digits, and then the command. For example, to give
|
||||
the @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}.
|
||||
|
||||
|
||||
@node Readline Init File
|
||||
@section Readline Init File
|
||||
|
||||
Although the Readline library comes with a set of Emacs-like
|
||||
keybindings, it is possible that you would like to use a different set
|
||||
of keybindings. You can customize programs that use Readline by putting
|
||||
commands in an @dfn{init} file in your home directory. The name of this
|
||||
file is @file{~/.inputrc}.
|
||||
|
||||
When a program which uses the Readline library starts up, the
|
||||
@file{~/.inputrc} file is read, and the keybindings are set.
|
||||
|
||||
In addition, the @code{C-x C-r} command re-reads this init file, thus
|
||||
incorporating any changes that you might have made to it.
|
||||
|
||||
@menu
|
||||
* Readline Init Syntax:: Syntax for the commands in @file{~/.inputrc}.
|
||||
* Readline Vi Mode:: Switching to @code{vi} mode in Readline.
|
||||
@end menu
|
||||
|
||||
@node Readline Init Syntax
|
||||
@subsection Readline Init Syntax
|
||||
|
||||
There are only four constructs allowed in the @file{~/.inputrc}
|
||||
file:
|
||||
|
||||
@table @asis
|
||||
@item Variable Settings
|
||||
You can change the state of a few variables in Readline. You do this by
|
||||
using the @code{set} command within the init file. Here is how you
|
||||
would specify that you wish to use Vi line editing commands:
|
||||
|
||||
@example
|
||||
set editing-mode vi
|
||||
@end example
|
||||
|
||||
Right now, there are only a few variables which can be set; so few in
|
||||
fact, that we just iterate them here:
|
||||
|
||||
@table @code
|
||||
|
||||
@item editing-mode
|
||||
@vindex editing-mode
|
||||
The @code{editing-mode} variable controls which editing mode you are
|
||||
using. By default, GNU Readline starts up in Emacs editing mode, where
|
||||
the keystrokes are most similar to Emacs. This variable can either be
|
||||
set to @code{emacs} or @code{vi}.
|
||||
|
||||
@item horizontal-scroll-mode
|
||||
@vindex horizontal-scroll-mode
|
||||
This variable can either be set to @code{On} or @code{Off}. Setting it
|
||||
to @code{On} means that the text of the lines that you edit will scroll
|
||||
horizontally on a single screen line when they are larger than the width
|
||||
of the screen, instead of wrapping onto a new screen line. By default,
|
||||
this variable is set to @code{Off}.
|
||||
|
||||
@item mark-modified-lines
|
||||
@vindex mark-modified-lines
|
||||
This variable when set to @code{On}, says to display an asterisk
|
||||
(@samp{*}) at the starts of history lines which have been modified.
|
||||
This variable is off by default.
|
||||
|
||||
@item prefer-visible-bell
|
||||
@vindex prefer-visible-bell
|
||||
If this variable is set to @code{On} it means to use a visible bell if
|
||||
one is available, rather than simply ringing the terminal bell. By
|
||||
default, the value is @code{Off}.
|
||||
@end table
|
||||
|
||||
@item Key Bindings
|
||||
The syntax for controlling keybindings in the @file{~/.inputrc} file is
|
||||
simple. First you have to know the @i{name} of the command that you
|
||||
want to change. The following pages contain tables of the command name,
|
||||
the default keybinding, and a short description of what the command
|
||||
does.
|
||||
|
||||
Once you know the name of the command, simply place the name of the key
|
||||
you wish to bind the command to, a colon, and then the name of the
|
||||
command on a line in the @file{~/.inputrc} file. The name of the key
|
||||
can be expressed in different ways, depending on which is most
|
||||
comfortable for you.
|
||||
|
||||
@table @asis
|
||||
@item @w{@var{keyname}: @var{function-name} or @var{macro}}
|
||||
@var{keyname} is the name of a key spelled out in English. For example:
|
||||
@example
|
||||
Control-u: universal-argument
|
||||
Meta-Rubout: backward-kill-word
|
||||
Control-o: ">&output"
|
||||
@end example
|
||||
|
||||
In the above example, @samp{C-u} is bound to the function
|
||||
@code{universal-argument}, and @samp{C-o} is bound to run the macro
|
||||
expressed on the right hand side (that is, to insert the text
|
||||
@samp{>&output} into the line).
|
||||
|
||||
@item @w{"@var{keyseq}": @var{function-name} or @var{macro}}
|
||||
@var{keyseq} differs from @var{keyname} above in that strings denoting
|
||||
an entire key sequence can be specified. Simply place the key sequence
|
||||
in double quotes. GNU Emacs style key escapes can be used, as in the
|
||||
following example:
|
||||
|
||||
@example
|
||||
"\C-u": universal-argument
|
||||
"\C-x\C-r": re-read-init-file
|
||||
"\e[11~": "Function Key 1"
|
||||
@end example
|
||||
|
||||
In the above example, @samp{C-u} is bound to the function
|
||||
@code{universal-argument} (just as it was in the first example),
|
||||
@samp{C-x C-r} is bound to the function @code{re-read-init-file}, and
|
||||
@samp{ESC [ 1 1 ~} is bound to insert the text @samp{Function Key 1}.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@menu
|
||||
* Commands For Moving:: Moving about the line.
|
||||
* Commands For History:: Getting at previous lines.
|
||||
* Commands For Text:: Commands for changing text.
|
||||
* Commands For Killing:: Commands for killing and yanking.
|
||||
* Numeric Arguments:: Specifying numeric arguments, repeat counts.
|
||||
* Commands For Completion:: Getting Readline to do the typing for you.
|
||||
* Miscellaneous Commands:: Other miscillaneous commands.
|
||||
@end menu
|
||||
|
||||
@node Commands For Moving
|
||||
@subsubsection Commands For Moving
|
||||
@ftable @code
|
||||
@item beginning-of-line (C-a)
|
||||
Move to the start of the current line.
|
||||
|
||||
@item end-of-line (C-e)
|
||||
Move to the end of the line.
|
||||
|
||||
@item forward-char (C-f)
|
||||
Move forward a character.
|
||||
|
||||
@item backward-char (C-b)
|
||||
Move back a character.
|
||||
|
||||
@item forward-word (M-f)
|
||||
Move forward to the end of the next word.
|
||||
|
||||
@item backward-word (M-b)
|
||||
Move back to the start of this, or the previous, word.
|
||||
|
||||
@item clear-screen (C-l)
|
||||
Clear the screen leaving the current line at the top of the screen.
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Commands For History
|
||||
@subsubsection Commands For Manipulating The History
|
||||
|
||||
@ftable @code
|
||||
@item accept-line (Newline, Return)
|
||||
Accept the line regardless of where the cursor is. If this line is
|
||||
non-empty, add it to the history list. If this line was a history
|
||||
line, then restore the history line to its original state.
|
||||
|
||||
@item previous-history (C-p)
|
||||
Move `up' through the history list.
|
||||
|
||||
@item next-history (C-n)
|
||||
Move `down' through the history list.
|
||||
|
||||
@item beginning-of-history (M-<)
|
||||
Move to the first line in the history.
|
||||
|
||||
@item end-of-history (M->)
|
||||
Move to the end of the input history, i.e., the line you are entering!
|
||||
|
||||
@item reverse-search-history (C-r)
|
||||
Search backward starting at the current line and moving `up' through
|
||||
the history as necessary. This is an incremental search.
|
||||
|
||||
@item forward-search-history (C-s)
|
||||
Search forward starting at the current line and moving `down' through
|
||||
the the history as neccessary.
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Commands For Text
|
||||
@subsubsection Commands For Changing Text
|
||||
|
||||
@ftable @code
|
||||
@item delete-char (C-d)
|
||||
Delete the character under the cursor. If the cursor is at the
|
||||
beginning of the line, and there are no characters in the line, and
|
||||
the last character typed was not C-d, then return EOF.
|
||||
|
||||
@item backward-delete-char (Rubout)
|
||||
Delete the character behind the cursor. A numeric arg says to kill
|
||||
the characters instead of deleting them.
|
||||
|
||||
@item quoted-insert (C-q, C-v)
|
||||
Add the next character that you type to the line verbatim. This is
|
||||
how to insert things like C-q for example.
|
||||
|
||||
@item tab-insert (M-TAB)
|
||||
Insert a tab character.
|
||||
|
||||
@item self-insert (a, b, A, 1, !, ...)
|
||||
Insert yourself.
|
||||
|
||||
@item transpose-chars (C-t)
|
||||
Drag the character before point forward over the character at point.
|
||||
Point moves forward as well. If point is at the end of the line, then
|
||||
transpose the two characters before point. Negative args don't work.
|
||||
|
||||
@item transpose-words (M-t)
|
||||
Drag the word behind the cursor past the word in front of the cursor
|
||||
moving the cursor over that word as well.
|
||||
|
||||
@item upcase-word (M-u)
|
||||
Uppercase the current (or following) word. With a negative argument,
|
||||
do the previous word, but do not move point.
|
||||
|
||||
@item downcase-word (M-l)
|
||||
Lowercase the current (or following) word. With a negative argument,
|
||||
do the previous word, but do not move point.
|
||||
|
||||
@item capitalize-word (M-c)
|
||||
Uppercase the current (or following) word. With a negative argument,
|
||||
do the previous word, but do not move point.
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Commands For Killing
|
||||
@subsubsection Killing And Yanking
|
||||
|
||||
@ftable @code
|
||||
|
||||
@item kill-line (C-k)
|
||||
Kill the text from the current cursor position to the end of the line.
|
||||
|
||||
@item backward-kill-line ()
|
||||
Kill backward to the beginning of the line. This is normally unbound.
|
||||
|
||||
@item kill-word (M-d)
|
||||
Kill from the cursor to the end of the current word, or if between
|
||||
words, to the end of the next word.
|
||||
|
||||
@item backward-kill-word (M-DEL)
|
||||
Kill the word behind the cursor.
|
||||
|
||||
@item unix-line-discard (C-u)
|
||||
Do what C-u used to do in Unix line input. We save the killed text on
|
||||
the kill-ring, though.
|
||||
|
||||
@item unix-word-rubout (C-w)
|
||||
Do what C-w used to do in Unix line input. The killed text is saved
|
||||
on the kill-ring. This is different than backward-kill-word because
|
||||
the word boundaries differ.
|
||||
|
||||
@item yank (C-y)
|
||||
Yank the top of the kill ring into the buffer at point.
|
||||
|
||||
@item yank-pop (M-y)
|
||||
Rotate the kill-ring, and yank the new top. You can only do this if
|
||||
the prior command is yank or yank-pop.
|
||||
@end ftable
|
||||
|
||||
@node Numeric Arguments
|
||||
@subsubsection Specifying Numeric Arguments
|
||||
@ftable @code
|
||||
|
||||
@item digit-argument (M-0, M-1, ... M--)
|
||||
Add this digit to the argument already accumulating, or start a new
|
||||
argument. M-- starts a negative argument.
|
||||
|
||||
@item universal-argument ()
|
||||
Do what C-u does in emacs. By default, this is not bound.
|
||||
@end ftable
|
||||
|
||||
|
||||
@node Commands For Completion
|
||||
@subsubsection Letting Readline Type For You
|
||||
|
||||
@ftable @code
|
||||
@item complete (TAB)
|
||||
Attempt to do completion on the text before point. This is
|
||||
implementation defined. Generally, if you are typing a filename
|
||||
argument, you can do filename completion; if you are typing a command,
|
||||
you can do command completion, if you are typing in a symbol to GDB, you
|
||||
can do symbol name completion, if you are typing in a variable to Bash,
|
||||
you can do variable name completion...
|
||||
|
||||
@item possible-completions (M-?)
|
||||
List the possible completions of the text before point.
|
||||
@end ftable
|
||||
|
||||
@node Miscellaneous Commands
|
||||
@subsubsection Some Miscellaneous Commands
|
||||
@ftable @code
|
||||
|
||||
@item re-read-init-file (C-x C-r)
|
||||
Read in the contents of your @file{~/.inputrc} file, and incorporate
|
||||
any bindings found there.
|
||||
|
||||
@item abort (C-g)
|
||||
Ding! Stops things.
|
||||
|
||||
@item do-uppercase-version (M-a, M-b, ...)
|
||||
Run the command that is bound to your uppercase brother.
|
||||
|
||||
@item prefix-meta (ESC)
|
||||
Make the next character that you type be metafied. This is for people
|
||||
without a meta key. Typing @samp{ESC f} is equivalent to typing
|
||||
@samp{M-f}.
|
||||
|
||||
@item undo (C-_)
|
||||
Incremental undo, separately remembered for each line.
|
||||
|
||||
@item revert-line (M-r)
|
||||
Undo all changes made to this line. This is like typing the `undo'
|
||||
command enough times to get back to the beginning.
|
||||
@end ftable
|
||||
|
||||
@node Readline Vi Mode
|
||||
@subsection Readline Vi Mode
|
||||
|
||||
While the Readline library does not have a full set of Vi editing
|
||||
functions, it does contain enough to allow simple editing of the line.
|
||||
|
||||
In order to switch interactively between Emacs and Vi editing modes, use
|
||||
the command M-C-j (toggle-editing-mode).
|
||||
|
||||
When you enter a line in Vi mode, you are already placed in `insertion'
|
||||
mode, as if you had typed an `i'. Pressing @key{ESC} switches you into
|
||||
`edit' mode, where you can edit the text of the line with the standard
|
||||
Vi movement keys, move to previous history lines with `k', and following
|
||||
lines with `j', and so forth.
|
||||
|
1606
readline/doc/texindex.c
Normal file
1606
readline/doc/texindex.c
Normal file
File diff suppressed because it is too large
Load Diff
2883
readline/doc/texinfo.tex
Normal file
2883
readline/doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load Diff
12
readline/examples/Makefile
Normal file
12
readline/examples/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# This is the Makefile for the examples subdirectory of readline. -*- text -*-
|
||||
#
|
||||
|
||||
EXECUTABLES = fileman
|
||||
CFLAGS = -g -I../..
|
||||
LDFLAGS = -g -L..
|
||||
|
||||
fileman: fileman.o
|
||||
$(CC) $(LDFLAGS) -o fileman fileman.o -lreadline -ltermcap
|
||||
|
||||
fileman.o: fileman.c
|
||||
|
395
readline/examples/fileman.c
Normal file
395
readline/examples/fileman.c
Normal file
@ -0,0 +1,395 @@
|
||||
/* fileman.c -- A tiny application which demonstrates how to use the
|
||||
GNU Readline library. This application interactively allows users
|
||||
to manipulate files and their modes. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
/* The names of functions that actually do the manipulation. */
|
||||
int com_list (), com_view (), com_rename (), com_stat (), com_pwd ();
|
||||
int com_delete (), com_help (), com_cd (), com_quit ();
|
||||
|
||||
/* A structure which contains information on the commands this program
|
||||
can understand. */
|
||||
|
||||
typedef struct {
|
||||
char *name; /* User printable name of the function. */
|
||||
Function *func; /* Function to call to do the job. */
|
||||
char *doc; /* Documentation for this function. */
|
||||
} COMMAND;
|
||||
|
||||
COMMAND commands[] = {
|
||||
{ "cd", com_cd, "Change to directory DIR" },
|
||||
{ "delete", com_delete, "Delete FILE" },
|
||||
{ "help", com_help, "Display this text" },
|
||||
{ "?", com_help, "Synonym for `help'" },
|
||||
{ "list", com_list, "List files in DIR" },
|
||||
{ "ls", com_list, "Synonym for `list'" },
|
||||
{ "pwd", com_pwd, "Print the current working directory" },
|
||||
{ "quit", com_quit, "Quit using Fileman" },
|
||||
{ "rename", com_rename, "Rename FILE to NEWNAME" },
|
||||
{ "stat", com_stat, "Print out statistics on FILE" },
|
||||
{ "view", com_view, "View the contents of FILE" },
|
||||
{ (char *)NULL, (Function *)NULL, (char *)NULL }
|
||||
};
|
||||
|
||||
/* The name of this program, as taken from argv[0]. */
|
||||
char *progname;
|
||||
|
||||
/* When non-zero, this global means the user is done using this program. */
|
||||
int done = 0;
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
progname = argv[0];
|
||||
|
||||
initialize_readline (); /* Bind our completer. */
|
||||
|
||||
/* Loop reading and executing lines until the user quits. */
|
||||
while (!done)
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = readline ("FileMan: ");
|
||||
|
||||
if (!line)
|
||||
{
|
||||
done = 1; /* Encountered EOF at top level. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove leading and trailing whitespace from the line.
|
||||
Then, if there is anything left, add it to the history list
|
||||
and execute it. */
|
||||
stripwhite (line);
|
||||
|
||||
if (*line)
|
||||
{
|
||||
add_history (line);
|
||||
execute_line (line);
|
||||
}
|
||||
}
|
||||
|
||||
if (line)
|
||||
free (line);
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Execute a command line. */
|
||||
execute_line (line)
|
||||
char *line;
|
||||
{
|
||||
register int i;
|
||||
COMMAND *find_command (), *command;
|
||||
char *word;
|
||||
|
||||
/* Isolate the command word. */
|
||||
i = 0;
|
||||
while (line[i] && !whitespace (line[i]))
|
||||
i++;
|
||||
|
||||
word = line;
|
||||
|
||||
if (line[i])
|
||||
line[i++] = '\0';
|
||||
|
||||
command = find_command (word);
|
||||
|
||||
if (!command)
|
||||
{
|
||||
fprintf (stderr, "%s: No such command for FileMan.\n", word);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get argument to command, if any. */
|
||||
while (whitespace (line[i]))
|
||||
i++;
|
||||
|
||||
word = line + i;
|
||||
|
||||
/* Call the function. */
|
||||
(*(command->func)) (word);
|
||||
}
|
||||
|
||||
/* Look up NAME as the name of a command, and return a pointer to that
|
||||
command. Return a NULL pointer if NAME isn't a command name. */
|
||||
COMMAND *
|
||||
find_command (name)
|
||||
char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; commands[i].name; i++)
|
||||
if (strcmp (name, commands[i].name) == 0)
|
||||
return (&commands[i]);
|
||||
|
||||
return ((COMMAND *)NULL);
|
||||
}
|
||||
|
||||
/* Strip whitespace from the start and end of STRING. */
|
||||
stripwhite (string)
|
||||
char *string;
|
||||
{
|
||||
register int i = 0;
|
||||
|
||||
while (whitespace (string[i]))
|
||||
i++;
|
||||
|
||||
if (i)
|
||||
strcpy (string, string + i);
|
||||
|
||||
i = strlen (string) - 1;
|
||||
|
||||
while (i > 0 && whitespace (string[i]))
|
||||
i--;
|
||||
|
||||
string[++i] = '\0';
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Interface to Readline Completion */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Tell the GNU Readline library how to complete. We want to try to complete
|
||||
on command names if this is the first word in the line, or on filenames
|
||||
if not. */
|
||||
initialize_readline ()
|
||||
{
|
||||
char **fileman_completion ();
|
||||
|
||||
/* Allow conditional parsing of the ~/.inputrc file. */
|
||||
rl_readline_name = "FileMan";
|
||||
|
||||
/* Tell the completer that we want a crack first. */
|
||||
rl_attempted_completion_function = (Function *)fileman_completion;
|
||||
}
|
||||
|
||||
/* Attempt to complete on the contents of TEXT. START and END show the
|
||||
region of TEXT that contains the word to complete. We can use the
|
||||
entire line in case we want to do some simple parsing. Return the
|
||||
array of matches, or NULL if there aren't any. */
|
||||
char **
|
||||
fileman_completion (text, start, end)
|
||||
char *text;
|
||||
int start, end;
|
||||
{
|
||||
char **matches;
|
||||
char *command_generator ();
|
||||
|
||||
matches = (char **)NULL;
|
||||
|
||||
/* If this word is at the start of the line, then it is a command
|
||||
to complete. Otherwise it is the name of a file in the current
|
||||
directory. */
|
||||
if (start == 0)
|
||||
matches = completion_matches (text, command_generator);
|
||||
|
||||
return (matches);
|
||||
}
|
||||
|
||||
/* Generator function for command completion. STATE lets us know whether
|
||||
to start from scratch; without any state (i.e. STATE == 0), then we
|
||||
start at the top of the list. */
|
||||
char *
|
||||
command_generator (text, state)
|
||||
char *text;
|
||||
int state;
|
||||
{
|
||||
static int list_index, len;
|
||||
char *name;
|
||||
|
||||
/* If this is a new word to complete, initialize now. This includes
|
||||
saving the length of TEXT for efficiency, and initializing the index
|
||||
variable to 0. */
|
||||
if (!state)
|
||||
{
|
||||
list_index = 0;
|
||||
len = strlen (text);
|
||||
}
|
||||
|
||||
/* Return the next name which partially matches from the command list. */
|
||||
while (name = commands[list_index].name)
|
||||
{
|
||||
list_index++;
|
||||
|
||||
if (strncmp (name, text, len) == 0)
|
||||
return (name);
|
||||
}
|
||||
|
||||
/* If no names matched, then return NULL. */
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* FileMan Commands */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* String to pass to system (). This is for the LIST, VIEW and RENAME
|
||||
commands. */
|
||||
static char syscom[1024];
|
||||
|
||||
/* List the file(s) named in arg. */
|
||||
com_list (arg)
|
||||
char *arg;
|
||||
{
|
||||
if (!arg)
|
||||
arg = "*";
|
||||
|
||||
sprintf (syscom, "ls -FClg %s", arg);
|
||||
system (syscom);
|
||||
}
|
||||
|
||||
com_view (arg)
|
||||
char *arg;
|
||||
{
|
||||
if (!valid_argument ("view", arg))
|
||||
return;
|
||||
|
||||
sprintf (syscom, "cat %s | more", arg);
|
||||
system (syscom);
|
||||
}
|
||||
|
||||
com_rename (arg)
|
||||
char *arg;
|
||||
{
|
||||
too_dangerous ("rename");
|
||||
}
|
||||
|
||||
com_stat (arg)
|
||||
char *arg;
|
||||
{
|
||||
struct stat finfo;
|
||||
|
||||
if (!valid_argument ("stat", arg))
|
||||
return;
|
||||
|
||||
if (stat (arg, &finfo) == -1)
|
||||
{
|
||||
perror (arg);
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("Statistics for `%s':\n", arg);
|
||||
|
||||
printf ("%s has %d link%s, and is %d bytes in length.\n", arg,
|
||||
finfo.st_nlink, (finfo.st_nlink == 1) ? "" : "s", finfo.st_size);
|
||||
printf (" Created on: %s", ctime (&finfo.st_ctime));
|
||||
printf (" Last access at: %s", ctime (&finfo.st_atime));
|
||||
printf ("Last modified at: %s", ctime (&finfo.st_mtime));
|
||||
}
|
||||
|
||||
com_delete (arg)
|
||||
char *arg;
|
||||
{
|
||||
too_dangerous ("delete");
|
||||
}
|
||||
|
||||
/* Print out help for ARG, or for all of the commands if ARG is
|
||||
not present. */
|
||||
com_help (arg)
|
||||
char *arg;
|
||||
{
|
||||
register int i;
|
||||
int printed = 0;
|
||||
|
||||
for (i = 0; commands[i].name; i++)
|
||||
{
|
||||
if (!*arg || (strcmp (arg, commands[i].name) == 0))
|
||||
{
|
||||
printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!printed)
|
||||
{
|
||||
printf ("No commands match `%s'. Possibilties are:\n", arg);
|
||||
|
||||
for (i = 0; commands[i].name; i++)
|
||||
{
|
||||
/* Print in six columns. */
|
||||
if (printed == 6)
|
||||
{
|
||||
printed = 0;
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
printf ("%s\t", commands[i].name);
|
||||
printed++;
|
||||
}
|
||||
|
||||
if (printed)
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Change to the directory ARG. */
|
||||
com_cd (arg)
|
||||
char *arg;
|
||||
{
|
||||
if (chdir (arg) == -1)
|
||||
perror (arg);
|
||||
|
||||
com_pwd ("");
|
||||
}
|
||||
|
||||
/* Print out the current working directory. */
|
||||
com_pwd (ignore)
|
||||
char *ignore;
|
||||
{
|
||||
char dir[1024];
|
||||
|
||||
(void) getwd (dir);
|
||||
|
||||
printf ("Current directory is %s\n", dir);
|
||||
}
|
||||
|
||||
/* The user wishes to quit using this program. Just set DONE non-zero. */
|
||||
com_quit (arg)
|
||||
char *arg;
|
||||
{
|
||||
done = 1;
|
||||
}
|
||||
|
||||
/* Function which tells you that you can't do this. */
|
||||
too_dangerous (caller)
|
||||
char *caller;
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: Too dangerous for me to distribute. Write it yourself.\n",
|
||||
caller);
|
||||
}
|
||||
|
||||
/* Return non-zero if ARG is a valid argument for CALLER, else print
|
||||
an error message and return zero. */
|
||||
int
|
||||
valid_argument (caller, arg)
|
||||
char *caller, *arg;
|
||||
{
|
||||
if (!arg || !*arg)
|
||||
{
|
||||
fprintf (stderr, "%s: Argument required.\n", caller);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* compile-command: "cc -g -I../.. -L.. -o fileman fileman.c -lreadline -ltermcap"
|
||||
* end:
|
||||
*/
|
Loading…
Reference in New Issue
Block a user