nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH V3] input: allow distinguishing shifted from unshifted Meta keyst


From: Benno Schulenberg
Subject: [PATCH V3] input: allow distinguishing shifted from unshifted Meta keystrokes
Date: Thu, 12 Dec 2019 16:18:36 +0100

[V3: Lowercases only the default M-letter bindings.]

When the new option 'splitmeta' is set, nano will differentiate
between Meta+letter and Shift+Meta+letter.  In other words, typing
Alt+a will do something other than typing Alt+A, and binding M-a
will be different from binding M-A.

This kind of addresses https://savannah.gnu.org/bugs/?54659.
Requested-by: Peter Passchier <address@hidden>
---
 src/global.c |  8 ++++++--
 src/nano.c   | 14 +++++++++++++-
 src/nano.h   |  3 ++-
 src/rcfile.c |  3 ++-
 src/winio.c  | 10 ++++++----
 5 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/global.c b/src/global.c
index 1d23ccf4..71e428c4 100644
--- a/src/global.c
+++ b/src/global.c
@@ -499,9 +499,13 @@ int keycode_from_string(const char *keystring)
                else
                        return -1;
        } else if (keystring[0] == 'M') {
-               if (keystring[1] == '-' && keystring[3] == '\0')
+               if (keystring[1] == '-' && keystring[3] == '\0') {
+                       if (ISSET(SPLIT_META))
+                               return (unsigned char)keystring[2];
+                       else
+                               return tolower((unsigned char)keystring[2]);
                        return tolower((unsigned char)keystring[2]);
-               if (strcasecmp(keystring, "M-Space") == 0)
+               } if (strcasecmp(keystring, "M-Space") == 0)
                        return (int)' ';
                else
                        return -1;
diff --git a/src/nano.c b/src/nano.c
index 25a070b4..afbda4f4 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1541,7 +1541,8 @@ void unbound_key(int code)
                if (code == '[')
                        statusline(ALERT, _("Unbindable key: M-["));
                else
-                       statusline(ALERT, _("Unbound key: M-%c"), 
toupper(code));
+                       statusline(ALERT, _("Unbound key: M-%c"),
+                                               ISSET(SPLIT_META) ? code : 
toupper(code));
        } else if (code == ESC_CODE)
                statusline(ALERT, _("Unbindable key: ^["));
        else if (code < 0x20)
@@ -1903,6 +1904,8 @@ int main(int argc, char **argv)
 {
        int stdin_flags, optchr;
 #ifdef ENABLE_NANORC
+       keystruct *basekeys;
+               /* A pointer to where the default key bindings start. */
        bool ignore_rcfiles = FALSE;
                /* Whether to ignore the nanorc files. */
 #endif
@@ -2292,6 +2295,8 @@ int main(int argc, char **argv)
        shortcut_init();
 
 #ifdef ENABLE_NANORC
+       basekeys = sclist;
+
        if (!ignore_rcfiles) {
                /* Back up the command-line options that take an argument. */
 #ifdef ENABLED_WRAPORJUSTIFY
@@ -2384,6 +2389,13 @@ int main(int argc, char **argv)
                for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
                        flags[i] |= flags_cmdline[i];
        }
+
+       /* When using split Meta, change the letter after "M-" to lowercase. */
+       if (ISSET(SPLIT_META)) {
+               for (keystruct *chord = basekeys; chord != NULL; chord = 
chord->next)
+                       if (chord->meta && chord->keystr[3] == '\0')
+                               chord->keystr[2] = tolower(chord->keystr[2]);
+       }
 #endif /* ENABLE_NANORC */
 
        if (hardwrap == 0)
diff --git a/src/nano.h b/src/nano.h
index ba05501c..a568b419 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -537,7 +537,8 @@ enum
        LET_THEM_ZAP,
        BREAK_LONG_LINES,
        JUMPY_SCROLLING,
-       EMPTY_LINE
+       EMPTY_LINE,
+       SPLIT_META
 };
 
 /* Flags for the menus in which a given function should be present. */
diff --git a/src/rcfile.c b/src/rcfile.c
index 97993561..a0d76775 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -89,6 +89,7 @@ static const rcoption rcopts[] = {
 #ifdef ENABLE_SPELLER
        {"speller", 0},
 #endif
+       {"splitmeta", SPLIT_META},
        {"suspend", SUSPEND},
        {"tabsize", 0},
        {"tempfile", TEMP_FILE},
@@ -431,7 +432,7 @@ void parse_binding(char *ptr, bool dobind)
                if (keycopy[2] == '\0') {
                        jot_error(N_("Key name is too short"));
                        goto free_things;
-               } else
+               } else if (!ISSET(SPLIT_META))
                        keycopy[2] = toupper((unsigned char)keycopy[2]);
        }
 
diff --git a/src/winio.c b/src/winio.c
index b702a30c..d905aadd 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -401,9 +401,11 @@ int parse_kbinput(WINDOW *win)
                                                key_buffer_len == 0 || 
*key_buffer == ESC_CODE) {
                                /* One escape followed by a single non-escape:
                                 * meta key sequence mode. */
-                               if (!solitary || (keycode >= 0x20 && keycode < 
0x7F))
+                               if (!solitary || (keycode >= 0x20 && keycode < 
0x7F)) {
                                        meta_key = TRUE;
-                               retval = tolower(keycode);
+                                       retval = ISSET(SPLIT_META) ? keycode : 
tolower(keycode);
+                               } else
+                                       retval = tolower(keycode);
                        } else
                                /* One escape followed by a non-escape, and 
there
                                 * are more codes waiting: escape sequence 
mode. */
@@ -478,7 +480,7 @@ int parse_kbinput(WINDOW *win)
                                                 * or control character 
sequence mode. */
                                                if (!solitary) {
                                                        meta_key = TRUE;
-                                                       retval = 
tolower(keycode);
+                                                       retval = 
ISSET(SPLIT_META) ? keycode : tolower(keycode);
                                                } else
                                                        retval = 
get_control_kbinput(keycode);
                                        else {
@@ -507,7 +509,7 @@ int parse_kbinput(WINDOW *win)
                        if (key_buffer_len == 0) {
                                if (!solitary) {
                                        meta_key = TRUE;
-                                       retval = tolower(keycode);
+                                       retval = ISSET(SPLIT_META) ? keycode : 
tolower(keycode);
                                } else
                                        /* Three escapes followed by a 
non-escape, and no
                                         * other codes are waiting: normal 
input mode. */
-- 
2.24.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]