]> diplodocus.org Git - nmh/blob - sbr/read_switch_multiword_via_readline.c
df91701c7872d841b49c756abdd19373a4de601d
[nmh] / sbr / read_switch_multiword_via_readline.c
1 /* read_switch_multiword_via_readline.c -- get an answer from the user, with readline
2 *
3 * This code is Copyright (c) 2012, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include "h/mh.h"
9 #include "read_switch_multiword_via_readline.h"
10 #include "smatch.h"
11 #include "brkstring.h"
12 #include "ambigsw.h"
13 #include "print_sw.h"
14
15 #ifdef READLINE_SUPPORT
16 #include <readline/readline.h>
17 #include <readline/history.h>
18
19 static struct swit *rl_cmds;
20
21 static char *nmh_command_generator(const char *, int);
22 static char **nmh_completion(const char *, int, int);
23 static void initialize_readline(void);
24
25 static char ansbuf[BUFSIZ];
26
27 /*
28 * getans, but with readline support
29 */
30
31 char **
32 read_switch_multiword_via_readline(char *prompt, struct swit *ansp)
33 {
34 char *ans, **cpp;
35
36 initialize_readline();
37 rl_cmds = ansp;
38
39 for (;;) {
40 ans = readline(prompt);
41 /*
42 * If we get an EOF, return
43 */
44
45 if (ans == NULL)
46 return NULL;
47
48 if (ans[0] == '?' || ans[0] == '\0') {
49 puts("Options are:");
50 print_sw(ALL, ansp, "", stdout);
51 free(ans);
52 continue;
53 }
54 add_history(ans);
55 strncpy(ansbuf, ans, sizeof(ansbuf));
56 ansbuf[sizeof(ansbuf) - 1] = '\0';
57 free(ans);
58
59 cpp = brkstring(ansbuf, " ", NULL);
60 switch (smatch(*cpp, ansp)) {
61 case AMBIGSW:
62 ambigsw(*cpp, ansp);
63 continue;
64 case UNKWNSW:
65 printf(" -%s unknown. Hit <CR> for help.\n", *cpp);
66 continue;
67 default:
68 return cpp;
69 }
70 }
71 }
72
73 static void
74 initialize_readline(void)
75 {
76 rl_readline_name = "Nmh";
77 rl_attempted_completion_function = nmh_completion;
78 }
79
80 static char **
81 nmh_completion(const char *text, int start, int end)
82 {
83 NMH_UNUSED (end);
84
85 if (start == 0)
86 return rl_completion_matches(text, nmh_command_generator);
87
88 return NULL;
89 }
90
91 static char *
92 nmh_command_generator(const char *text, int state)
93 {
94 static int list_index, len;
95 char *name, *p;
96 char buf[256];
97
98 if (!state) {
99 list_index = 0;
100 len = strlen(text);
101 }
102
103 while ((name = rl_cmds[list_index].sw)) {
104 list_index++;
105 strncpy(buf, name, sizeof(buf));
106 buf[sizeof(buf) - 1] = '\0';
107 p = *brkstring(buf, " ", NULL);
108 if (strncmp(p, text, len) == 0)
109 return strdup(p);
110 }
111
112 return NULL;
113 }
114 #endif /* READLINE_SUPPORT */