You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As far as I can see, setting curbuf->b_u_curhead in ex_undojoin() provides no benefit and introduces some bugs.
ex_undojoin() sets curbuf->b_u_curhead at the same time as setting curbuf->b_u_synced to FALSE. When the undo state is synced with u_sync(), both b_u_curhead is set to NULL and b_u_synced is set to TRUE (unless the undo list is corrupt and u_get_headentry returns NULL when called in u_getbot()).
Throughout the source code there are 3 places where b_u_curhead is used without resetting b_u_synced to TRUE, these are bugs 1 and 2 below, and what causes using undojoin twice in a function to give the error E790 undojoin is not allowed after undo.
There is only one place where b_u_synced is set to TRUE without setting b_u_curhead back to NULL, this is bug 3 below.
Overall I think not setting b_u_curhead in ex_undojoin() would fix these bugs (though they could be fixed in other ways) and would not cause any regressions.
The three bugs this introduces are:
1 :undojoin | redo
Essentially swaps the order of things
Test
With the file test.txt
first line
second line
Run the following: vim -N -u NONE test.txt
ixx<esc>
:undojoin | redo<CR>
Observe
leaves the buffer as it was opened
running undo puts the x's back into the buffer.
cannot go backwards in time from there -- undo history is false
2 :undojoin | write breaks the :earlier 1f command
Test
open a new file vim -N -u NONE test.txt
first write to the file<esc>
:w<CR>
osecond write to the file<esc>
osecond line not written<esc>
:undojoin | w<CR>
:earlier 1f<CR>
Observe in the buffer
first write to the file
second write to the file
But this text was never written to disk.
3 Interrupt after :undojoin
Artificially send an interrupt during u_savecommon() after calling ex_undojoin().
This leaves the undo tree with a superfluous branch, that hasn't
actually been undone but is there as if it had been.
With the file orig_vim_debug_this.txt
Test line for actions
yy
:put
attach gdb to nvim here -- run session provided below
:undojoin | delete
artificial Ctrl-c in gdb in u_savecommon() for delete
Observe in the buffer
The second line was not removed
Pressing 'u' does not remove the line -- vim thinks the end of the
changelist has been reached.
Pressing 'Ctrl-r' removes the line -- vim now thinks it is a change we
have already undone.
If we make another change, that percieved available redo is moved to
an alternate branch.
vim [19:36:50] % gdb src/vim
Reading symbols from src/vim...(no debugging symbols found)...done.
(gdb) set pagination off
(gdb) python
>import subprocess as sp
>matching_processes = []
>for pid in [val.decode('utf-8') for val in
> sp.check_output(['pgrep', 'vim']).splitlines()]:
> with open('/proc/{}/cmdline'.format(pid), 'r') as infile:
> cur_cmdline = infile.read()
> if 'orig_vim_debug_this' in cur_cmdline:
> matching_processes.append(pid)
>
>if len(matching_processes) == 1:
> gdb.execute('attach {}'.format(matching_processes[0]))
>else:
> print(matching_processes)
>end
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x00007fe462e37093 in __select_nocancel () from /usr/lib/libc.so.6
(gdb) break ex_undojoin
Breakpoint 1 at 0x58d9f0
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>set variable $savecommon_shouldbreak = 1
>cont
>end
(gdb) break u_savecommon if $savecommon_shouldbreak
Breakpoint 2 at 0x58b840
(gdb) command 2
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>set variable $savecommon_shouldbreak = 0
>end
(gdb) cont
Continuing.
Breakpoint 2, 0x000000000058b840 in u_savecommon ()
(gdb) set variable got_int = 1
(gdb) cont
Continuing.
The text was updated successfully, but these errors were encountered:
Problem: After :undojoin some commands don't work properly, such as :redo.
(Matthew Malcomson)
Solution: Don't set curbuf->b_u_curhead. (closesvim#1390)
As far as I can see, setting
curbuf->b_u_curhead
inex_undojoin()
provides no benefit and introduces some bugs.ex_undojoin()
setscurbuf->b_u_curhead
at the same time as settingcurbuf->b_u_synced
toFALSE
. When the undo state is synced withu_sync()
, bothb_u_curhead
is set toNULL
andb_u_synced
is set toTRUE
(unless the undo list is corrupt andu_get_headentry
returnsNULL
when called inu_getbot()
).Throughout the source code there are 3 places where
b_u_curhead
is used without resettingb_u_synced
toTRUE
, these are bugs 1 and 2 below, and what causes usingundojoin
twice in a function to give the errorE790 undojoin is not allowed after undo
.There is only one place where
b_u_synced
is set toTRUE
without settingb_u_curhead
back toNULL
, this is bug 3 below.Overall I think not setting
b_u_curhead
inex_undojoin()
would fix these bugs (though they could be fixed in other ways) and would not cause any regressions.The three bugs this introduces are:
1
:undojoin | redo
Essentially swaps the order of things
Test
With the file
test.txt
Run the following:
vim -N -u NONE test.txt
Observe
leaves the buffer as it was opened
running undo puts the x's back into the buffer.
cannot go backwards in time from there -- undo history is false
2
:undojoin | write
breaks the:earlier 1f
commandTest
open a new file
vim -N -u NONE test.txt
Observe in the buffer
But this text was never written to disk.
3 Interrupt after
:undojoin
Artificially send an interrupt during
u_savecommon()
after callingex_undojoin()
.This leaves the undo tree with a superfluous branch, that hasn't
actually been undone but is there as if it had been.
With the file
orig_vim_debug_this.txt
Observe in the buffer
The second line was not removed
Pressing 'u' does not remove the line -- vim thinks the end of the
changelist has been reached.
Pressing 'Ctrl-r' removes the line -- vim now thinks it is a change we
have already undone.
If we make another change, that percieved available redo is moved to
an alternate branch.
The text was updated successfully, but these errors were encountered: