ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-ReadLine-Gnu/Gnu.pm
Revision: 1.7
Committed: Fri May 11 15:38:02 2012 UTC (12 years ago) by root
Branch: MAIN
CVS Tags: rel-1_0
Changes since 1.6: +5 -4 lines
Log Message:
1.0

File Contents

# User Rev Content
1 root 1.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 root 1.2 my $rl = new AnyEvent::ReadLine::Gnu prompt => "hi> ", on_line => sub {
14 root 1.1 # 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 root 1.7 our $VERSION = '1.0';
62 root 1.1
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 root 1.7 The callback will be installed with the C<CallbackHandlerInstall>, which
79     means it handles history expansion and history, among other things.
80    
81 root 1.1 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 root 1.2 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 root 1.1 =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 root 1.2 # 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 root 1.1 sub new {
137     my ($class, %arg) = @_;
138    
139     $in = $arg{in} || *STDIN;
140     $out = $arg{out} || *STDOUT;
141     $prompt = $arg{prompt} || "> ";
142 root 1.2 $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 root 1.1
145     $self = $class->SUPER::new ($arg{name} || $0, $in, $out);
146    
147 root 1.7 $Term::ReadLine::Gnu::Attribs{term_set} = ["", "", "", ""];
148 root 1.2 $self->CallbackHandlerInstall ($prompt, \&on_line);
149 root 1.1
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 root 1.2 This function can be called even when readline has never been initialised.
222 root 1.1
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 root 1.3 =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 root 1.4 By default, readline does filename completion on TAB, and reads its
263     config files.
264 root 1.3
265 root 1.5 Tab completion can be disabled by calling C<< $rl->unbind_key (9) >>.
266    
267 root 1.4 =item tty settings
268 root 1.3
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 root 1.4 =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 root 1.3 =back
280    
281     Oh, and the above list is probably not complete.
282    
283 root 1.1 =head1 AUTHOR, CONTACT, SUPPORT
284    
285     Marc Lehmann <schmorp@schmorp.de>
286 root 1.6 http://software.schmorp.de/pkg/AnyEvent-ReadLine-Gnu.html
287 root 1.1
288 root 1.5 =head1 SEE ALSO
289    
290     L<rltelnet> - a simple tcp_connect-with-readline program using this module.
291    
292 root 1.1 =cut
293