]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
changes to placing rl_point after alias-expand-line or history-expand-line
authorChet Ramey <chet.ramey@case.edu>
Wed, 15 Feb 2023 20:31:02 +0000 (15:31 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 15 Feb 2023 20:31:02 +0000 (15:31 -0500)
CWRU/CWRU.chlog
bashline.c
externs.h
lib/readline/tcap.h
stringlib.c

index 8f41fe846be9af8391fc8d071bd02eb660447be8..ca99ee9801f021e0926ebb01e0aa1b76ab161cff 100644 (file)
@@ -5316,10 +5316,14 @@ parse.y
        - execute_variable_command: call bind_lastarg instead of bind_variable
          to avoid exporting $_ if allexport is set. Fix from
          Emanuele Torre <torreemanuele6@gmail.com>
-
-bashhist.c
        - history_delimiting_chars: if we're parsing some kind of delimited
          construct that's *not* a quoted string, don't bother adding an extra
          newline to the history if the current history entry already ends in
          a newline. From https://savannah.gnu.org/support/?110838 via
          Ganapathi Kamath <hgkamath@hotmail.com>
+
+                                  2/13
+                                  ----
+bashline.c
+       - set_up_new_line: add some more heuristics to try and usefully
+         position rl_point
index dfe5ab9bf913e6069365453b616a01b667a2ea74..3238b13a9f9cad13e25af031d0090b56d6bbd7be 100644 (file)
@@ -2707,11 +2707,15 @@ maybe_make_readline_line (const char *new_line)
     }
 }
 
-/* Make NEW_LINE be the current readline line.  This frees NEW_LINE. */
+/* Make NEW_LINE be the current readline line.  This frees NEW_LINE. We use
+   several heuristics to decide where to put rl_point. */
+
 static void
 set_up_new_line (char *new_line)
 {
-  int old_point, at_end;
+
+  int old_point, old_end, dist, nb;
+  char *s, *t;
 
   /* If we didn't expand anything, don't change anything. */
   if (STREQ (new_line, rl_line_buffer))
@@ -2721,7 +2725,9 @@ set_up_new_line (char *new_line)
     }
 
   old_point = rl_point;
-  at_end = rl_point == rl_end;
+  old_end = rl_end;
+  dist = rl_end - rl_point;
+  nb = rl_end - old_end;
 
   /* If the line was history and alias expanded, then make that
      be one thing to undo. */
@@ -2729,14 +2735,31 @@ set_up_new_line (char *new_line)
   free (new_line);
 
   /* Place rl_point where we think it should go. */
-  if (at_end)
+  if (dist == 0)
     rl_point = rl_end;
-  else if (old_point < rl_end)
+  else if (old_point == 0)
     {
+      /* this is what the old code did, but separate it out so we can treat
+        it differently */
+      rl_point = 0;
+      if (!whitespace (rl_line_buffer[rl_point]))
+       rl_forward_word (1, 0);
+    }
+  else if (rl_point < old_point+nb)
+    {
+      /* let's assume that this means the new point is within the changed region */
       rl_point = old_point;
       if (!whitespace (rl_line_buffer[rl_point]))
        rl_forward_word (1, 0);
     }
+  else
+    rl_point = rl_end - dist;  /* try to put point the same distance from end */
+
+  if (rl_point < 0)
+    rl_point = 0;
+  else if (rl_point > rl_end)
+    rl_point = rl_end;
+  rl_mark = 0;         /* XXX */
 }
 
 #if defined (ALIAS)
index 535feb3c0d5a72206f5c1d1009cbf618fce25fff..a5945060d2d6d087fec7ed91b89e94cf14d877cc 100644 (file)
--- a/externs.h
+++ b/externs.h
@@ -169,6 +169,9 @@ extern char *strsub (const char *, const char *, const char *, int);
 extern char *strcreplace (const char *, int, const char *, int);
 extern void strip_leading (char *);
 extern void strip_trailing (char *, int, int);
+extern int str_firstdiff (const char *, const char *);
+extern int str_lastsame (const char *, const char *);
+
 extern void xbcopy (const void *, void *, size_t);
 
 /* Functions from version.c. */
index 1121061b8ecef23ff4847f2611cccd27ffbc8563..467ea60e90391fe84e2cf4276438f183a211524b 100644 (file)
@@ -1,6 +1,6 @@
 /* tcap.h -- termcap library functions and variables. */
 
-/* Copyright (C) 1996-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2015,2023 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.      
@@ -46,14 +46,14 @@ extern char *UP, *BC;
 
 extern short ospeed;
 
-extern int tgetent PARAMS((char *, const char *));
-extern int tgetflag PARAMS((const char *));
-extern int tgetnum PARAMS((const char *));
-extern char *tgetstr PARAMS((const char *, char **));
+extern int tgetent (char *, const char *);
+extern int tgetflag (const char *);
+extern int tgetnum (const char *);
+extern char *tgetstr (const char *, char **);
 
-extern int tputs PARAMS((const char *, int, int (*)(int));
+extern int tputs (const char *, int, int (*)(int));
 
-extern char *tgoto PARAMS((const char *, int, int));
+extern char *tgoto (const char *, int, int);
 
 #endif /* HAVE_TERMCAP_H */
 
index 8fd9d394e7ee27585f7bc401182d1c14db70618c..049f33094efe8405ef879bd9ed456419b3996f39 100644 (file)
@@ -270,6 +270,36 @@ strip_trailing (char *string, int len, int newlines_only)
   string[len + 1] = '\0';
 }
 
+int
+str_firstdiff (const char *s, const char *t)
+{
+  int n;
+
+  if (s == 0 || t == 0 || *s == '\0' || *t == '\0')
+    return 0;
+  for (n = 0; s[n] && t[n] && s[n] == t[n]; n++)
+    ;
+  return n;
+}
+
+/* This returns the index in OLD of a common suffix of OLD and NEW */
+int
+str_lastsame (const char *old, const char *new)
+{
+  const char *o, *n;
+
+  if (old == 0 || *old == '\0' || new == 0 || *new == '\0')
+    return 0;  /* XXX */
+
+  o = old + STRLEN (old) - 1;
+  n = new + STRLEN (new) - 1;
+
+  while (o > old && n > new && (*o == *n))
+    o--, n--;
+
+  return (o - old);
+}
+
 /* A wrapper for bcopy that can be prototyped in general.h */
 void
 xbcopy (const void *s, void *d, size_t n)