ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-ReadLine-Gnu/Gnu.pm
Revision: 1.8
Committed: Tue Dec 12 15:50:45 2017 UTC (6 years, 4 months ago) by root
Branch: MAIN
CVS Tags: rel-1_1, HEAD
Changes since 1.7: +2 -2 lines
Log Message:
1.1

File Contents

# Content
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<Term::ReadLine> 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 use common::sense;
49 use AnyEvent;
50
51 BEGIN {
52 # we try our best
53 local $ENV{PERL_RL} = "Gnu";
54
55 require Term::ReadLine;
56 require Term::ReadLine::Gnu;
57 }
58
59 use base Term::ReadLine::;
60
61 our $VERSION = '1.1';
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<Term::ReadLine::Gnu> 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<CallbackHandlerInstall>, 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<hide> 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<hide>
168 readline, output your thing, then C<show> it again.
169
170 Since user input will not be processed while readline is hidden, you
171 should call C<show> 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<hide> has to be followed to a call to
193 C<show>. 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 <schmorp@schmorp.de>
286 http://software.schmorp.de/pkg/AnyEvent-ReadLine-Gnu.html
287
288 =head1 SEE ALSO
289
290 L<rltelnet> - a simple tcp_connect-with-readline program using this module.
291
292 =cut
293