commit 9a67d7958fdf751f4a7ea582575bd467eefffc4f
parent 23f73cb8b3d90dd44c14771838588a554af77c5c
Author: Benno Schulenberg <bensberg@telfort.nl>
Date: Fri, 3 Apr 2020 11:07:36 +0200
undo: choose the proper x positions to place the cursor and rejoin lines
Normally, when undoing an <Enter> that created automatic indentation,
the created whitespace should be skipped when rejoining the two lines.
In other words: take the data starting from tail_x in the second line.
But when the <Enter> occurred at the end of leading whitespace, then
that whitespace has disappeared from the original line and it should
be copied back in from the second line. That is: from x is zero.
This fixes https://savannah.gnu.org/bugs/?58108.
Reported-by: Liu Hao <lh_mouse@126.com>
Bug existed since version 4.9, commit 1961c052.
Diffstat:
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/text.c b/src/text.c
@@ -504,6 +504,7 @@ void do_undo(void)
linestruct *line = NULL, *intruder;
linestruct *oldcutbuffer;
char *data, *undidmsg = NULL;
+ size_t original_x, regain_from_x;
if (u == NULL) {
statusbar(_("Nothing to undo"));
@@ -526,12 +527,17 @@ void do_undo(void)
break;
case ENTER:
undidmsg = _("line break");
+ /* An <Enter> at the end of leading whitespace while autoindenting has
+ * deleted the whitespace, and stored an x position of zero. In that
+ * case, adjust the positions to return to and to scoop data from. */
+ original_x = (u->head_x == 0) ? u->tail_x : u->head_x;
+ regain_from_x = (u->head_x == 0) ? 0 : u->tail_x;
line->data = charealloc(line->data, strlen(line->data) +
- strlen(&u->strdata[u->tail_x]) + 1);
- strcat(line->data, &u->strdata[u->tail_x]);
+ strlen(&u->strdata[regain_from_x]) + 1);
+ strcat(line->data, &u->strdata[regain_from_x]);
unlink_node(line->next);
renumber_from(line);
- goto_line_posx(u->head_lineno, u->head_x);
+ goto_line_posx(u->head_lineno, original_x);
break;
case BACK:
case DEL: