From: Aliaksei Budavei <0x000c70@gmail.com> Date: Tue, 10 Feb 2026 21:55:36 +0000 (+0100) Subject: tests(commondumps): Mark and fold lines in screendump views X-Git-Tag: v9.1.2145~2 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=238b0b0587213f999a56cd096da3be920ef2ff1e;p=thirdparty%2Fvim.git tests(commondumps): Mark and fold lines in screendump views - Dynamically set mark "`" to pair disparate lines and initially set marks "`a", "`b", etc. for as many lines in the difference part. Note that users are free to delete or change any set alphabetic marks without it affecting the dynamic updating of mark "`"; alphabetic marks only serve to help with arriving at "summary" lines, e.g. "`a````". - Create a fold for the difference part (but defer to users the closing of it) so that disparate lines that fit real estate can be viewed at the same time, as an alternative to the builtin "s" keystroke that swaps top and bottom parts in place. - Fold and mark lines with the "git difftool" extension too. closes: #19380 Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com> Signed-off-by: Christian Brabandt --- diff --git a/src/testdir/commondumps.vim b/src/testdir/commondumps.vim index 3dbdab5328..cdf56597f0 100644 --- a/src/testdir/commondumps.vim +++ b/src/testdir/commondumps.vim @@ -1,5 +1,78 @@ vim9script +# Query the paired position for the cursor line and use it, if available, for +# mark "`". +def TryChangingLastJumpMark(marks: dict>) + const pos: list = get(marks, line('.'), []) + if !empty(pos) + setpos("'`", [0, pos[0], pos[1], 0]) + endif +enddef + +# Fold the difference part and the bottom part when the top and the bottom +# parts are identical; otherwise, create a fold for the difference part and +# manage marks for disparate lines: dynamically set mark "`" to pair such +# lines and initially set "`a", "`b", etc. marks for difference part lines. +def FoldAndMarkDumpDiffParts() + defer call('setpos', ['.', getpos('.')]) + # Shape the pattern after get_separator() from "terminal.c". + const separator: string = '^\(=\+\)\=\s\S.*\.dump\s\1$' + const start_lnum: number = search(separator, 'eW', (line('$') / 2)) + if start_lnum > 0 + const end_lnum: number = search(separator, 'eW') + if end_lnum > 0 + # Collect [line_nr, col_nr] pairs (matching the first non-blank column) + # from the difference part "bs" and assemble corresponding pairs for the + # top part "as" and the bottom part "cs". + const parts: list>> = + getline((start_lnum + 1), (end_lnum - 1)) + ->map((idx: number, s: string) => + [matchlist(s, '\(^\s*\S\)')->get(1, '')->strwidth(), idx]) + ->reduce(((as: list, bs: list, cs: list) => + (xs: list>>, pair: list) => { + const col_nr: number = pair[0] + if col_nr != 0 + const idx: number = pair[1] + xs[0]->add([get(as, idx, as[-1]), col_nr]) + xs[1]->add([bs[idx], col_nr]) + xs[2]->add([get(cs, idx, cs[-1]), col_nr]) + endif + return xs + })(range(1, (start_lnum - 1)), + range((start_lnum + 1), (end_lnum - 1)), + range((end_lnum + 1), line('$'))), + [[], [], []]) + if empty(parts[1]) + setlocal foldenable foldmethod=manual + exec 'normal ' .. start_lnum .. 'GzfG' + else + setlocal nofoldenable foldmethod=manual + exec ':' .. start_lnum .. ',' .. end_lnum .. 'fold' + var marks: dict> = {} + var names: list = range(97, (97 + 25)) + ->map((_: number, n: number) => nr2char(n, true)) + for idx in range(parts[1]->len()) + if !empty(names) + setpos(("'" .. remove(names, 0)), + [0, parts[1][idx][0], parts[1][idx][1], 0]) + endif + # Point "bs" to "cs", "cs" to "as", "as" to "cs". + marks[parts[1][idx][0]] = parts[2][idx] + marks[parts[2][idx][0]] = parts[0][idx] + marks[parts[0][idx][0]] = parts[2][idx] + endfor + autocmd_add([{ + replace: true, + group: 'viewdumps', + event: 'CursorMoved', + bufnr: bufnr(), + cmd: printf('TryChangingLastJumpMark(%s)', string(marks)), + }]) + endif + endif + endif +enddef + # See below on how to configure the git difftool extension # Extend "git difftool" with the capability for loading screendump files. @@ -16,6 +89,7 @@ if v:progname =~? '\ 0 - const end_lnum: number = search(separator, 'eW') - if end_lnum > 0 && getline((start_lnum + 1), (end_lnum - 1)) - ->filter((_: number, line: string) => line !~ '^\s\+$') - ->empty() - setlocal foldenable foldmethod=manual - exec 'normal ' .. start_lnum .. 'GzfG' - endif - endif - finally - normal `c - endtry -enddef - # Render a loaded screendump file or the difference of a loaded screendump # file and its namesake file from the "dumps" directory. def Render() @@ -118,7 +168,7 @@ def Render() fnamemodify(failed_fname, ':p:h:h') .. '/dumps') if filereadable(dumps_fname) term_dumpdiff(failed_fname, dumps_fname) - FoldDumpDiffCopy() + FoldAndMarkDumpDiffParts() else term_dumpload(failed_fname) endif