From e9dee887a92fe0cf81f43c713509f279296ad88c Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Sat, 21 Nov 2009 16:26:59 +0000
Subject: [PATCH] 2009-11-21 Chris Allegretta <chrisa@asty.org>         *
 rcfile.c: Add unbinding keyword, fixes Savannah bug 22852 reported by frankd.

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4433 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog        |  3 +++
 doc/man/nanorc.5 |  7 +++++
 src/rcfile.c     | 67 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index db668b0f..6092ec60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2009-11-21 Chris Allegretta <chrisa@asty.org>
+	* rcfile.c: Add unbinding keyword, fixes Savannah bug 22852 reported by frankd.
+
 2009-11-19 Chris Allegretta <chrisa@asty.org>
 	* nano.c (die_save_file) Try nd match the permissions of the file we were
 	  editing but only make a minimal effort to do so. Fixes Savannah bug 27273
diff --git a/doc/man/nanorc.5 b/doc/man/nanorc.5
index 4d56d7ff..19e9b458 100644
--- a/doc/man/nanorc.5
+++ b/doc/man/nanorc.5
@@ -534,6 +534,13 @@ The 'go to directory' menu.
 .TP
 .B all
 A special name meaning: apply to all menus where this function exists.
+
+.TP
+.B unbind \fIkey\fP \fImenu\fP
+Unbind the key \fIkey\fP from the menu named \fImenu\fP or from all 
+menus by using \fIall\fP.  Same key syntax as for binding.
+Rebinds the key \fIkey\fP to a new function named \fIfunction\fP in the
+context of menu \fImenu\fP.  The format of  \fIkey\fP should be one of:
 .SH FILES
 .TP
 .I SYSCONFDIR/nanorc
diff --git a/src/rcfile.c b/src/rcfile.c
index be1ba2ba..2bd67a67 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -454,7 +454,6 @@ void parse_keybinding(char *ptr)
 	return;
     }
 
-
     /* now let's have some fun.  Try and delete the other entries
        we found for the same menu, then make this new new
        beginning */
@@ -470,6 +469,70 @@ void parse_keybinding(char *ptr)
     sclist = newsc;
 }
 
+/* Let user unbind a sequence from a given (or all) menus */
+void parse_unbinding(char *ptr)
+{
+    char *keyptr = NULL, *keycopy = NULL, *menuptr = NULL;
+    sc *s;
+    int i, menu;
+
+    assert(ptr != NULL);
+
+    if (*ptr == '\0') {
+	rcfile_error(N_("Missing key name"));
+	return;
+    }
+
+    keyptr = ptr;
+    ptr = parse_next_word(ptr);
+    keycopy = mallocstrcpy(NULL, keyptr);
+    for (i = 0; i < strlen(keycopy); i++)
+	keycopy[i] = toupper(keycopy[i]);
+
+#ifdef DEBUG
+    fprintf(stderr, "Starting unbinding code");
+#endif
+
+    if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F' && keycopy[0] != 'K') {
+	rcfile_error(
+		N_("keybindings must begin with \"^\", \"M\", or \"F\""));
+	return;
+    }
+
+    menuptr = ptr;
+    ptr = parse_next_word(ptr);
+
+    if (!strcmp(menuptr, "")) {
+	rcfile_error(
+		/* Note to translators, do not translate the word "all"
+		   in the sentence below, everything else is fine */
+		N_("Must specify menu to bind key to (or \"all\")"));
+	return;
+    }
+
+    menu = strtomenu(menuptr);
+    if (menu < 1) {
+	rcfile_error(
+		N_("Could not map name \"%s\" to a menu"), menuptr);
+	return;
+    }
+
+
+#ifdef DEBUG
+    fprintf(stderr, "unbinding \"%s\" from menu = %d\n", keycopy, menu);
+#endif
+
+    /* Now find the apropriate entries in the menu to delete */
+    for (s = sclist; s != NULL; s = s->next) {
+        if (((s->menu & menu)) && !strcmp(s->keystr,keycopy)) {
+	    s->menu &= ~menu;
+#ifdef DEBUG
+	    fprintf(stderr, "deleted menu entry %d\n", s->menu);
+#endif
+	}
+    }
+}
+
 
 /* Read and parse additional syntax files. */
 void parse_include(char *ptr)
@@ -895,6 +958,8 @@ void parse_rcfile(FILE *rcstream
 	    parse_colors(ptr, TRUE);
 	else if (strcasecmp(keyword, "bind") == 0)
 	    parse_keybinding(ptr);
+	else if (strcasecmp(keyword, "unbind") == 0)
+	    parse_unbinding(ptr);
 #endif /* ENABLE_COLOR */
 	else
 	    rcfile_error(N_("Command \"%s\" not understood"), keyword);
-- 
GitLab