File Coverage

blib/lib/AnyEvent/ReadLine/Gnu.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             AnyEvent::ReadLine::Gnu - event-based interface to Term::ReadLine::Gnu
4              
5             =head1 SYNOPSIS
6              
7             use AnyEvent::ReadLine::Gnu;
8              
9             # works always, prints message to stdout
10             AnyEvent::ReadLine::Gnu->print ("message\n");
11              
12             # now initialise readline
13             my $rl = new AnyEvent::ReadLine::Gnu prompt => "hi> ", on_line => sub {
14             # called for each line entered by the user
15             AnyEvent::ReadLine::Gnu->print ("you entered: $_[0]\n");
16             };
17              
18             # asynchronously print something
19             my $t = AE::timer 1, 1, sub {
20             $rl->hide;
21             print "async message 1\n"; # mind the \n
22             $rl->show;
23              
24             # the same, but shorter:
25             $rl->print ("async message 2\n");
26             };
27              
28             # do other eventy stuff...
29             AE::cv->recv;
30              
31             =head1 DESCRIPTION
32              
33             The L module family is bizarre (and you are encouraged not
34             to look at its sources unless you want to go blind). It does support
35             event-based operations, somehow, but it's hard to figure out.
36              
37             It also has some utility functions for printing messages asynchronously,
38             something that, again, isn't obvious how to do.
39              
40             This module has figured it all out for you, once and for all.
41              
42             =over 4
43              
44             =cut
45              
46             package AnyEvent::ReadLine::Gnu;
47              
48 1     1   1567 use common::sense;
  1         10  
  1         5  
49 1     1   1758 use AnyEvent;
  1         6745  
  1         90  
