]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - lib/readline/isearch.c
bash-5.1-alpha release
[thirdparty/bash.git] / lib / readline / isearch.c
index 6f6a7a6583954940aee5e422a6e221c66c5d993a..201a37bbcff0d4c84fa2e92a8792a70e2f73c078 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                 */
 /* **************************************************************** */
 
-/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library (Readline), a library
    for reading lines of text with interactive input and history editing.      
@@ -66,7 +66,6 @@ static int rl_search_history PARAMS((int, int));
 
 static _rl_search_cxt *_rl_isearch_init PARAMS((int));
 static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
-static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
 
 /* Last line found by the current incremental search, so we don't `find'
    identical lines many times in a row.  Now part of isearch context. */
@@ -79,8 +78,7 @@ static int last_isearch_string_len;
 static char * const default_isearch_terminators = "\033\012";
 
 _rl_search_cxt *
-_rl_scxt_alloc (type, flags)
-     int type, flags;
+_rl_scxt_alloc (int type, int flags)
 {
   _rl_search_cxt *cxt;
 
@@ -121,9 +119,7 @@ _rl_scxt_alloc (type, flags)
 }
 
 void
-_rl_scxt_dispose (cxt, flags)
-     _rl_search_cxt *cxt;
-     int flags;
+_rl_scxt_dispose (_rl_search_cxt *cxt, int flags)
 {
   FREE (cxt->search_string);
   FREE (cxt->allocated_line);
@@ -135,8 +131,7 @@ _rl_scxt_dispose (cxt, flags)
 /* Search backwards through the history looking for a string which is typed
    interactively.  Start with the current line. */
 int
-rl_reverse_search_history (sign, key)
-     int sign, key;
+rl_reverse_search_history (int sign, int key)
 {
   return (rl_search_history (-sign, key));
 }
@@ -144,8 +139,7 @@ rl_reverse_search_history (sign, key)
 /* Search forwards through the history looking for a string which is typed
    interactively.  Start with the current line. */
 int
-rl_forward_search_history (sign, key)
-     int sign, key;
+rl_forward_search_history (int sign, int key)
 {
   return (rl_search_history (sign, key));
 }
@@ -156,9 +150,7 @@ rl_forward_search_history (sign, key)
    WHERE is the history list number of the current line.  If it is
    -1, then this line is the starting one. */
 static void
-rl_display_search (search_string, flags, where)
-     char *search_string;
-     int flags, where;
+rl_display_search (char *search_string, int flags, int where)
 {
   char *message;
   int msglen, searchlen;
@@ -193,11 +185,13 @@ rl_display_search (search_string, flags, where)
   strcpy (message + msglen, "i-search)`");
   msglen += 10;
 
-  if (search_string)
+  if (search_string && *search_string)
     {
       strcpy (message + msglen, search_string);
       msglen += searchlen;
     }
+  else
+    _rl_optimize_redisplay ();
 
   strcpy (message + msglen, "': ");
 
@@ -207,8 +201,7 @@ rl_display_search (search_string, flags, where)
 }
 
 static _rl_search_cxt *
-_rl_isearch_init (direction)
-     int direction;
+_rl_isearch_init (int direction)
 {
   _rl_search_cxt *cxt;
   register int i;
@@ -264,15 +257,17 @@ _rl_isearch_init (direction)
 
   _rl_iscxt = cxt;             /* save globally */
 
+  /* experimental right now */
+  _rl_init_executing_keyseq ();
+
   return cxt;
 }
 
 static void
-_rl_isearch_fini (cxt)
-     _rl_search_cxt *cxt;
+_rl_isearch_fini (_rl_search_cxt *cxt)
 {
   /* First put back the original state. */
-  strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
+  rl_replace_line (cxt->lines[cxt->save_line], 0);
 
   rl_restore_prompt ();
 
@@ -297,18 +292,24 @@ _rl_isearch_fini (cxt)
       else
        cxt->sline_index = strlen (rl_line_buffer);
       rl_mark = cxt->save_mark;
+      rl_deactivate_mark ();
     }
 
   rl_point = cxt->sline_index;
   /* Don't worry about where to put the mark here; rl_get_previous_history
-     and rl_get_next_history take care of it. */
+     and rl_get_next_history take care of it.
+     If we want to highlight the search string, this is where to set the
+     point and mark to do it. */
+  _rl_fix_point (0);
+  rl_deactivate_mark ();
 
+/*  _rl_optimize_redisplay (); */
   rl_clear_message ();
 }
 
+/* XXX - we could use _rl_bracketed_read_mbstring () here. */
 int
