From 1a4ec6c2d329be3074d9a00a9488c4609fd9a921 Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@justemail.net>
Date: Mon, 20 Jun 2016 22:13:14 +0200
Subject: [PATCH] moving: allow specifying negative numbers in "Go To Line"

The negatives are taken to mean: from the end of the file,
and: from the end of the line.

This fulfills https://savannah.gnu.org/bugs/?48248.
---
 doc/man/nanorc.5      |  3 ++-
 doc/texinfo/nano.texi |  3 ++-
 src/search.c          | 21 ++++++++++++++++-----
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/doc/man/nanorc.5 b/doc/man/nanorc.5
index 40e3a645..2680047e 100644
--- a/doc/man/nanorc.5
+++ b/doc/man/nanorc.5
@@ -518,7 +518,8 @@ Goes to the first line of the file.
 Goes to the last line of the file.
 .TP
 .B gotoline
-Goes to a specific line (and column if specified).
+Goes to a specific line (and column if specified).  Negative numbers count
+from the end of the file (and end of the line).
 .TP
 .B gototext
 Switches from targeting a line number to searching for text.
diff --git a/doc/texinfo/nano.texi b/doc/texinfo/nano.texi
index fb135820..6f26b994 100644
--- a/doc/texinfo/nano.texi
+++ b/doc/texinfo/nano.texi
@@ -1104,7 +1104,8 @@ Goes to the first line of the file.
 Goes to the last line of the file.
 
 @item gotoline
-Goes to a specific line (and column if specified).
+Goes to a specific line (and column if specified).  Negative numbers count
+from the end of the file (and end of the line).
 
 @item gototext
 Switches from targeting a line number to searching for text.
diff --git a/src/search.c b/src/search.c
index 3108ba44..0dc3853b 100644
--- a/src/search.c
+++ b/src/search.c
@@ -932,11 +932,8 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
 	if (i > 0)
 	    return;
 
-	/* Do a bounds check.  Display a warning on an out-of-bounds
-	 * line or column number only if we hit Enter at the statusbar
-	 * prompt. */
-	if (!parse_line_column(answer, &line, &column) ||
-			line < 1 || column < 1) {
+	/* Try to extract one or two numbers from the user's response. */
+	if (!parse_line_column(answer, &line, &column)) {
 	    statusbar(_("Invalid line or column number"));
 	    return;
 	}
@@ -948,10 +945,24 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
 	    column = openfile->placewewant + 1;
     }
 
+    /* Take a negative line number to mean: from the end of the file. */
+    if (line < 0)
+	line = openfile->filebot->lineno + line + 1;
+    if (line < 1)
+	line = 1;
+
+    /* Iterate to the requested line. */
     for (openfile->current = openfile->fileage; line > 1 &&
 		openfile->current != openfile->filebot; line--)
 	openfile->current = openfile->current->next;
 
+    /* Take a negative column number to mean: from the end of the line. */
+    if (column < 0)
+	column = strlenpt(openfile->current->data) + column + 2;
+    if (column < 1)
+	column = 1;
+
+    /* Set the x position that corresponds to the requested column. */
     openfile->current_x = actual_x(openfile->current->data, column - 1);
     openfile->placewewant = column - 1;
 
-- 
GitLab