I've made an attempt at fixing this, since undoing/redoing cuts shows this problem, but undoing/redoing joins doesn't. And if one type of minor text operation can handle it while another can't, I figure that's not so minor a problem. When trying the latter operation (and quoting your description where it applies), we get:
To reproduce, run 'nano --ignore' and type:
word <Down> Backspace M-U
Note that it says: [ Undid action (line join) ], but nothing changes, obviously. Continue typing:
M-U M-E M-E
Now it says: [ Redid action (line join) ], and the cursor is placed again at the end of the line (as expected), just before the magic line. Continue typing:
M-U
Now the cursor jumps to the start of the magicline, and the cursor was there when the "line join" (Backspace) was done (as expected).
----------
Also, if I follow your original instructions using ^K, but press ^^ before ^K (so that nano ends up undoing/redoing a cut of an empty marked region), the same problem occurs, so it's not just full line cuts that face this issue.
So, in order to fix this, we should take a cue from what line joins are doing. It turns out that do_undo() and do_redo() have bits of special code to position the cursor properly when dealing with line joins in this case: the undo/redo operations don't change the text, but they do change the cursor position.
The same thing can be accomplished for cuts via minor adjustments to undo_cut() and redo_cut(). Currently, they handle such cuts by immediately returning if the cutbuffer is empty. But, by not returning until just after the cursor is positioned in preparation for the cut, everything works as expected. Even better, no new lines of code are required.
As for your expected behavior ("nano should simply ignore any attempt to cut the magic line: no undo item should be added for it"), that would be the ideal solution in the long term, but that's also more complicated to do since it involves fiddling with the undo stack, and I'm still trying to understand more of the undo code. Not to mention, it would have to be done for the joining code as well as the cutting code. At least this way, the problem is fixed without needing any new code.
The patch is against current git: 9a7ba5d.
(file #44340)
|