source: perl/lib/BarnOwl.pm @ 7c83a32

release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 7c83a32 was 22b54a7, checked in by Alex Dehnert <adehnert@mit.edu>, 12 years ago
Useful filter-modifying commands filterappend FILTER TEXT filterand FILTER TEXT filteror FILTER TEXT Append TEXT onto FILTER with appropriate ('', 'and', 'or') separators The admin message can be enabled or disabled by (un)setting showfilterchange.
  • Property mode set to 100644
File size: 9.0 KB
Line 
1use strict;
2use warnings;
3
4package BarnOwl;
5
6BEGIN {
7# bootstrap in C bindings and glue
8    *owl:: = \*BarnOwl::;
9    bootstrap BarnOwl 1.2;
10};
11
12use lib(get_data_dir() . "/lib");
13use lib(get_config_dir() . "/lib");
14
15use BarnOwl::Hook;
16use BarnOwl::Hooks;
17use BarnOwl::Message;
18use BarnOwl::Style;
19use BarnOwl::Timer;
20use BarnOwl::Editwin;
21
22=head1 NAME
23
24BarnOwl
25
26=head1 DESCRIPTION
27
28The BarnOwl module contains the core of BarnOwl's perl
29bindings. Source in this module is also run at startup to bootstrap
30barnowl by defining things like the default style.
31
32=for NOTE
33These following functions are defined in perlglue.xs. Keep the
34documentation here in sync with the user-visible commands defined
35there!
36
37=head2 command STRING
38
39Executes a BarnOwl command in the same manner as if the user had
40executed it at the BarnOwl command prompt. If the command returns a
41value, return it as a string, otherwise return undef.
42
43=head2 getcurmsg
44
45Returns the current message as a C<BarnOwl::Message> subclass, or
46undef if there is no message selected
47
48=head2 getnumcols
49
50Returns the width of the display window BarnOwl is currently using
51
52=head2 getidletime
53
54Returns the length of time since the user has pressed a key, in
55seconds.
56
57=head2 zephyr_getrealm
58
59Returns the zephyr realm barnowl is running in
60
61=head2 zephyr_getsender
62
63Returns the fully-qualified name of the zephyr sender barnowl is
64running as, e.g. C<nelhage@ATHENA.MIT.EDU>
65
66=head2 zephyr_zwrite COMMAND MESSAGE
67
68Sends a zephyr programmatically. C<COMMAND> should be a C<zwrite>
69command line, and C<MESSAGE> is the zephyr body to send.
70
71=head2 ztext_stylestrip STRING
72
73Strips zephyr formatting from a string and returns the result
74
75=head2 zephyr_getsubs
76
77Returns the list of subscription triples <class,instance,recipient>,
78separated by newlines.
79
80=head2 queue_message MESSAGE
81
82Enqueue a message in the BarnOwl message list, logging it and
83processing it appropriately. C<MESSAGE> should be an instance of
84BarnOwl::Message or a subclass.
85
86=head2 admin_message HEADER BODY
87
88Display a BarnOwl B<Admin> message, with the given header and body.
89
90=head2 start_question PROMPT CALLBACK
91
92Displays C<PROMPT> on the screen and lets the user enter a line of
93text, and calls C<CALLBACK>, which must be a perl subroutine
94reference, with the text the user entered
95
96=head2 start_password PROMPT CALLBACK
97
98Like C<start_question>, but echoes the user's input as C<*>s when they
99input.
100
101=head2 start_edit_win PROMPT CALLBACK
102
103Like C<start_question>, but displays C<PROMPT> on a line of its own
104and opens the editwin. If the user cancels the edit win, C<CALLBACK>
105is not invoked.
106
107=head2 get_data_dir
108
109Returns the BarnOwl system data directory, where system libraries and
110modules are stored
111
112=head2 get_config_dir
113
114Returns the BarnOwl user configuration directory, where user modules
115and configuration are stored (by default, C<$HOME/.owl>)
116
117=head2 popless_text TEXT
118
119Show a popup window containing the given C<TEXT>
120
121=head2 popless_ztext TEXT
122
123Show a popup window containing the provided zephyr-formatted C<TEXT>
124
125=head2 error STRING
126
127Reports an error and log it in `show errors'. Note that in any
128callback or hook called in perl code from BarnOwl, a C<die> will be
129caught and passed to C<error>.
130
131=head2 getnumcolors
132
133Returns the number of colors this BarnOwl is capable of displaying
134
135=head2 add_dispatch FD CALLBACK
136
137Adds a file descriptor to C<BarnOwl>'s internal C<select()>
138loop. C<CALLBACK> will be invoked whenever data is available to be
139read from C<FD>.
140
141=head2 remove_dispatch FD
142
143Remove a file descriptor previously registered via C<add_dispatch>
144
145=head2 create_style NAME OBJECT
146
147Creates a new barnowl style with the given NAME defined by the given
148object. The object must have a C<description> method which returns a
149string description of the style, and a and C<format_message> method
150which accepts a C<BarnOwl::Message> object and returns a string that
151is the result of formatting the message for display.
152
153=cut
154
155# perlconfig.c will set this to the value of the -c command-line
156# switch, if present.
157our $configfile;
158
159if(!$configfile && -f $ENV{HOME} . "/.barnowlconf") {
160    $configfile = $ENV{HOME} . "/.barnowlconf";
161}
162$configfile ||= $ENV{HOME}."/.owlconf";
163
164# populate global variable space for legacy owlconf files
165sub _receive_msg_legacy_wrap {
166    my ($m) = @_;
167    $m->legacy_populate_global();
168    return &BarnOwl::Hooks::_receive_msg($m);
169}
170
171=head2 AUTOLOAD
172
173BarnOwl.pm has a C<AUTOLOAD> method that translates unused names in
174the BarnOwl:: namespace to a call to BarnOwl::command() with that
175command. Underscores are also translated to C<->s, so you can do
176e.g. C<BarnOwl::start_command()> and it will be translated into
177C<start-command>.
178
179So, if you're looking for functionality that you can't find in the
180perl interface, check C<:show commands> or C<commands.c> in the
181BarnOwl source tree -- there's a good chance it exists as a BarnOwl
182command.
183
184=head3 BUGS
185
186There are horrible quoting issues here. The AUTOLOAD simple joins your
187commands with spaces and passes them unmodified to C<::command>
188
189=cut
190
191# make BarnOwl::<command>("foo") be aliases to BarnOwl::command("<command> foo");
192sub AUTOLOAD {
193    our $AUTOLOAD;
194    my $called = $AUTOLOAD;
195    $called =~ s/.*:://;
196    $called =~ s/_/-/g;
197    return &BarnOwl::command("$called ".join(" ",@_));
198}
199
200=head2 new_command NAME FUNC [{ARGS}]
201
202Add a new owl command. When owl executes the command NAME, FUNC will
203be called with the arguments passed to the command, with NAME as the
204first argument.
205
206ARGS should be a hashref containing any or all of C<summary>,
207C<usage>, or C<description> keys:
208
209=over 4
210
211=item summary
212
213A one-line summary of the purpose of the command
214
215=item usage
216
217A one-line usage synopsis, showing available options and syntax
218
219=item description
220
221A longer description of the syntax and semantics of the command,
222explaining usage and options
223
224=back
225
226=cut
227
228sub new_command {
229    my $name = shift;
230    my $func = shift;
231    my $args = shift || {};
232    my %args = (
233        summary     => "",
234        usage       => "",
235        description => "",
236        %{$args}
237    );
238
239    BarnOwl::Internal::new_command($name, $func, $args{summary}, $args{usage}, $args{description});
240}
241
242=head2 new_variable_int NAME [{ARGS}]
243
244=head2 new_variable_bool NAME [{ARGS}]
245
246=head2 new_variable_string NAME [{ARGS}]
247
248Add a new owl variable, either an int, a bool, or a string, with the
249specified name.
250
251ARGS can optionally contain the following keys:
252
253=over 4
254
255=item default
256
257The default and initial value for the variable
258
259=item summary
260
261A one-line summary of the variable's purpose
262
263=item description
264
265A longer description of the function of the variable
266
267=back
268
269=cut
270
271sub new_variable_int {
272    unshift @_, \&BarnOwl::Internal::new_variable_int, 0;
273    goto \&_new_variable;
274}
275
276sub new_variable_bool {
277    unshift @_, \&BarnOwl::Internal::new_variable_bool, 0;
278    goto \&_new_variable;
279}
280
281sub new_variable_string {
282    unshift @_, \&BarnOwl::Internal::new_variable_string, "";
283    goto \&_new_variable;
284}
285
286sub _new_variable {
287    my $func = shift;
288    my $default_default = shift;
289    my $name = shift;
290    my $args = shift || {};
291    my %args = (
292        summary     => "",
293        description => "",
294        default     => $default_default,
295        %{$args});
296    $func->($name, $args{default}, $args{summary}, $args{description});
297}
298
299=head2 quote STRING
300
301Return a version of STRING fully quoted to survive processing by
302BarnOwl's command parser.
303
304=cut
305
306sub quote {
307    my $str = shift;
308    return "''" if $str eq '';
309    if ($str !~ /['" ]/) {
310        return "$str";
311    }
312    if ($str !~ /'/) {
313        return "'$str'";
314    }
315    $str =~ s/"/"'"'"/g;
316    return '"' . $str . '"';
317}
318
319=head2 Modify filters by appending text
320
321=cut
322
323BarnOwl::new_command("filterappend",
324    sub { filter_append_helper('appending', '', @_); },
325    {
326        summary => "append '<text>' to filter",
327        usage => "filterappend <filter> <text>",
328    });
329
330BarnOwl::new_command("filterand",
331    sub { filter_append_helper('and-ing', 'and', @_); },
332    {
333        summary => "append 'and <text>' to filter",
334        usage => "filterand <filter> <text>",
335    });
336
337BarnOwl::new_command("filteror",
338    sub { filter_append_helper('or-ing', 'or', @_); },
339    {
340        summary => "append 'or <text>' to filter",
341        usage => "filteror <filter> <text>",
342    });
343
344=head3 filter_append_helper ACTION SEP FUNC FILTER APPEND_TEXT
345
346Helper to append to filters.
347
348=cut
349
350sub filter_append_helper
351{
352    my $action = shift;
353    my $sep = shift;
354    my $func = shift;
355    my $filter = shift;
356    my @append = @_;
357    my $oldfilter = BarnOwl::getfilter($filter);
358    chomp $oldfilter;
359    my $newfilter = join(' ', $oldfilter, $sep, @_);
360    my $msgtext = "To filter '$filter' $action\n'".join(' ', @append)."' to get\n'$newfilter'";
361    if (BarnOwl::getvar('showfilterchange') eq 'on') {
362        BarnOwl::admin_message("Filter", $msgtext);
363    }
364    BarnOwl::filter($filter, $newfilter);
365    return;
366}
367BarnOwl::new_variable_bool("showfilterchange",
368                           { default => 1,
369                             summary => 'Show modifications to filters by filterappend and friends.'});
370
3711;
Note: See TracBrowser for help on using the repository browser.