FBB::ReadLineBuf(3bobcat)

πŸ’– FBB::ReadLineBuf(3bobcat) πŸ’– β€” editing input lines

ok so bestie, buckle up: this is FBB::ReadLineBuf(3bobcat), from the bobcat family, and she is literally the moment. Editing input lines has never been this cute, and every last detail is here, fr fr. πŸ’…


✨ NAME ✨

FBB::ReadLineBuf β€” a std::streambuf that serves line-editing and history manipulation. It's giving main character energy for your terminal input. πŸ‘‘


🌸 SYNOPSIS 🌸

#include <bobcat/readlinebuf>
Linking option: -lbobcat  -lreadline

πŸ¦‹ DESCRIPTION πŸ¦‹

The FBB::ReadLineBuf object can be used as a std::streambuf of std::istream objects, which means it unlocks line-editing and history manipulation. Iconic behavior, honestly. ✨

The ReadLineBuf class uses Gnu's readline library to allow editing of input lines. You can use the ReadLineBuf object to construct a std::istream that supports in-line editing of lines read from the terminal. And every line may be preceded by a configurable prompt β€” yes, you get to customize her whole look. πŸŽ€

Since Gnu's readline library operates on global data there can only be one ReadLineBuf object. So that's why ReadLineBuf is a singleton class: in any program there can only be one ReadLineBuf object. (Gnu's readline library does, however, offer functions allowing programs to use multiple histories. So it would in principle be possible to design a non-singleton ReadLineBuf class. Since programs normally only interact with a single terminal, there is probably little use for non-singleton ReadLineBuf class.) Like… she's exclusive. One of her. Periodt. πŸ’€

ReadLineBuf offers editing capabilities while the user is entering lines. Just like Gnu's readline(3) function, the line editing commands are by default similar to those of emacs(1), but they can easily be reconfigured, e.g. to offer vi(1)-like characteristics. Glow-up available on request. πŸ’…

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 ReadLineBuf 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 ReadLineBuf 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). Noted, bestie. πŸ“

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. She's a fixer, a repeater, and a whole vibe. πŸ”₯

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. iykyk. 🧚

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. Lowkey dramatic, but okay. 😭

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.


🌈 Event Designators 🌈