50              
51             BEGIN {
52             # we try our best
53 1     1   11 local $ENV{PERL_RL} = "Gnu";
54              
55 1         1097 require Term::ReadLine;
56 1         12022 require Term::ReadLine::Gnu;
57             }
58              
59             use base Term::ReadLine::;
60              
61             our $VERSION = '1.0';
62              
63             =item $rl = new AnyEvent::ReadLine::Gnu key => value...
64              
65             Creates a new AnyEvent::ReadLine object.
66              
67             Actually, it only configures readline and provides a convenient way to
68             call the show and hide methods, as well as readline methods - this is a
69             singleton.
70              
71             The returned object is the standard L object, all
72             methods that are documented (or working) for that module should work on
73             this object.
74              
75             Once initialised, this module will also restore the terminal settings on a
76             normal program exit.
77              
78             The callback will be installed with the C, which
79             means it handles history expansion and history, among other things.
80              
81             The following key-value pairs are supported:
82              
83             =over 4
84              
85             =item on_line => $cb->($string)
86              
87             The only mandatory parameter - passes the callback that will receive lines
88             that are completed by the user.
89              
90             The string will be in locale-encoding (a multibyte character string). For
91             example, in an utf-8 using locale it will be utf-8. There is no portable
92             way known to the author to convert this into e.g. a unicode string.
93              
94             =item prompt => $string
95              
96             The prompt string to use, defaults to C<< > >>.
97              
98             =item name => $string
99              
100             The readline application name, defaults to C<$0>.
101              
102             =item in => $glob
103              
104             The input filehandle (should be a glob): defaults to C<*STDIN>.
105              
106             =item out => $glob
107              
108             The output filehandle (should be a glob): defaults to C<*STDOUT>.
109              
110             =back
111              
112             =cut
113              
114             our $self;
115             our $prompt;
116             our $cb;
117             our $hidden;
118             our $rw;
119             our ($in, $out);
120              
121             our $saved_point;
122             our $saved_line;
123              
124             # we postpone calling the user clalback here because readline
125             # still has the input buffer at this point, so calling hide and
126             # show might not have the desired effect.
127             sub on_line {
128             my $line = shift;
129             my $point = $self->{point};
130              
131             AE::postpone sub {
132             $cb->($line, $point);
133             };
134             }
135              
136             sub new {
137             my ($class, %arg) = @_;
138              
139             $in = $arg{in} || *STDIN;
140             $out = $arg{out} || *STDOUT;
141             $prompt = $arg{prompt} || "> ";
142             $cb = $arg{on_line} || $arg{cb}
143             or do { require Carp; Carp::croak ("AnyEvent::ReadLine::Gnu->new on_line callback argument mandatry, but missing") };
144              
145             $self = $class->SUPER::new ($arg{name} || $0, $in, $out);
146              
147             $Term::ReadLine::Gnu::Attribs{term_set} = ["", "", "", ""];
148             $self->CallbackHandlerInstall ($prompt, \&on_line);
149              
150             $hidden = 1;
151             $self->show;
152              
153             $self
154             }
155              
156             =item $rl->hide
157              
158             =item AnyEvent::ReadLine::Gnu->hide
159              
160             These methods I the readline prompt and text. Basically, it removes
161             the readline feedback from your terminal.
162              
163             It is safe to call even when AnyEvent::ReadLine::Gnu has not yet been
164             initialised.
165              
166             This is immensely useful in an event-based program when you want to output
167             some stuff to the terminal without disturbing the prompt - just C
168             readline, output your thing, then C it again.
169              
170             Since user input will not be processed while readline is hidden, you
171             should call C as soon as possible.
172              
173             =cut
174              
175             sub hide {
176             return if !$self || $hidden++;
177              
178             undef $rw;
179              
180             $saved_point = $self->{point};
181             $saved_line = $self->{line_buffer};
182              
183             $self->rl_set_prompt ("");
184             $self->{line_buffer} = "";
185             $self->rl_redisplay;
186             }
187              
188             =item $rl->show
189              
190             =item AnyEvent::ReadLine::Gnu->show
191              
192             Undos any hiding. Every call to C has to be followed to a call to
193             C. The last call will redisplay the readline prompt, current input
194             line and cursor position. Keys entered while the prompt was hidden will be
195             processed again.
196              
197             =cut
198              
199             sub show {
200             return if !$self || --$hidden;
201              
202             if (defined $saved_point) {
203             $self->rl_set_prompt ($prompt);
204             $self->{line_buffer} = $saved_line;
205             $self->{point} = $saved_point;
206             $self->redisplay;
207             }
208              
209             $rw = AE::io $in, 0, sub {
210             $self->rl_callback_read_char;
211             };
212             }
213              
214             =item $rl->print ($string, ...)
215              
216             =item AnyEvent::ReadLine::Gnu->print ($string, ...)
217              
218             Prints the given strings to the terminal, by first hiding the readline,
219             printing the message, and showing it again.
220              
221             This function can be called even when readline has never been initialised.
222              
223             The last string should end with a newline.
224              
225             =cut
226              
227             sub print {
228             shift;
229              
230             hide;
231             my $out = $out || *STDOUT;
232             print $out @_;
233             show;
234             }
235              
236             END {
237             return unless $self;
238              
239             $self->hide;
240             $self->callback_handler_remove;
241             }
242              
243             1;
244              
245             =back
246              
247             =head1 CAVEATS
248              
249             There are some issues with readline that can be problematic in event-based
250             programs:
251              
252             =over 4
253              
254             =item blocking I/O
255              
256             Readline uses blocking terminal I/O. Under most circumstances, this does
257             not cause big delays, but ttys have the potential to block programs
258             indefinitely (e.g. on XOFF).
259              
260             =item unexpected disk I/O
261              
262             By default, readline does filename completion on TAB, and reads its
263             config files.
264              
265             Tab completion can be disabled by calling C<< $rl->unbind_key (9) >>.
266              
267             =item tty settings
268              
269             After readline has been initialised, it will mangle the termios tty
270             settings. This does not normally affect output very much, but should be
271             taken into consideration.
272              
273             =item output intermixing
274              
275             Your program might wish to print messages (for example, log messages) to
276             STDOUT or STDERR. This will usually cause confusion, unless readline is
277             hidden with the hide method.
278              
279             =back
280              
281             Oh, and the above list is probably not complete.
282              
283             =head1 AUTHOR, CONTACT, SUPPORT
284              
285             Marc Lehmann
286             http://software.schmorp.de/pkg/AnyEvent-ReadLine-Gnu.html
287              
288             =head1 SEE ALSO
289              
290             L - a simple tcp_connect-with-readline program using this module.
291              
292             =cut
293