The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Term::CLI::ReadLine - Term::ReadLine compatibility layer for Term::CLI

VERSION

version 0.059000

SYNOPSIS

 use Term::CLI::ReadLine;

 sub initialise {
    my $term = Term::CLI::ReadLine->new( ... );
    ... # Use Term::ReadLine methods on $term.
 }

 # The original $term reference is now out of scope, but
 # we can get a reference to it again:

 sub somewhere_else {
    my $term = Term::CLI::ReadLine->term;
    ... # Use Term::ReadLine methods on $term.
 }

DESCRIPTION

This class provides a compatibility layer between Term::ReadLine(3p) and Term::CLI(3p). If Term::ReadLine::Gnu(3p) is not loaded as the Term::ReadLine implementation, this class will compensate for the lack of certain functions by replacing or wrapping methods that are needed by the rest of the Term::CLI(3p) classes.

The ultimate purpose is to behave as consistently as possible regardless of the Term::ReadLine interface that has been loaded.

This class inherits from Term::ReadLine and behaves as a singleton with a class accessor to access that single instance, because even though Term::ReadLine(3p) has an object-oriented interface, the Term::ReadLine::Gnu(3p) and Term::ReadLine::Perl(3p) modules really only keep a single instance around (if you create multiple Term::ReadLine objects, all parameters and history are shared).

CONSTRUCTORS

new ( ... )

Create a new Term::CLI::ReadLine(3p) object and return a reference to it.

Arguments are identical to Term::ReadLine(3p).

A reference to the newly created object is stored internally and can be retrieved later with the term class method. Note that repeated calls to new will reset this internal reference.

METHODS

See Term::ReadLine(3p), Term::ReadLine::Gnu(3p) and/or Term::ReadLine::Perl for the inherited methods.

completion_quote_character

In a Term::ReadLine::Gnu environment this returns the rl_completion_quote_character. This value is set during completion if the text to be completed has an open quote. Consider the case:

    foo 'bar <TAB>

When the completion function is called, the rl_completion_quote_character will contain a single quote, '.

For non-GNU ReadLine backends, this function returns an empty string.

echo_signal_char ( signal )

Print the character that generates a particular signal when entered from the keyboard (e.g. ^C for keyboard interrupt).

This method also accepts a signal name instead of a signal number. It only works for INT (2), QUIT (3), and TSTP (20) signals as these are the only ones that can be entered from a keyboard.

If Term::ReadLine::Gnu is loaded, this method wraps around the method of the same name in Term::ReadLine::Gnu (translating a signal name to a number first). For other Term::ReadLine implementations, it emulates the Term::ReadLine::Gnu behaviour.

readline ( prompt )

Wrap around the original Term::ReadLine's readline with custom signal handling, see the CAVEATS section in Term::CLI.

This also calls AddHistory if autohistory is not set in Features.

term_width

Return the width of the terminal in characters, as given by Term::ReadLine.

term_height

Return the height of the terminal in characters, as given by Term::ReadLine.

ignore_keyboard_signals ( SIGNAME, ... )

Ensure that SIGNAME signals cannot be entered from the keyboard. SIGNAME should be the name of a signal that can be entered from the keyboard, i.e. one of: INT, QUIT, TSTP.

By default, the QUIT keyboard signal is already disabled.

