From 57d3fdb7de4b7211a616f76601a60e1a57c2d04b Mon Sep 17 00:00:00 2001
From: Koichi Murase <myoga.murase@gmail.com>
Date: Mon, 11 Feb 2019 12:43:31 +0900
Subject: [PATCH 1/3] translate meta characters when convert-meta is set

---
 lib/readline/bind.c | 64 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 34 insertions(+), 30 deletions(-)

diff --git a/lib/readline/bind.c b/lib/readline/bind.c
index 57ae10f..042c345 100644
--- a/lib/readline/bind.c
+++ b/lib/readline/bind.c
@@ -143,17 +143,21 @@ rl_bind_key (int key, rl_command_func_t *function)
 
   if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
     {
-      if (_rl_keymap[ESC].type == ISKMAP)
-	{
-	  Keymap escmap;
+      Keymap escmap;
 
-	  escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
-	  key = UNMETA (key);
-	  escmap[key].type = ISFUNC;
-	  escmap[key].function = function;
-	  return (0);
+      if (_rl_keymap[ESC].type != ISKMAP)
+	{
+	  if (_rl_keymap[key].type == ISMACR)
+	    xfree ((char *)_rl_keymap[key].function);
+	  _rl_keymap[key].type = ISKMAP;
+	  _rl_keymap[key].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
 	}
-      return (key);
+
+      escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
+      key = UNMETA (key);
+      escmap[key].type = ISFUNC;
+      escmap[key].function = function;
+      return (0);
     }
 
   /* If it's bound to a function or macro, just overwrite.  Otherwise we have
@@ -397,16 +401,6 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
 	  return -1;
         }
 
-      if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
-	{
-	  ic = UNMETA (ic);
-	  if (map[ESC].type == ISKMAP)
-	    {
-	      prevmap = map;
-	      map = FUNCTION_TO_KEYMAP (map, ESC);
-	    }
-	}
-
       if ((i + 1) < keys_len)
 	{
 	  if (map[ic].type != ISKMAP)
@@ -492,7 +486,8 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
 int
 rl_translate_keyseq (const char *seq, char *array, int *len)
 {
-  register int i, c, l, temp;
+  register int i, l, temp;
+  unsigned char c;
 
   for (i = l = 0; c = seq[i]; i++)
     {
@@ -520,8 +515,11 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
 		{
 		  i++;		/* seq[i] == '-' */
 		  /* XXX - obey convert-meta setting */
-		  if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
-		    array[l++] = ESC;	/* ESC is meta-prefix */
+		  if (_rl_convert_meta_chars_to_ascii)
+		    {
+		      array[l++] = ESC;	/* ESC is meta-prefix */
+		      array[l++] = UNMETA (seq[++i]);
+		    }
 		  else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')
 		    {
 		      i += 4;
@@ -590,8 +588,8 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
 	      for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++)
 	        c = (c * 8) + OCTVALUE (seq[i]);
 	      i--;	/* auto-increment in for loop */
-	      array[l++] = c & largest_char;
-	      break;
+	      c &= largest_char;
+	      goto normal_char;
 	    case 'x':
 	      i++;
 	      for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
@@ -599,16 +597,22 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
 	      if (temp == 2)
 	        c = 'x';
 	      i--;	/* auto-increment in for loop */
-	      array[l++] = c & largest_char;
-	      break;
-	    default:	/* backslashes before non-special chars just add the char */
-	      array[l++] = c;
-	      break;	/* the backslash is stripped */
+	      c &= largest_char;
+	      goto normal_char;
+	    default:		/* backslashes before non-special chars just add the char */
+	      goto normal_char;	/* the backslash is stripped */
 	    }
 	  continue;
 	}
 
-      array[l++] = c;
+    normal_char:
+      if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
+	{
+	  array[l++] = ESC;	/* ESC is meta-prefix */
+	  array[l++] = UNMETA (c);
+	}
+      else
+	array[l++] = c;
     }
 
   *len = l;
-- 
2.9.5

