Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libedit GNU readline(3) regards history chronologically, ...



details:   https://anonhg.NetBSD.org/src/rev/49dd00cf60b7
branches:  trunk
changeset: 815283:49dd00cf60b7
user:      christos <christos%NetBSD.org@localhost>
date:      Mon May 09 21:27:55 2016 +0000

description:
GNU readline(3) regards history chronologically, that is, from the
perspective of the dawn of time, so "next" means "newer" and "previous"
means "older".  Libedit, by contrast, uses reverse chronology and
regards history from the perspective of the present, such that "next"
means "longer ago" and "previous" means "not so long ago".

The following patch fixes previous_history() and next_history()
as proposed by Bastian Maerkisch.

But there is a related problem demonstrated by Bastian's regression
tests that his patch did not fix:  next_history() can advance not
only to the newest entry, but beyond it, which core libedit cannot
do.  So that feature must be implemented locally in readline.c.

With that, the last of Bastians tests is fixed, test_movement_direction().

This patch also improves libedit documentation to more clearly state
what "previous" and "next" mean.  GNU readline documentation is
just as unclear, but we can't easily fix that since libedit doesn't
include its own readline.3 manual.

(Ingo Schwarze)

diffstat:

 lib/libedit/editline.3 |   6 ++++--
 lib/libedit/editline.7 |   6 ++++--
 lib/libedit/readline.c |  32 +++++++++++++++++++++++++++-----
 3 files changed, 35 insertions(+), 9 deletions(-)

diffs (171 lines):

diff -r 983eac2b9aab -r 49dd00cf60b7 lib/libedit/editline.3
--- a/lib/libedit/editline.3    Mon May 09 21:25:11 2016 +0000
+++ b/lib/libedit/editline.3    Mon May 09 21:27:55 2016 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: editline.3,v 1.89 2016/04/28 15:50:33 christos Exp $
+.\"    $NetBSD: editline.3,v 1.90 2016/05/09 21:27:55 christos Exp $
 .\"
 .\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -26,7 +26,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 24, 2016
+.Dd May 9, 2016
 .Dt EDITLINE 3
 .Os
 .Sh NAME
@@ -761,8 +761,10 @@
 Return the last element in the history.
 .It Dv H_PREV
 Return the previous element in the history.
+It is newer than the current one.
 .It Dv H_NEXT
 Return the next element in the history.
+It is older than the current one.
 .It Dv H_CURR
 Return the current element in the history.
 .It Dv H_SET
diff -r 983eac2b9aab -r 49dd00cf60b7 lib/libedit/editline.7
--- a/lib/libedit/editline.7    Mon May 09 21:25:11 2016 +0000
+++ b/lib/libedit/editline.7    Mon May 09 21:27:55 2016 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: editline.7,v 1.4 2016/05/02 12:51:25 wiz Exp $
+.\"    $NetBSD: editline.7,v 1.5 2016/05/09 21:27:55 christos Exp $
 .\"    $OpenBSD: editline.7,v 1.1 2016/04/20 01:11:45 schwarze Exp $
 .\"
 .\" Copyright (c) 2016 Ingo Schwarze <schwarze%openbsd.org@localhost>
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd May 2, 2016
+.Dd May 7, 2016
 .Dt EDITLINE 7
 .Os
 .Sh NAME
@@ -408,6 +408,7 @@
 buffer.
 .It Ic ed-next-history Pq vi command: j, +, Ctrl-N; emacs: Ctrl-N
 Replace the edit buffer with the next history line.
+That line is older than the current line.
 With an argument, go forward by that number of history lines.
 It is a non-fatal error to advance by more lines than are available.
 .It Ic ed-next-line Pq not bound by default
@@ -427,6 +428,7 @@
 edit buffer.
 .It Ic ed-prev-history Pq vi command: k, -, Ctrl-P; emacs: Ctrl-P
 Replace the edit buffer with the previous history line.
+That line is newer than the current line.
 With an argument, go back by that number of lines.
 It is a non-fatal error to back up by more lines than are available.
 .It Ic ed-prev-line Pq not bound by default
diff -r 983eac2b9aab -r 49dd00cf60b7 lib/libedit/readline.c
--- a/lib/libedit/readline.c    Mon May 09 21:25:11 2016 +0000
+++ b/lib/libedit/readline.c    Mon May 09 21:27:55 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: readline.c,v 1.131 2016/05/09 21:25:11 christos Exp $  */
+/*     $NetBSD: readline.c,v 1.132 2016/05/09 21:27:55 christos Exp $  */
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: readline.c,v 1.131 2016/05/09 21:25:11 christos Exp $");
+__RCSID("$NetBSD: readline.c,v 1.132 2016/05/09 21:27:55 christos Exp $");
 #endif /* not lint && not SCCSID */
 
 #include <sys/types.h>
@@ -156,6 +156,14 @@
  */
 int rl_completion_append_character = ' ';
 
+/*
+ * When the history cursor is on the newest element and next_history()
+ * is called, GNU readline moves the cursor beyond the newest element.
+ * The editline library does not provide data structures to express
+ * that state, so we need a local flag.
+ */
+static int current_history_valid = 1;
+
 /* stuff below is used internally by libedit for readline emulation */
 
 static History *h = NULL;
@@ -291,6 +299,8 @@
        int editmode = 1;
        struct termios t;
 
+       current_history_valid = 1;
+
        if (e != NULL)
                el_end(e);
        if (h != NULL)
@@ -1451,6 +1461,7 @@
        (void)history(h, &ev, H_ENTER, line);
        if (history(h, &ev, H_GETSIZE) == 0)
                history_length = ev.num;
+       current_history_valid = 1;
 
        return !(history_length > 0); /* return 0 if all is okay */
 }
@@ -1543,6 +1554,7 @@
 
        (void)history(h, &ev, H_CLEAR);
        history_length = 0;
+       current_history_valid = 1;
 }
 
 
@@ -1575,7 +1587,7 @@
 current_history(void)
 {
 
-       return _move_history(H_CURR);
+       return current_history_valid ? _move_history(H_CURR) : NULL;
 }
 
 
@@ -1620,6 +1632,7 @@
 
        (void)history(h, &ev, H_CURR);
        curr_num = ev.num;
+       current_history_valid = 1;
 
        /*
         * use H_DELDATA to set to nth history (without delete) by passing
@@ -1635,12 +1648,17 @@
 
 /*
  * returns previous event in history and shifts pointer accordingly
+ * Note that readline and editline define directions in opposite ways.
  */
 HIST_ENTRY *
 previous_history(void)
 {
 
-       return _move_history(H_PREV);
+       if (current_history_valid == 0) {
+               current_history_valid = 1;
+               return _move_history(H_CURR);
+       }
+       return _move_history(H_NEXT);
 }
 
 
@@ -1650,8 +1668,12 @@
 HIST_ENTRY *
 next_history(void)
 {
+       HIST_ENTRY *he;
 
-       return _move_history(H_NEXT);
+       he = _move_history(H_PREV);
+       if (he == NULL)
+               current_history_valid = 0;
+       return he;
 }
 
 



Home | Main Index | Thread Index | Old Index