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.
master
Benno Schulenberg 2016-06-20 22:13:14 +02:00
parent 6bb30978fb
commit 1a4ec6c2d3
3 changed files with 20 additions and 7 deletions

View File

@ -518,7 +518,8 @@ Goes to the first line of the file.
Goes to the last line of the file. Goes to the last line of the file.
.TP .TP
.B gotoline .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 .TP
.B gototext .B gototext
Switches from targeting a line number to searching for text. Switches from targeting a line number to searching for text.

View File

@ -1104,7 +1104,8 @@ Goes to the first line of the file.
Goes to the last line of the file. Goes to the last line of the file.
@item gotoline @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 @item gototext
Switches from targeting a line number to searching for text. Switches from targeting a line number to searching for text.

View File

@ -932,11 +932,8 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
if (i > 0) if (i > 0)
return; return;
/* Do a bounds check. Display a warning on an out-of-bounds /* Try to extract one or two numbers from the user's response. */
* line or column number only if we hit Enter at the statusbar if (!parse_line_column(answer, &line, &column)) {
* prompt. */
if (!parse_line_column(answer, &line, &column) ||
line < 1 || column < 1) {
statusbar(_("Invalid line or column number")); statusbar(_("Invalid line or column number"));
return; return;
} }
@ -948,10 +945,24 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
column = openfile->placewewant + 1; 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 && for (openfile->current = openfile->fileage; line > 1 &&
openfile->current != openfile->filebot; line--) openfile->current != openfile->filebot; line--)
openfile->current = openfile->current->next; 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->current_x = actual_x(openfile->current->data, column - 1);
openfile->placewewant = column - 1; openfile->placewewant = column - 1;