readline tab completion for mail
Showing
5 changed files
with
115 additions
and
36 deletions
... | @@ -35,35 +35,19 @@ mail_help (int argc, char **argv) | ... | @@ -35,35 +35,19 @@ mail_help (int argc, char **argv) |
35 | } | 35 | } |
36 | else | 36 | else |
37 | { | 37 | { |
38 | int status = 0; | 38 | int status = 0, cmd = 0; |
39 | int command = 0; | 39 | while (++cmd < argc) |
40 | while (++command < argc) | ||
41 | { | 40 | { |
42 | char *cmd = argv[command]; | 41 | struct mail_command_entry entry = util_find_entry (argv[cmd]); |
43 | int i = 0, printed = 0, sl = 0, ll = 0, len = strlen (cmd); | 42 | if (entry.synopsis != NULL) |
44 | while (mail_command_table[i].shortname != 0 && printed == 0) | 43 | printf ("%s\n", entry.synopsis); |
45 | { | 44 | else |
46 | sl = strlen (mail_command_table[i].shortname); | ||
47 | ll = strlen (mail_command_table[i].longname); | ||
48 | if (sl == len && !strcmp (mail_command_table[i].shortname, cmd)) | ||
49 | { | ||
50 | printed = 1; | ||
51 | printf ("%s\n", mail_command_table[i].synopsis); | ||
52 | } | ||
53 | else if (sl < len && !strncmp (mail_command_table[i].longname, | ||
54 | cmd, len)) | ||
55 | { | ||
56 | printed = 1; | ||
57 | printf ("%s\n", mail_command_table[i].synopsis); | ||
58 | } | ||
59 | i++; | ||
60 | } | ||
61 | if (printed == 0) | ||
62 | { | 45 | { |
63 | printf ("Unknown command: %s\n", cmd); | ||
64 | status = 1; | 46 | status = 1; |
47 | printf ("Unknown command: %s\n", argv[cmd]); | ||
65 | } | 48 | } |
66 | } | 49 | } |
50 | return status; | ||
67 | } | 51 | } |
68 | return 1; | 52 | return 1; |
69 | } | 53 | } | ... | ... |
... | @@ -113,7 +113,7 @@ static struct argp argp = { options, parse_opt, args_doc, doc }; | ... | @@ -113,7 +113,7 @@ static struct argp argp = { options, parse_opt, args_doc, doc }; |
113 | int | 113 | int |
114 | main (int argc, char **argv) | 114 | main (int argc, char **argv) |
115 | { | 115 | { |
116 | char *command = NULL; | 116 | char *command = NULL, *cmd = NULL; |
117 | char *from[] = { "from", "*" }; | 117 | char *from[] = { "from", "*" }; |
118 | struct arguments args; | 118 | struct arguments args; |
119 | 119 | ||
... | @@ -163,12 +163,32 @@ main (int argc, char **argv) | ... | @@ -163,12 +163,32 @@ main (int argc, char **argv) |
163 | mail_from (1, from); | 163 | mail_from (1, from); |
164 | cursor = realcursor; | 164 | cursor = realcursor; |
165 | 165 | ||
166 | /* Initialize readline */ | ||
167 | rl_readline_name = "mail"; | ||
168 | rl_attempted_completion_function = (CPPFunction *)util_command_completion; | ||
169 | |||
166 | while (1) | 170 | while (1) |
167 | { | 171 | { |
172 | int len; | ||
168 | free (command); | 173 | free (command); |
169 | command = readline ("? "); | 174 | command = readline ("? "); |
170 | util_do_command (command); | 175 | len = strlen (command); |
171 | add_history (command); | 176 | while (command[len-1] == '\\') |
177 | { | ||
178 | char *buf; | ||
179 | char *command2 = readline ("> "); | ||
180 | |||
181 | command[len-1] = '\0'; | ||
182 | buf = malloc ((len + strlen (command2)) * sizeof (char)); | ||
183 | strcpy (buf, command); | ||
184 | strcat (buf, command2); | ||
185 | free (command); | ||
186 | command = buf; | ||
187 | len = strlen (command); | ||
188 | } | ||
189 | cmd = util_stripwhite (command); | ||
190 | util_do_command (cmd); | ||
191 | add_history (cmd); | ||
172 | } | 192 | } |
173 | } | 193 | } |
174 | 194 | ... | ... |
... | @@ -110,8 +110,11 @@ int util_get_argcv __P((const char *command, int *argc, char ***argv)); | ... | @@ -110,8 +110,11 @@ int util_get_argcv __P((const char *command, int *argc, char ***argv)); |
110 | int util_expand_msglist __P((const int argc, char **argv, int **list)); | 110 | int util_expand_msglist __P((const int argc, char **argv, int **list)); |
111 | int util_do_command __P((const char *cmd)); | 111 | int util_do_command __P((const char *cmd)); |
112 | int util_msglist_command __P((int (*func)(int, char**), int argc, char **argv)); | 112 | int util_msglist_command __P((int (*func)(int, char**), int argc, char **argv)); |
113 | int* util_command_get __P((char *cmd)); | 113 | Function* util_command_get __P((char *cmd)); |
114 | int util_free_argv __P((int argc, char **argv)); | 114 | int util_free_argv __P((int argc, char **argv)); |
115 | char **util_command_completion __P((char *cmd, int start, int end)); | ||
116 | char *util_command_generator __P((char *text, int state)); | ||
117 | char *util_stripwhite __P((char *string)); | ||
115 | 118 | ||
116 | #ifdef __cplusplus | 119 | #ifdef __cplusplus |
117 | } | 120 | } | ... | ... |
... | @@ -35,10 +35,12 @@ extern "C" { | ... | @@ -35,10 +35,12 @@ extern "C" { |
35 | struct mail_command_entry { | 35 | struct mail_command_entry { |
36 | char *shortname; | 36 | char *shortname; |
37 | char *longname; | 37 | char *longname; |
38 | int (*func) __P((int, char**)); | 38 | Function *func; |
39 | char *synopsis; | 39 | char *synopsis; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct mail_command_entry util_find_entry __P((char *cmd)); | ||
43 | |||
42 | static struct mail_command_entry mail_command_table[] = { | 44 | static struct mail_command_entry mail_command_table[] = { |
43 | { "a", "alias", mail_alias, | 45 | { "a", "alias", mail_alias, |
44 | "a[lias] [alias [address...]]" }, | 46 | "a[lias] [alias [address...]]" }, | ... | ... |
... | @@ -166,15 +166,19 @@ util_do_command (const char *cmd) | ... | @@ -166,15 +166,19 @@ util_do_command (const char *cmd) |
166 | int argc = 0; | 166 | int argc = 0; |
167 | char **argv = NULL; | 167 | char **argv = NULL; |
168 | int status = 0; | 168 | int status = 0; |
169 | int (*command) (int, char**) = NULL; | 169 | Function *command; |
170 | 170 | ||
171 | if (cmd[0] == '#') | 171 | if (cmd[0] == '#') |
172 | return 0; | 172 | return 0; |
173 | 173 | ||
174 | if (cmd) | ||
175 | { | ||
174 | if (util_get_argcv (cmd, &argc, &argv) != 0) | 176 | if (util_get_argcv (cmd, &argc, &argv) != 0) |
175 | return util_free_argv (argc, argv); | 177 | return util_free_argv (argc, argv); |
176 | |||
177 | command = util_command_get (argv[0]); | 178 | command = util_command_get (argv[0]); |
179 | } | ||
180 | else | ||
181 | command = util_command_get ("quit"); | ||
178 | 182 | ||
179 | if (command != NULL) | 183 | if (command != NULL) |
180 | status = command (argc, argv); | 184 | status = command (argc, argv); |
... | @@ -218,23 +222,89 @@ util_msglist_command (int (*func)(int, char**), int argc, char **argv) | ... | @@ -218,23 +222,89 @@ util_msglist_command (int (*func)(int, char**), int argc, char **argv) |
218 | /* | 222 | /* |
219 | * returns the function to run for command | 223 | * returns the function to run for command |
220 | */ | 224 | */ |
221 | int * | 225 | Function * |
222 | util_command_get (char *cmd) | 226 | util_command_get (char *cmd) |
223 | { | 227 | { |
224 | int i = 0; | 228 | struct mail_command_entry entry = util_find_entry (cmd); |
229 | return entry.func; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * returns the mail_command_entry structure for the command matching cmd | ||
234 | */ | ||
235 | struct mail_command_entry | ||
236 | util_find_entry (char *cmd) | ||
237 | { | ||
238 | int i = 0, ll = 0, sl = 0; | ||
225 | int len = strlen (cmd); | 239 | int len = strlen (cmd); |
226 | int sl, ll; | ||
227 | 240 | ||
228 | while (mail_command_table[i].shortname != 0) | 241 | while (mail_command_table[i].shortname != 0) |
229 | { | 242 | { |
230 | sl = strlen (mail_command_table[i].shortname); | 243 | sl = strlen (mail_command_table[i].shortname); |
231 | ll = strlen (mail_command_table[i].longname); | 244 | ll = strlen (mail_command_table[i].longname); |
232 | if (sl == len && !strcmp (mail_command_table[i].shortname, cmd)) | 245 | if (sl == len && !strcmp (mail_command_table[i].shortname, cmd)) |
233 | return mail_command_table[i].func; | 246 | return mail_command_table[i]; |
234 | else if (sl < len && !strncmp (mail_command_table[i].longname, cmd, len)) | 247 | else if (sl < len && !strncmp (mail_command_table[i].longname, cmd, len)) |
235 | return mail_command_table[i].func; | 248 | return mail_command_table[i]; |
249 | i++; | ||
250 | } | ||
251 | return mail_command_table[i]; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * readline tab completion | ||
256 | */ | ||
257 | char ** | ||
258 | util_command_completion (char *cmd, int start, int end) | ||
259 | { | ||
260 | if (start == 0) | ||
261 | return completion_matches (cmd, util_command_generator); | ||
262 | return NULL; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * more readline | ||
267 | */ | ||
268 | char * | ||
269 | util_command_generator (char *text, int state) | ||
270 | { | ||
271 | static int i, len; | ||
272 | char *name; | ||
273 | |||
274 | if (!state) | ||
275 | { | ||
276 | i = 0; | ||
277 | len = strlen (text); | ||
278 | } | ||
279 | |||
280 | while ((name = mail_command_table[i].longname)) | ||
281 | { | ||
236 | i++; | 282 | i++; |
283 | /*if (strlen (mail_command_table[i].shortname) > strlen(name)) | ||
284 | name = mail_command_table[i].shortname; */ | ||
285 | if (strncmp (name, text, len) == 0) | ||
286 | return (strdup(name)); | ||
237 | } | 287 | } |
238 | 288 | ||
239 | return NULL; | 289 | return NULL; |
240 | } | 290 | } |
291 | |||
292 | /* | ||
293 | * removes whitespace from the beginning and end of a string | ||
294 | */ | ||
295 | char * | ||
296 | util_stripwhite (char *string) | ||
297 | { | ||
298 | register char *s, *t; | ||
299 | for (s = string; whitespace (*s); s++) | ||
300 | ; | ||
301 | if (*s == 0) | ||
302 | return s; | ||
303 | t = s + strlen (s) - 1; | ||
304 | while (t > s && whitespace (*t)) | ||
305 | t--; | ||
306 | *++t = '\0'; | ||
307 | return s; | ||
308 | } | ||
309 | |||
310 | ... | ... |
-
Please register or sign in to post a comment