Curses: fix extended command input
The extended command input prompt was behaving in an unintended way: Typing #a<enter> executed #adjust. Spaces in the entry prevented matching any command. No error message was given when no command was matched. Fix all of those, so it behaves more like the tty. Clean up the tty, curses, and X11 windowport code, so they don't use the extcmdlist array directly, but query with extcmds_match and extcmds_getentry.
This commit is contained in:
@@ -1764,21 +1764,6 @@ ec_scroll_to_view(int ec_indx) /* might be greater than extended_cmd_selected */
|
||||
}
|
||||
}
|
||||
|
||||
/* decide whether extcmdlist[idx] should be part of extended commands menu */
|
||||
static boolean
|
||||
ignore_extcmd(int idx)
|
||||
{
|
||||
/* #shell or #suspect might not be available;
|
||||
'extmenu' option controls whether we show full list
|
||||
or just the traditional extended commands */
|
||||
if ((extcmdlist[idx].flags & (CMD_NOT_AVAILABLE|INTERNALCMD)) != 0
|
||||
|| ((extcmdlist[idx].flags & AUTOCOMPLETE) == 0 && !ec_full_list)
|
||||
|| strlen(extcmdlist[idx].ef_txt) < 2) /* ignore "#" and "?" */
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
ec_key(Widget w, XEvent *event, String *params, Cardinal *num_params)
|
||||
@@ -1899,22 +1884,24 @@ ec_key(Widget w, XEvent *event, String *params, Cardinal *num_params)
|
||||
static void
|
||||
init_extended_commands_popup(void)
|
||||
{
|
||||
int i, j, num_commands, ignore_cmds = 0;
|
||||
int i, j, num_commands;
|
||||
int *matches;
|
||||
int ecmflags = ECM_NO1CHARCMD;
|
||||
|
||||
/* count commands */
|
||||
for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++)
|
||||
if (ignore_extcmd(num_commands))
|
||||
++ignore_cmds;
|
||||
if (ec_full_list)
|
||||
ecmflags |= ECM_IGNOREAC;
|
||||
|
||||
j = num_commands - ignore_cmds;
|
||||
num_commands = extcmds_match(NULL, ecmflags, &matches);
|
||||
|
||||
j = num_commands;
|
||||
command_list = (const char **) alloc((unsigned) (j * sizeof (char *) + 1));
|
||||
command_indx = (short *) alloc((unsigned) (j * sizeof (short) + 1));
|
||||
|
||||
for (i = j = 0; i < num_commands; i++) {
|
||||
if (ignore_extcmd(i))
|
||||
continue;
|
||||
command_indx[j] = (short) i;
|
||||
command_list[j++] = extcmdlist[i].ef_txt;
|
||||
struct ext_func_tab *ec = extcmds_getentry(matches[i]);
|
||||
|
||||
command_indx[j] = matches[i];
|
||||
command_list[j++] = ec->ef_txt;
|
||||
}
|
||||
command_list[j] = (char *) 0;
|
||||
command_indx[j] = -1;
|
||||
|
||||
@@ -368,11 +368,12 @@ curses_character_input_dialog(const char *prompt, const char *choices,
|
||||
int
|
||||
curses_ext_cmd(void)
|
||||
{
|
||||
int count, letter, prompt_width, startx, starty, winx, winy;
|
||||
int letter, prompt_width, startx, starty, winx, winy;
|
||||
int messageh, messagew, maxlen = BUFSZ - 1;
|
||||
int ret = -1;
|
||||
char cur_choice[BUFSZ];
|
||||
int matches = 0;
|
||||
int *ecmatches;
|
||||
WINDOW *extwin = NULL, *extwin2 = NULL;
|
||||
|
||||
if (iflags.extmenu) {
|
||||
@@ -421,10 +422,12 @@ curses_ext_cmd(void)
|
||||
|
||||
/* if we have an autocomplete command, AND it matches uniquely */
|
||||
if (matches == 1) {
|
||||
struct ext_func_tab *ec = extcmds_getentry(ecmatches[0]);
|
||||
|
||||
curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, ON);
|
||||
wmove(extwin, starty, (int) strlen(cur_choice) + startx + 2);
|
||||
wprintw(extwin, "%s",
|
||||
extcmdlist[ret].ef_txt + (int) strlen(cur_choice));
|
||||
ec->ef_txt + (int) strlen(cur_choice));
|
||||
curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, OFF);
|
||||
}
|
||||
|
||||
@@ -441,13 +444,11 @@ curses_ext_cmd(void)
|
||||
}
|
||||
|
||||
if (letter == '\r' || letter == '\n') {
|
||||
(void) mungspaces(cur_choice);
|
||||
if (ret == -1) {
|
||||
for (count = 0; extcmdlist[count].ef_txt; count++) {
|
||||
if (!strcasecmp(cur_choice, extcmdlist[count].ef_txt)) {
|
||||
ret = count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
matches = extcmds_match(cur_choice, ECM_IGNOREAC|ECM_EXACTMATCH, &ecmatches);
|
||||
if (matches == 1)
|
||||
ret = ecmatches[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -463,6 +464,7 @@ curses_ext_cmd(void)
|
||||
cur_choice[prompt_width - 1] = '\0';
|
||||
letter = '*';
|
||||
prompt_width--;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* honor kill_char if it's ^U or similar, but not if it's '@' */
|
||||
@@ -478,30 +480,16 @@ curses_ext_cmd(void)
|
||||
cur_choice[prompt_width + 1] = '\0';
|
||||
ret = -1;
|
||||
}
|
||||
for (count = 0; extcmdlist[count].ef_txt; count++) {
|
||||
if (!wizard && (extcmdlist[count].flags & WIZMODECMD))
|
||||
continue;
|
||||
if (!(extcmdlist[count].flags & AUTOCOMPLETE))
|
||||
continue;
|
||||
if ((int) strlen(extcmdlist[count].ef_txt) > prompt_width) {
|
||||
if (strncasecmp(cur_choice, extcmdlist[count].ef_txt,
|
||||
prompt_width) == 0) {
|
||||
if ((extcmdlist[count].ef_txt[prompt_width] ==
|
||||
lowc(letter)) || letter == '*') {
|
||||
if (matches == 0) {
|
||||
ret = count;
|
||||
}
|
||||
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
matches = extcmds_match(cur_choice, ECM_NOFLAGS, &ecmatches);
|
||||
if (matches == 1)
|
||||
ret = ecmatches[0];
|
||||
}
|
||||
|
||||
curses_destroy_win(extwin);
|
||||
if (extwin2)
|
||||
curses_destroy_win(extwin2);
|
||||
if (ret == -1 && *cur_choice)
|
||||
pline("%s: unknown extended command.", cur_choice);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,23 +248,13 @@ xwaitforspace(register const char *s) /* chars allowed besides return */
|
||||
static boolean
|
||||
ext_cmd_getlin_hook(char *base)
|
||||
{
|
||||
int oindex, com_index;
|
||||
int *ecmatches;
|
||||
int nmatches = extcmds_match(base, ECM_NOFLAGS, &ecmatches);
|
||||
|
||||
com_index = -1;
|
||||
for (oindex = 0; extcmdlist[oindex].ef_txt != (char *) 0; oindex++) {
|
||||
if (extcmdlist[oindex].flags & (CMD_NOT_AVAILABLE|INTERNALCMD))
|
||||
continue;
|
||||
if ((extcmdlist[oindex].flags & AUTOCOMPLETE)
|
||||
&& !(!wizard && (extcmdlist[oindex].flags & WIZMODECMD))
|
||||
&& !strncmpi(base, extcmdlist[oindex].ef_txt, strlen(base))) {
|
||||
if (com_index == -1) /* no matches yet */
|
||||
com_index = oindex;
|
||||
else /* more than 1 match */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (com_index >= 0) {
|
||||
Strcpy(base, extcmdlist[com_index].ef_txt);
|
||||
if (nmatches == 1) {
|
||||
struct ext_func_tab *ec = extcmds_getentry(ecmatches[0]);
|
||||
|
||||
Strcpy(base, ec->ef_txt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -278,8 +268,9 @@ ext_cmd_getlin_hook(char *base)
|
||||
int
|
||||
tty_get_ext_cmd(void)
|
||||
{
|
||||
int i;
|
||||
char buf[BUFSZ];
|
||||
int nmatches;
|
||||
int *ecmatches;
|
||||
|
||||
if (iflags.extmenu)
|
||||
return extcmd_via_menu();
|
||||
@@ -298,9 +289,7 @@ tty_get_ext_cmd(void)
|
||||
if (buf[0] == 0 || buf[0] == '\033')
|
||||
return -1;
|
||||
|
||||
for (i = 0; extcmdlist[i].ef_txt != (char *) 0; i++)
|
||||
if (!strcmpi(buf, extcmdlist[i].ef_txt))
|
||||
break;
|
||||
nmatches = extcmds_match(buf, ECM_IGNOREAC|ECM_EXACTMATCH, &ecmatches);
|
||||
|
||||
if (!g.in_doagain) {
|
||||
int j;
|
||||
@@ -309,12 +298,12 @@ tty_get_ext_cmd(void)
|
||||
savech('\n');
|
||||
}
|
||||
|
||||
if (extcmdlist[i].ef_txt == (char *) 0) {
|
||||
if (nmatches != 1) {
|
||||
pline("%s: unknown extended command.", buf);
|
||||
i = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return i;
|
||||
return ecmatches[0];
|
||||
}
|
||||
|
||||
#endif /* TTY_GRAPHICS */
|
||||
|
||||
Reference in New Issue
Block a user