-_rl_search_getchar (cxt)
-     _rl_search_cxt *cxt;
+_rl_search_getchar (_rl_search_cxt *cxt)
 {
   int c;
 
@@ -335,11 +336,12 @@ _rl_search_getchar (cxt)
    -1 if the caller should just free the context and return, 0 if we should
    break out of the loop, and 1 if we should continue to read characters. */
 int
-_rl_isearch_dispatch (cxt, c)
-     _rl_search_cxt *cxt;
-     int c;
+_rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
 {
-  int n, wstart, wlen, limit, cval;
+  int n, wstart, wlen, limit, cval, incr;
+  char *paste;
+  size_t pastelen;
+  int j;
   rl_command_func_t *f;
 
   f = (rl_command_func_t *)NULL;
@@ -351,6 +353,24 @@ _rl_isearch_dispatch (cxt, c)
       return -1;
     }
 
+  _rl_add_executing_keyseq (c);
+
+  /* XXX - experimental code to allow users to bracketed-paste into the search
+     string even when ESC is one of the isearch-terminators. Not perfect yet. */
+  if (_rl_enable_bracketed_paste && c == ESC && strchr (cxt->search_terminators, c) && (n = _rl_nchars_available ()) > (2*BRACK_PASTE_SLEN-1))
+    {
+      j = _rl_read_bracketed_paste_prefix (c);
+      if (j == 1)
+       {
+         cxt->lastc = -7;              /* bracketed paste, see below */
+         goto opcode_dispatch; 
+        }
+      else if (_rl_pushed_input_available ())  /* eat extra char we pushed back */
+       c = cxt->lastc = rl_read_key ();
+      else
+       c = cxt->lastc;                 /* last ditch */
+    }
+
   /* If we are moving into a new keymap, modify cxt->keymap and go on.
      This can be a problem if c == ESC and we want to terminate the
      incremental search, so we check */
@@ -396,7 +416,16 @@ add_character:
   /* Translate the keys we do something with to opcodes. */
   if (c >= 0 && cxt->keymap[c].type == ISFUNC)
     {
-      f = cxt->keymap[c].function;
+      /* If we have a multibyte character, see if it's bound to something that
+        affects the search. */
+      if (cxt->mb[1])
+       f = rl_function_of_keyseq (cxt->mb, cxt->keymap, (int *)NULL);
+      else
+       {
+         f = cxt->keymap[c].function;
+         if (f == rl_do_lowercase_version)
+           f = cxt->keymap[_rl_to_lower (c)].function;
+       }
 
       if (f == rl_reverse_search_history)
        cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
@@ -410,6 +439,8 @@ add_character:
        cxt->lastc = -5;
       else if (c == CTRL ('Y') || f == rl_yank)        /* XXX */
        cxt->lastc = -6;
+      else if (f == rl_bracketed_paste_begin)
+       cxt->lastc = -7;
     }
 
   /* If we changed the keymap earlier while translating a key sequence into
@@ -461,9 +492,14 @@ add_character:
        }
       else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert)
        {
-         rl_stuff_char (cxt->lastc);
-         rl_execute_next (cxt->prevc);
-         /* XXX - do we insert everything in cxt->pmb? */
+         _rl_term_executing_keyseq ();         /* should this go in the caller? */
+
+         _rl_pending_command.map = cxt->keymap;
+         _rl_pending_command.count = 1;        /* XXX */
+         _rl_pending_command.key = cxt->lastc;
+         _rl_pending_command.func = f;
+         _rl_command_to_execute = &_rl_pending_command;
+
          return (0);
        }
     }
@@ -509,6 +545,9 @@ add_character:
        return (0);
       }
 
+  _rl_init_executing_keyseq ();
+
+opcode_dispatch:
   /* Now dispatch on the character.  `Opcodes' affect the search string or
      state.  Other characters are added to the string.  */
   switch (cxt->lastc)
@@ -526,9 +565,10 @@ add_character:
              rl_display_search (cxt->search_string, cxt->sflags, -1);
              break;
            }
+         /* XXX - restore keymap here? */
          return (1);
        }
-      else if (cxt->sflags & SF_REVERSE)
+      else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0)
        cxt->sline_index--;
       else if (cxt->sline_index != cxt->sline_len)
        cxt->sline_index++;
@@ -553,14 +593,27 @@ add_character:
         do until we have a real isearch-undo. */
       if (cxt->search_string_index == 0)
        rl_ding ();
-      else
+      else if (MB_CUR_MAX == 1 || rl_byte_oriented)
        cxt->search_string[--cxt->search_string_index] = '\0';
+      else
+       {
+         wstart = _rl_find_prev_mbchar (cxt->search_string, cxt->search_string_index, MB_FIND_NONZERO);
+         if (wstart >= 0)
+           cxt->search_string[cxt->search_string_index = wstart] = '\0';
+         else
+           cxt->search_string[cxt->search_string_index = 0] = '\0';
+       }
+
+      if (cxt->search_string_index == 0)
+       rl_ding ();
+
       break;
 
     case -4:   /* C-G, abort */
       rl_replace_line (cxt->lines[cxt->save_line], 0);
       rl_point = cxt->save_point;
       rl_mark = cxt->save_mark;
