NAME¶
FBB::ReadLineStream - std::istream offering line-editing and history
SYNOPSIS¶
#include <bobcat/readlinestream>
Linking option: -lreadline -lbobcat
DESCRIPTION¶
A
FBB::ReadLineStream object is a
std::istream objects, allowing
line-editing and history manipulation.
The
ReadLineStream class uses Gnu’s readline library to allow
editing of input lines. The
ReadLineStream object can be used to
construct a
std::istream allowing in-line editing of lines read from
the terminal. All lines may be preceded by a configurable prompt.
Since Gnu’s readline library operates on global data there can only be one
ReadLineStream (and underlying
ReadLineBuf) object.
ReadLineStream is a singleton class: in any program there can only be
one
ReadLineStream object.
ReadLineStream offers editing capabilities while the user is entering
lines. Like Gnu’s
readline(3) function, the line editing commands
are by default similar to those of
emacs(1), but can easily be
reconfigured, e.g. to offer
vi(1)-like characteristics.
History manipulation is provided as an option. The collected history may be
accessed for reading using an
FBB::ReadLineHistory object.
Specific information about the facilities offered by the Gnu software used by
ReadLineStream is provided in the GNU Readline Library documentation (
http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html).
Gnu’s
readline function reads its information from the standard
input file. Programs using
ReadLineStream should normally not extract
information from
std::cin. However, as the standard input file has a
file descriptor (0), redirection should be possible (e.g., using
FBB::Redirector).
When the command line is kept, history expansion is offered as an option.
History expansion introduces words from the history list into the input
stream, making it easy to repeat commands, to insert elements of a previous
input line into the current input line, or to fix errors in previous command
lines.
History expansion is usually performed immediately after a complete line is
read.
The line selected from the history is called the
event, and the portions
of that line that are processed are called
words. Various modifiers are
available to manipulate selected words. This is comparable to the way a
program like
bash(1) breaks up its input line into `words’.
History expansion is introduced by the use of the history expansion character,
by default equal to the
!-character. Only backslash (
\) and
single quotes can change the history expansion character into a normal
character.
The remainder of this section is copied almost verbatim from the
history(3) man-page. The reader is referred to that man-page or to the
Gnu History Library documentation for further details.
The following
event designators are supported:
- o
- !: starts a history substitution, except when
followed by a blank, newline, = or (.
- o
- !n: refers to command line n.
- o
- !-n: refers to the current command line minus
n.
- o
- !! refers to the previous command. This is a synonym
for `!-1’.
- o
- !string refers to the most recent command starting
with string.
- o
- !?string[?] refers to the most recent command
containing string. The trailing ? may be omitted if string is
followed immediately by a newline.
- o
- ^string1^string2^ (quick substitution) repeats the
last command, replacing string1 with string2. Equivalent to
!!:s/string1/string2/.
- o
- !# the entire command line typed so far.
Word Designators
Word designators are used to select desired words from the event. A
:
separates the event specification from the word designator. It may 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
0 (zero). Words are inserted into the current line separated by single spaces.
- o
- 0 (zero) The zeroth word. For the shell, this is the
command word.
- o
- n The nth word.
- o
- ^ The first argument. That is, word 1.
- o
- $ The last argument.
- o
- % The word matched by the most recent
?string? search.
- o
- x-y A range of words; `-y’ abbreviates
`0-y’.
- o
- * All of the words but the zeroth. 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.
- o
- x* Abbreviates x-$.
- o
- x- Abbreviates x-$ like x*, but omits
the last word. If a word designator is supplied without an event
specification, the previous command is used as the event.
Modifiers
After the optional word designator, there may appear a sequence of one or more
of the following modifiers, each preceded by a
:.
- o
- h removes a trailing file name component, leaving
only the head.
- o
- t removes all leading file name components, leaving
the tail.
- o
- r removes a trailing suffix of the form .xxx,
leaving the basename.
- o
- e removes all but the trailing suffix.
- o
- p prints the new command but does not execute
it.
- o
- q quotes the substituted words, escaping further
substitutions.
- o
- x quotes the substituted words as with q, but break
into words at blanks and newlines.
- o
- s/old/new/ substitutes new for the first occurrence
of old in the event line. Any delimiter can be used in place of /.
The final delimiter is optional if it is the last character of the event
line. The delimiter may be quoted in old and new with a single backslash.
If & appears in new, it is replaced by old. A single backslash
will quote the &. If old is null, it is set to the last
old substituted, or, if no previous history substitutions took place, the
last string in a !?string[?] search.
- o
- & repeats the previous substitution.
- o
- g Causes changes to be applied over the entire event
line. This is used in conjunction with tt:s (e.g., :gs/old/new/) or
:&. If used with :s, any delimiter can be used in place
of /, and the final delimiter is optional if it is the last
character of the event line. An a may be used as a synonym for
g.
- o
- G Apply the following s modifier once to each
word in the event line. )
NAMESPACE¶
FBB
All constructors, members, operators and manipulators, mentioned in this
man-page, are defined in the namespace
FBB.
INHERITS FROM¶
FBB::ReadLineBuf (privately),
std::istream (publicly)
ENUMERATIONS¶
The
enum Type defines the following value:
- o
- DONT_EXPAND_HISTORY: history expansion is not
requested;
- o
- EXPAND_HISTORY: history expansion is requested.
The
enum Expansion provides meaningful return values for the history
expansion process. Its values are:
- o
- DONT_EXEC: history expansion succeeded, but the
expanded line should not be executed. E.g., after entering the line
ls *
the line
!!:p
should cause the using program to display, rather than exectute
ls *. Note that interpretation of this expansion return
value is not the task of the ReadLineBuf object, but of the program
using the ReadLineBuf object.
- o
- ERROR: the history expansion failed. See also the
member expansionError below;
- o
- EXPANDED: the history expansion succeeded;
- o
- NO_EXPANSION: no history expansion took place.
CONSTRUCTORS¶
Preamble: since there can only be one
ReadLineBuf object, any attempt to
define a second
ReadLineStream object will fail as there can only be a
single
ReadLineBuf object in any program. An attempt to define a second
ReadLineBuf object results in a
logic_error exception being
thrown.
- o
- ReadLineStream(std::string const &prompt =
"", Type type = NO_EXPANSION):
This constructor initializes the ReadLineStream object with an
initial prompt, using a history of at most INT_MAX lines, by
default not using history expansion.
- o
- ReadLineStream(std::string const &prompt, size_t
historySize, Type type = NO_EXPANSION):
This constructor initializes the ReadLineStream with an initial
prompt, an initial history of a predefined maximum size, by default not
using history expansion. Specifying a history size 0 results in no history
being kept, any value equal to or exceeding the predefined constant
INT_MAX results in a history of at most INT_MAX lines. If no
history is requested but type is specified as EXPAND_HISTORY
a logic_error exception is thrown. The standard copy constructor is
not available.
MEMBER FUNCTIONS¶
All members of
std::streambuf are available, as
FBB::ReadLineStream inherits from this class.
- o
- ReadLineStream::Expansion expansion() const:
The status of the history expansion after retrieving a line from the
terminal is returned. Its value is determined after each line retrieved
from the terminal. If no history expansion is requested it returns
Expansion::ERROR.
- o
- std::string const &expansionError() const:
A short textual description of the nature of the error when expansion
returns Expansion::ERROR is returned. If no history expansion is
requested an empty string is returned.
- o
- bool setExpansion(Type type):
History expansion can be activated or stopped using this member. When
history expansion is requested but the ReadLineStream object
maintains no history the function returns false. Otherwise it
returns true.
- o
- void setPrompt(std::string const &prompt =
""):
The prompt that is displayed in front of the next line read from the
terminal can be modified by this member. When called without arguments no
prompt will be displayed. setPrompt can be called while input lines
are being received. The new prompt will be active after the current line
has been read from the terminal.
- o
- bool useTimestamps(std::string (*timestamp)() = 0):
When initialized with the address of a function returning a
std::string the entered commands will be given a timestamp equal to
the text returned by the function pointed to by timestamp. The
timestamps can be retrieved using the ReadLineHistory(3) object. By
default or after passing an explicit 0-pointer to useTimestamps no
timestamps are stored. The value false is returned when no history
is kept, otherwise true is returned.
EXAMPLE¶
#include <iostream>
#include <istream>
#include <cstdio>
#include <sstream>
#include <iomanip>
#include <bobcat/readlinestream>
using namespace std;
using namespace FBB;
int main()
{
ReadLineStream in("", 10, ReadLineBuf::EXPAND_HISTORY);
size_t count = 0;
string line;
while (true)
{
ostringstream prompt;
prompt << setw(2) << ++count << ": ";
in.setPrompt(prompt.str());
if (!getline(in, line)) // uses the last-set prompt
break;
cout << "Retrieved: " << line << "\n"
"Expansion status: ";
switch (in.expansion())
{
case ReadLineBuf::ERROR:
cout << "ERROR: " << in.expansionError() << ’\n’;
break;
case ReadLineBuf::NO_EXPANSION:
cout << "no expansion performed\n";
break;
case ReadLineBuf::DONT_EXEC:
cout << "don’t execute the expanded line\n";
break;
case ReadLineBuf::EXPANDED:
cout << "expansion successfully performed\n";
break;
}
}
}
FILES¶
bobcat/readlinebuf - defines the class interface
SEE ALSO¶
bobcat(7),
readline(3),
readlinebuf(3),
readlinehistory(3)
BUGS¶
None Reported.
DISTRIBUTION FILES¶
- o
- bobcat_3.01.00-x.dsc: detached signature;
- o
- bobcat_3.01.00-x.tar.gz: source archive;
- o
- bobcat_3.01.00-x_i386.changes: change log;
- o
- libbobcat1_3.01.00-x_*.deb: debian package holding
the libraries;
- o
- libbobcat1-dev_3.01.00-x_*.deb: debian package
holding the libraries, headers and manual pages;
- o
- http://sourceforge.net/projects/bobcat: public
archive location;
BOBCAT¶
Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’.
COPYRIGHT¶
This is free software, distributed under the terms of the GNU General Public
License (GPL).
AUTHOR¶
Frank B. Brokken (
f.b.brokken@rug.nl).