1RlwrapFilter(3pm) User Contributed Perl Documentation RlwrapFilter(3pm)
2
3
4
6 RlwrapFilter - Perl class for rlwrap filters
7
9 use lib $ENV{RLWRAP_FILTERDIR};
10 use RlwrapFilter;
11
12 $filter = new RlwrapFilter;
13
14 $filter -> output_handler(sub {s/apple/orange/; $_}); # re-write output
15 $filter -> prompt_handler(\&pimp_the_prompt); # change prompt
16 $filter -> history_handler(sub {s/with password \w+/with password ****/; $_}); # keep passwords out of history
17
18 $filter -> run;
19
21 rlwrap (1) (<https://github.com/hanslub42/rlwrap>) is a tiny utility
22 that sits between the user and any console command, in order to bestow
23 readline capabilities (line editing, history recall) to commands that
24 don't have them.
25
26 Since version 0.32, rlwrap can use filters to script almost every
27 aspect of rlwrap's interaction with the user: changing the history, re-
28 writing output and input, calling a pager or computing completion word
29 lists from the current input.
30
31 Filters can be combined in a pipeline using the special pipeline
32 filter.
33
34 RlwrapFilter makes it very simple to write rlwrap filters in perl. A
35 filter only needs to instantiate a RlwrapFilter object, change a few of
36 its default handlers and then call its 'run' method.
37
38 There is also a Python 3 module rlwrapfilter.py, distributed together
39 with rlwrap, that provides more or less the same API as its perl
40 counterpart.
41
43 CONSTRUCTOR
44 $f = new RlwrapFilter
45 $f = RlwrapFilter -> new(prompt_handler => sub {"Hi! > "},
46 minimal_rlwrap_version => "0.35", ...)
47 Return a new RlwrapFilter object.
48
49 SETTING/GETTING HANDLERS
50 Handlers are user-defined callbacks that specify one or more of an
51 RlwrapFilter object's handler methods (handle_input, handle_prompt)
52 They get called from the 'run' method in response to a message sent
53 from rlwrap. Messages consist of a tag indicating which handler should
54 be called (e.g. TAG_INPUT, TAG_HISTORY) and the message text. Usually,
55 a filter overrides only one or at most two methods.
56
57 CALLING CONVENTIONS
58 In many cases (e.g. TAG_INPUT, TAG_OUTPUT, TAG_PROMPT) the message text
59 is a simple string. Their handlers are called with the message text
60 (i.e. the un-filtered input, output, prompt) as their only argument.
61 For convenience, $_ is set to the same value. They should return the
62 re-written message text.
63
64 Some handlers (those for TAG_COMPLETION and TAG_HOTKEY) are a little
65 more complex: their message text (accessible via $_) is a tab-separated
66 list of fields; they get called with multiple arguments and are
67 evaluated in list context.
68
69 The message handlers are called in a fixed cyclic order: prompt,
70 completion, history, input, echo, output, prompt, ... etc ad infinitum.
71 Rlwrap may always skip a handler when in direct mode; on the other
72 hand, completion and output handlers may get called more than once in
73 succession. If a handler is left undefined, the result is as if the
74 message text were returned unaltered (in fact, rlwrap knows when this
75 is the case and won't even bother to send the message)
76
77 It is important to note that the filter, and hence all its handlers,
78 are bypassed when command is in direct mode, i.e. when it asks for
79 single keystrokes (and also, for security reasons, when it doesn't
80 echo, e.g. when asking for a password). If you don't want this to
81 happen, use rlwrap -a to force rlwrap to remain in readline mode and to
82 apply the filter to all of command's in- and output. This will make
83 editors and pagers (which respond to single keystrokes) unusable,
84 unless you use rlwrap's -N option (linux only)
85
86 The getters/setters for the respective handlers are listed below:
87
88 $handler = $f -> prompt_handler, $f -> prompt_handler(\&handler)
89 The prompt handler re-writes prompts and gets called when rlwrap
90 decides it is time to "cook" the prompt, by default some 40 ms
91 after the last output has arrived. Of course, rlwrap cannot read
92 the mind of command, so what looks like a prompt to rlwrap may
93 actually be the beginning of an output line that took command a
94 little longer to formulate. If this is a problem, specify a longer
95 "cooking" time with rlwrap's -w option, use the
96 prompts_are_never_empty method or "reject" the prompt (cf. the
97 prompt_rejected method)
98
99 $handler = $f -> completion_handler, $f ->
100 completion_handler(\&handler)
101 The completion handler gets called with three arguments: the entire
102 input line, the prefix (partial word to complete), and rlwrap's own
103 completion list. It should return a (possibly revised) list of
104 completions. As an example, suppose the user has typed "She played
105 for A<TAB>". The handler will be called like this:
106
107 myhandler("She played for A", "A", "Arsenal", "Arendal", "Anderlecht")
108
109 it could then return a list of stronger clubs: ("Ajax", "AZ67",
110 "Arnhem")
111
112 $handler = $f -> history_handler, $f -> history_handler(\&handler)
113 Every input line is submitted to this handler, the return value is
114 put in rlwrap's history. Returning an empty or undefined value will
115 keep the input line out of the history.
116
117 $handler = $f -> hotkey_handler, $f -> hotkey_handler(\&handler)
118 If, while editing an input line, the user presses a key that is
119 bound to "rlwrap_hotkey" in .inputrc, the handler is called with
120 five arguments: the hotkey, the prefix (i.e. the part of the
121 current input line before the cursor), the remaining part of the
122 input line (postfix), the history as one string ("line 1\nline
123 2\n...line N", and the history position. It has to return a similar
124 list, except that the first element will be printed in the "echo
125 area" if it is changed from its original value.
126
127 Example: if the current input line is "pea soup" (with the cursor
128 on the space), and the user presses CTRL+P, which happens to be
129 bound to "rlwrap-hotkey" in .inputrc, the handler is called like
130 this:
131
132 my_handler("\0x10", "pea", " soup", "tomato soup\nasparagus..", 12) # 16 = CTRL-P
133
134 If you prefer peanut soup, the handler should return
135
136 ("Mmmm!", "peanut", " soup", "asparagus..", 11)
137
138 after which the input line will be "peanut soup" (with the cursor
139 again on the space), the echo area will display "Mmmm!", and any
140 reference to inferior soups will have been purged from the history.
141
142 If the returned input line ends with a newline rlwrap will
143 immediately accept the result.
144
145 $handler = $f -> input_handler, $f -> input_handler(\&handler)
146 Every input line is submitted to this handler, The handler's return
147 value is written to command's pty (pseudo-terminal).
148
149 $handler = $f -> echo_handler, $f -> echo_handler(\&handler)
150 The first line of output that is read back from command's pty is
151 the echo'ed input line. If your input handler alters the input
152 line, it is the altered input that will be echo'ed back. If you
153 don't want to confuse the user, use an echo handler that returns
154 your original input.
155
156 If you use rlwrap in --multi-line mode, additional echo lines will
157 have to be handled by the output handler
158
159 $handler = $f -> output_handler, $f -> output_handler(\&handler)
160 All command output after the echo line is submitted to the output
161 handler (including newlines). This handler may get called many
162 times in succession, dependent on the size of command's write()
163 calls, and the whims of your system's scheduler. Therefore your
164 handler should be prepared to rewrite your output in "chunks",
165 where you even don't have the guarantee that the chunks contain
166 entire unbroken lines.
167
168 If you want to handle command's entire output in one go, you can
169 specify an output handler that returns an empty string, and then
170 use $filter -> cumulative_output in your prompt handler to send the
171 re-written output "out-of-band" just before the prompt:
172
173 $filter -> output_handler(sub {""});
174
175 $filter -> prompt_handler(
176 sub{ $filter -> send_output_oob(mysub($filter -> cumulative_output));
177 "Hi there > "
178 });
179
180 Note that when rlwrap is run in --multi-line mode the echo handler
181 will still only handle the first echo line. The remainder will
182 generally be echoed back preceded by a continuation prompt; it is
183 up to the output handler what to do with it.
184
185 $handler = $f -> signal_handler, $f -> signal_handler(\&handler)
186 As rlwrap is transparent to signals, signals get passed on to
187 command. This handler gets called (as handler($signo)) for signals
188 SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGCONT, SIGUSR1, SIGUSR2, and
189 SIGWINCH, before the signal is delivered. It receives (and should
190 return) $signo as a string. The returned signal is delivered to
191 command; return "0" to ignore the signal altogether. Output can be
192 written out-of-band (to rlwrap) or cloak_and_dagger (to command,
193 see below)
194
195 $handler = $f -> message_handler, $f -> message_handler(\&handler)
196 This handler gets called (as handler($message, $tag)) for every
197 incoming message, and every tag (including out-of-band tags),
198 before all other handlers. Its return value is ignored, but it may
199 be useful for logging and debugging purposes. The $tag is an
200 integer that can be converted to a tag name by the 'tag2name'
201 method
202
203 OTHER METHODS
204 $f -> help_text("Usage...")
205 Set the help text for this filter. It will be displayed by rlwrap
206 -z <filter>. The second line of the help text is used by "rlwrap -z
207 listing"; it should be a short description of what the filter does.
208
209 $f -> minimal_rlwrap_version("x.yy")
210 Die unless rlwrap is version x.yy or newer
211
212 $dir = $f -> cwd
213 return the name of command's current working directory. This uses
214 the /proc filesystem, and may only work on newer linux systems (on
215 older linux and on Solaris, it will return something like
216 "/proc/12345/cwd", useful to find the contents of command's working
217 directory, but not its name)
218
219 $text = $f -> cumulative_output
220 return the current cumulative output. All (untreated) output gets
221 appended to the cumulative output after the output_handler has been
222 called. The cumulative output starts with a fresh slate with every
223 OUTPUT message that directly follows an INPUT message (ignoring
224 out-of-band messages and rejected prompts)
225
226 When necessary (i.e. when rlwrap is in "impatient mode") the prompt
227 is removed from $filter->cumulative_output by the time the prompt
228 handler is called.
229
230 $tag = $f -> previous_tag
231 The tag of the last preceding in-band message. A tag is an integer
232 between 0 and 255, its name can be found with the following method:
233
234 $name = $f -> tag2name($tag)
235 Convert the tag (an integer) to its name (e.g. "TAG_PROMPT")
236
237 $name = $f -> name2tag($tag)
238 Convert a valid tag name like "TAG_PROMPT" to a tag (an integer)
239
240 $f -> send_output_oob($text)
241 Make rlwrap display $text. $text is sent "out-of-band": rlwrap will
242 not see it until just after it has sent the next message to the
243 filter
244
245 $f -> send_ignore_oob($text)
246 Send an out-of-band TAG_IGNORE message to rlwrap. rlwrap will
247 silently discard it, but it can be useful when debugging filters
248
249 $f -> add_to_completion_list(@words)
250 $f -> remove_from_completion_list(@words)
251 Permanently add or remove the words in @words to/from rlwrap's
252 completion list.
253
254 $f -> cloak_and_dagger($question, $prompt, $timeout);
255 Send $question to command's input and read back everything that
256 comes back until $prompt is seen at "end-of-chunk", or no new
257 chunks arrive for $timeout seconds, whichever comes first. Return
258 the response (without the final $prompt). rlwrap remains
259 completely unaware of this conversation.
260
261 $f -> cloak_and_dagger_verbose($verbosity)
262 If $verbosity evaluates to a true value, make rlwrap print all
263 questions sent to command by the "cloak_and_dagger" method, and
264 command's responses. By default, $verbosity = 0; setting it to 1
265 will mess up the screen but greatly facilitate the (otherwise
266 rather tricky) use of "cloak_and_dagger"
267
268 $self -> prompt_rejected
269 A special text ("_THIS_CANNOT_BE_A_PROMPT_") to be returned by a
270 prompt handler to "reject" the prompt. This will make rlwrap skip
271 cooking the prompt. $self->previous_tag and
272 $self->cumulative_output will not be touched.
273
274 $text = $f -> prompts_are_never_empty($val)
275 If $val evaluates to a true value, automatically reject empty
276 prompts.
277
278 $f -> command_line
279 In scalar context: the rlwrapped command and its arguments as a
280 string ("command -v blah") in list context: the same as a list
281 ("command", "-v", "blah")
282
283 $f -> running_under_rlwrap
284 Whether the filter is run by rlwrap, or directly from the command
285 line
286
287 $f -> run
288 Start an event loop that reads rlwrap's messages from the input
289 pipe, calls the appropriate handlers and writes the result to the
290 output pipe. This method never returns.
291
293 rlwrap communicates with a filter through messages consisting of a tag
294 byte (TAG_OUTPUT, TAG_PROMPT etc. - to inform the filter of what is
295 being sent), an unsigned 32-bit integer containing the length of the
296 message, the message text and an extra newline. For every message sent,
297 rlwrap expects, and waits for an answer message with the same tag.
298 Sending back a different (in-band) tag is an error and instantly kills
299 rlwrap, though filters may precede their answer message with "out-of-
300 band" messages to output text (TAG_OUTPUT_OUT_OF_BAND), report errors
301 (TAG_ERROR), and to manipulate the completion word list
302 (TAG_ADD_TO_COMPLETION_LIST and TAG_REMOVE_FROM_COMPLETION_LIST) Out-
303 of-band messages are not serviced by rlwrap until right after it has
304 sent the next in-band message - the communication with the filter is
305 synchronous and driven by rlwrap.
306
307 Messages are received and sent via two pipes. STDIN, STDOUT and STDERR
308 are still connected to the user's terminal, and you can read and write
309 them directly, though this may mess up the screen and confuse the user
310 unless you are careful. A filter can even communicate with the
311 rlwrapped command behind rlwrap's back (cf the cloak_and_dagger()
312 method)
313
314 The protocol uses the following tags (tags > 128 are out-of-band)
315
316 TAG_INPUT 0
317 TAG_OUTPUT 1
318 TAG_HISTORY 2
319 TAG_COMPLETION 3
320 TAG_PROMPT 4
321 TAG_HOTKEY 5
322 TAG_SIGNAL 6
323
324 TAG_WHAT_ARE_YOUR_INTERESTS 127
325
326 TAG_IGNORE 251
327 TAG_ADD_TO_COMPLETION_LIST 252
328 TAG_REMOVE_FROM_COMPLETION_LIST 253
329 TAG_OUTPUT_OUT_OF_BAND 254
330 TAG_ERROR 255
331
332 To see how this works, you can eavesdrop on the protocol using the
333 logger filter.
334
335 The constants TAG_INPUT, ... are exported by the RlwrapFilter.pm
336 module.
337
338 TAG_WHAT_ARE_YOUR_INTERESTS is only ever used internally, to prevent
339 the exchange of messages that won't be handled by the filter anyway. It
340 will be seen by the general message handler, and therefore show up
341 (exactly once, at program start) in the output of e.g. the logger
342 filter.
343
345 As STDIN is still connected to the users teminal, one might expect the
346 filter to receive SIGINT, SIGTERM, SIGTSTP directly from the terminal
347 driver if the user presses CTRL-C, CTRL-Z etc Normally, we don't want
348 this - it would confuse rlwrap, and the user (who thinks she is talking
349 straight to the rlwapped command) probably meant those signals to be
350 sent to the command itself. For this reason the filter starts with all
351 signals blocked.
352
353 Filters that interact with the users terminal (e.g. to run a pager)
354 should unblock signals like SIGTERM, SIGWINCH.
355
357 The filter is started by rlwrap after command, and stays alive as long
358 as rlwrap runs. Filter methods are immediately usable. When command
359 exits, the filter stays around for a little longer in order to process
360 command's last words. As calling the cwd and cloak_and_dagger methods
361 at that time will make the filter die with an error, it may be
362 advisable to wrap those calls in eval{}
363
364 If a filter calls die() it will send an (out-of-band) TAG_ERROR message
365 to rlwrap before exiting. rlwrap will then report the message and exit
366 (just after its next in-band message - out-of-band messages are not
367 always processed immediately)
368
369 die() within an eval() sets $@ as usual.
370
372 Before calling a filter, rlwrap sets the following environment
373 variables:
374
375 RLWRAP_FILTERDIR directory where RlwrapFilter.pm and most filters live (set by rlwrap, can be
376 overridden by the user before calling rlwrap)
377
378 PATH rlwrap automatically adds $RLWRAP_FILTERDIR to the front of filter's PATH
379
380 RLWRAP_VERSION rlwrap version (e.g. "0.35")
381
382 RLWRAP_COMMAND_PID process ID of the rlwrapped command
383
384 RLWRAP_COMMAND_LINE command line of the rlwrapped command
385
386 RLWRAP_IMPATIENT whether rlwrap is in "impatient mode" (cf rlwrap (1)). In impatient mode,
387 the candidate prompt is filtered through the output handler (and displayed before
388 being overwritten by the cooked prompt).
389
390 RLWRAP_INPUT_PIPE_FD File descriptor of input pipe. For internal use only
391
392 RLWRAP_OUTPUT_PIPE_FD File descriptor of output pipe. For internal use only
393
394 RLWRAP_MASTER_PTY_FD File descriptor of command's pty.
395
396 RLWRAP_BREAK_CHARS The characters rlwrap considers word-breaking (cf. the --break-chars option in rlwrap (1))
397
399 While RlwrapFilter.pm makes it easy to write simple filters, debugging
400 them can be a problem. A couple of useful tricks:
401
402 LOGGING
403 When running a filter, the in- and outgoing messages can be logged by
404 the logger filter, using a pipeline:
405
406 rlwrap -z 'pipeline logger incoming : my_filter : logger outgoing' command
407
408 RUNNING WITHOUT rlwrap
409 When called by rlwrap, filters get their input from
410 $RLWRAP_INPUT_PIPE_FD and write their output to $RLWRAP_OUTPUT_PIPE_FD,
411 and expect and write messages consisting of a tag byte, a 32-bit length
412 and the message proper. This is not terribly useful when running a
413 filter directly from the command line (outside rlwrap), even if we set
414 the RLWRAP_*_FD ourselves.
415
416 Therefore, when run directly from the command line, a filter expects
417 input messages on its standard input of the form
418
419 TAG_PROMPT myprompt >
420
421 (i.a. a tag name, one space and a message followed by a newline. The
422 message will not contain the final newline) and it will respond in the
423 same way on its standard output. Of course, rlwrap can help with the
424 tedious typing of tag names:
425
426 rlwrap -f tagnames filter_to_be_debugged
427
428 Because rlwrap cannot put TABs and newlines in input lines, filters
429 will convert '\t' and '\n' into TAB and newline when run directly from
430 the command line.
431
433 rlwrap (1), readline (3)
434
435
436
437perl v5.32.0 2021-01-17 RlwrapFilter(3pm)