#define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */
/*
- * This is currently used only by the tty port and is
- * controlled via runtime option 'extmenu'.
+ * This is currently used only by the tty interface and is
+ * controlled via runtime option 'extmenu'. (Most other interfaces
+ * already use a menu all the time for extended commands.)
+ *
* ``# ?'' is counted towards the limit of the number of commands,
* so we actually support MAX_EXT_CMD-1 "real" extended commands.
*
char buf[BUFSZ];
char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
int i, n, nchoices, acount;
- int ret, biggest;
+ int ret, len, biggest;
int accelerator, prevaccelerator;
int matchlevel = 0;
+ boolean wastoolong, one_per_line;
ret = 0;
cbuf[0] = '\0';
continue;
if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
choices[i] = efp;
- if ((int) strlen(efp->ef_desc) > biggest) {
- biggest = strlen(efp->ef_desc);
- Sprintf(fmtstr, "%%-%ds", biggest + 15);
- }
+ if ((len = (int) strlen(efp->ef_desc)) > biggest)
+ biggest = len;
if (++i > MAX_EXT_CMD) {
#if defined(BETA)
impossible(
choices[i] = (struct ext_func_tab *) 0;
nchoices = i;
/* if we're down to one, we have our selection so get out of here */
- if (nchoices == 1) {
- for (i = 0; extcmdlist[i].ef_txt != (char *) 0; i++)
- if ((extcmdlist[i].flags & AUTOCOMPLETE)
- && !(!wizard && (extcmdlist[i].flags & WIZMODECMD))
- && !strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) {
- ret = i;
- break;
- }
+ if (nchoices <= 1) {
+ ret = (nchoices == 1) ? (int) (choices[0] - extcmdlist) : -1;
break;
}
/* otherwise... */
win = create_nhwindow(NHW_MENU);
start_menu(win);
+ Sprintf(fmtstr, "%%-%ds", biggest + 15);
+ prompt[0] = '\0';
+ wastoolong = FALSE; /* True => had to wrap due to line width
+ * ('w' in wizard mode) */
+ /* -3: two line menu header, 1 line menu footer (for prompt) */
+ one_per_line = (nchoices < ROWNO - 3);
accelerator = prevaccelerator = 0;
acount = 0;
for (i = 0; choices[i]; ++i) {
accelerator = choices[i]->ef_txt[matchlevel];
- if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) {
+ if (accelerator != prevaccelerator || one_per_line)
+ wastoolong = FALSE;
+ if (accelerator != prevaccelerator || one_per_line
+ || (acount >= 2
+ /* +4: + sizeof " or " - sizeof "" */
+ && (strlen(prompt) + 4 + strlen(choices[i]->ef_txt)
+ /* -6: enough room for 1 space left margin
+ * + "%c - " menu selector + 1 space right margin */
+ >= min(sizeof prompt, COLNO - 6)))) {
if (acount) {
/* flush extended cmds for that letter already in buf */
Sprintf(buf, fmtstr, prompt);
add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
buf, FALSE);
acount = 0;
+ if (!(accelerator != prevaccelerator || one_per_line))
+ wastoolong = TRUE;
}
}
prevaccelerator = accelerator;
- if (!acount || nchoices < (ROWNO - 3)) {
- Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,
- choices[i]->ef_desc);
+ if (!acount || one_per_line) {
+ Sprintf(prompt, "%s%s [%s]", wastoolong ? "or " : "",
+ choices[i]->ef_txt, choices[i]->ef_desc);
} else if (acount == 1) {
- Sprintf(prompt, "%s or %s", choices[i - 1]->ef_txt,
- choices[i]->ef_txt);
+ Sprintf(prompt, "%s%s or %s", wastoolong ? "or " : "",
+ choices[i - 1]->ef_txt, choices[i]->ef_txt);
} else {
Strcat(prompt, " or ");
Strcat(prompt, choices[i]->ef_txt);
struct ext_func_tab extcmdlist[] = {
{ '#', "#", "perform an extended command",
doextcmd, IFBURIED | GENERALCMD },
- { M('?'), "?", "get this list of extended commands",
+ { M('?'), "?", "list all extended commands",
doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
{ M('a'), "adjust", "adjust inventory letters",
doorganize, IFBURIED | AUTOCOMPLETE },