fix: refresh diff colors on terminal theme changes
This commit is contained in:
+50
-17
@@ -62,6 +62,19 @@ struct TerminalSession {
|
||||
hook: Arc<Mutex<HookState>>,
|
||||
}
|
||||
|
||||
struct ColorSchemeNotifications(bool);
|
||||
|
||||
impl crossterm::Command for ColorSchemeNotifications {
|
||||
fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
|
||||
f.write_str(if self.0 { "\x1b[?2031h" } else { "\x1b[?2031l" })
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn restore_terminal() {
|
||||
let _ = disable_raw_mode();
|
||||
let _ = execute!(
|
||||
@@ -70,6 +83,7 @@ fn restore_terminal() {
|
||||
DisableBracketedPaste,
|
||||
DisableMouseCapture,
|
||||
DisableFocusChange,
|
||||
ColorSchemeNotifications(false),
|
||||
LeaveAlternateScreen,
|
||||
Show
|
||||
);
|
||||
@@ -109,7 +123,8 @@ impl TerminalSession {
|
||||
EnterAlternateScreen,
|
||||
EnableBracketedPaste,
|
||||
EnableMouseCapture,
|
||||
EnableFocusChange
|
||||
EnableFocusChange,
|
||||
ColorSchemeNotifications(true)
|
||||
)?;
|
||||
body()
|
||||
}));
|
||||
@@ -787,7 +802,7 @@ pub fn run(session: &mut EditorSession) -> io::Result<()> {
|
||||
pending = following;
|
||||
}
|
||||
Event::Resize(_, _) => redraw = true,
|
||||
Event::FocusGained => query_theme = true,
|
||||
Event::FocusGained | Event::ColorSchemeChanged => query_theme = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -2982,8 +2997,8 @@ impl DiffColors {
|
||||
Color::Rgb(channels[0], channels[1], channels[2])
|
||||
};
|
||||
Self {
|
||||
row: [blend(theme.red, 12), blend(theme.green, 12)],
|
||||
character: [blend(theme.red, 28), blend(theme.green, 28)],
|
||||
row: [blend(theme.red, 18), blend(theme.green, 18)],
|
||||
character: [blend(theme.red, 38), blend(theme.green, 38)],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4247,19 +4262,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn character_diff_backgrounds_preserve_common_unicode_and_syntax_across_viewports() {
|
||||
for (theme, row, character) in [
|
||||
(
|
||||
Some(LIGHT_DIFF_THEME),
|
||||
[Color::Rgb(245, 219, 217), Color::Rgb(222, 234, 218)],
|
||||
[Color::Rgb(239, 185, 187), Color::Rgb(186, 218, 190)],
|
||||
),
|
||||
(
|
||||
Some(DARK_DIFF_THEME),
|
||||
[Color::Rgb(44, 29, 36), Color::Rgb(22, 44, 38)],
|
||||
[Color::Rgb(76, 35, 44), Color::Rgb(26, 68, 50)],
|
||||
),
|
||||
(None, [Color::Reset; 2], [Color::Reset; 2]),
|
||||
] {
|
||||
for theme in [Some(LIGHT_DIFF_THEME), Some(DARK_DIFF_THEME), None] {
|
||||
let mut diff = diff_comparison(vec![syntax_diff_file(
|
||||
"changes.rs",
|
||||
"let 界e\u{301} = old + old;",
|
||||
@@ -4272,6 +4275,36 @@ mod tests {
|
||||
..WheelPanels::default()
|
||||
};
|
||||
render_diff(&mut terminal, &diff, &mut panels);
|
||||
let row = panels.diff_colors.row;
|
||||
let character = panels.diff_colors.character;
|
||||
if let Some(theme) = theme {
|
||||
for (index, accent) in [theme.red, theme.green].into_iter().enumerate() {
|
||||
let Color::Rgb(r, g, b) = row[index] else {
|
||||
panic!("theme row background must be RGB");
|
||||
};
|
||||
let Color::Rgb(cr, cg, cb) = character[index] else {
|
||||
panic!("theme character background must be RGB");
|
||||
};
|
||||
for ((common, changed), (background, accent)) in [r, g, b]
|
||||
.into_iter()
|
||||
.zip([cr, cg, cb])
|
||||
.zip(theme.background.into_iter().zip(accent))
|
||||
{
|
||||
assert!(
|
||||
(background.min(accent)..=background.max(accent)).contains(&common)
|
||||
);
|
||||
assert!(
|
||||
(background.min(accent)..=background.max(accent)).contains(&changed)
|
||||
);
|
||||
if background != accent {
|
||||
assert!(changed.abs_diff(accent) < common.abs_diff(accent));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert_eq!(row, [Color::Reset; 2]);
|
||||
assert_eq!(character, [Color::Reset; 2]);
|
||||
}
|
||||
for index in 0..2 {
|
||||
let pane = panels.diff.as_ref().unwrap().regions[index + 1].0;
|
||||
let buffer = terminal.backend().buffer();
|
||||
|
||||
Reference in New Issue
Block a user