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