feat(config-settings): add __config_settings_diff_redraw

This commit is contained in:
2026-09-08 04:08:00 -04:00
parent 7b02348f64
commit ece3e9dbfb
2 changed files with 63 additions and 0 deletions
@@ -0,0 +1,47 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# __config_settings_diff_redraw <old_joined> <new_joined>
#
# DESCRIPTION
# Rewrites an on-screen panel frame in place, touching only the lines
# that changed. Assumes the cursor is already positioned at the top-left
# of the frame (the caller moves it there with a plain \e[<n>A -- no
# \e[J -- before calling this). Line count in old_joined and new_joined
# must be equal; a caller facing a height or width change should use the
# existing full erase+redraw path instead of calling this.
#
# Unchanged lines advance the cursor with a bare newline, leaving
# whatever is already on screen untouched. Changed lines clear just that
# line (\e[2K), return to its start (\r), print the new content, and
# advance (\n). This is what removes the erase-then-redraw flicker: the
# screen is never blanked, only the handful of lines that actually
# differ are ever touched, and each of those is cleared and rewritten in
# the same breath rather than blanked-then-paused-then-filled.
#
# ARGUMENTS
# old_joined Previous frame, lines joined with \n
# new_joined New frame, lines joined with \n (same line count as old)
#
# EXIT STATUS
# 0 Always
#
# RETURNS
# The ANSI sequence needed to turn the old frame into the new one,
# printed to stdout
#
# EXAMPLE
# __config_settings_diff_redraw (string join \n -- $prev_frame) \
# (string join \n -- $new_frame)
function __config_settings_diff_redraw
set -l old (string split \n -- $argv[1])
set -l new (string split \n -- $argv[2])
for i in (seq (count $new))
if test "$old[$i]" = "$new[$i]"
printf '\n'
else
printf '\e[2K\r%s\n' $new[$i]
end
end
end
+16
View File
@@ -125,6 +125,22 @@ function test_draw_line_count_matches_panel_h
end
end
function test_diff_redraw_unchanged_lines_are_bare_newlines
functions -q __config_settings_diff_redraw; or return 1
set -l old (string join \n -- AAA BBB CCC | string collect)
set -l new (string join \n -- AAA BBB CCC | string collect)
set -l out (__config_settings_diff_redraw "$old" "$new" | string collect -N)
test "$out" = \n\n\n
end
function test_diff_redraw_changed_line_is_cleared_and_rewritten
functions -q __config_settings_diff_redraw; or return 1
set -l old (string join \n -- AAA BBB CCC | string collect)
set -l new (string join \n -- AAA XYZ CCC | string collect)
set -l out (__config_settings_diff_redraw "$old" "$new" | string collect -N)
test "$out" = \n\e\[2K\rXYZ\n\n
end
function functional_test_main
set -l names (functions -a | string match 'test_*' | sort)
set -l failed 0