aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-07-07 20:30:46 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-07-07 21:21:32 +0200
commitfdb338fe12da6b21b6a7aa8c1090621a359dd9c7 (patch)
tree566577d22eb78d206a5cb3ffac5c0e475a4727b1
parent9056ef41946dca407015ec45505e99d3542e82d1 (diff)
downloadsdn-fdb338fe12da6b21b6a7aa8c1090621a359dd9c7.tar.gz
sdn-fdb338fe12da6b21b6a7aa8c1090621a359dd9c7.tar.xz
sdn-fdb338fe12da6b21b6a7aa8c1090621a359dd9c7.zip
Allow binding to custom key sequences
And document this feature in the manual page.
-rw-r--r--LICENSE2
-rw-r--r--sdn.114
-rw-r--r--sdn.cpp24
3 files changed, 33 insertions, 7 deletions
diff --git a/LICENSE b/LICENSE
index 3bfb256..5e342a0 100644
--- a/LICENSE
+++ b/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.
diff --git a/sdn.1 b/sdn.1
index 07da89e..097a5de 100644
--- a/sdn.1
+++ b/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 ,
diff --git a/sdn.cpp b/sdn.cpp
index 30cdb83..4636ff3 100644
--- a/sdn.cpp
+++ b/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);