txt2key() - parsing key binding specifications
While testing some addtional ?i (list of key assignments) changes, I wanted to give every key a binding. When I tried BIND=M-^A:exploremode the text to key conversion didn't like that. This adds support for M-^x and M-C-x plus variations where dashes are omitted. This adds support for ^? even though that isn't really a control character. I bound #terrain to it and surprising--to me at least--the <delete> key worked to invoke that command. Also changes 'char txt2key(...)' to be 'uchar txt2key(...)'.
This commit is contained in:
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 extern.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.886 $ */
|
/* NetHack 3.7 extern.h $NHDT-Date: 1607561572 2020/12/10 00:52:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.928 $ */
|
||||||
/* Copyright (c) Steve Creps, 1988. */
|
/* Copyright (c) Steve Creps, 1988. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ E void FDECL(pushch, (CHAR_P));
|
|||||||
E void FDECL(savech, (CHAR_P));
|
E void FDECL(savech, (CHAR_P));
|
||||||
E const char *FDECL(key2extcmddesc, (UCHAR_P));
|
E const char *FDECL(key2extcmddesc, (UCHAR_P));
|
||||||
E boolean FDECL(bind_specialkey, (UCHAR_P, const char *));
|
E boolean FDECL(bind_specialkey, (UCHAR_P, const char *));
|
||||||
E char FDECL(txt2key, (char *));
|
E uchar FDECL(txt2key, (char *));
|
||||||
E void FDECL(parseautocomplete, (char *, BOOLEAN_P));
|
E void FDECL(parseautocomplete, (char *, BOOLEAN_P));
|
||||||
E void FDECL(reset_commands, (BOOLEAN_P));
|
E void FDECL(reset_commands, (BOOLEAN_P));
|
||||||
E void FDECL(rhack, (char *));
|
E void FDECL(rhack, (char *));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 cmd.c $NHDT-Date: 1607471879 2020/12/08 23:57:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.429 $ */
|
/* NetHack 3.7 cmd.c $NHDT-Date: 1607561570 2020/12/10 00:52:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.430 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -379,7 +379,7 @@ const struct ext_func_tab *efp; /* if Null, add a footnote to the menu */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* here after #? - now list all full-word commands and provid
|
/* here after #? - now list all full-word commands and provide
|
||||||
some navigation capability through the long list */
|
some navigation capability through the long list */
|
||||||
int
|
int
|
||||||
doextlist(VOID_ARGS)
|
doextlist(VOID_ARGS)
|
||||||
@@ -2858,19 +2858,21 @@ const char *command;
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns a one-byte character from the text (it may massacre the txt
|
/* returns a one-byte character from the text; may change txt[] */
|
||||||
* buffer) */
|
uchar
|
||||||
char
|
|
||||||
txt2key(txt)
|
txt2key(txt)
|
||||||
char *txt;
|
char *txt;
|
||||||
{
|
{
|
||||||
|
uchar uc;
|
||||||
|
boolean makemeta = FALSE;
|
||||||
|
|
||||||
txt = trimspaces(txt);
|
txt = trimspaces(txt);
|
||||||
if (!*txt)
|
if (!*txt)
|
||||||
return '\0';
|
return '\0';
|
||||||
|
|
||||||
/* simple character */
|
/* simple character */
|
||||||
if (!txt[1])
|
if (!txt[1])
|
||||||
return txt[0];
|
return (uchar) txt[0];
|
||||||
|
|
||||||
/* a few special entries */
|
/* a few special entries */
|
||||||
if (!strcmp(txt, "<enter>"))
|
if (!strcmp(txt, "<enter>"))
|
||||||
@@ -2881,25 +2883,55 @@ char *txt;
|
|||||||
return '\033';
|
return '\033';
|
||||||
|
|
||||||
/* control and meta keys */
|
/* control and meta keys */
|
||||||
switch (*txt) {
|
if (highc(*txt) == 'M') {
|
||||||
case 'm': /* can be mx, Mx, m-x, M-x */
|
/*
|
||||||
case 'M':
|
* M <nothing> return 'M'
|
||||||
txt++;
|
* M - <nothing> return M-'-'
|
||||||
|
* M <other><nothing> return M-<other>
|
||||||
|
* otherwise M is pending until after ^/C- processing.
|
||||||
|
* Since trailing spaces are discarded, the only way to
|
||||||
|
* specify M-' ' is via "160".
|
||||||
|
*/
|
||||||
|
if (!txt[1])
|
||||||
|
return (uchar) *txt;
|
||||||
|
/* skip past 'M' or 'm' and maybe '-' */
|
||||||
|
++txt;
|
||||||
if (*txt == '-' && txt[1])
|
if (*txt == '-' && txt[1])
|
||||||
txt++;
|
++txt;
|
||||||
if (txt[1])
|
if (!txt[1])
|
||||||
return '\0';
|
return M((uchar) *txt);
|
||||||
return M(*txt);
|
makemeta = TRUE;
|
||||||
case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */
|
|
||||||
case 'C':
|
|
||||||
case '^':
|
|
||||||
txt++;
|
|
||||||
if (*txt == '-' && txt[1])
|
|
||||||
txt++;
|
|
||||||
if (txt[1])
|
|
||||||
return '\0';
|
|
||||||
return C(*txt);
|
|
||||||
}
|
}
|
||||||
|
if (*txt == '^' || highc(*txt) == 'C') {
|
||||||
|
/*
|
||||||
|
* C <nothing> return 'C' or M-'C'
|
||||||
|
* C - <nothing> return '-' or M-'-'
|
||||||
|
* C [-] <other><nothing> return C-<other> or M-C-<other>
|
||||||
|
* C [-] ? return <rubout>
|
||||||
|
* otherwise return C-<other> or M-C-<other>
|
||||||
|
*/
|
||||||
|
uc = (uchar) *txt;
|
||||||
|
if (!txt[1])
|
||||||
|
return makemeta ? M(uc) : uc;
|
||||||
|
++txt;
|
||||||
|
/* unlike M-x, lots of values of x are invalid for C-x;
|
||||||
|
checking and rejecting them is not worthwhile; GIGO;
|
||||||
|
we do accept "^-x" as synonym for "^x" or "C-x" */
|
||||||
|
if (*txt == '-' && txt[1])
|
||||||
|
++txt;
|
||||||
|
/* and accept ^?, which gets used despite not being a control char */
|
||||||
|
if (*txt == '?')
|
||||||
|
return (uchar) (makemeta ? '\377' : '\177'); /* rubout/delete */
|
||||||
|
uc = C((uchar) *txt);
|
||||||
|
return makemeta ? M(uc) : uc;
|
||||||
|
}
|
||||||
|
if (makemeta && *txt)
|
||||||
|
return M((uchar) *txt);
|
||||||
|
|
||||||
|
/* FIXME: should accept single-quote single-character single-quote
|
||||||
|
and probably single-quote backslash octal-digits single-quote;
|
||||||
|
if we do that, the M- and C- results should be pending until
|
||||||
|
after, so that C-'X' becomes valid for ^X */
|
||||||
|
|
||||||
/* ascii codes: must be three-digit decimal */
|
/* ascii codes: must be three-digit decimal */
|
||||||
if (*txt >= '0' && *txt <= '9') {
|
if (*txt >= '0' && *txt <= '9') {
|
||||||
@@ -2929,9 +2961,9 @@ char *txt; /* sufficiently long buffer */
|
|||||||
if (c == ' ')
|
if (c == ' ')
|
||||||
Sprintf(txt, "<space>");
|
Sprintf(txt, "<space>");
|
||||||
else if (c == '\033')
|
else if (c == '\033')
|
||||||
Sprintf(txt, "<esc>");
|
Sprintf(txt, "<esc>"); /* "<escape>" won't fit */
|
||||||
else if (c == '\n')
|
else if (c == '\n')
|
||||||
Sprintf(txt, "<enter>");
|
Sprintf(txt, "<enter>"); /* "<return>" won't fit */
|
||||||
else if (c == '\177')
|
else if (c == '\177')
|
||||||
Sprintf(txt, "<del>"); /* "<delete>" won't fit */
|
Sprintf(txt, "<del>"); /* "<delete>" won't fit */
|
||||||
else
|
else
|
||||||
|
|||||||
+13
-12
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 options.c $NHDT-Date: 1606445249 2020/11/27 02:47:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.482 $ */
|
/* NetHack 3.7 options.c $NHDT-Date: 1607561571 2020/12/10 00:52:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.484 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Michael Allison, 2008. */
|
/*-Copyright (c) Michael Allison, 2008. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -281,7 +281,7 @@ static boolean FDECL(is_wc2_option, (const char *));
|
|||||||
static boolean FDECL(wc2_supported, (const char *));
|
static boolean FDECL(wc2_supported, (const char *));
|
||||||
static void FDECL(wc_set_font_name, (int, char *));
|
static void FDECL(wc_set_font_name, (int, char *));
|
||||||
static int FDECL(wc_set_window_colors, (char *));
|
static int FDECL(wc_set_window_colors, (char *));
|
||||||
static boolean FDECL(illegal_menu_cmd_key, (CHAR_P));
|
static boolean FDECL(illegal_menu_cmd_key, (UCHAR_P));
|
||||||
#ifndef CHANGE_COLOR
|
#ifndef CHANGE_COLOR
|
||||||
int FDECL(optfn_palette, (int, int, BOOLEAN_P, char *, char *));
|
int FDECL(optfn_palette, (int, int, BOOLEAN_P, char *, char *));
|
||||||
#endif
|
#endif
|
||||||
@@ -4664,7 +4664,7 @@ char *op;
|
|||||||
escapes(op, op_buf);
|
escapes(op, op_buf);
|
||||||
c = *op_buf;
|
c = *op_buf;
|
||||||
|
|
||||||
if (illegal_menu_cmd_key(c))
|
if (illegal_menu_cmd_key((uchar) c))
|
||||||
return optn_err;
|
return optn_err;
|
||||||
add_menu_cmd_alias(c, default_menu_cmd_info[midx].cmd);
|
add_menu_cmd_alias(c, default_menu_cmd_info[midx].cmd);
|
||||||
}
|
}
|
||||||
@@ -6362,10 +6362,10 @@ const char *optn;
|
|||||||
/* parse key:command */
|
/* parse key:command */
|
||||||
boolean
|
boolean
|
||||||
parsebindings(bindings)
|
parsebindings(bindings)
|
||||||
char* bindings;
|
char *bindings;
|
||||||
{
|
{
|
||||||
char *bind;
|
char *bind;
|
||||||
char key;
|
uchar key;
|
||||||
int i;
|
int i;
|
||||||
boolean ret = FALSE;
|
boolean ret = FALSE;
|
||||||
|
|
||||||
@@ -6400,7 +6400,7 @@ char* bindings;
|
|||||||
config_error_add("Bad menu key %s:%s", visctrl(key), bind);
|
config_error_add("Bad menu key %s:%s", visctrl(key), bind);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else
|
} else
|
||||||
add_menu_cmd_alias(key, default_menu_cmd_info[i].cmd);
|
add_menu_cmd_alias((char) key, default_menu_cmd_info[i].cmd);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7151,18 +7151,19 @@ char **opp;
|
|||||||
/* Check if character c is illegal as a menu command key */
|
/* Check if character c is illegal as a menu command key */
|
||||||
boolean
|
boolean
|
||||||
illegal_menu_cmd_key(c)
|
illegal_menu_cmd_key(c)
|
||||||
char c;
|
uchar c;
|
||||||
{
|
{
|
||||||
if (c == 0 || c == '\r' || c == '\n' || c == '\033'
|
if (c == 0 || c == '\r' || c == '\n' || c == '\033' || c == ' '
|
||||||
|| c == ' ' || digit(c) || (letter(c) && c != '@')) {
|
|| digit((char) c) || (letter((char) c) && c != '@')) {
|
||||||
config_error_add("Reserved menu command key '%s'", visctrl(c));
|
config_error_add("Reserved menu command key '%s'", visctrl((char) c));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else { /* reject default object class symbols */
|
} else { /* reject default object class symbols */
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 1; j < MAXOCLASSES; j++)
|
for (j = 1; j < MAXOCLASSES; j++)
|
||||||
if (c == def_oc_syms[j].sym) {
|
if (c == (uchar) def_oc_syms[j].sym) {
|
||||||
config_error_add("Menu command key '%s' is an object class",
|
config_error_add("Menu command key '%s' is an object class",
|
||||||
visctrl(c));
|
visctrl((char) c));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user