Small Issues and Documentation Gaps in diff workflow

1 view
Skip to first unread message

Narendran Gopalakrishnan

unread,
7:21 PM (3 hours ago) 7:21 PM
to vim_dev
Dear All,

In Vim and Neovim, found the following gaps/deviations from documentation, when testing the script https://github.com/gnarendran/EasyDiff/blob/main/EasyDiff.vim that automates diff navigation between/inside Changes, merges, deletes, and undos, across two vertically split windows in diff mode:

1. To undo Change Merges/Deletes that were performed in the alternate window, the script has to win_execute on the alternate window. But win_execute of ex command 'noautocmd silent undo' fails to trigger cursorbind (cursor in the local window doesn't move). Even 'syncbind' has no effect on the situation. But win_execute of the equivalent normal command 'silent normal! u' honors cursorbind and re-synchronizes the cursors (cursor in the local window is also moves). Any other normal command like \<C-g> as well tickles cusorbind to re-sync the cursors. The following are executed in winnr() == 1, after a remote edit in winnr() == 2:
:call win_execute(win_getid(2), "noautocmd silent undo")| "cursorbind not effected
:call win_execute(win_getid(2), "noautocmd silent undo|normal \<C-g>")| "Works
:call win_execute(win_getid(2), "silent normal! u")| "Works - the workaround

It is as if win_execute of *normal commands* trigger cursorbind, but that of *ex* commands like :undo don't. Not sure if some existing scripts rely on this behavior or if this may be considered a genuine bug (present in both vim-9.2 and nvim-0.12.0). 

2. Edits performed on the alternate window either using dp or win_execute do, remain in a single undo-block. To assign each such edit its own changenr(), :help undo-blocks suggests the workaround 'let &g:undolevels = &g:undolevels' after the edit. But though this is a global option, the solution works only if the assignment is also done in the alternate window, like:
" Perform the edit in the alternate window and then:
call win_execute(a:changed_winid, 'noautocmd let &g:undolevels = &g:undolevels'
\. '| noautocmd let g:EasyDiff_tmp = changenr()')
let changenr = g:EasyDiff_tmp
...
It would be nice if the documentation could clarify this.

3. diff_filler(line_num) is documented to give the number of Filler lines preceding line_num. But no solution is documented to find the number of Filler lines at EOF (as there is no real line after it). However, Gemini suggested that the EOF Filler may be considered to precede a *virtual line* last_line_num+1 and then diff_filler(last_line_num+1) gives the number of EOF Filler lines. This solution indeed works in both nvim and vim, though only a clearer documentation can validate it.

4. The EOF Filler also has a presentation nit. If the file is larger than a screenful, then a 'EOF Filler' that is present, isn't rendered even with 'set diffopt+=filler'. True, \<C-e> will expose the EOF Filler if present, but it would be clearer if at least one line of the EOF Filler is shown by default, indicating its presence, as the intermediate Fillers are fully visible. Couldn't find a decent workaround for this (both vim and nvim).

Thanks & Regards,
Narendran Gopalakrishnan.
Reply all
Reply to author
Forward
0 new messages