Allow binding to custom key sequences
And document this feature in the manual page.
This commit is contained in:
parent
9056ef4194
commit
fdb338fe12
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2017 - 2020, Přemysl Eric Janouch <p@janouch.name>
|
||||
Copyright (c) 2017 - 2021, Přemysl Eric Janouch <p@janouch.name>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
14
sdn.1
14
sdn.1
@ -98,6 +98,20 @@ normal h parent
|
||||
normal l choose
|
||||
normal M-f4 quit
|
||||
.Ed
|
||||
.Pp
|
||||
Midnight Commander binds the same traversal actions to sequences normally
|
||||
unknown to ncurses, due to them being missing from terminfo.
|
||||
You'll need to define them manually to match your terminal.
|
||||
For rxvt, that would be:
|
||||
.Bd -literal -offset indent
|
||||
define C-ppage ^[[5^
|
||||
define C-npage ^[[6^
|
||||
normal C-ppage parent
|
||||
normal C-npage choose
|
||||
.Ed
|
||||
.Pp
|
||||
Escape characters must be inserted verbatim, e.g., by pressing C-v ESC in vi,
|
||||
or C-q ESC in Emacs.
|
||||
.Ss Pa look
|
||||
Terminal attributes are accepted in a format similar to that of
|
||||
.Xr git-config 1 ,
|
||||
|
24
sdn.cpp
24
sdn.cpp
@ -1,7 +1,7 @@
|
||||
//
|
||||
// sdn: simple directory navigator
|
||||
//
|
||||
// Copyright (c) 2017 - 2020, Přemysl Eric Janouch <p@janouch.name>
|
||||
// Copyright (c) 2017 - 2021, Přemysl Eric Janouch <p@janouch.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted.
|
||||
@ -544,6 +544,7 @@ static struct {
|
||||
|
||||
map<string, wint_t, stringcaseless> name_to_key;
|
||||
map<wint_t, string> key_to_name;
|
||||
map<string, wint_t> custom_keys;
|
||||
string action_names[ACTION_COUNT]; ///< Stylized action names
|
||||
|
||||
// Refreshed by reload():
|
||||
@ -1566,7 +1567,9 @@ fun parse_key (const string &key_name) -> wint_t {
|
||||
c |= ALT;
|
||||
p += 2;
|
||||
}
|
||||
if (!strncmp (p, "C-", 2)) {
|
||||
if (g.name_to_key.count (p)) {
|
||||
return c | g.name_to_key.at (p);
|
||||
} else if (!strncmp (p, "C-", 2)) {
|
||||
p += 2;
|
||||
if (*p < '?' || *p > 'z') {
|
||||
cerr << "bindings: invalid combination: " << key_name << endl;
|
||||
@ -1574,8 +1577,6 @@ fun parse_key (const string &key_name) -> wint_t {
|
||||
}
|
||||
c |= CTRL (toupper (*p));
|
||||
p += 1;
|
||||
} else if (g.name_to_key.count (p)) {
|
||||
return c | g.name_to_key.at (p);
|
||||
} else {
|
||||
wchar_t w; mbstate_t mb {};
|
||||
auto len = strlen (p) + 1, res = mbrtowc (&w, p, len, &mb);
|
||||
@ -1604,7 +1605,9 @@ fun learn_named_key (const string &name, wint_t key) {
|
||||
fun load_bindings () {
|
||||
learn_named_key ("space", ' ');
|
||||
learn_named_key ("escape", 0x1b);
|
||||
for (int kc = KEY_MIN; kc < KEY_MAX; kc++) {
|
||||
|
||||
int kc = 0;
|
||||
for (kc = KEY_MIN; kc <= KEY_MAX; kc++) {
|
||||
const char *name = keyname (kc);
|
||||
if (!name)
|
||||
continue;
|
||||
@ -1638,11 +1641,18 @@ fun load_bindings () {
|
||||
if (tokens.empty ())
|
||||
continue;
|
||||
if (tokens.size () < 3) {
|
||||
cerr << "bindings: expected: context binding action";
|
||||
cerr << "bindings: expected: define name key-sequence"
|
||||
" | context binding action";
|
||||
continue;
|
||||
}
|
||||
|
||||
auto context = tokens[0], key_name = tokens[1], action = tokens[2];
|
||||
if (context == "define") {
|
||||
// We haven't run initscr() yet, so define_key() would fail here
|
||||
learn_named_key (key_name, SYM | (g.custom_keys[action] = ++kc));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto m = g_binding_contexts.find (context);
|
||||
if (m == g_binding_contexts.end ()) {
|
||||
cerr << "bindings: invalid context: " << context << endl;
|
||||
@ -1754,6 +1764,8 @@ int main (int argc, char *argv[]) {
|
||||
cerr << "cannot initialize screen" << endl;
|
||||
return 1;
|
||||
}
|
||||
for (const auto &definition_kc : g.custom_keys)
|
||||
define_key (definition_kc.first.c_str (), definition_kc.second);
|
||||
|
||||
load_colors ();
|
||||
load_cmdline (argc, argv);
|
||||
|
Loading…
Reference in New Issue
Block a user