summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2023-02-15 15:31:02 -0500
committerChet Ramey <chet.ramey@case.edu>2023-02-15 15:31:02 -0500
commit5857180657e632de6956f2d30fe7004f0e99bb46 (patch)
tree5f7598fa92b0201ebdf352a6f90bcef72e284ac1
parentd7a6d947dfdbb41d806f4bd65f8a74bffb5acbb4 (diff)
downloadbash-5857180657e632de6956f2d30fe7004f0e99bb46.tar.gz
changes to placing rl_point after alias-expand-line or history-expand-line
-rw-r--r--CWRU/CWRU.chlog8
-rw-r--r--bashline.c33
-rw-r--r--externs.h3
-rw-r--r--lib/readline/tcap.h14
-rw-r--r--stringlib.c30
5 files changed, 74 insertions, 14 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog
index 8f41fe84..ca99ee98 100644
--- a/CWRU/CWRU.chlog
+++ b/CWRU/CWRU.chlog
@@ -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
diff --git a/bashline.c b/bashline.c
index dfe5ab9b..3238b13a 100644
--- a/bashline.c
+++ b/bashline.c
@@ -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)
diff --git a/externs.h b/externs.h
index 535feb3c..a5945060 100644
--- 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. */
diff --git a/lib/readline/tcap.h b/lib/readline/tcap.h
index 1121061b..467ea60e 100644
--- a/lib/readline/tcap.h
+++ b/lib/readline/tcap.h
@@ -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 */
diff --git a/stringlib.c b/stringlib.c
index 8fd9d394..049f3309 100644
--- a/stringlib.c
+++ b/stringlib.c
@@ -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)