+      rl_deactivate_mark ();
       rl_restore_prompt();
       rl_clear_message ();
 
@@ -620,22 +673,45 @@ add_character:
       cxt->search_string[cxt->search_string_index] = '\0';
       break;
 
+    case -7:   /* bracketed paste */
+      paste = _rl_bracketed_text (&pastelen);
+      if (paste == 0 || *paste == 0)
+       {
+         free (paste);
+         break;
+       }
+      rl_activate_mark ();
+      if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size)
+       {
+         cxt->search_string_size += pastelen + 2;
+         cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+       }
+      strcpy (cxt->search_string + cxt->search_string_index, paste);
+      cxt->search_string_index += pastelen;
+      free (paste);
+      break;
+
     /* Add character to search string and continue search. */
     default:
-      if (cxt->search_string_index + 2 >= cxt->search_string_size)
+#if defined (HANDLE_MULTIBYTE)
+      wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb);
+#else
+      wlen = 1;
+#endif
+      if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
        {
-         cxt->search_string_size += 128;
+         cxt->search_string_size += 128;       /* 128 much greater than MB_CUR_MAX */
          cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
        }
 #if defined (HANDLE_MULTIBYTE)
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        {
-         int j, l;
+         int j;
 
          if (cxt->mb[0] == 0 || cxt->mb[1] == 0)
            cxt->search_string[cxt->search_string_index++] = cxt->mb[0];
          else
-           for (j = 0, l = RL_STRLEN (cxt->mb); j < l; )
+           for (j = 0; j < wlen; )
              cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
        }
       else
@@ -647,6 +723,12 @@ add_character:
 
   for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
     {
+      if (cxt->search_string_index == 0)
+       {
+         cxt->sflags |= SF_FAILED;
+         break;
+       }
+
       limit = cxt->sline_len - cxt->search_string_index + 1;
 
       /* Search the current line. */
@@ -659,6 +741,12 @@ add_character:
            }
          else
            cxt->sline_index += cxt->direction;
+
+         if (cxt->sline_index < 0)
+           {
+             cxt->sline_index = 0;
+             break;
+           }
        }
       if (cxt->sflags & SF_FOUND)
        break;
@@ -686,17 +774,26 @@ add_character:
             (cxt->search_string_index > cxt->sline_len));
 
       if (cxt->sflags & SF_FAILED)
-       break;
+       {
+         /* XXX - reset sline_index if < 0 */
+         if (cxt->sline_index < 0)
+           cxt->sline_index = 0;
+         break;
+       }
 
       /* Now set up the line for searching... */
       cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
     }
 
+  /* reset the keymaps for the next time through the loop */
+  cxt->keymap = cxt->okeymap = _rl_keymap;
+
   if (cxt->sflags & SF_FAILED)
     {
       /* We cannot find the search string.  Ding the bell. */
       rl_ding ();
       cxt->history_pos = cxt->last_found_line;
+      rl_deactivate_mark ();
       rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
       return 1;
     }
@@ -708,7 +805,10 @@ add_character:
     {
       cxt->prev_line_found = cxt->lines[cxt->history_pos];
       rl_replace_line (cxt->lines[cxt->history_pos], 0);
+      rl_activate_mark ();     
       rl_point = cxt->sline_index;
+      if (rl_mark_active_p () && cxt->search_string_index > 0)
+       rl_mark = rl_point + cxt->search_string_index;
       cxt->last_found_line = cxt->history_pos;
       rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
     }
@@ -716,10 +816,8 @@ add_character:
   return 1;
 }
 
-static int
-_rl_isearch_cleanup (cxt, r)
-     _rl_search_cxt *cxt;
-     int r;
+int
+_rl_isearch_cleanup (_rl_search_cxt *cxt, int r)
 {
   if (r >= 0)
     _rl_isearch_fini (cxt);
@@ -736,8 +834,7 @@ _rl_isearch_cleanup (cxt, r)
    DIRECTION is which direction to search; >= 0 means forward, < 0 means
    backwards. */
 static int
-rl_search_history (direction, invoking_key)
-     int direction, invoking_key;
+rl_search_history (int direction, int invoking_key)
 {
   _rl_search_cxt *cxt;         /* local for now, but saved globally */
   int c, r;
@@ -775,8 +872,7 @@ rl_search_history (direction, invoking_key)
    If _rl_isearch_dispatch finishes searching, this function is responsible
    for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
 int
-_rl_isearch_callback (cxt)
-     _rl_search_cxt *cxt;
+_rl_isearch_callback (_rl_search_cxt *cxt)
 {
   int c, r;