Aliaksei Budavei | 6bff6a2 | 2024-08-19 21:33:26 +0200 | [diff] [blame] | 1 | vim9script |
| 2 | |
Aliaksei Budavei | 5eaacef | 2025-01-11 17:10:06 +0100 | [diff] [blame] | 3 | # See below on how to configure the git difftool extension |
| 4 | |
| 5 | # Extend "git difftool" with the capability for loading screendump files. |
| 6 | if v:progname =~? '\<g\=vimdiff$' |
| 7 | # Let "(g)vimdiff" render other files. |
| 8 | if [argv(0), argv(1)] |
| 9 | ->filter((_: number, fname: string) => |
| 10 | fname =~? '^\%(/dev/null\|.\+\.dump\)$') |
| 11 | ->len() == 2 |
| 12 | try |
| 13 | if argv(0) ==? '/dev/null' |
| 14 | term_dumpload(argv(1)) |
| 15 | elseif argv(1) ==? '/dev/null' |
| 16 | term_dumpload(argv(0)) |
| 17 | else |
| 18 | term_dumpdiff(argv(0), argv(1)) |
| 19 | endif |
| 20 | finally |
| 21 | silent bwipeout 1 2 |
| 22 | endtry |
| 23 | endif |
| 24 | |
| 25 | # Always stop from further sourcing this script for "(g)vimdiff". |
| 26 | finish |
| 27 | endif |
| 28 | |
| 29 | # CONSIDER ALTERNATIVES FOR ENABLING THE ABOVE EXTENSION. |
Aliaksei Budavei | 6bff6a2 | 2024-08-19 21:33:26 +0200 | [diff] [blame] | 30 | # |
Aliaksei Budavei | 5eaacef | 2025-01-11 17:10:06 +0100 | [diff] [blame] | 31 | # For convenience, it is assumed that there is a defined "$VIM_FORK_PATHNAME" |
| 32 | # environment variable holding an absolute pathname for the root directory of |
| 33 | # this repository. |
| 34 | # |
| 35 | # |
| 36 | # A. USE Git FOR CONFIGURATION. |
| 37 | # |
| 38 | # Define the following Git variables with "git config --edit --local" (where |
| 39 | # the "vimdumps" name is arbitrary): |
| 40 | # |
| 41 | # ------------------------------------------------------------------------------ |
| 42 | # [diff] |
| 43 | # tool = vimdumps |
| 44 | # [difftool.vimdumps] |
| 45 | # cmd = vimdiff -S "${VIM_FORK_PATHNAME:?}"/src/testdir/commondumps.vim -o -- "$LOCAL" "$REMOTE" |
| 46 | # ------------------------------------------------------------------------------ |
| 47 | # |
| 48 | # Rendered screendump files (among other files) between revisions can now be |
| 49 | # compared, two at a time, by using "git difftool", e.g.: |
| 50 | # git difftool 50423ab8~1 50423ab8 |
| 51 | # git difftool 50423ab8~1 50423ab8 -- '**/*.dump' |
| 52 | # |
| 53 | # The raw files can also be examined: |
| 54 | # :all |
| 55 | # |
| 56 | # |
| 57 | # B. USE Bash FOR CONFIGURATION (on Debian GNU/Linux). |
| 58 | # |
| 59 | # 1. Make an alias that sources this file, e.g.: |
| 60 | # alias git_vimdiff="git difftool -x 'vimdiff -S "${VIM_FORK_PATHNAME:?}"/vim/src/testdir/commondumps.vim -o --'" |
| 61 | # |
| 62 | # 2. Enable programmable completion for the alias, e.g.: |
| 63 | # cat ~/.local/share/bash-completion/completions/git_vimdiff |
| 64 | # |
| 65 | # ------------------------------------------------------------------------------ |
| 66 | # ## Consider (un)setting "$BASH_COMPLETION_USER_DIR" and/or "$XDG_DATA_HOME" so |
| 67 | # ## that this file can be found and sourced; look for these variables in the |
| 68 | # ## "/usr/share/bash-completion/bash_completion" script. |
| 69 | # ## |
| 70 | # ## Look for __git_complete() examples in the header comment of the sourced |
| 71 | # ## "/usr/share/bash-completion/completions/git" script. |
| 72 | # [ -r /usr/share/bash-completion/completions/git ] && |
| 73 | # . /usr/share/bash-completion/completions/git && |
| 74 | # __git_complete git_vimdiff _git_difftool |
| 75 | # ------------------------------------------------------------------------------ |
| 76 | # |
| 77 | # Rendered screendump files (among other files) between revisions can now be |
| 78 | # compared, two at a time, by using the alias, e.g.: |
| 79 | # git_vimdiff 50423ab8~1 50423ab8 |
| 80 | # git_vimdiff 50423ab8~1 50423ab8 -- '**/*.dump' |
| 81 | # |
| 82 | # The raw files can also be examined: |
| 83 | # :all |
| 84 | |
| 85 | |
| 86 | # Script-local functions |
| 87 | # |
| 88 | # Fold the difference part and the bottom part when the top and the bottom |
| 89 | # parts are identical. |
| 90 | def FoldDumpDiffCopy() |
| 91 | try |
| 92 | normal mc |
| 93 | # Shape the pattern after get_separator() from "terminal.c". |
| 94 | const separator: string = '^\(=\+\)\=\s\S.*\.dump\s\1$' |
| 95 | const start_lnum: number = search(separator, 'eW', (line('$') / 2)) |
| 96 | if start_lnum > 0 |
| 97 | const end_lnum: number = search(separator, 'eW') |
| 98 | if end_lnum > 0 && getline((start_lnum + 1), (end_lnum - 1)) |
| 99 | ->filter((_: number, line: string) => line !~ '^\s\+$') |
| 100 | ->empty() |
| 101 | setlocal foldenable foldmethod=manual |
| 102 | exec 'normal ' .. start_lnum .. 'GzfG' |
| 103 | endif |
| 104 | endif |
| 105 | finally |
| 106 | normal `c |
| 107 | endtry |
| 108 | enddef |
| 109 | |
Aliaksei Budavei | 6bff6a2 | 2024-08-19 21:33:26 +0200 | [diff] [blame] | 110 | # Render a loaded screendump file or the difference of a loaded screendump |
| 111 | # file and its namesake file from the "dumps" directory. |
| 112 | def Render() |
| 113 | const failed_fname: string = bufname() |
| 114 | try |
| 115 | setlocal suffixesadd=.dump |
| 116 | const dumps_fname: string = findfile( |
| 117 | fnamemodify(failed_fname, ':p:t'), |
| 118 | fnamemodify(failed_fname, ':p:h:h') .. '/dumps') |
| 119 | if filereadable(dumps_fname) |
| 120 | term_dumpdiff(failed_fname, dumps_fname) |
Aliaksei Budavei | 5eaacef | 2025-01-11 17:10:06 +0100 | [diff] [blame] | 121 | FoldDumpDiffCopy() |
Aliaksei Budavei | 6bff6a2 | 2024-08-19 21:33:26 +0200 | [diff] [blame] | 122 | else |
| 123 | term_dumpload(failed_fname) |
| 124 | endif |
| 125 | finally |
| 126 | exec 'bwipeout ' .. failed_fname |
| 127 | endtry |
| 128 | enddef |
| 129 | |
Aliaksei Budavei | 5eaacef | 2025-01-11 17:10:06 +0100 | [diff] [blame] | 130 | # Public functions |
| 131 | # |
Aliaksei Budavei | 6bff6a2 | 2024-08-19 21:33:26 +0200 | [diff] [blame] | 132 | # Search for the "failed" directory in the passed _subtreedirname_ directories |
| 133 | # (usually "\<src\>" or "\<syntax\>") and, if found, select its passed _count_ |
zeertzjq | 8feed3a | 2024-09-29 10:37:47 +0200 | [diff] [blame] | 134 | # occurrence, add all its "*.dump" files to the argument list and list them; |
Aliaksei Budavei | 6bff6a2 | 2024-08-19 21:33:26 +0200 | [diff] [blame] | 135 | # also define a BufRead autocommand that would invoke "Render()" for every |
| 136 | # "*.dump" file. |
| 137 | def g:Init(subtreedirname: string, count: number) |
| 138 | # Support sourcing this script from any directory in the direct path that |
| 139 | # leads to the project's root directory. |
| 140 | const failed_path: string = finddir('failed', getcwd() .. '/**', -1) |
| 141 | ->filter(((cwdpath: string, parentdirname: string) => |
| 142 | (_: number, dirpath: string) => |
| 143 | cwdpath =~ parentdirname || dirpath =~ parentdirname)( |
| 144 | getcwd(), |
| 145 | subtreedirname)) |
| 146 | ->get(count, '') .. '/' |
| 147 | var error: string = null_string |
| 148 | |
| 149 | if failed_path == '/' |
| 150 | error = 'No such directory: "failed"' |
| 151 | else |
| 152 | const failed_fnames: string = failed_path .. readdir(failed_path, |
| 153 | (fname: string) => fname =~ '^.\+\.dump$') |
| 154 | ->join(' ' .. failed_path) |
| 155 | |
| 156 | if failed_fnames =~ 'failed/$' |
| 157 | error = 'No such file: "*.dump"' |
| 158 | else |
| 159 | exec ':0argedit ' .. failed_fnames |
| 160 | buffers |
| 161 | endif |
| 162 | endif |
| 163 | |
| 164 | autocmd_add([{ |
| 165 | replace: true, |
| 166 | group: 'viewdumps', |
| 167 | event: 'BufRead', |
| 168 | pattern: '*.dump', |
| 169 | cmd: 'Render()', |
| 170 | }]) |
| 171 | |
| 172 | # Unconditionally help, in case a list of filenames is passed to the |
| 173 | # command, the first terminal window with its BufRead event. |
| 174 | silent doautocmd viewdumps BufRead |
| 175 | |
| 176 | if error != null_string |
| 177 | # Instead of sleeping, fill half a window with blanks and prompt |
| 178 | # hit-enter. |
| 179 | echom error .. repeat("\x20", |
| 180 | (winwidth(0) * (winheight(0) / 2) - strlen(error))) |
| 181 | endif |
| 182 | enddef |
| 183 | |
zeertzjq | 3e5bbb8 | 2024-10-22 23:11:27 +0200 | [diff] [blame] | 184 | # vim:fdm=syntax:sw=2:ts=8:noet:nosta: |