source: commands.c @ 486688f

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 486688f was 486688f, checked in by Erik Nygren <nygren@mit.edu>, 21 years ago
Will attempt to keep the current message as close as possible to the previous current message after an expunge. "set <variable>" and "unset <variable>" now work for boolean variables. (although I'm not totally happy with how I implemented it.)
  • Property mode set to 100644
File size: 53.3 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include "owl.h"
6
7static const char fileIdent[] = "$Id$";
8
9/* fn is "char *foo(int argc, char **argv, char *buff)" */
10#define OWLCMD_ARGS(name, fn, ctx, summary, usage, description) \
11        { name, summary, usage, description, ctx, \
12          NULL, fn, NULL, NULL, NULL, NULL, NULL }
13
14/* fn is "void foo(void)" */
15#define OWLCMD_VOID(name, fn, ctx, summary, usage, description) \
16        { name, summary, usage, description, ctx, \
17          NULL, NULL, fn, NULL, NULL, NULL, NULL }
18
19/* fn is "void foo(int)" */
20#define OWLCMD_INT(name, fn, ctx, summary, usage, description) \
21        { name, summary, usage, description, ctx, \
22          NULL, NULL, NULL, fn, NULL, NULL, NULL }
23
24#define OWLCMD_ALIAS(name, actualname) \
25        { name, OWL_CMD_ALIAS_SUMMARY_PREFIX actualname, "", "", OWL_CTX_ANY, \
26          actualname, NULL, NULL, NULL, NULL, NULL, NULL }
27
28/* fn is "char *foo(void *ctx, int argc, char **argv, char *buff)" */
29#define OWLCMD_ARGS_CTX(name, fn, ctx, summary, usage, description) \
30        { name, summary, usage, description, ctx, \
31          NULL, NULL, NULL, NULL, ((char*(*)(void*,int,char**,char*))fn), NULL, NULL }
32
33/* fn is "void foo(void)" */
34#define OWLCMD_VOID_CTX(name, fn, ctx, summary, usage, description) \
35        { name, summary, usage, description, ctx, \
36          NULL, NULL, NULL, NULL, NULL, ((void(*)(void*))(fn)), NULL }
37
38/* fn is "void foo(int)" */
39#define OWLCMD_INT_CTX(name, fn, ctx, summary, usage, description) \
40        { name, summary, usage, description, ctx, \
41          NULL, NULL, NULL, NULL, NULL, NULL, ((void(*)(void*,int))fn) }
42
43
44owl_cmd commands_to_init[]
45  = {
46  OWLCMD_ARGS("zlog", owl_command_zlog, OWL_CTX_ANY,
47              "send a login or logout notification",
48              "zlog in [tty]\nzlog out",
49              "zlog in will send a login notification, zlog out will send a\n"
50              "logout notification.  By default a login notification is sent\n"
51              "when owl is started and a logout notification is sent when owl\n"
52              "is exited.  This behavior can be changed with the 'startuplogin'\n"
53              "and 'shudownlogout' variables.  If a tty is specified for zlog in\n"
54              "then the owl variable 'tty' will be set to that string, causing\n"
55              "it to be used as the zephyr location tty.\n"),
56
57  OWLCMD_VOID("quit", owl_command_quit, OWL_CTX_ANY,
58              "exit owl",
59              "",
60              "Exit owl and run any shutdown activities."),
61  OWLCMD_ALIAS("exit", "quit"),
62  OWLCMD_ALIAS("q",    "quit"),
63 
64  OWLCMD_ARGS("start-command", owl_command_start_command, OWL_CTX_INTERACTIVE,
65              "prompts the user to enter a command",
66              "start-command [initial-value]",
67              "Initializes the command field to initial-value."),
68
69  OWLCMD_ARGS("alias", owl_command_alias, OWL_CTX_ANY,
70              "creates a command alias",
71              "alias <new_command> <old_command>",
72              "Creates a command alias from new_command to old_command.\n"
73              "Any arguments passed to <new_command> will be appended to\n"
74              "<old_command> before it is executed.\n"),
75
76  OWLCMD_ARGS("bindkey", owl_command_bindkey, OWL_CTX_ANY,
77              "creates a binding in a keymap",
78              "bindkey <keymap> <keyseq> command <command>",
79              "Binds a key sequence to a command within a keymap.\n"
80              "Use 'show keymaps' to see the existing keymaps.\n"
81              "Key sequences may be things like M-C-t or NPAGE.\n"),
82
83  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
84              "send a zephyr",
85              "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
86              "Zwrite send a zephyr to the one or more users specified.\n\n"
87              "The following options are available:\n\n"
88              "-m    Specifies a message to send without prompting.\n"
89              "      Note that this does not yet log an outgoing message.\n"
90              "      This must be the last argument.\n\n"
91              "-n    Do not send a ping message.\n\n"
92              "-C    If the message is sent to more than one user include a\n"
93              "      \"cc:\" line in the text\n\n"
94              "-c class\n"
95              "      Send to the specified zephyr class\n\n"
96              "-i instance\n"
97              "      Send to the specified zephyr instance\n\n"
98              "-r realm\n"
99              "      Send to a foreign realm\n"
100              "-O opcode\n"
101              "      Send to the specified opcode\n"),
102 
103  OWLCMD_ARGS("reply", owl_command_reply,  OWL_CTX_INTERACTIVE,
104              "reply to the current message",
105              "reply [-e] [ sender | all | zaway ]",
106              "If -e is specified, the zwrite command line is presented to\n"
107              "allow editing.\n\n"
108              "If 'sender' is specified, reply to the sender.\n\n"
109              "If 'all' or no args are specified, reply publically to the\n"
110              "same class/instance for non-personal messages and to the\n"
111              "sender for personal messages.\n\n"
112              "If 'zaway' is specified, replies with a zaway message.\n\n"),
113
114  OWLCMD_ARGS("set", owl_command_set, OWL_CTX_ANY,
115              "set a variable value",
116              "set [-q] <variable> [<value>]\n"
117              "set",
118              "Set the named variable to the specified value.  If no\n"
119              "arguments are used print the value of all variables.\n"
120              "If value is unspecified and the variable is a boolean, will set it to 'on'.\n"
121              "If -q is specified, is silent and doesn't print a message.\n"),
122
123  OWLCMD_ARGS("unset", owl_command_unset, OWL_CTX_ANY,
124              "unset a boolean variable value",
125              "set [-q] <variable>\n"
126              "set",
127              "Set the named boolean variable to off.\n"
128              "If -q is specified, is silent and doesn't print a message.\n"),
129
130  OWLCMD_ARGS("print", owl_command_print, OWL_CTX_ANY,
131              "print a variable value",
132              "print <variable>\n"
133              "print",
134              "Print the value of the named variable.  If no arugments\n"
135              "are used print the value of all variables.\n"),
136
137  OWLCMD_VOID("version", owl_command_version, OWL_CTX_ANY,
138              "print the version of the running owl", "", ""),
139
140  OWLCMD_ARGS("subscribe", owl_command_subscribe, OWL_CTX_ANY,
141              "subscribe to a zephyr class, instance, recipient",
142              "subscribe [-t] <class> <instance> [recipient]",
143              "Subscribe the specified class and instance.  If the recipient\n"
144              "is not listed on the command line it defaults\n"
145              "to * (the wildcard recipient).  If the -t option is present\n"
146              "the subscription will only be temporary, i.e., it will not\n"
147              "be written to the subscription file and will therefore not\n"
148              "be present the next time owl is started.\n"),
149  OWLCMD_ALIAS("sub", "subscribe"),
150
151  OWLCMD_ARGS("unsubscribe", owl_command_unsubscribe, OWL_CTX_ANY,
152              "unsubscribe from a zephyr class, instance, recipient",
153              "unsubscribe [-t] <class> <instance> [recipient]",
154              "Unsubscribe from the specified class and instance.  If the\n"
155              "recipient is not listed on the command line it defaults\n"
156              "to * (the wildcard recipient).  If the -t option is present\n"
157              "the unsubscription will only be temporary, i.e., it will not\n"
158              "be updated in the subscription file and will therefore not\n"
159              "be in effect the next time owl is started.\n"),
160  OWLCMD_ALIAS("unsub", "unsubscribe"),
161
162  OWLCMD_VOID("unsuball", owl_command_unsuball, OWL_CTX_ANY,
163              "unsubscribe from all zephyrs", "", ""),
164 
165  OWLCMD_VOID("getsubs", owl_command_getsubs, OWL_CTX_ANY,
166              "print all current subscriptions",
167              "getsubs",
168              "getsubs retrieves the current subscriptions from the server\n"
169              "and displays them.\n"),
170
171  OWLCMD_ARGS("smartzpunt", owl_command_smartzpunt, OWL_CTX_INTERACTIVE,
172              "creates a zpunt based on the current message",
173              "smartzpunt [-i | --instance]",
174              "Starts a zpunt command based on the current message's class\n"
175              "(and instance if -i is specified).\n"),
176
177  OWLCMD_ARGS("zpunt", owl_command_zpunt, OWL_CTX_ANY,
178              "suppress a given zephyr triplet",
179              "zpunt <class> <instance> [recipient]\n"
180              "zpunt <instance>",
181              "The zpunt command will supress message to the specified\n"
182              "zephyr triplet.  In the second usage messages as supressed\n"
183              "for class MESSAGE and the named instance.\n\n"
184              "SEE ALSO:  zunpunt, show zpunts\n"),
185
186  OWLCMD_ARGS("zunpunt", owl_command_zunpunt, OWL_CTX_ANY,
187              "undo a previous zpunt",
188              "zunpunt <class> <instance> [recipient]\n"
189              "zunpunt <instance>",
190              "The zunpunt command will allow messages that were previosly\n"
191              "suppressed to be received again.\n\n"
192              "SEE ALSO:  zpunt, show zpunts\n"),
193
194  OWLCMD_VOID("info", owl_command_info, OWL_CTX_INTERACTIVE,
195              "display detailed information about the current message",
196              "", ""),
197 
198  OWLCMD_ARGS("help", owl_command_help, OWL_CTX_INTERACTIVE,
199              "display help on using owl",
200              "help [command]", ""),
201
202  OWLCMD_ARGS("zlist", owl_command_zlist, OWL_CTX_INTERACTIVE,
203              "List users logged in",
204              "znol [-f file]",
205              "Print a znol-style listing of users logged in"),
206 
207  OWLCMD_VOID("recv:shiftleft", owl_command_shift_left, OWL_CTX_INTERACTIVE,
208              "scrolls receive window to the left", "", ""),
209
210  OWLCMD_VOID("recv:shiftright", owl_command_shift_right, OWL_CTX_INTERACTIVE,
211              "scrolls receive window to the left", "", ""),
212
213  OWLCMD_VOID("recv:pagedown", owl_function_mainwin_pagedown, 
214              OWL_CTX_INTERACTIVE,
215              "scrolls down by a page", "", ""),
216
217  OWLCMD_VOID("recv:pageup", owl_function_mainwin_pageup, OWL_CTX_INTERACTIVE,
218              "scrolls up by a page", "", ""),
219
220  OWLCMD_INT ("recv:scroll", owl_function_page_curmsg, OWL_CTX_INTERACTIVE,
221              "scrolls current message up or down", 
222              "recv:scroll <numlines>", 
223              "Scrolls the current message up or down by <numlines>.\n"
224              "Scrolls up if <numlines> is negative, else scrolls down.\n"),
225
226  OWLCMD_ARGS("next", owl_command_next, OWL_CTX_INTERACTIVE,
227              "move the pointer to the next message",
228              "recv:next [ --filter <name> ] [ --skip-deleted ] [ --last-if-none ]\n"
229              "          [ --smart-filter | --smart-filter-instance ]",
230              "Moves the pointer to the next message in the current view.\n"
231              "If --filter is specified, will only consider messages in\n"
232              "the filter <name>.\n"
233              "If --smart-filter or --smart-filter-instance is specified,\n"
234              "goes to the next message that is similar to the current message.\n"
235              "If --skip-deleted is specified, deleted messages will\n"
236              "be skipped.\n"
237              "If --last-if-none is specified, will stop at last message\n"
238              "in the view if no other suitable messages are found.\n"),
239  OWLCMD_ALIAS("recv:next", "next"),
240
241  OWLCMD_ARGS("prev", owl_command_prev, OWL_CTX_INTERACTIVE,
242              "move the pointer to the previous message",
243              "recv:prev [ --filter <name> ] [ --skip-deleted ] [ --first-if-none ]\n"
244              "          [ --smart-filter | --smart-filter-instance ]",
245              "Moves the pointer to the next message in the current view.\n"
246              "If --filter is specified, will only consider messages in\n"
247              "the filter <name>.\n"
248              "If --smart-filter or --smart-filter-instance is specified,\n"
249              "goes to the previous message that is similar to the current message.\n"
250              "If --skip-deleted is specified, deleted messages will\n"
251              "be skipped.\n"
252              "If --first-if-none is specified, will stop at first message\n"
253              "in the view if no other suitable messages are found.\n"),
254  OWLCMD_ALIAS("recv:prev", "prev"),
255
256  OWLCMD_ALIAS("recv:next-notdel", "recv:next --skip-deleted --last-if-none"),
257  OWLCMD_ALIAS("next-notdel",      "recv:next --skip-deleted --last-if-none"),
258
259  OWLCMD_ALIAS("recv:prev-notdel", "recv:prev --skip-deleted --first-if-none"),
260  OWLCMD_ALIAS("prev-notdel",      "recv:prev --skip-deleted --first-if-none"),
261
262  OWLCMD_ALIAS("recv:next-personal", "recv:next --filter personal"),
263
264  OWLCMD_ALIAS("recv:prev-personal", "recv:prev --filter personal"),
265
266  OWLCMD_VOID("first", owl_command_first, OWL_CTX_INTERACTIVE,
267              "move the pointer to the first message", "", ""),
268  OWLCMD_ALIAS("recv:first", "first"),
269
270  OWLCMD_VOID("last", owl_command_last, OWL_CTX_INTERACTIVE,
271              "move the pointer to the last message", "", 
272              "Moves the pointer to the last message in the view.\n"
273              "If we are already at the last message in the view,\n"
274              "blanks the screen and moves just past the end of the view\n"
275              "so that new messages will appear starting at the top\n"
276              "of the screen.\n"),
277  OWLCMD_ALIAS("recv:last", "last"),
278
279  OWLCMD_VOID("expunge", owl_command_expunge, OWL_CTX_INTERACTIVE,
280              "remove all messages marked for deletion", "", ""),
281
282  OWLCMD_VOID("resize", owl_command_resize, OWL_CTX_ANY,
283              "resize the window to the current screen size", "", ""),
284
285  OWLCMD_VOID("redisplay", owl_command_redisplay, OWL_CTX_ANY,
286              "redraw the entire window", "", ""),
287
288  OWLCMD_VOID("suspend", owl_command_suspend, OWL_CTX_ANY,
289              "suspend owl", "", ""),
290
291  OWLCMD_ARGS("echo", owl_command_echo, OWL_CTX_ANY,
292              "pops up a message in popup window",
293              "echo [args .. ]\n\n", ""),
294
295  OWLCMD_ARGS("exec", owl_command_exec, OWL_CTX_ANY,
296              "run a command from the shell",
297              "exec [args .. ]", ""),
298
299  OWLCMD_ARGS("aexec", owl_command_aexec, OWL_CTX_INTERACTIVE,
300              "run a command from the shell and display in an admin message",
301              "aexec [args .. ]", ""),
302
303  OWLCMD_ARGS("pexec", owl_command_pexec, OWL_CTX_INTERACTIVE,
304              "run a command from the shell and display in a popup window",
305              "pexec [args .. ]", ""),
306
307  OWLCMD_ARGS("perl", owl_command_perl, OWL_CTX_ANY,
308              "run a perl expression",
309              "perl [args .. ]", ""),
310
311  OWLCMD_ARGS("aperl", owl_command_aperl, OWL_CTX_INTERACTIVE,
312              "run a perl expression and display in an admin message",
313              "aperl [args .. ]", ""),
314
315  OWLCMD_ARGS("pperl", owl_command_pperl, OWL_CTX_INTERACTIVE,
316              "run a perl expression and display in a popup window",
317              "pperl [args .. ]", ""),
318
319  OWLCMD_ARGS("multi", owl_command_multi, OWL_CTX_ANY,
320              "runs multiple ;-separated commands",
321              "multi <command1> ( ; <command2> )*\n",
322              "Runs multiple semicolon-separated commands in order.\n"
323              "Note quoting isn't supported here yet.\n"
324              "If you want to do something fancy, use perl.\n"),
325
326  OWLCMD_ARGS("(", owl_command_multi, OWL_CTX_ANY,
327              "runs multiple ;-separated commands",
328              "'(' <command1> ( ; <command2> )* ')'\n",
329              "Runs multiple semicolon-separated commands in order.\n"
330              "You must have a space before the final ')'\n"
331              "Note quoting isn't supported here yet.\n"
332              "If you want to do something fancy, use perl.\n"),
333
334  OWLCMD_VOID("pop-message", owl_command_pop_message, OWL_CTX_RECWIN,
335              "pops up a message in a window", "", ""),
336
337  OWLCMD_VOID("openurl", owl_command_openurl, OWL_CTX_INTERACTIVE,
338              "opens up a URL from the current message",
339              "", 
340              "Uses the 'webbrowser' variable to determine\n"
341              "which browser to use.  Currently, 'netscape'\n"
342              "and 'galeon' are supported.\n"),
343
344  OWLCMD_ARGS("zaway", owl_command_zaway, OWL_CTX_INTERACTIVE,
345              "running a command from the shell",
346              "zaway [ on | off | toggle ]\n"
347              "zaway <message>",
348              "Turn on or off the default zaway message.  If a message is\n"
349              "specified turn on zaway with that message\n"),
350
351  OWLCMD_ARGS("load-subs", owl_command_loadsubs, OWL_CTX_ANY,
352              "load subscriptions from a file",
353              "load-subs <file>\n", ""),
354
355  OWLCMD_VOID("about", owl_command_about, OWL_CTX_INTERACTIVE,
356              "print information about owl", "", ""),
357
358  OWLCMD_VOID("status", owl_command_status, OWL_CTX_ANY,
359              "print status information about the running owl", "", ""),
360 
361  OWLCMD_ARGS("zlocate", owl_command_zlocate, OWL_CTX_INTERACTIVE,
362              "locate a user",
363              "zlocate [-d] <user>", 
364              "Performs a zlocate on a user and puts the result into\n"
365              "a popwin.  If -d is specified, does not authenticate\n"
366              "the lookup request.\n"),
367 
368  OWLCMD_ARGS("filter", owl_command_filter, OWL_CTX_ANY,
369              "create a message filter",
370              "filter <name> [ -c color ] [ <expression> ... ]",
371              "The filter command creates a filter with the specified name,\n"
372              "or if one already exists it is replaced.  Example filter\n"
373              "syntax would be:\n\n"
374              "     filter myfilter -c red ( class ^foobar$ ) or ( class ^quux$ and instance ^bar$ )\n\n"
375              "Valid matching fields are class, instance, recipient, sender,\n"
376              "opcode and realm. Valid operations are 'and', 'or' and 'not'.\n"
377              "Spaces must be present before and after parenthesis.  If the\n"
378              "optional color argument is used it specifies the color that\n"
379              "messages matching this filter should be displayed in.\n\n"
380
381              "SEE ALSO: view, viewclass, viewuser\n"),
382
383  OWLCMD_ARGS("colorview", owl_command_colorview, OWL_CTX_INTERACTIVE,
384              "change the color on the current filter",
385              "colorview <color>",
386              "The color of messages in the current filter will be changed\n"
387              "to <color>.  Use the 'show colors' command for a list\n"
388              "of valid colors.\n\n"
389              "SEE ALSO: 'show colors'\n"),
390
391  OWLCMD_ARGS("view", owl_command_view, OWL_CTX_INTERACTIVE,
392              "view messages matching a filter",
393              "view <filter>\n"
394              "view -d <expression>\n"
395              "view --home",
396              "In the first usage, The view command sets the current view to\n"
397              "the specified filter.   This causes only messages matching\n"
398              "that filter to be displayed.\n"
399              "\n"
400              "In the second usage a filter expression\n"
401              "and be specified directly\n"
402              "after -d.  Owl will build an internal filter based on this\n"
403              "filter and change the current view to use it.\n\n"
404              "If --home is specified, switches to the view specified by\n"
405              "the 'view_home' variable.\n\n"
406              "SEE ALSO: filter, viewclass, viewuser\n"),
407
408  OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE,
409              "view only messages similar to the current message",
410              "smartnarrow [-i | --instance]",
411              "If the curmsg is a personal message narrow\n"
412              "   to the converstaion with that user.\n"
413              "If the curmsg is a class message, instance foo, recip *\n"
414              "   message, narrow to the class, inst.\n"
415              "If the curmsg is a class message then narrow\n"
416              "    to the class.\n"
417              "If the curmsg is a class message and '-i' is specied\n"
418              "    then narrow to the class, instance\n"),
419
420  OWLCMD_ARGS("smartfilter", owl_command_smartfilter, OWL_CTX_INTERACTIVE,
421              "returns the name of a filter based on the current message",
422              "smartfilter [-i | --instance]",
423              "If the curmsg is a personal message, the filter is\n"
424              "   the converstaion with that user.\n"
425              "If the curmsg is a class message, instance foo, recip *\n"
426              "   message, the filter is the class, inst.\n"
427              "If the curmsg is a class message, the filter is that class.\n"
428              "If the curmsg is a class message and '-i' is specied\n"
429              "    the filter is that <class,instance> pair\n"),
430
431  OWLCMD_ARGS("viewclass", owl_command_viewclass, OWL_CTX_INTERACTIVE,
432              "view messages matching a particular class",
433              "viewclass <class>",
434              "The viewclass command will automatically create a filter\n"
435              "matching the specified class and switch the current view\n"
436              "to it.\n\n"
437              "SEE ALSO: filter, view, viewuser\n"),
438  OWLCMD_ALIAS("vc", "viewclass"),
439
440  OWLCMD_ARGS("viewuser", owl_command_viewuser, OWL_CTX_INTERACTIVE,
441              "view messages matching a particular user",
442              "viewuser <user>",
443              "The viewuser command will automatically create a filter\n"
444              "matching the specified user and switch the current\n"
445              "view to it.\n\n"
446              "SEE ALSO: filter, view, viewclass\n"),
447  OWLCMD_ALIAS("vu", "viewuser"),
448
449  OWLCMD_ARGS("show", owl_command_show, OWL_CTX_INTERACTIVE,
450              "show information",
451              "show variables\n"
452              "show variable <variable>\n"
453              "show filters\n"
454              "show filter <filter>\n"
455              "show keymaps\n"
456              "show keymap <keymap>\n"
457              "show commands\n"
458              "show command <command>\n"
459              "show subs\n"
460              "show subscriptions\n"
461              "show zpunts\n"
462              "show colors\n"
463              "show terminal\n"
464              "show version\n"
465              "show status\n",
466
467              "Show colors will display a list of valid colors for the\n"
468              "     terminal."
469              "Show filters will list the names of all filters.\n"
470              "Show filter <filter> will show the definition of a particular\n"
471              "     filter.\n\n"
472              "Show zpunts will show the active zpunt filters.\n\n"
473              "Show keymaps will list the names of all keymaps.\n"
474              "Show keymap <keymap> will show the key bindings in a keymap.\n\n"
475              "Show commands will list the names of all keymaps.\n"
476              "Show command <command> will provide information about a command.\n\n"
477              "Show variables will list the names of all variables.\n\n"
478              "SEE ALSO: filter, view, alias, bindkey, help\n"),
479 
480  OWLCMD_ARGS("delete", owl_command_delete, OWL_CTX_INTERACTIVE,
481              "mark a message for deletion",
482              "delete [ -id msgid ] [ --no-move ]\n"
483              "delete view\n"
484              "delete trash",
485              "If no message id is specified the current message is marked\n"
486              "for deletion.  Otherwise the message with the given message\n"
487              "id is marked for deltion.\n"
488              "If '--no-move' is specified, don't move after deletion.\n"
489              "If 'trash' is specified, deletes all trash/auto messages\n"
490              "in the current view.\n"
491              "If 'view' is specified, deletes all messages in the\n"
492              "current view.\n"),
493  OWLCMD_ALIAS("del", "delete"),
494
495  OWLCMD_ARGS("undelete", owl_command_undelete, OWL_CTX_INTERACTIVE,
496              "unmark a message for deletion",
497              "undelete [ -id msgid ] [ --no-move ]\n"
498              "undelete view",
499              "If no message id is specified the current message is\n"
500              "unmarked for deletion.  Otherwise the message with the\n"
501              "given message id is marked for undeltion.\n"
502              "If '--no-move' is specified, don't move after deletion.\n"
503              "If 'view' is specified, undeletes all messages\n"
504              "in the current view.\n"),
505  OWLCMD_ALIAS("undel", "undelete"),
506
507  OWLCMD_VOID("beep", owl_command_beep, OWL_CTX_ANY,
508              "ring the terminal bell",
509              "beep",
510              "Beep will ring the terminal bell.\n"
511              "If the variable 'bell' has been\n"
512              "set to 'off' this command does nothing.\n"),
513
514  OWLCMD_ARGS("debug", owl_command_debug, OWL_CTX_ANY,
515              "prints a message into the debug log",
516              "debug <message>", ""),
517
518  OWLCMD_ARGS("getview", owl_command_getview, OWL_CTX_INTERACTIVE,
519              "returns the name of the filter for the current view",
520              "", ""),
521
522  OWLCMD_ARGS("getvar", owl_command_getvar, OWL_CTX_INTERACTIVE,
523              "returns the value of a variable",
524              "getvar <varname>", ""),
525
526  OWLCMD_ARGS("search", owl_command_search, OWL_CTX_INTERACTIVE,
527              "search messages for a particular string",
528              "search [-r] [<string>]",
529              "The search command will find messages that contain the\n"
530              "specified string and move the cursor there.  If no string\n"
531              "argument is supplied then the previous one is used.  By\n"
532              "default searches are done fowards, if -r is used the search\n"
533              "is performed backwards"),
534
535  /****************************************************************/
536  /************************* EDIT-SPECIFIC ************************/
537  /****************************************************************/
538
539  OWLCMD_VOID_CTX("edit:move-next-word", owl_editwin_move_to_nextword, 
540                  OWL_CTX_EDIT,
541                  "moves cursor forward a word",
542                  "", ""),
543
544  OWLCMD_VOID_CTX("edit:move-prev-word", owl_editwin_move_to_previousword, 
545                  OWL_CTX_EDIT,
546                  "moves cursor backwards a word",
547                  "", ""),
548
549  OWLCMD_VOID_CTX("edit:move-to-buffer-start", owl_editwin_move_to_top,
550                  OWL_CTX_EDIT,
551                  "moves cursor to the top left (start) of the buffer",
552                  "", ""),
553
554  OWLCMD_VOID_CTX("edit:move-to-buffer-end", owl_editwin_move_to_end, 
555                  OWL_CTX_EDIT,
556                  "moves cursor to the bottom right (end) of the buffer",
557                  "", ""),
558
559  OWLCMD_VOID_CTX("edit:move-to-line-end", owl_editwin_move_to_line_end, 
560                  OWL_CTX_EDIT,
561                  "moves cursor to the end of the line",
562                  "", ""),
563
564  OWLCMD_VOID_CTX("edit:move-to-line-start", owl_editwin_move_to_line_start, 
565                  OWL_CTX_EDIT,
566                  "moves cursor to the beginning of the line",
567                  "", ""),
568
569  OWLCMD_VOID_CTX("edit:move-left", owl_editwin_key_left, 
570                  OWL_CTX_EDIT,
571                  "moves the cursor left by a character",
572                  "", ""),
573
574  OWLCMD_VOID_CTX("edit:move-right", owl_editwin_key_right,
575                  OWL_CTX_EDIT,
576                  "moves the cursor right by a character",
577                  "", ""),
578
579  OWLCMD_VOID_CTX("edit:delete-next-word", owl_editwin_delete_nextword,
580                  OWL_CTX_EDIT,
581                  "deletes the word to the right of the cursor",
582                  "", ""),
583
584  OWLCMD_VOID_CTX("edit:delete-prev-word", owl_editwin_delete_previousword,
585                  OWL_CTX_EDIT,
586                  "deletes the word to the left of the cursor",
587                  "", ""),
588
589  OWLCMD_VOID_CTX("edit:delete-prev-char", owl_editwin_backspace,
590                  OWL_CTX_EDIT,
591                  "deletes the character to the left of the cursor",
592                  "", ""),
593
594  OWLCMD_VOID_CTX("edit:delete-next-char", owl_editwin_delete_char, 
595                  OWL_CTX_EDIT,
596                  "deletes the character to the right of the cursor",
597                  "", ""),
598
599  OWLCMD_VOID_CTX("edit:delete-to-line-end", owl_editwin_delete_to_endofline,
600                  OWL_CTX_EDIT,
601                  "deletes from the cursor to the end of the line",
602                  "", ""),
603
604  OWLCMD_VOID_CTX("edit:delete-all", owl_editwin_clear, 
605                  OWL_CTX_EDIT,
606                  "deletes all of the contents of the buffer",
607                  "", ""),
608
609  OWLCMD_VOID_CTX("edit:transpose-chars", owl_editwin_transpose_chars,
610                  OWL_CTX_EDIT,
611                  "Interchange characters around point, moving forward one character.",
612                  "", ""),
613
614  OWLCMD_VOID_CTX("edit:fill-paragraph", owl_editwin_fill_paragraph, 
615                  OWL_CTX_EDIT,
616                  "fills the current paragraph to line-wrap well",
617                  "", ""),
618
619  OWLCMD_VOID_CTX("edit:recenter", owl_editwin_recenter, 
620                  OWL_CTX_EDIT,
621                  "recenters the buffer",
622                  "", ""),
623
624  OWLCMD_ARGS_CTX("edit:insert-text", owl_command_edit_insert_text, 
625                  OWL_CTX_EDIT,
626                  "inserts text into the buffer",
627                  "edit:insert-text <text>", ""),
628
629  OWLCMD_VOID_CTX("edit:cancel", owl_command_edit_cancel, 
630                  OWL_CTX_EDIT,
631                  "cancels the current command",
632                  "", ""),
633
634  OWLCMD_VOID_CTX("edit:history-next", owl_command_edit_history_next, 
635                  OWL_CTX_EDIT,
636                  "replaces the text with the previous history",
637                  "", ""),
638
639  OWLCMD_VOID_CTX("edit:history-prev", owl_command_edit_history_prev, 
640                  OWL_CTX_EDIT,
641                  "replaces the text with the previous history",
642                  "", ""),
643
644  OWLCMD_VOID_CTX("editline:done", owl_command_editline_done, 
645                  OWL_CTX_EDITLINE,
646                  "completes the command (eg, executes command being composed)",
647                  "", ""),
648
649  OWLCMD_VOID_CTX("editmulti:move-up-line", owl_editwin_key_up, 
650                  OWL_CTX_EDITMULTI,
651                  "moves the cursor up one line",
652                  "", ""),
653
654  OWLCMD_VOID_CTX("editmulti:move-down-line", owl_editwin_key_down, 
655                  OWL_CTX_EDITMULTI,
656                  "moves the cursor down one line",
657                  "", ""),
658
659  OWLCMD_VOID_CTX("editmulti:done", owl_command_editmulti_done, 
660                  OWL_CTX_EDITMULTI,
661                  "completes the command (eg, sends message being composed)",
662                  "", ""),
663
664  OWLCMD_VOID_CTX("editmulti:done-or-delete", owl_command_editmulti_done_or_delete, 
665                  OWL_CTX_EDITMULTI,
666                  "completes the command, but only if at end of message",
667                  "", 
668                  "If only whitespace is to the right of the cursor,\n"
669                  "runs 'editmulti:done'.\n"\
670                  "Otherwise runs 'edit:delete-next-char'\n"),
671
672  /****************************************************************/
673  /********************** POPLESS-SPECIFIC ************************/
674  /****************************************************************/
675
676  OWLCMD_VOID_CTX("popless:scroll-down-page", owl_viewwin_pagedown, 
677                  OWL_CTX_POPLESS,
678                  "scrolls down one page",
679                  "", ""),
680
681  OWLCMD_VOID_CTX("popless:scroll-down-line", owl_viewwin_linedown, 
682                  OWL_CTX_POPLESS,
683                  "scrolls down one line",
684                  "", ""),
685
686  OWLCMD_VOID_CTX("popless:scroll-up-page", owl_viewwin_pageup, 
687                  OWL_CTX_POPLESS,
688                  "scrolls up one page",
689                  "", ""),
690
691  OWLCMD_VOID_CTX("popless:scroll-up-line", owl_viewwin_lineup, 
692                  OWL_CTX_POPLESS,
693                  "scrolls up one line",
694                  "", ""),
695
696  OWLCMD_VOID_CTX("popless:scroll-to-top", owl_viewwin_top, 
697                  OWL_CTX_POPLESS,
698                  "scrolls to the top of the buffer",
699                  "", ""),
700
701  OWLCMD_VOID_CTX("popless:scroll-to-bottom", owl_viewwin_bottom, 
702                  OWL_CTX_POPLESS,
703                  "scrolls to the bottom of the buffer",
704                  "", ""),
705
706  OWLCMD_INT_CTX ("popless:scroll-right", owl_viewwin_right, 
707                  OWL_CTX_POPLESS,
708                  "scrolls right in the buffer",
709                  "popless:scroll-right <num-chars>", ""),
710
711  OWLCMD_INT_CTX ("popless:scroll-left", owl_viewwin_left, 
712                  OWL_CTX_POPLESS,
713                  "scrolls left in the buffer",
714                  "popless:scroll-left <num-chars>", ""),
715
716  OWLCMD_VOID_CTX("popless:quit", owl_command_popless_quit, 
717                  OWL_CTX_POPLESS,
718                  "exits the popless window",
719                  "", ""),
720
721  /* This line MUST be last! */
722  { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
723
724};
725
726void owl_command_info() {
727  owl_function_info();
728}
729
730char *owl_command_help(int argc, char **argv, char *buff) {
731  if (argc!=2) {
732    owl_help();
733    return NULL;
734  }
735 
736  owl_function_help_for_command(argv[1]);
737  return NULL;
738}
739
740char *owl_command_zlist(int argc, char **argv, char *buff) {
741  int elapsed=0, timesort=0;
742  char *file=NULL;
743
744  argc--;
745  argv++;
746  while (argc) {
747    if (!strcmp(argv[0], "-e")) {
748      elapsed=1;
749      argc--;
750      argv++;
751    } else if (!strcmp(argv[0], "-t")) {
752      timesort=1;
753      argc--;
754      argv++;
755    } else if (!strcmp(argv[0], "-f")) {
756      if (argc==1) {
757        owl_function_makemsg("zlist: -f needs an argument");
758        return(NULL);
759      }
760      file=argv[1];
761      argc-=2;
762      argv+=2;
763    } else {
764      owl_function_makemsg("zlist: unknown argument");
765      return(NULL);
766    }
767  }
768  owl_function_zlist(file, elapsed, timesort);
769  return(NULL);
770}
771
772void owl_command_about() {
773  owl_function_about();
774}
775
776void owl_command_version() {
777  char buff[1024];
778
779  sprintf(buff, "Owl version %s", OWL_VERSION_STRING);
780  owl_function_makemsg(buff);
781}
782
783char *owl_command_next(int argc, char **argv, char *buff) {
784  char *filter=NULL;
785  int skip_deleted=0, last_if_none=0;
786  while (argc>1) {
787    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
788      skip_deleted=1;
789      argc-=1; argv+=1; 
790    } else if (argc>=1 && !strcmp(argv[1], "--last-if-none")) {
791      last_if_none=1;
792      argc-=1; argv+=1; 
793    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
794      filter = owl_strdup(argv[2]);
795      argc-=2; argv+=2; 
796    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
797      filter = owl_function_smartfilter(0);
798      argc-=2; argv+=2; 
799    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
800      filter = owl_function_smartfilter(1);
801      argc-=2; argv+=2; 
802    } else {
803      owl_function_makemsg("Invalid arguments to command 'next'.");
804      return(NULL);
805    }
806  }
807  owl_function_nextmsg_full(filter, skip_deleted, last_if_none);
808  if (filter) owl_free(filter);
809  return(NULL);
810}
811
812char *owl_command_prev(int argc, char **argv, char *buff) {
813  char *filter=NULL;
814  int skip_deleted=0, first_if_none=0;
815  while (argc>1) {
816    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
817      skip_deleted=1;
818      argc-=1; argv+=1; 
819    } else if (argc>=1 && !strcmp(argv[1], "--first-if-none")) {
820      first_if_none=1;
821      argc-=1; argv+=1; 
822    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
823      filter = owl_strdup(argv[2]);
824      argc-=2; argv+=2; 
825    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
826      filter = owl_function_smartfilter(0);
827      argc-=2; argv+=2; 
828    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
829      filter = owl_function_smartfilter(1);
830      argc-=2; argv+=2; 
831   } else {
832      owl_function_makemsg("Invalid arguments to command 'prev'.");
833      return(NULL);
834    }
835  }
836  owl_function_prevmsg_full(filter, skip_deleted, first_if_none);
837  if (filter) owl_free(filter);
838  return(NULL);
839}
840
841char *owl_command_smartnarrow(int argc, char **argv, char *buff) {
842  char *filtname = NULL;
843
844  if (argc == 1) {
845    filtname = owl_function_smartfilter(0);
846  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
847    filtname = owl_function_smartfilter(1);
848  } else {
849    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
850  }
851  if (filtname) {
852    owl_function_change_view(filtname);
853    owl_free(filtname);
854  }
855  return NULL;
856}
857
858char *owl_command_smartfilter(int argc, char **argv, char *buff) {
859  char *filtname = NULL;
860
861  if (argc == 1) {
862    filtname = owl_function_smartfilter(0);
863  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
864    filtname = owl_function_smartfilter(1);
865  } else {
866    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
867  }
868  return filtname;
869}
870
871void owl_command_expunge() {
872  owl_function_expunge();
873}
874
875void owl_command_first() {
876  owl_global_set_rightshift(&g, 0);
877  owl_function_firstmsg();
878}
879
880void owl_command_last() {
881  owl_function_lastmsg();
882}
883
884void owl_command_resize() {
885  owl_function_resize();
886}
887
888void owl_command_redisplay() {
889  owl_function_full_redisplay();
890  owl_global_set_needrefresh(&g);
891}
892
893void owl_command_shift_right() {
894  owl_function_shift_right();
895}
896
897void owl_command_shift_left() {
898  owl_function_shift_left();
899}
900
901void owl_command_unsuball() {
902  owl_function_unsuball();
903}
904
905char *owl_command_loadsubs(int argc, char **argv, char *buff) {
906  if (argc == 2) {
907    owl_function_loadsubs(argv[1]);
908  } else if (argc == 1) {
909    owl_function_loadsubs(NULL);
910  } else {
911    owl_function_makemsg("Wrong number of arguments for load-subs.");
912    return NULL;
913  }
914  return NULL;
915}
916
917void owl_command_suspend() {
918  owl_function_suspend();
919}
920
921char *owl_command_start_command(int argc, char **argv, char *buff) {
922  buff = skiptokens(buff, 1);
923  owl_function_start_command(buff);
924  return NULL;
925}
926
927char *owl_command_zaway(int argc, char **argv, char *buff) {
928 
929  if ((argc==1) ||
930      ((argc==2) && !strcmp(argv[1], "on"))) {
931    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
932    owl_function_zaway_on();
933    return NULL;
934  }
935
936  if (argc==2 && !strcmp(argv[1], "off")) {
937    owl_function_zaway_off();
938    return NULL;
939  }
940
941  if (argc==2 && !strcmp(argv[1], "toggle")) {
942    owl_function_zaway_toggle();
943    return NULL;
944  }
945
946  buff = skiptokens(buff, 1);
947  owl_global_set_zaway_msg(&g, buff);
948  owl_function_zaway_on();
949  return NULL;
950}
951
952
953char *owl_command_set(int argc, char **argv, char *buff) {
954  char *var, *val;
955  int  silent=0;
956  int requirebool=0;
957
958  if (argc == 1) {
959    owl_function_printallvars();
960    return NULL;
961  } 
962
963  if (argc > 1 && !strcmp("-q",argv[1])) {
964    silent = 1;
965    argc--; argv++;
966  }
967
968  if (argc == 2) {
969    var=argv[1];
970    val="on";
971    requirebool=1;
972  } else if (argc == 3) {
973    var=argv[1];
974    val=argv[2];
975  } else {
976    owl_function_makemsg("Wrong number of arguments for set command");
977    return NULL;
978  }
979  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, requirebool);
980  return NULL;
981}
982
983char *owl_command_unset(int argc, char **argv, char *buff) {
984  char *var, *val;
985  int  silent=0;
986
987  if (argc > 1 && !strcmp("-q",argv[1])) {
988    silent = 1;
989    argc--; argv++;
990  }
991  if (argc == 2) {
992    var=argv[1];
993    val="off";
994  } else {
995    owl_function_makemsg("Wrong number of arguments for unset command");
996    return NULL;
997  }
998  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, 1);
999  return NULL;
1000}
1001
1002char *owl_command_print(int argc, char **argv, char *buff) {
1003  char *var;
1004  char valbuff[1024];
1005
1006  if (argc==1) {
1007    owl_function_printallvars();
1008    return NULL;
1009  } else if (argc!=2) {
1010    owl_function_makemsg("Wrong number of arguments for print command");
1011    return NULL;
1012  }
1013
1014  var=argv[1];
1015   
1016  if (0 == owl_variable_get_tostring(owl_global_get_vardict(&g), 
1017                                     var, valbuff, 1024)) {
1018    owl_function_makemsg("%s = '%s'", var, valbuff);
1019  } else {
1020    owl_function_makemsg("Unknown variable '%s'.", var);
1021  }
1022  return NULL;
1023}
1024
1025
1026char *owl_command_exec(int argc, char **argv, char *buff) {
1027  return owl_function_exec(argc, argv, buff, 0);
1028}
1029
1030char *owl_command_pexec(int argc, char **argv, char *buff) {
1031  return owl_function_exec(argc, argv, buff, 1);
1032}
1033
1034char *owl_command_aexec(int argc, char **argv, char *buff) {
1035  return owl_function_exec(argc, argv, buff, 2);
1036}
1037
1038char *owl_command_perl(int argc, char **argv, char *buff) {
1039  return owl_function_perl(argc, argv, buff, 0);
1040}
1041
1042char *owl_command_pperl(int argc, char **argv, char *buff) {
1043  return owl_function_perl(argc, argv, buff, 1);
1044}
1045
1046char *owl_command_aperl(int argc, char **argv, char *buff) {
1047  return owl_function_perl(argc, argv, buff, 2);
1048}
1049
1050char *owl_command_multi(int argc, char **argv, char *buff) {
1051  char *lastrv = NULL, *newbuff;
1052  char **commands;
1053  int  ncommands, i;
1054  if (argc < 2) {
1055    owl_function_makemsg("Invalid arguments to 'multi' command.");   
1056    return NULL;
1057  }
1058  newbuff = owl_strdup(buff);
1059  newbuff = skiptokens(newbuff, 1);
1060  if (!strcmp(argv[0], "(")) {
1061    for (i=strlen(newbuff)-1; i>=0; i--) {
1062      if (newbuff[i] == ')') {
1063        newbuff[i] = '\0';
1064        break;
1065      } else if (newbuff[i] != ' ') {
1066        owl_function_makemsg("Invalid arguments to 'multi' command.");   
1067        owl_free(newbuff);
1068        return NULL;
1069      }
1070    }
1071  }
1072  commands = atokenize(newbuff, ";", &ncommands);
1073  for (i=0; i<ncommands; i++) {
1074    if (lastrv) {
1075      owl_free(lastrv);
1076    }
1077    lastrv = owl_function_command(commands[i]);
1078  }
1079  atokenize_free(commands, ncommands);
1080  return lastrv;
1081}
1082
1083
1084char *owl_command_alias(int argc, char **argv, char *buff) {
1085  if (argc < 3) {
1086    owl_function_makemsg("Invalid arguments to 'alias' command.");
1087    return NULL;
1088  }
1089  buff = skiptokens(buff, 2);
1090  owl_function_command_alias(argv[1], buff);
1091  return (NULL);
1092}
1093
1094
1095char *owl_command_bindkey(int argc, char **argv, char *buff) {
1096  owl_keymap *km;
1097  int ret;
1098
1099  if (argc < 5 || strcmp(argv[3], "command")) {
1100    owl_function_makemsg("Usage: bindkey <keymap> <binding> command <cmd>", argv[3], argc);
1101    return NULL;
1102  }
1103  km = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), argv[1]);
1104  if (!km) {
1105    owl_function_makemsg("No such keymap '%s'", argv[1]);
1106    return NULL;
1107  }
1108  buff = skiptokens(buff, 4);
1109  ret = owl_keymap_create_binding(km, argv[2], buff, NULL, "*user*");
1110  if (ret!=0) {
1111    owl_function_makemsg("Unable to bind '%s' in keymap '%s' to '%s'.",
1112                         argv[2], argv[1], buff);
1113    return NULL;
1114  }
1115  return NULL;
1116}
1117
1118void owl_command_quit() {
1119  owl_function_quit();
1120}
1121
1122char *owl_command_debug(int argc, char **argv, char *buff) {
1123  if (argc<2) {
1124    owl_function_makemsg("Need at least one argument to debug command");
1125    return NULL;
1126  }
1127
1128  if (!owl_global_is_debug_fast(&g)) {
1129    owl_function_makemsg("Debugging is not turned on");
1130    return NULL;
1131  }
1132
1133  owl_function_debugmsg(argv[1]);
1134  return NULL;
1135}
1136
1137char *owl_command_ktest(int argc, char **argv, char *buff) {
1138  owl_function_popless_text("foobar");
1139  return NULL;
1140}
1141
1142char *owl_command_zlog(int argc, char **argv, char *buff) {
1143  if ((argc<2) || (argc>3)) {
1144    owl_function_makemsg("Wrong number of arguments for zlog command");
1145    return(NULL);
1146  }
1147
1148  if (!strcmp(argv[1], "in")) {
1149    if (argc>2) {
1150      owl_global_set_tty(&g, argv[2]);
1151    }
1152    owl_function_zlog_in();
1153  } else if (!strcmp(argv[1], "out")) {
1154    if (argc!=2) {
1155      owl_function_makemsg("Wrong number of arguments for zlog command");
1156      return(NULL);
1157    }
1158    owl_function_zlog_out();
1159  } else {
1160    owl_function_makemsg("Invalid subcommand for zlog");
1161  }
1162  return(NULL);
1163}
1164
1165
1166void owl_command_zlog_out() {
1167  owl_function_zlog_out();
1168}
1169
1170
1171char *owl_command_subscribe(int argc, char **argv, char *buff) {
1172  char *recip="";
1173  int temp=0;
1174 
1175  if (argc<3) {
1176    owl_function_makemsg("Not enough arguments to the subscribe command");
1177    return(NULL);
1178  }
1179  argc--;
1180  argv++;
1181
1182  if (!strcmp(argv[0], "-t")) {
1183    temp=1;
1184    argc--;
1185    argv++;
1186  }
1187  if (argc<2) {
1188    owl_function_makemsg("Not enough arguments to the subscribe command");
1189    return(NULL);
1190  }
1191
1192  if (argc>3) {
1193    owl_function_makemsg("Too many arguments to the subscribe command");
1194    return(NULL);
1195  }
1196
1197  if (argc==2) {
1198    recip="";
1199  } else if (argc==3) {
1200    recip=argv[2];
1201  }
1202
1203  owl_function_subscribe(argv[0], argv[1], recip);
1204  if (!temp) {
1205    owl_zephyr_addsub(NULL, argv[0], argv[1], recip);
1206  }
1207  return(NULL);
1208}
1209
1210
1211char *owl_command_unsubscribe(int argc, char **argv, char *buff) {
1212  char *recip="";
1213  int temp=0;
1214
1215  if (argc<3) {
1216    owl_function_makemsg("Not enough arguments to the unsubscribe command");
1217    return(NULL);
1218  }
1219  argc--;
1220  argv++;
1221
1222  if (!strcmp(argv[0], "-t")) {
1223    temp=1;
1224    argc--;
1225    argv++;
1226  }
1227  if (argc<2) {
1228    owl_function_makemsg("Not enough arguments to the subscribe command");
1229    return(NULL);
1230  }
1231
1232  if (argc>3) {
1233    owl_function_makemsg("Too many arguments to the unsubscribe command");
1234    return(NULL);
1235  }
1236
1237  if (argc==2) {
1238    recip="";
1239  } else if (argc==3) {
1240    recip=argv[2];
1241  }
1242
1243  owl_function_unsubscribe(argv[0], argv[1], recip);
1244  if (!temp) {
1245    owl_zephyr_delsub(NULL, argv[0], argv[1], recip);
1246  }
1247  return(NULL);
1248}
1249
1250char *owl_command_echo(int argc, char **argv, char *buff) {
1251  buff = skiptokens(buff, 1);
1252  owl_function_popless_text(buff);
1253  return NULL;
1254}
1255
1256void owl_command_getsubs() {
1257  owl_function_getsubs();
1258}
1259
1260void owl_command_status() {
1261  owl_function_status();
1262}
1263
1264char *owl_command_zwrite(int argc, char **argv, char *buff) {
1265  char *tmpbuff, *pos, *cmd, *msg;
1266
1267  /* check for a zwrite -m */
1268  for (pos = buff; *pos; pos = skiptokens(pos, 1)) {
1269    if (!strncmp(pos, "-m ", 3)) {
1270      cmd = owl_strdup(buff);
1271      msg = cmd+(pos-buff);
1272      *msg = '\0';
1273      msg += 3;
1274      owl_zwrite_create_and_send_from_line(cmd, msg);
1275      owl_free(cmd);
1276      return NULL;
1277    }
1278  }
1279
1280  if (argc < 2) {
1281    owl_function_makemsg("Not enough arguments to the zwrite command.");
1282  } else {
1283    tmpbuff = owl_strdup(buff);
1284    owl_function_zwrite_setup(tmpbuff);
1285    owl_global_set_buffercommand(&g, tmpbuff);
1286    owl_free(tmpbuff);
1287  }
1288  return NULL;
1289}
1290
1291char *owl_command_reply(int argc, char **argv, char *buff) {
1292  int edit=0;
1293 
1294  if (argc>=2 && !strcmp("-e", argv[1])) {
1295    edit=1;
1296    argv++;
1297    argc--;
1298  }
1299
1300  if ((argc==1) || (argc==2 && !strcmp(argv[1], "all"))) {   
1301    owl_function_reply(0, !edit);
1302  } else if (argc==2 && !strcmp(argv[1], "sender")) {
1303    owl_function_reply(1, !edit);
1304  } else if (argc==2 && !strcmp(argv[1], "zaway")) {
1305    owl_message *m;
1306    owl_view    *v;
1307    v = owl_global_get_current_view(&g);   
1308    m = owl_view_get_element(v, owl_global_get_curmsg(&g));
1309    if (m) owl_zephyr_zaway(m);
1310  } else {
1311    owl_function_makemsg("Invalid arguments to the reply command.");
1312  }
1313  return NULL;
1314}
1315
1316char *owl_command_filter(int argc, char **argv, char *buff) {
1317  owl_function_create_filter(argc, argv);
1318  return NULL;
1319}
1320
1321char *owl_command_zlocate(int argc, char **argv, char *buff) {
1322  if (argc==2) {
1323    owl_function_zlocate(argv[1], 1);
1324  } else if (argc==3) {
1325    if (!strcmp(argv[1], "-d")) {
1326      owl_function_zlocate(argv[2], 0);
1327    } else {
1328      owl_function_makemsg("Invalid option to the zlocate command");
1329      return NULL;
1330    }
1331  } else {
1332    owl_function_makemsg("Wrong number of arguments for zlocate command");
1333    return NULL;
1334  }
1335  return NULL;
1336}
1337
1338char *owl_command_view(int argc, char **argv, char *buff) {
1339  if (argc<2) {
1340    owl_function_makemsg("Wrong number of arguments to view command");
1341    return NULL;
1342  }
1343
1344  if (argc == 2 && !strcmp(argv[1], "--home")) {
1345    owl_function_change_view(owl_global_get_view_home(&g));
1346    return NULL;
1347  }
1348
1349  /* is it a dynamic filter? */
1350  if (!strcmp(argv[1], "-d")) {
1351    char **myargv;
1352    int i;
1353
1354    myargv=owl_malloc((argc*sizeof(char *))+50);
1355    myargv[0]="";
1356    myargv[1]="owl-dynamic";
1357    for (i=2; i<argc; i++) {
1358      myargv[i]=argv[i];
1359    }
1360    owl_function_create_filter(argc, myargv);
1361    owl_function_change_view("owl-dynamic");
1362    owl_free(myargv);
1363    return NULL;
1364  }
1365
1366  /* otherwise it's a normal view command */
1367  if (argc>2) {
1368    owl_function_makemsg("Wrong number of arguments to view command");
1369    return NULL;
1370  }
1371  owl_function_change_view(argv[1]);
1372  return NULL;
1373}
1374
1375
1376char *owl_command_show(int argc, char **argv, char *buff) {
1377
1378  if (argc<2) {
1379    owl_function_help_for_command("show");
1380    return NULL;
1381  }
1382
1383  if (!strcmp(argv[1], "filter") || !strcmp(argv[1], "filters")) {
1384    if (argc==2) {
1385      owl_function_show_filters();
1386    } else {
1387      owl_function_show_filter(argv[2]);
1388    }
1389  } else if (argc==2 
1390             && (!strcmp(argv[1], "zpunts") || !strcmp(argv[1], "zpunted"))) {
1391    owl_function_show_zpunts();
1392  } else if (!strcmp(argv[1], "command") || !strcmp(argv[1], "commands")) {
1393    if (argc==2) {
1394      owl_function_show_commands();
1395    } else {
1396      owl_function_show_command(argv[2]);
1397    }
1398  } else if (!strcmp(argv[1], "variable") || !strcmp(argv[1], "variables")) {
1399    if (argc==2) {
1400      owl_function_show_variables();
1401    } else {
1402      owl_function_show_variable(argv[2]);
1403    }
1404  } else if (!strcmp(argv[1], "keymap") || !strcmp(argv[1], "keymaps")) {
1405    if (argc==2) {
1406      owl_function_show_keymaps();
1407    } else {
1408      owl_function_show_keymap(argv[2]);
1409    }
1410  } else if (!strcmp(argv[1], "colors")) {
1411    owl_function_show_colors();
1412  } else if (!strcmp(argv[1], "subs") || !strcmp(argv[1], "subscriptions")) {
1413    owl_function_getsubs();
1414  } else if (!strcmp(argv[1], "terminal") || !strcmp(argv[1], "term")) {
1415    owl_function_show_term();
1416  } else if (!strcmp(argv[1], "version")) {
1417    owl_function_about();
1418  } else if (!strcmp(argv[1], "status")) {
1419    owl_function_status();
1420  } else {
1421    owl_function_makemsg("Unknown subcommand for 'show' command (see 'help show' for allowed args)");
1422    return NULL;
1423  }
1424  return NULL;
1425}
1426
1427char *owl_command_viewclass(int argc, char **argv, char *buff) {
1428  char *filtname;
1429  if (argc!=2) {
1430    owl_function_makemsg("Wrong number of arguments to viewclass command");
1431    return NULL;
1432  }
1433  filtname = owl_function_fastclassinstfilt(argv[1], NULL);
1434  owl_function_change_view(filtname);
1435  owl_free(filtname);
1436  return NULL;
1437}
1438
1439char *owl_command_viewuser(int argc, char **argv, char *buff) {
1440  char *filtname;
1441  if (argc!=2) {
1442    owl_function_makemsg("Wrong number of arguments to viewuser command");
1443    return NULL;
1444  }
1445  filtname = owl_function_fastuserfilt(argv[1]);
1446  owl_function_change_view(filtname);
1447  owl_free(filtname);
1448  return NULL;
1449}
1450
1451
1452void owl_command_pop_message(void) {
1453  owl_function_curmsg_to_popwin();
1454}
1455
1456void owl_command_openurl(void) {
1457  owl_function_openurl();
1458}
1459
1460char *owl_command_delete(int argc, char **argv, char *buff) {
1461  int move_after = 1;
1462
1463  if (argc>1 && !strcmp(argv[1], "--no-move")) {
1464    move_after = 0;
1465    argc--; 
1466    argv++;
1467  }
1468
1469  if (argc==1) {
1470    owl_function_deletecur(move_after);
1471    return NULL;
1472  }
1473
1474  if (argc==2 && !strcmp(argv[1], "view")) {
1475    owl_function_delete_curview_msgs(1);
1476    return NULL;
1477  }
1478
1479  if (argc==2 && !strcmp(argv[1], "trash")) {
1480    owl_function_delete_automsgs();
1481    return NULL;
1482  }
1483
1484  if (argc==3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
1485    owl_function_delete_by_id(atoi(argv[2]), 1);
1486    return NULL;
1487  }
1488
1489  owl_function_makemsg("Unknown arguments to delete command");
1490  return NULL;
1491}
1492
1493char *owl_command_undelete(int argc, char **argv, char *buff) {
1494  int move_after = 1;
1495
1496  if (argc>1 && !strcmp(argv[1], "--no-move")) {
1497    move_after = 0;
1498    argc--; 
1499    argv++;
1500  }
1501
1502  if (argc==1) {
1503    owl_function_undeletecur(move_after);
1504    return NULL;
1505  }
1506
1507  if (argc==2 && !strcmp(argv[1], "view")) {
1508    owl_function_delete_curview_msgs(0);
1509    return NULL;
1510  }
1511
1512  if (argc==3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
1513    owl_function_delete_by_id(atoi(argv[2]), 0);
1514    return NULL;
1515  }
1516
1517  owl_function_makemsg("Unknown arguments to delete command");
1518  return NULL;
1519}
1520
1521void owl_command_beep() {
1522  owl_function_beep();
1523}
1524
1525char *owl_command_colorview(int argc, char **argv, char *buff) {
1526  if (argc!=2) {
1527    owl_function_makemsg("Wrong number of arguments to colorview command");
1528    return NULL;
1529  }
1530  owl_function_color_current_filter(argv[1]);
1531  return NULL;
1532}
1533
1534char *owl_command_zpunt(int argc, char **argv, char *buff) {
1535  owl_command_zpunt_and_zunpunt(argc, argv, 0);
1536  return NULL;
1537}
1538
1539char *owl_command_zunpunt(int argc, char **argv, char *buff) {
1540  owl_command_zpunt_and_zunpunt(argc, argv, 1);
1541  return NULL;
1542}
1543
1544
1545void owl_command_zpunt_and_zunpunt(int argc, char **argv, int type) {
1546  /* if type==0 then zpunt
1547   * if type==1 then zunpunt
1548   */
1549  char *class, *inst, *recip;
1550
1551  class="message";
1552  inst="";
1553  recip="*";
1554
1555  if (argc==1) {
1556    /* show current punt filters */
1557    owl_function_show_zpunts();
1558    return;
1559  } else if (argc==2) {
1560    inst=argv[1];
1561  } else if (argc==3) {
1562    class=argv[1];
1563    inst=argv[2];
1564  } else if (argc==4) {
1565    class=argv[1];
1566    inst=argv[2];
1567    recip=argv[3];
1568  } else {
1569    owl_function_makemsg("Wrong number of arguments to the zpunt command");
1570    return;
1571  }
1572
1573  owl_function_zpunt(class, inst, recip, type);
1574  if (type==0) {
1575    owl_function_makemsg("<%s, %s, %s> added to punt list.", class, inst, recip);
1576  } else if (type==1) {
1577    owl_function_makemsg("<%s, %s, %s> removed from punt list.", class, inst, recip);
1578  }
1579}
1580
1581char *owl_command_smartzpunt(int argc, char **argv, char *buff) {
1582  if (argc == 1) {
1583    owl_function_smartzpunt(0);
1584  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
1585    owl_function_smartzpunt(1);
1586  } else {
1587    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
1588  }
1589  return NULL;
1590}
1591
1592char *owl_command_getview(int argc, char **argv, char *buff) {
1593  char *filtname;
1594  if (argc != 1) {
1595    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
1596    return NULL;
1597  }
1598  filtname = owl_view_get_filtname(owl_global_get_current_view(&g));
1599  if (filtname) filtname = owl_strdup(filtname);
1600  return filtname;
1601}
1602
1603char *owl_command_getvar(int argc, char **argv, char *buff) {
1604  char tmpbuff[1024];
1605  if (argc != 2) {
1606    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
1607    return NULL;
1608  }
1609  if (owl_variable_get_tostring(owl_global_get_vardict(&g), 
1610                                argv[1], tmpbuff, 1024)) {
1611    return NULL;
1612  }
1613  return owl_strdup(tmpbuff); 
1614}
1615
1616char *owl_command_search(int argc, char **argv, char *buff) {
1617  int direction;
1618  char *buffstart;
1619
1620  direction=OWL_DIRECTION_DOWNWARDS;
1621  buffstart=skiptokens(buff, 1);
1622  if (argc>1 && !strcmp(argv[1], "-r")) {
1623    direction=OWL_DIRECTION_UPWARDS;
1624    buffstart=skiptokens(buff, 2);
1625  }
1626   
1627  if (argc==1 || (argc==2 && !strcmp(argv[1], "-r"))) {
1628    owl_function_search_continue(direction);
1629  } else {
1630    owl_function_search_start(buffstart, direction);
1631  }
1632 
1633  return(NULL);
1634}
1635
1636/*********************************************************************/
1637/************************** EDIT SPECIFIC ****************************/
1638/*********************************************************************/
1639
1640void owl_command_edit_cancel(owl_editwin *e) {
1641  owl_history *hist;
1642
1643  owl_function_makemsg("Command cancelled.");
1644
1645  hist=owl_editwin_get_history(e);
1646  owl_history_store(hist, owl_editwin_get_text(e));
1647  owl_history_reset(hist);
1648
1649  owl_editwin_fullclear(e);
1650  owl_global_set_needrefresh(&g);
1651  wnoutrefresh(owl_editwin_get_curswin(e));
1652  owl_global_set_typwin_inactive(&g);
1653  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
1654}
1655
1656void owl_command_edit_history_prev(owl_editwin *e) {
1657  owl_history *hist;
1658  char *ptr;
1659
1660  hist=owl_editwin_get_history(e);
1661  if (!owl_history_is_touched(hist)) {
1662    owl_history_store(hist, owl_editwin_get_text(e));
1663    owl_history_set_partial(hist);
1664  }
1665  ptr=owl_history_get_prev(hist);
1666  if (ptr) {
1667    owl_editwin_clear(e);
1668    owl_editwin_insert_string(e, ptr);
1669    owl_editwin_redisplay(e, 0);
1670    owl_global_set_needrefresh(&g);
1671  } else {
1672    owl_function_beep();
1673  }
1674}
1675
1676void owl_command_edit_history_next(owl_editwin *e) {
1677  owl_history *hist;
1678  char *ptr;
1679
1680  hist=owl_editwin_get_history(e);
1681  ptr=owl_history_get_next(hist);
1682  if (ptr) {
1683    owl_editwin_clear(e);
1684    owl_editwin_insert_string(e, ptr);
1685    owl_editwin_redisplay(e, 0);
1686    owl_global_set_needrefresh(&g);
1687  } else {
1688    owl_function_beep();
1689  }
1690}
1691
1692char *owl_command_edit_insert_text(owl_editwin *e, int argc, char **argv, char *buff) {
1693  buff = skiptokens(buff, 1);
1694  owl_editwin_insert_string(e, buff);
1695  owl_editwin_redisplay(e, 0);
1696  owl_global_set_needrefresh(&g); 
1697  return NULL;
1698}
1699
1700void owl_command_editline_done(owl_editwin *e) {
1701  owl_history *hist=owl_editwin_get_history(e);
1702  char *rv, *cmd;
1703
1704  owl_history_store(hist, owl_editwin_get_text(e));
1705  owl_history_reset(hist);
1706  owl_global_set_typwin_inactive(&g);
1707  cmd = owl_strdup(owl_editwin_get_text(e));
1708  owl_editwin_fullclear(e);
1709  rv = owl_function_command(cmd);
1710  owl_free(cmd);
1711
1712  wnoutrefresh(owl_editwin_get_curswin(e));
1713  owl_global_set_needrefresh(&g);
1714
1715  if (rv) {
1716    owl_function_makemsg("%s", rv);
1717    owl_free(rv);
1718  }
1719}
1720
1721void owl_command_editmulti_done(owl_editwin *e) {
1722  owl_history *hist=owl_editwin_get_history(e);
1723
1724  owl_history_store(hist, owl_editwin_get_text(e));
1725  owl_history_reset(hist);
1726
1727  owl_function_run_buffercommand();
1728  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
1729  owl_editwin_fullclear(e);
1730  owl_global_set_typwin_inactive(&g);
1731  owl_global_set_needrefresh(&g);
1732  wnoutrefresh(owl_editwin_get_curswin(e));
1733}
1734
1735void owl_command_editmulti_done_or_delete(owl_editwin *e) {
1736  if (owl_editwin_is_at_end(e)) {
1737    owl_command_editmulti_done(e);
1738  } else {
1739    owl_editwin_delete_char(e);
1740  }
1741}
1742
1743
1744/*********************************************************************/
1745/*********************** POPLESS SPECIFIC ****************************/
1746/*********************************************************************/
1747
1748void owl_command_popless_quit(owl_viewwin *vw) {
1749  owl_popwin_close(owl_global_get_popwin(&g));
1750  owl_viewwin_free(vw);
1751  owl_global_set_needrefresh(&g);
1752}
Note: See TracBrowser for help on using the repository browser.