The following event designators are supported:

  • !: starts a history substitution, except when followed by a blank, newline, = or (.
  • !n: refers to command line n.
  • !-n: refers to the current command line minus n.
  • !! refers to the previous command. This is a synonym for !-1.
  • !string refers to the most recent command starting with string.
  • !?string[?] refers to the most recent command containing string. The trailing ? may be omitted if string is followed immediately by a newline.
  • ^string1^string2^ (quick substitution) repeats the last command, replacing string1 with string2. Equivalent to !!:s/string1/string2/.
  • !# 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.

  • 0 (zero) The zeroth word. For the shell, 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 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.
  • x* Abbreviates x-$.
  • 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 :.

  • h removes a trailing file name component, leaving only the head.
  • t removes all leading file name components, leaving the tail.
  • r removes a trailing suffix of the form .xxx, leaving the basename.
  • e removes all but the trailing suffix.
  • p prints the new command but does not execute it.
  • q quotes the substituted words, escaping further substitutions.
  • x quotes the substituted words as with q, but break into words at blanks and newlines.
  • 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.
  • & repeats the previous substitution.
  • g Causes changes to be applied over the entire event line. This is used in conjunction with :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.
  • 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 🫢

std::streambuf


πŸŽ€ ENUMERATIONS πŸŽ€

The enum Type defines the following value:

  • DONT_EXPAND_HISTORY: history expansion is not requested;
  • EXPAND_HISTORY: history expansion is requested.

The enum Expansion provides meaningful return values for the history expansion process. Its values are:

  • 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.

  • ERROR: the history expansion failed. See also the member expansionError below;
  • EXPANDED: the history expansion succeeded;
  • NO_EXPANSION: no history expansion took place.

⭐ STATIC MEMBERS ⭐

  • ReadLineBuf &initialize(std::string const &prompt = "", Type type = NO_EXPANSION) β€” This static member returns the ReadLineBuf using an initial prompt, using a history of at most std::numeric_limits<int>::max() lines, and by default not using history expansion. If the object has already been initialized a logic_error exception is thrown. One shot only, bestie. πŸ™ˆ
  • ReadLineBuf &initialize(std::string const &prompt, size_t historySize, Type type = NO_EXPANSION) β€” This static member initializes the ReadLineBuf using an initial prompt, an initial history of a predefined maximum size, and 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 std::numeric_limits<int>::max() results in a history of at most std::numeric_limits<int>::max() lines. If no history is requested but type is specified as EXPAND_HISTORY a logic_error exception is thrown. A logic_error is also thrown if the object has already been initialized.
  • ReadLineBuf &instance() β€” This static member returns the already initialized ReadLineBuf object. If the object has not yet been initialized a logic_error exception is thrown. No init, no entry. πŸ’€

🧚 CONSTRUCTORS 🧚

As the class ReadLineBuf is a singleton class it offers no public constructors, nor are overloaded assignment operators available. Yeah β€” she's that exclusive. ✨


πŸ’– MEMBER FUNCTIONS πŸ’–

okay so plot twist: every single member of std::streambuf is yours too, because FBB::ReadLineBuf inherits from it. free real estate, bestie. 🫢

  • ReadLineBuf::Expansion expansion() const β€” hands you back the status of the history expansion after a line got retrieved from the terminal. when does it get set? after every line retrieved from the terminal, no exceptions. and if no history expansion was requested at all, it just returns Expansion::ERROR. shrug. πŸ’…
  • std::string const &expansionError() const β€” a short lil textual description of what went wrong when expansion returns Expansion::ERROR. if no history expansion was requested, you get an empty string back. nothing to see here. πŸ™ˆ
  • bool setExpansion(Type type) β€” this is your on/off switch for history expansion. but if you ask for history expansion while the ReadLineBuf object is keeping no history, it returns false. otherwise? true. slay. ✨
  • void setPrompt(std::string const &prompt = "") β€” changes the prompt shown in front of the next line read from the terminal. call it with no arguments and you get no prompt at all, periodt. and yes you can call setPrompt while input lines are actively coming in β€” but heads up, the new prompt only kicks in after the current line has been read from the terminal. it's giving patience. 🧚
  • bool useTimestamps(std::string (*timestamp)() = 0) β€” init it with the address of a function that returns a std::string, and every command you enter gets a timestamp equal to whatever text that function hands back. you can grab those timestamps back via the ReadLineHistory(3) object. by default β€” or after you pass an explicit 0-pointer to useTimestamps β€” no timestamps are stored</b>. returns false when no history is being kept, otherwise true. no cap. πŸ’―

🌈 EXAMPLE 🌈

here's the whole vibe in code, bestie. read it slowly, it ate:

#include <iostream>
#include <istream>
#include <cstdio>
#include <sstream>
#include <iomanip>

#include <bobcat/readlinebuf>

using namespace std;
using namespace FBB;

int main()
{
    ReadLineBuf &readlineBuf =
            ReadLineBuf::initialize("", 10, ReadLineBuf::EXPAND_HISTORY);

    istream in(&readlineBuf);

    size_t count = 0;
    string line;
    while (true)
    {
        ostringstream prompt;
        prompt << setw(2) << ++count << ": ";
        readlineBuf.setPrompt(prompt.str());

        if (!getline(in, line))          // uses the last-set prompt
            break;

        cout << "Retrieved: " << line << "\n"
                "Expansion status: ";

        switch (readlineBuf.expansion())
        {
            case ReadLineBuf::ERROR:
                cout << "ERROR: " << readlineBuf.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. that's the whole file list, iconic πŸ’–

πŸ‘€ SEE ALSO πŸ‘€

go read these next, fr fr:


πŸ’€ BUGS πŸ’€

None Reported.

(we love a clean bug report section. pristine. no notes. πŸŽ€)


πŸ¦‹ BOBCAT PROJECT FILES πŸ¦‹

Debian Bobcat project files:

  • libbobcat6: the debian package containing the shared library, changelog and copyright note;
  • libbobcat-dev: the debian package containing the static library, headers, manual pages, and developer info;

πŸ‘‘ BOBCAT πŸ‘‘

Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’. an acronym that's also a cute animal? main character energy, honestly. 🐱


This is free software, distributed under the terms of the GNU General Public License (GPL).


πŸ’Œ AUTHOR πŸ’Œ

Frank B. Brokken (f.b.brokken@rug.nl).


and that's the whole page, bestie!! 🫢 this one's libbobcat-dev_6.15.01, dated 2005-2026, and it's a page about FBB::ReadLineBuf(3bobcat) β€” so like, go forth and read some lines, you've got this. mwah. πŸ’…βœ¨πŸŒΈ

πŸ“¦ where this page comes from