Provided by: rlwrap_0.37-5_amd64 bug

NAME

       RlwrapFilter - Perl class for rlwrap filters

SYNOPSIS

         use lib $ENV{RLWRAP_FILTERDIR};
         use RlwrapFilter;

         $filter = new RlwrapFilter;

         $filter -> output_handler(sub {s/apple/orange/; $_}); # re-write output
         $filter -> prompt_handler(\&pimp_the_prompt); # change prompt
         $filter -> history_handler(sub {s/with password \w+/with password ****/; $_}); # keep passwords out of history

         $filter -> run;

DESCRIPTION

       rlwrap (1) (<http://utopia.knoware.nl/~hlub/uck/rlwrap>) is a tiny utility that sits
       between the user and any console command, in order to bestow readline capabilities (line
       editing, history recall) to commands that don't have them.

       Since version 0.32, rlwrap can use filters to script almost every aspect of rlwrap's
       interaction with the user: changing the history, re-writing output and input, calling a
       pager or computing completion word lists from the current input.

       RlwrapFilter makes it very simple to write rlwrap filters in perl. A filter only needs to
       instantiate a RlwrapFilter object, change a few of its default handlers and then call its
       'run' method.

PUBLIC METHODS

   CONSTRUCTOR
       $f = new RlwrapFilter
       $f = RlwrapFilter -> new(prompt_handler => sub {"Hi! > "}, minimal_rlwrap_version =>
       "0.35", ...)
           Return a new RlwrapFilter object.

   SETTING/GETTING HANDLERS
       Handlers are user-defined callbacks that get called from the 'run' method with a message
       (i.e. the un-filtered input, output, prompt) as their first argument. For convenience, $_
       is set to the same value. They should return the re-written message text. They get called
       in a fixed cyclic order: prompt, completion, history, input, echo, output, prompt, ... etc
       ad infinitum. Rlwrap may always skip a handler when in direct mode, on the other hand,
       completion and output handlers may get called more than once in succession. If a handler
       is left undefined, the result is as if the message text were returned unaltered.

       It is important to note that the filter, and hence all its handlers, are bypassed when
       command is in direct mode, i.e. when it asks for single keystrokes (and also, for security
       reasons, when it doesn't echo, e.g. when asking for a password). If you don't want this to
       happen, use rlwrap -a to force rlwrap to remain in readline mode and to apply the filter
       to all of command's in- and output. This will make editors and pagers (which respond to
       single keystrokes) unusable, unless you use rlwrap's -N option (linux only)

       The getters/setters for the respective handlers are listed below:

       $handler = $f -> prompt_handler, $f -> prompt_handler(\&handler)
           The prompt handler re-writes prompts and gets called when rlwrap decides it is time to
           "cook" the prompt, by default some 40 ms after the last output has arrived. Of course,
           rlwrap cannot read the mind of command, so what looks like a prompt to rlwrap may
           actually be the beginning of an output line that took command a little longer to
           formulate. If this is a problem, specify a longer "cooking" time with rlwrap's -w
           option, use the prompts_are_never_empty method or "reject" the prompt (cf. the
           prompt_rejected method)

       $handler = $f -> completion_handler, $f -> completion_handler(\&handler)
           The completion handler gets called with the the entire input line, the prefix (partial
           word to complete), and rlwrap's own completion list as arguments. It should return a
           (possibly revised) list of completions.  As an example, suppose the user has typed
           "She played for A<TAB>". The handler will be called like this:

                myhandler("She played for A", "A", "Arsenal", "Arendal", "Anderlecht")

           it could then return a list of stronger clubs: ("Ajax", "AZ67",  "Arnhem")

       $handler = $f -> history_handler, $f -> history_handler(\&handler)
           Every input line is submitted to this handler, the return value is put in rlwrap's
           history. Returning an empty or undefined value will keep the input line out of the
           history.

       $handler = $f -> input_handler, $f -> input_handler(\&handler)
           Every input line is submitted to this handler, The handler's return value is written
           to command's pty (pseudo-terminal).

       $handler = $f -> echo_handler, $f -> echo_handler(\&handler)
           The first line of output that is read back from command's pty is the echo'ed input
           line. If your input handler alters the input line, it is the altered input that will
           be echo'ed back. If you don't want to confuse the user, use an echo handler that
           returns your original input.

           If you use rlwrap in --multi-line mode, additional echo lines will have to be handled
           by the output handler

       $handler = $f -> output_handler, $f -> output_handler(\&handler)
           All command output after the echo line is submitted to the output handler (including
           newlines). This handler may get called many times in succession, dependent on the size
           of command's write() calls, and the whims of your system's scheduler. Therefore your
           handler should be prepared to rewrite your output in "chunks", where you even don't
           have the guarantee that the chunks contain entire unbroken lines.

           If you want to handle command's entire output in one go, you can specify an output
           handler that returns an empty string, and then use $filter -> cumulative_output in
           your prompt handler to send the re-written output "out-of-band" just before the
           prompt:

               $filter -> output_handler(sub {""});

               $filter -> prompt_handler(
                             sub{ $filter -> send_output_oob(mysub($filter -> cumulative_output));
                                  "Hi there > "
                                });

           Note that when rlwrap is run in --multi-line mode the echo handler will still only
           handle the first echo line.  The remainder will generally be echoed back preceded by a
           continuation prompt; it is up to the output handler what to do with it.

       $handler = $f -> message_handler, $f -> message_handler(\&handler)
           This handler gets called (as handler($message, $tag)) for every incoming message, and
           every tag (including out-of-band tags), before all other handlers. Its return value is
           ignored, but it may be useful for logging and debugging purposes. The $tag is an
           integer that can be converted to a tag name by the 'tag2name' method

   OTHER METHODS
       $f -> help_text("Usage...")
           Set the help text for this filter. It will be displayed by rlwrap -z <filter>. The
           second line of the help text is used by "rlwrap -z listing"; it should be a short
           description of what the filter does.

       $f -> minimal_rlwrap_version("x.yy")
           Die unless rlwrap is version x.yy or newer

       $dir = $f -> cwd
           return the name of command's current working directory. This uses the /proc
           filesystem, and may only work on newer linux systems (on older linux and on Solaris,
           it will return something like "/proc/12345/cwd", useful to find the contents of
           command's working directory, but not its name)

       $text = $f -> cumulative_output
           return the current cumulative output. All (untreated) output gets appended to the
           cumulative output after the output_handler has been called. The cumulative output
           starts with a fresh slate with every OUTPUT message that directly follows an INPUT
           message (ignoring out-of-band messages and rejected prompts)

           When necessary (i.e. when rlwrap is in "impatient mode") the prompt is removed from
           $filter->cumulative_output by the time the prompt handler is called.

       $tag = $f -> previous_tag
           The tag of the last preceding in-band message. A tag is an integer between 0 and 255,
           its name can be found with the following method:

       $name = $f -> tag2name($tag)
           Convert the tag (an integer) to its name (e.g. "TAG_PROMPT")

       $name = $f -> name2tag($tag)
           Convert a valid tag name like "TAG_PROMPT" to a tag (an integer)

       $f -> send_output_oob($text)
           Make rlwrap display $text. $text is sent "out-of-band": rlwrap will not see it until
           just  after it has sent the next message to the filter

       $f -> send_ignore_oob($text)
           Send an out-of-band TAG_IGNORE message to rlwrap. rlwrap will silently discard it, but
           it can be useful when debugging filters

       $f -> add_to_completion_list(@words)
       $f -> remove_from_completion_list(@words)
           Permanently add or remove the words in @words to/from rlwrap's completion list.

       $f -> cloak_and_dagger($question, $prompt, $timeout);
           Send $question to command's input and read back everything that comes back until
           $prompt is seen at "end-of-chunk", or no new chunks arrive for $timeout seconds,
           whichever comes first.  Return the response (without the final $prompt).  rlwrap
           remains completely unaware of this conversation.

       $f -> cloak_and_dagger_verbose($verbosity)
           If $verbosity evaluates to a true value, make rlwrap print all questions sent to
           command by the "cloak_and_dagger" method, and command's responses. By default,
           $verbosity = 0; setting it to 1 will mess up the screen but greatly facilitate the
           (otherwise rather tricky) use of "cloak_and_dagger"

       $self -> prompt_rejected
           A special text ("_THIS_CANNOT_BE_A_PROMPT_") to be returned by a prompt handler to
           "reject" the prompt. This will make rlwrap skip cooking the prompt.
           $self->previous_tag and $self->cumulative_output will not be touched.

       $text = $f -> prompts_are_never_empty($val)
           If $val evaluates to a true value, automatically reject empty prompts.

       $f -> command_line
           In scalar context: the rlwrapped command and its arguments as a string ("command -v
           blah") in list context: the same as a list ("command", "-v", "blah")

       $f -> running_under_rlwrap
           Whether the filter is run by rlwrap, or directly from the command line

       $f -> run
           Start an event loop that reads rlwrap's messages from the input pipe, calls the
           appropriate handlers and writes the result to the output pipe.  This method never
           returns.

LOW LEVEL PROTOCOL

       rlwrap communicates with a filter through messages consisting of a tag byte (TAG_OUTPUT,
       TAG_PROMPT etc. - to inform the filter of what is being sent), an unsigned 32-bit integer
       containing the length of the message, the message text and an extra newline. For every
       message sent, rlwrap expects, and waits for an answer message with the same tag. Sending
       back a different (in-band) tag is an error and instantly kills rlwrap, though filters may
       precede their answer message with "out-of-band" messages to output text
       (TAG_OUTPUT_OUT_OF_BAND), report errors (TAG_ERROR), and to manipulate the completion word
       list (TAG_ADD_TO_COMPLETION_LIST and TAG_REMOVE_FROM_COMPLETION_LIST) Out-of-band messages
       are not serviced by rlwrap until right after it has sent the next in-band message - the
       communication with the filter is synchronous and driven by rlwrap.

       Messages are received and sent via two pipes. STDIN, STDOUT and STDERR are still connected
       to the user's terminal, and you can read and write them directly, though this may mess up
       the screen and confuse the user unless you are careful. A filter can even communicate with
       the rlwrapped command behind rlwrap's back (cf the cloak_and_dagger() method)

       The protocol uses the following tags (tags > 128 are out-of-band)

        TAG_INPUT       0
        TAG_OUTPUT      1
        TAG_HISTORY     2
        TAG_COMPLETION  3
        TAG_PROMPT      4

        TAG_IGNORE                      251
        TAG_ADD_TO_COMPLETION_LIST      252
        TAG_REMOVE_FROM_COMPLETION_LIST 253
        TAG_OUTPUT_OUT_OF_BAND          254
        TAG_ERROR                       255

       To see how this works, you can eavesdrop on the protocol using the 'logger' filter.

       The constants TAG_INPUT, ... are exported by the RlwrapFilter.pm module.

SIGNALS

       As STDIN is still connected to the users teminal, one might expect the filter to receive
       SIGINT, SIGTERM, SIGTSTP directly from the terminal driver if the user presses CTRL-C,
       CTRL-Z etc Normally, we don't want this - it would confuse rlwrap, and the user (who
       thinks she is talking straight to the rlwapped command) probably meant those signals to be
       sent to the command itself. For this reason the filter starts with all signals blocked.

       Filters that interact with the users terminal (e.g. to run a pager) should unblock signals
       like SIGTERM, SIGWINCH.

FILTER LIFETIME

       The filter is started by rlwrap after command, and stays alive as long as rlwrap runs.
       Filter methods are immediately usable. When command exits, the filter stays around for a
       little longer in order to process command's last words. As calling the cwd and
       cloak_and_dagger methods at that time will make the filter die with an error, it may be
       advisable to wrap those calls in eval{}

       If a filter calls die() it will send an (out-of-band) TAG_ERROR message to rlwrap before
       exiting. rlwrap will then report the message and exit (just after its next in-band message
       - out-of-band messages are not always processed immediately)

       die() within an eval() sets $@ as usual.

ENVIRONMENT

       Before calling a filter, rlwrap sets the following environment variables:

           RLWRAP_FILTERDIR      directory where RlwrapFilter.pm and most filters live (set by B<rlwrap>, can be
                                 overridden by the user before calling rlwrap)

           PATH                  rlwrap automatically adds $RLWRAP_FILTERDIR to the front of filter's PATH

           RLWRAP_VERSION        rlwrap version (e.g. "0.35")

           RLWRAP_COMMAND_PID    process ID of the rlwrapped command

           RLWRAP_COMMAND_LINE   command line of the rlwrapped command

           RLWRAP_IMPATIENT      whether rlwrap is in "impatient mode" (cf B<rlwrap (1)>). In impatient mode,
                                 the candidate prompt is filtered through the output handler (and displayed before
                                 being overwritten by the cooked prompt).

           RLWRAP_INPUT_PIPE_FD  File descriptor of input pipe. For internal use only

           RLWRAP_OUTPUT_PIPE_FD File descriptor of output pipe. For internal use only

           RLWRAP_MASTER_PTY_FD File descriptor of I<command>'s pty.

DEBUGGING FILTERS

       While RlwrapFilter.pm makes it easy to write simple filters, debugging them can be a
       problem. A couple of useful tricks:

   LOGGING
       When running a filter, the in- and outgoing messages can be logged by the logger filter,
       using a pipeline:

         rlwrap -z 'pipeline logger incoming : my_filter : logger outgoing' command

   RUNNING WITHOUT rlwrap
       When called by rlwrap, filters get their input from $RLWRAP_INPUT_PIPE_FD and write their
       output to $RLWRAP_OUTPUT_PIPE_FD, and expect and write messages consisting of a tag byte,
       a 32-bit length and the message proper. This is not terribly useful when running a filter
       directly from the command line (outside rlwrap), even if we set the RLWRAP_*_FD ourselves.

       Therfore, when run directly from the command line, a filter expects input messages on its
       standard input of the form

       TAG_PROMPT >

       (i.a. a tag name, one space and a message) and it will respond in the same way on its
       standard output

SEE ALSO

       rlwrap (1), readline (3)