From a8043200cb6e517b13debe4413d46f27a924400f Mon Sep 17 00:00:00 2001
From: Koichi Murase <myoga.murase@gmail.com>
Date: Mon, 11 Feb 2019 19:02:17 +0900
Subject: [PATCH 1/2] support "bind -x" for different keymaps

---
 bashline.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/bashline.c b/bashline.c
index 489be69..ed20b8b 100644
--- a/bashline.c
+++ b/bashline.c
@@ -64,6 +64,7 @@
 #include "builtins/common.h"
 
 #include <readline/rlconf.h>
+#include <readline/rldefs.h>
 #include <readline/readline.h>
 #include <readline/history.h>
 #include <readline/rlmbutil.h>
@@ -183,6 +184,7 @@ static int putx __P((int));
 #endif
 static int bash_execute_unix_command __P((int, int));
 static void init_unix_command_map __P((void));
+static Keymap get_unix_command_map __P((Keymap));
 static int isolate_sequence __P((char *, int, int, int *));
 
 static int set_saved_history __P((void));
@@ -4162,7 +4164,10 @@ bash_quote_filename (s, rtype, qcp)
 }
 
 /* Support for binding readline key sequences to Unix commands. */
-static Keymap cmd_xmap;
+static Keymap cmd_xmap_emacs_standard;
+static Keymap cmd_xmap_vi_insertion;
+static Keymap cmd_xmap_vi_movement;
+static Keymap cmd_xmap_other;
 
 #ifdef _MINIX
 static void
@@ -4191,10 +4196,13 @@ bash_execute_unix_command (count, key)
   char *cmd, *value, *ce, old_ch;
   SHELL_VAR *v;
   char ibuf[INT_STRLEN_BOUND(int) + 1];
+  Keymap cmd_xmap;
 
   /* First, we need to find the right command to execute.  This is tricky,
      because we might have already indirected into another keymap, so we
      have to walk cmd_xmap using the entire key sequence. */
+
+  cmd_xmap = get_unix_command_map (rl_executing_keymap);
   cmd = (char *)rl_function_of_keyseq_len (rl_executing_keyseq, rl_key_sequence_length, cmd_xmap, &type);
     
   if (cmd == 0 || type != ISMACR)
@@ -4282,9 +4290,10 @@ bash_execute_unix_command (count, key)
 int
 print_unix_command_map ()
 {
-  Keymap save;
+  Keymap save, cmd_xmap;
 
   save = rl_get_keymap ();
+  cmd_xmap = get_unix_command_map (save);
   rl_set_keymap (cmd_xmap);
   rl_macro_dumper (1);
   rl_set_keymap (save);
@@ -4294,7 +4303,35 @@ print_unix_command_map ()
 static void
 init_unix_command_map ()
 {
-  cmd_xmap = rl_make_bare_keymap ();
+  cmd_xmap_emacs_standard = rl_make_bare_keymap ();
+  cmd_xmap_vi_insertion = rl_make_bare_keymap ();
+  cmd_xmap_vi_movement = rl_make_bare_keymap ();
+  cmd_xmap_other = rl_make_bare_keymap ();
+  cmd_xmap_emacs_standard[CTRL ('X')].type = ISKMAP;
+  cmd_xmap_emacs_standard[CTRL ('X')].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
+  cmd_xmap_emacs_standard[CTRL ('[')].type = ISKMAP;
+  cmd_xmap_emacs_standard[CTRL ('[')].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
+}
+
+static Keymap
+get_unix_command_map (keymap)
+      Keymap keymap;
+{
+  if (cmd_xmap_emacs_standard == 0)
+    init_unix_command_map ();
+
+  if (keymap == emacs_standard_keymap)
+    return cmd_xmap_emacs_standard;
+  else if (keymap == emacs_ctlx_keymap)
+    return FUNCTION_TO_KEYMAP (cmd_xmap_emacs_standard, CTRL ('X'));
+  else if (keymap == emacs_meta_keymap)
+    return FUNCTION_TO_KEYMAP (cmd_xmap_emacs_standard, CTRL ('['));
+  else if (keymap == vi_insertion_keymap)
+    return cmd_xmap_vi_insertion;
+  else if (keymap == vi_movement_keymap)
+    return cmd_xmap_vi_movement;
+  else
+    return cmd_xmap_other;
 }
 
 static int
@@ -4353,9 +4390,7 @@ bind_keyseq_to_unix_command (line)
   Keymap kmap;
   char *kseq, *value;
   int i, kstart;
-
-  if (cmd_xmap == 0)
-    init_unix_command_map ();
+  Keymap cmd_xmap;
 
   kmap = rl_get_keymap ();
 
@@ -4389,6 +4424,7 @@ bind_keyseq_to_unix_command (line)
   value = substring (line, kstart, i);
 
   /* Save the command to execute and the key sequence in the CMD_XMAP */
+  cmd_xmap = get_unix_command_map (kmap);
   rl_generic_bind (ISMACR, kseq, value, cmd_xmap);
 
   /* and bind the key sequence in the current keymap to a function that
-- 
2.9.5