Notes:

  1. This will only disable the keys for the given signals during a readline operation. Outside of that, they will still generate signals.

  2. This only disables the keyboard sequences, not the actual signals themselves (i.e. you can still kill -3 PID from another terminal.

  3. Disabling the INT key will cause Ctrl-C to no longer discard the input line under Term::ReadLine::Gnu; it will discard it under Term::ReadLine::Perl! It is therefore recommended to just set $SIG{INT} to IGNORE instead.

  4. Disabling the TSTP key works under Term::ReadLine::Gnu, but not under Term::ReadLine::Perl. The latter maps the key in raw mode and explicitly sends a TSTP signal to itself.

See also SIGNAL HANDLING below.

no_ignore_keyboard_signals ( SIGNAME, ... )

(Re-)Enable keyboard generation for SIGNAME signals. See ignore_keyboard_signals above for valid SIGNAME values.

reset_ignore_keyboard_signals

Reset all keyboard signal generation to the defaults.

AddHistory ( line, ... )
GetHistory
ReadHistory ( file )
SetHistory ( line, ... )
StifleHistory ( max_lines )
stifle_history ( max_lines )
WriteHistory ( file )

Depending on the underlying Term::ReadLine implementation, these will either call the parent class's method, or implement a proper emulation.

In the case of Term::ReadLine::Perl, this means that ReadHistory and WriteHistory implement their own file I/O read/write (because Term::ReadLine::Perl doesn't provide them); furthermore, StifleHistory uses knowledge of Term::ReadLine::Perl's internals to manipulate the history.

In cases where history is not supported at all (e.g. Term::ReadLine::Stub, the history list is kept in this object and manipulated.

STUB METHODS

If Term::ReadLine is not using the GNU ReadLine library, this object provides stubs for a few GNU ReadLine methods:

free_line_state
forced_update_display

If Term::ReadLine::Perl is loaded, this will use knowledge of its internals to force an redraw of the input line.

crlf

Prints a newline to the terminal's output.

replace_line ( str )

If Term::ReadLine::Perl is loaded, this will use knowledge of its internals to replace the current input line with str.

deprep_terminal
prep_terminal

If Term::ReadLine::Perl is loaded, this will use knowledge of its internals to either restore (deprep) terminal settings to what they were before calling readline, or to set them to what readline uses. You will rarely (if ever) need these, since the ReadLine libraries usually take care if this themselves.

One exception to this is in signal handlers: Term::CLI::ReadLine calls these methods during its signal handling.

get_screen_size

Use Term::ReadKey::GetTerminalSize to get the appropriate dimensions and return them as (height, width).

CLASS METHODS

term

Return the latest Term::CLI::ReadLine object created.

SIGNAL HANDLING

The class sets its own signal handlers in the readline function where necessary.

The following signals may be caught: ALRM, CONT, HUP, INT, QUIT, TERM.

The signal handlers will:

  • Restore the terminal to a "sane" state, i.e. the state it was in before readline was called (the CONT signal being an exception to this rule).

  • If any signal handler was set prior to the call to readline, it will be called and if control returns Term::CLI::ReadLine's signal handler, the terminal will be set back to the state that readline expects it to be in.

  • If the signal handler was previously set to DEFAULT, it is restored as DEFAULT and the signal is re-thrown, so the default actions (abnormal exit and possible core dump) can take place.

Just how and when these "wrapper" signal handlers are installed depends on the selected Term::ReadLine implementation. The Gnu backend doesn't require separate handlers for signals that are set to IGNORE or DEFAULT. The Perl backend does require some wrapping.

The INT signal is always wrapped to ensure that the current input line is discarded and a newline is emitted.

Keyboard signals

One subtle difference between the Term::ReadLine::Gnu and Term::ReadLine::Perl is in keyboard-generated signal handling (interrupt, quit, suspend).

  • Term::ReadLine::Perl disables keyboard-generated signals. When it reads a Ctrl-C, it will send itself an INT signal, when it sees a Ctrl-Z, it will send a TSTP signal; the "quit" key Ctrl-\ is simply ignored.

  • Term::ReadLine::Gnu leaves keyboard-generated signals enabled and sets signal handlers to catch them.

This subtle difference means that:

For this reason, the module by default ignores the QUIT key sequence.

Recommendations

To behave as consistently as possible across the Term::ReadLine backends, the following is best if you don't want keyboard signals to kill or stop the program:

  1. Set $SIG{INT} to IGNORE.

  2. Set $SIG{TSTP} to IGNORE.

  3. Ignore keyboard signal QUIT (already default).

SEE ALSO

Term::CLI(3p), Term::ReadLine(3p), Term::ReadLine::Gnu(3p), Term::ReadLine::Perl(3p).

AUTHOR

Steven Bakker <sbakker@cpan.org>, 2018-2021.

COPYRIGHT AND LICENSE

Copyright (c) 2018 Steven Bakker

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See "perldoc perlartistic."

This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.