1 | ### The owlconf config file -*- perl -*- |
---|
2 | ### $Id$ |
---|
3 | ### |
---|
4 | ### !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! |
---|
5 | ### This is an example file intended to demonstrate how to use |
---|
6 | ### various features of owl. Some of the key bindings, in particular, |
---|
7 | ### are more for examples than things you may actually want to use. |
---|
8 | ### Make sure to read through it first and understand it before just using it. |
---|
9 | ### Don't blame me if anything in here ends up vaporizing your dog. |
---|
10 | ### !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! |
---|
11 | ### |
---|
12 | ### |
---|
13 | ### This file is interpreted by the perl interpreter. |
---|
14 | ### If you wish to execute an owl command use the |
---|
15 | ### function owl::command(). i.e. |
---|
16 | ### |
---|
17 | ### owl::command("set zsigproc /mit/kretch/bin/getzsig"); |
---|
18 | ### |
---|
19 | ### will set the owl variable zsigproc. Subroutines created with |
---|
20 | ### the names below will be executed at the specified times: |
---|
21 | ### |
---|
22 | ### subroutine name properties |
---|
23 | ### --------------- ---------- |
---|
24 | ### owl::startup() run when owl first starts |
---|
25 | ### owl::shutdown() run when owl exits |
---|
26 | ### owl::format_msg() formats messages that are passed to it |
---|
27 | ### owl::receive_msg() run when a message is received, and after |
---|
28 | ### it has been added to the message list |
---|
29 | ### |
---|
30 | ### The format_msg and receive_msg functions are passed owl::Message objects. |
---|
31 | ### The message attributes may be dereferenced with $m->attribute |
---|
32 | ### |
---|
33 | ### |
---|
34 | |
---|
35 | # tokens for sepbar are: |
---|
36 | # .username = ping |
---|
37 | # >username = login |
---|
38 | # <username = logout |
---|
39 | # :username = personal message |
---|
40 | # M = mail received |
---|
41 | my @sepbartokens = (); |
---|
42 | |
---|
43 | # Map for mail messages from msg id to pop msg id |
---|
44 | my %mail_id_map = (); |
---|
45 | |
---|
46 | # (originally from jdaniel) |
---|
47 | sub mail_add_message ($) { |
---|
48 | my ($m) = @_; |
---|
49 | my $from = `from -t`; |
---|
50 | # example value: |
---|
51 | # You have 188 messages (667593 bytes) on PO11.MIT.EDU. |
---|
52 | my ($msg_num) = $from =~ m/(\d+)/; |
---|
53 | $mail_id_map{$m->id} = $msg_num; |
---|
54 | } |
---|
55 | |
---|
56 | |
---|
57 | sub mail_pop_curmsg () { |
---|
58 | my $m = owl::getcurmsg(); |
---|
59 | if (!$m->is_mail || !defined $mail_id_map{$m->id}) { |
---|
60 | &owl::command("pop-message"); |
---|
61 | } else { |
---|
62 | &owl::command(sprintf 'pexec pop -request c -request "retr %d" -request q', |
---|
63 | $mail_id_map{$m->id}); |
---|
64 | } |
---|
65 | } |
---|
66 | |
---|
67 | sub zlocatesender { |
---|
68 | my $m = owl::getcurmsg(); |
---|
69 | if ($m->{"type"} eq "zephyr") { |
---|
70 | my $sender = $m->{"sender"}; |
---|
71 | owl::command("zlocate $sender"); |
---|
72 | } |
---|
73 | } |
---|
74 | |
---|
75 | # adds a sepbartoken and also updates the appendtosepbar variable |
---|
76 | sub sepbartokens_add { |
---|
77 | my ($token) = @_; |
---|
78 | $token =~ s/"//g; # " |
---|
79 | unshift @sepbartokens, $token; |
---|
80 | pop @sepbartokens if (@sepbartokens > 80); |
---|
81 | sepbartokens_set(); |
---|
82 | } |
---|
83 | |
---|
84 | # trims a sepbartoken from the list also updates the appendtosepbar variable |
---|
85 | sub sepbartokens_trim { |
---|
86 | my ($token) = @_; |
---|
87 | @sepbartokens = map { if ($_ ne $token) { $_; } else { (); } } @sepbartokens; |
---|
88 | sepbartokens_set(); |
---|
89 | } |
---|
90 | |
---|
91 | my $loopctr=0; |
---|
92 | |
---|
93 | # trims a sepbartoken from the list also updates the appendtosepbar variable |
---|
94 | sub sepbartokens_set { |
---|
95 | owl::command(sprintf "set -q appendtosepbar \"%s %s %s\"", (scalar localtime), (join " ", @sepbartokens)); |
---|
96 | } |
---|
97 | |
---|
98 | my $restoreview = undef; |
---|
99 | sub swapview { |
---|
100 | my $curview = owl::command("getview"); |
---|
101 | if ($restoreview) { |
---|
102 | owl::command("view $restoreview"); |
---|
103 | $restoreview = undef; |
---|
104 | } else { |
---|
105 | $restoreview = $curview; |
---|
106 | owl::command("smartnarrow"); |
---|
107 | } |
---|
108 | } |
---|
109 | |
---|
110 | my $lastcolored = undef; |
---|
111 | sub colorthread { |
---|
112 | if ($lastcolored) { |
---|
113 | owl::command("filter $lastcolored -c default"); |
---|
114 | } |
---|
115 | my $smartfilt = owl::command("smartfilter"); |
---|
116 | if (!$smartfilt or $smartfilt eq $lastcolored) { |
---|
117 | owl::command("filter $lastcolored -c default"); |
---|
118 | $lastcolored = undef; |
---|
119 | } else { |
---|
120 | owl::command("filter $smartfilt -c green"); |
---|
121 | $lastcolored = $smartfilt; |
---|
122 | } |
---|
123 | } |
---|
124 | |
---|
125 | # Load in things which don't belong in an owlconf |
---|
126 | # that people might use as an example... |
---|
127 | sub personal_startup { |
---|
128 | my $personalconf = $ENV{"HOME"}."/.owl/personalconf"; |
---|
129 | if (-f $personalconf) { |
---|
130 | my $b = ""; |
---|
131 | open INB, $personalconf; |
---|
132 | for (<INB>) { $b .= $_; } |
---|
133 | close INB; |
---|
134 | eval $b; |
---|
135 | } |
---|
136 | } |
---|
137 | |
---|
138 | sub owl::startup { |
---|
139 | owl::command("set -q logging on"); |
---|
140 | owl::command("set -q logpath ~/.zlog/owl/personal"); |
---|
141 | owl::command("set -q classlogpath ~/.zlog/owl/class"); |
---|
142 | owl::command("set -q logging on"); |
---|
143 | owl::command("set -q startuplogin off"); |
---|
144 | owl::command("set -q shutdownlogout off"); |
---|
145 | #owl::command("set personalbell on"); |
---|
146 | owl::command("set -q _burningears on"); |
---|
147 | owl::command("set -q rxping on"); |
---|
148 | owl::command("set -q typewinsize 5"); |
---|
149 | owl::command("filter me recipient %me% or ( sender %me% and class message and instance personal ) or class mail or type aim"); |
---|
150 | owl::command("filter owl instance ^owl.*"); |
---|
151 | |
---|
152 | owl::command(q(alias finger pperl $x=owl::getcurmsg()->hostname; `finger \@$x`;)); |
---|
153 | owl::command("bindkey recv f command finger"); |
---|
154 | |
---|
155 | owl::command("alias z zwrite"); |
---|
156 | owl::command("alias zw zwrite"); |
---|
157 | owl::command("alias v view"); |
---|
158 | |
---|
159 | owl::command("alias popmail perl mail_pop_curmsg();"); |
---|
160 | |
---|
161 | # toggle between a view and a smartnarrow with TAB |
---|
162 | owl::command("alias swapview perl swapview();"); |
---|
163 | owl::command("bindkey recv C-i command swapview"); |
---|
164 | |
---|
165 | # color the current thread |
---|
166 | owl::command("alias colorthread perl colorthread();"); |
---|
167 | owl::command("bindkey recv M-c command colorthread"); |
---|
168 | |
---|
169 | # zlocate current sender |
---|
170 | owl::command("bindkey recv L command perl zlocatesender();"); |
---|
171 | |
---|
172 | # Declare styles |
---|
173 | &owl::command("style vt perl format_msg_vt"); |
---|
174 | &owl::command("style brief perl format_msg_brief"); |
---|
175 | &owl::command("style custom perl format_msg_custom"); |
---|
176 | &owl::command("style debug perl format_msg_debug"); |
---|
177 | &owl::command("set -q default_style custom"); |
---|
178 | |
---|
179 | # Change to different view styles |
---|
180 | owl::command("bindkey recv \"C-s v\" command view -s vt"); |
---|
181 | owl::command("bindkey recv \"C-s c\" command view -s custom"); |
---|
182 | owl::command("bindkey recv \"C-s b\" command view -s brief"); |
---|
183 | owl::command("bindkey recv \"C-s d\" command view -s debug"); |
---|
184 | owl::command("bindkey recv \"C-s o\" command view -s standard"); |
---|
185 | |
---|
186 | # For fast-reading of zephyrs |
---|
187 | owl::command("bindkey recv M-k command ( smartnarrow ; delete view )"); |
---|
188 | owl::command("bindkey recv M-l command ( expunge ; view all )"); |
---|
189 | owl::command("bindkey recv M-K command ( smartnarrow ; delete view ; expunge ; view all )"); |
---|
190 | |
---|
191 | # Support for scroll mice |
---|
192 | &owl::command("bindkey recv \"M-[ A\" command recv:prev"); |
---|
193 | &owl::command("bindkey recv \"M-[ B\" command recv:next"); |
---|
194 | |
---|
195 | # This overrides the default "M" keybinding |
---|
196 | owl::command("bindkey recv M command popmail"); |
---|
197 | |
---|
198 | sepbartokens_add("..."); |
---|
199 | |
---|
200 | personal_startup(); |
---|
201 | } |
---|
202 | |
---|
203 | sub owl::shutdown { |
---|
204 | # not doing anything at the moment... |
---|
205 | } |
---|
206 | |
---|
207 | |
---|
208 | # run when a message is received, and after |
---|
209 | # it has been added to the message list. |
---|
210 | sub owl::receive_msg { |
---|
211 | my ($m) = @_; |
---|
212 | my ($out, $tmp); |
---|
213 | |
---|
214 | if ($m->is_admin && !$m->is_outgoing) { |
---|
215 | $m->delete(); |
---|
216 | return 1; |
---|
217 | } |
---|
218 | |
---|
219 | return 0 if (!$m->is_zephyr && !$m->is_aim); |
---|
220 | |
---|
221 | my $sender = $m->pretty_sender; |
---|
222 | |
---|
223 | if ($m->is_ping) { |
---|
224 | sepbartokens_add(".$sender"); |
---|
225 | $m->delete(); |
---|
226 | } elsif ($m->is_loginout) { |
---|
227 | $m->delete(); |
---|
228 | if ($m->is_login) { |
---|
229 | sepbartokens_add(">$sender"); |
---|
230 | sepbartokens_trim("<$sender"); |
---|
231 | } elsif ($m->is_logout) { |
---|
232 | sepbartokens_add("<$sender"); |
---|
233 | sepbartokens_trim(">$sender"); |
---|
234 | } |
---|
235 | } elsif ($m->is_mail) { |
---|
236 | mail_add_message($m); |
---|
237 | $m->delete(); |
---|
238 | sepbartokens_add("M"); |
---|
239 | } |
---|
240 | |
---|
241 | if ($m->is_personal) { |
---|
242 | sepbartokens_trim(".$sender"); |
---|
243 | sepbartokens_add(":$sender"); |
---|
244 | } |
---|
245 | |
---|
246 | return 1; |
---|
247 | } |
---|
248 | |
---|
249 | sub indent4 { |
---|
250 | my ($b) = @_; |
---|
251 | $b=~s/^/ /g; |
---|
252 | $b=~s/\n/\n /g; |
---|
253 | return $b; |
---|
254 | } |
---|
255 | |
---|
256 | # run to format a message |
---|
257 | sub format_msg_custom { |
---|
258 | my ($m) = @_; |
---|
259 | my ($out, $tmp); |
---|
260 | |
---|
261 | if ($m->is_admin) { |
---|
262 | $out = "\@bold([owl admin]) ".$m->header."\n"; |
---|
263 | $out.=indent4($m->body); |
---|
264 | return $out."\n"; |
---|
265 | } |
---|
266 | |
---|
267 | my $sender=$m->pretty_sender; |
---|
268 | |
---|
269 | if (($m->is_aim or $m->is_zephyr) && $m->is_loginout) { |
---|
270 | |
---|
271 | if ($m->is_login) { |
---|
272 | $out="\@bold(LOGIN)"; |
---|
273 | } elsif ($m->is_logout) { |
---|
274 | $out="\@bold(LOGOUT)"; |
---|
275 | } else { |
---|
276 | $out="\@bold(UNKNOWN)"; |
---|
277 | } |
---|
278 | $out.=" for \@bold($sender) on ".$m->type; |
---|
279 | if ($m->is_zephyr) { |
---|
280 | $out.=" at ".($m->login_host)." on ".($m->login_tty); |
---|
281 | } |
---|
282 | return("$out\n"); |
---|
283 | } |
---|
284 | |
---|
285 | if (!$m->is_zephyr && !$m->is_aim) { |
---|
286 | return "Unknown message type: ".$m->type."\n"; |
---|
287 | } |
---|
288 | |
---|
289 | if ($m->is_outgoing) { |
---|
290 | my $target = $m->recipient; |
---|
291 | if ($m->is_zephyr) { |
---|
292 | $target = $m->zwriteline; |
---|
293 | $target =~ s/^zwrite //; |
---|
294 | } |
---|
295 | $out = sprintf "\@bold([outgoing %s to %s]) / %s\n", $m->type, $target, $m->time; |
---|
296 | $out.=indent4($m->body); |
---|
297 | return "$out\n"; |
---|
298 | } |
---|
299 | |
---|
300 | if ($m->is_zephyr && $m->is_ping) { |
---|
301 | return("\@bold(PING) from \@bold($sender)\n"); |
---|
302 | } elsif ($m->is_zephyr && $m->is_mail) { |
---|
303 | $out = "\@bold(MAIL) "; |
---|
304 | if ($m->body =~ /^From:\s+(.+)\s*$/m) { $out .= "From $1 "; } |
---|
305 | if ($m->body =~ /^To:\s+(.+)\s*$/m) { $out .= "To $1 "; } |
---|
306 | if ($m->body =~ /^Subject:\s+(.+)\s*$/m) { $out .= "Subject $1 "; } |
---|
307 | return("$out\n"); |
---|
308 | } |
---|
309 | |
---|
310 | if ($m->is_zephyr) { |
---|
311 | $out = sprintf "[mit,%s,%s] / %s / %s", lc($m->class), |
---|
312 | lc($m->instance), $m->time, lc($m->host); |
---|
313 | if ($m->opcode ne "") {$out.=" op:".$m->opcode;} |
---|
314 | $out.="\n"; |
---|
315 | $out.= " \@bold($sender)> "; |
---|
316 | if ($m->zsig ne "") { |
---|
317 | my $zsig = $m->zsig; |
---|
318 | $zsig =~ s/(\n.*)+$/ [...]/; |
---|
319 | if (length($zsig)+5+length($sender) > 70) { |
---|
320 | $out.="# ..."; |
---|
321 | } else { |
---|
322 | $out.="# $zsig"; |
---|
323 | } |
---|
324 | } |
---|
325 | $out.="\n"; |
---|
326 | } else { |
---|
327 | $out = sprintf "[%s] / %s\n", lc($m->type), $m->time; |
---|
328 | $out.= " \@bold($sender)> "; |
---|
329 | $out.="\n"; |
---|
330 | } |
---|
331 | |
---|
332 | $out.=indent4($m->body); |
---|
333 | |
---|
334 | # make personal messages bold |
---|
335 | if ($m->is_personal) { |
---|
336 | $out="\@bold{".$out."}"; |
---|
337 | } |
---|
338 | |
---|
339 | return($out."\n"); |
---|
340 | } |
---|
341 | |
---|
342 | sub format_msg_debug { |
---|
343 | my ($m) = @_; |
---|
344 | return "\@bold(-------------MESSAGE-------------)\n".($m->serialize).".\n"; |
---|
345 | } |
---|
346 | |
---|
347 | sub format_msg_brief { |
---|
348 | my ($m) = @_; |
---|
349 | my $out = format_msg_vt($m); |
---|
350 | $out =~ s/\n/ /g; |
---|
351 | $out =~ s/ / /g; |
---|
352 | return($out."\n"); |
---|
353 | } |
---|
354 | |
---|
355 | |
---|
356 | sub format_msg_vt { |
---|
357 | my ($m) = @_; |
---|
358 | my ($out, $tmp); |
---|
359 | |
---|
360 | if ($m->is_admin) { |
---|
361 | $out = sprintf "%-29s \@i(%s)", "\@bold(OWL ADMIN)", $m->header; |
---|
362 | $tmp=$m->body; |
---|
363 | $tmp=~s/^/ /g; |
---|
364 | $tmp=~s/\n/\n /g; |
---|
365 | $out.="\n".$tmp; |
---|
366 | return $out; |
---|
367 | } |
---|
368 | |
---|
369 | my $sender=$m->pretty_sender; |
---|
370 | |
---|
371 | if ($m->is_outgoing) { |
---|
372 | my $target = $m->recipient; |
---|
373 | if ($m->is_zephyr) { |
---|
374 | $target = $m->zwriteline; |
---|
375 | $target =~ s/^zwrite //; |
---|
376 | } |
---|
377 | $out = sprintf "%-15s %-13s", "\@bold(OUTGOING)", "to $target via ".$m->type.": "; |
---|
378 | my $pagewidth = owl::getnumcols()-6; |
---|
379 | $out .= fill_text($m->body, $pagewidth, 22, 1); |
---|
380 | return $out; |
---|
381 | } |
---|
382 | |
---|
383 | if (!$m->is_zephyr && !$m->is_aim) { |
---|
384 | return "Unknown message type: ".$m->type."\n"; |
---|
385 | } |
---|
386 | |
---|
387 | if ($m->is_zephyr && $m->is_ping) { |
---|
388 | return (sprintf "%-15s %-13s\n", "\@bold(PING)", $sender); |
---|
389 | } elsif ($m->is_loginout) { |
---|
390 | my $state; |
---|
391 | if ($m->is_login) { |
---|
392 | $state="\@bold(LOGIN)"; |
---|
393 | } elsif ($m->is_logout) { |
---|
394 | $state="\@bold(LOGOUT)"; |
---|
395 | } else { |
---|
396 | $state="\@bold(UNKNOWN)"; |
---|
397 | } |
---|
398 | my $out = sprintf "%-15s %-13s ", $state, $sender; |
---|
399 | if ($m->is_zephyr) { |
---|
400 | $out .= sprintf "via %s on %s at %s", $m->type, $m->login_host, $m->login_tty; |
---|
401 | } else { |
---|
402 | $out .= sprintf "via %s", $m->type; |
---|
403 | } |
---|
404 | return "$out\n"; |
---|
405 | |
---|
406 | } elsif ($m->is_zephyr && $m->is_mail) { |
---|
407 | my $body = $m->body; |
---|
408 | $out = sprintf "%-15s %-13s ", "\@bold(MAIL)", ""; |
---|
409 | if ($body =~ /^From:\s+(.+)\s*$/m) { $out .= "From $1 "; } |
---|
410 | if ($body =~ /^To:\s+(.+)\s*$/m) { $out .= "To $1 "; } |
---|
411 | if ($body =~ /^Subject:\s+(.+)\s*$/m) { $out .= "Subject $1 "; } |
---|
412 | return($out."\n"); |
---|
413 | } |
---|
414 | |
---|
415 | my $channel = ""; |
---|
416 | my $body = $m->body; |
---|
417 | |
---|
418 | if ($m->is_zephyr) { |
---|
419 | my $inst = $m->instance; |
---|
420 | $channel = $m->class; |
---|
421 | if (lc($m->class) ne "message" and lc($m->instance) eq "personal") { |
---|
422 | $inst = ""; |
---|
423 | } |
---|
424 | $channel .= "[".$inst."]"; |
---|
425 | $channel = substr($channel,0,13); |
---|
426 | } else { |
---|
427 | $channel = "[".$m->type."]"; |
---|
428 | } |
---|
429 | |
---|
430 | $header = sprintf "%-8s %-13s ", lc($sender), lc($channel); |
---|
431 | |
---|
432 | if ($body =~ /=/) { |
---|
433 | # indent it |
---|
434 | $out.=$header."\n".indent4($body); |
---|
435 | } else { |
---|
436 | # fill it |
---|
437 | my $pagewidth = owl::getnumcols()-6; |
---|
438 | $out .= $header; |
---|
439 | $out .= fill_text($body, $pagewidth, 22, 1); |
---|
440 | } |
---|
441 | |
---|
442 | # note: no zsig added in this version |
---|
443 | |
---|
444 | # make personal messages bold |
---|
445 | if ($m->is_personal) { |
---|
446 | $out="\@bold{".$out."}"; |
---|
447 | } |
---|
448 | return($out); |
---|
449 | } |
---|
450 | |
---|
451 | sub fill_text { |
---|
452 | my ($in, $width, $indent, $unindent_first) = @_; |
---|
453 | $indent = 0 if (@_ < 3); |
---|
454 | my $unindent = $indent if ($unindent_first); |
---|
455 | my @words = split " ", $in; |
---|
456 | my $out = ""; |
---|
457 | my $outline = ""; |
---|
458 | if (!$unindent_first) { |
---|
459 | my $outline = " "x$indent; |
---|
460 | } |
---|
461 | for my $w (@words) { |
---|
462 | if (($outline ne "") |
---|
463 | && (length($outline)+length($w) > $width-$unindent)) { |
---|
464 | $out .= $outline."\n"; |
---|
465 | $outline = " "x$indent; |
---|
466 | $unindent = 0; |
---|
467 | } |
---|
468 | if ($outline =~ /.*\.$/) { |
---|
469 | $outline .= " "; |
---|
470 | } elsif ($outline ne "") { |
---|
471 | $outline .= " "; |
---|
472 | } |
---|
473 | $outline .= $w; |
---|
474 | } |
---|
475 | $out .= $outline . "\n"; |
---|
476 | } |
---|