mirror of
https://github.com/openai/codex.git
synced 2026-10-19 16:17:49 +00:00
Deduplicate TUI modifier handling and terminal color caching (#53556)
## What changed - Reuse `custom_terminal::ModifierDiff` when writing history spans. - Share the terminal default-color probe and cache implementation between Unix and Windows. Both changes remove duplicate implementations while preserving existing behavior. GitOrigin-RevId: 35f8d77ade972b791c6beac0678d2fe2be3aa763
This commit is contained in:
committed by
copyberry
parent
12cca49c81
commit
f82e365922
@@ -730,13 +730,13 @@ where
|
||||
/// The `ModifierDiff` struct is used to calculate the difference between two `Modifier`
|
||||
/// values. This is useful when updating the terminal display, as it allows for more
|
||||
/// efficient updates by only sending the necessary changes.
|
||||
struct ModifierDiff {
|
||||
pub(crate) struct ModifierDiff {
|
||||
pub from: Modifier,
|
||||
pub to: Modifier,
|
||||
}
|
||||
|
||||
impl ModifierDiff {
|
||||
fn queue<W: io::Write>(self, w: &mut W) -> io::Result<()> {
|
||||
pub(crate) fn queue<W: io::Write>(self, w: &mut W) -> io::Result<()> {
|
||||
use crossterm::style::Attribute as CAttribute;
|
||||
let removed = self.from - self.to;
|
||||
if removed.contains(Modifier::REVERSED) {
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::custom_terminal::ModifierDiff;
|
||||
use crate::render::line_utils::line_to_static;
|
||||
use crate::terminal_hyperlinks::HyperlinkLine;
|
||||
use crate::terminal_hyperlinks::decorate_spans;
|
||||
@@ -381,73 +382,6 @@ impl Command for ResetScrollRegion {
|
||||
}
|
||||
}
|
||||
|
||||
struct ModifierDiff {
|
||||
pub from: Modifier,
|
||||
pub to: Modifier,
|
||||
}
|
||||
|
||||
impl ModifierDiff {
|
||||
fn queue<W>(self, mut w: W) -> io::Result<()>
|
||||
where
|
||||
W: io::Write,
|
||||
{
|
||||
use crossterm::style::Attribute as CAttribute;
|
||||
let removed = self.from - self.to;
|
||||
if removed.contains(Modifier::REVERSED) {
|
||||
queue!(w, SetAttribute(CAttribute::NoReverse))?;
|
||||
}
|
||||
if removed.contains(Modifier::BOLD) {
|
||||
queue!(w, SetAttribute(CAttribute::NormalIntensity))?;
|
||||
if self.to.contains(Modifier::DIM) {
|
||||
queue!(w, SetAttribute(CAttribute::Dim))?;
|
||||
}
|
||||
}
|
||||
if removed.contains(Modifier::ITALIC) {
|
||||
queue!(w, SetAttribute(CAttribute::NoItalic))?;
|
||||
}
|
||||
if removed.contains(Modifier::UNDERLINED) {
|
||||
queue!(w, SetAttribute(CAttribute::NoUnderline))?;
|
||||
}
|
||||
if removed.contains(Modifier::DIM) {
|
||||
queue!(w, SetAttribute(CAttribute::NormalIntensity))?;
|
||||
}
|
||||
if removed.contains(Modifier::CROSSED_OUT) {
|
||||
queue!(w, SetAttribute(CAttribute::NotCrossedOut))?;
|
||||
}
|
||||
if removed.contains(Modifier::SLOW_BLINK) || removed.contains(Modifier::RAPID_BLINK) {
|
||||
queue!(w, SetAttribute(CAttribute::NoBlink))?;
|
||||
}
|
||||
|
||||
let added = self.to - self.from;
|
||||
if added.contains(Modifier::REVERSED) {
|
||||
queue!(w, SetAttribute(CAttribute::Reverse))?;
|
||||
}
|
||||
if added.contains(Modifier::BOLD) {
|
||||
queue!(w, SetAttribute(CAttribute::Bold))?;
|
||||
}
|
||||
if added.contains(Modifier::ITALIC) {
|
||||
queue!(w, SetAttribute(CAttribute::Italic))?;
|
||||
}
|
||||
if added.contains(Modifier::UNDERLINED) {
|
||||
queue!(w, SetAttribute(CAttribute::Underlined))?;
|
||||
}
|
||||
if added.contains(Modifier::DIM) {
|
||||
queue!(w, SetAttribute(CAttribute::Dim))?;
|
||||
}
|
||||
if added.contains(Modifier::CROSSED_OUT) {
|
||||
queue!(w, SetAttribute(CAttribute::CrossedOut))?;
|
||||
}
|
||||
if added.contains(Modifier::SLOW_BLINK) {
|
||||
queue!(w, SetAttribute(CAttribute::SlowBlink))?;
|
||||
}
|
||||
if added.contains(Modifier::RAPID_BLINK) {
|
||||
queue!(w, SetAttribute(CAttribute::RapidBlink))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn write_spans<'a, I>(mut writer: &mut impl Write, content: I) -> io::Result<()>
|
||||
where
|
||||
I: IntoIterator<Item = &'a Span<'a>>,
|
||||
|
||||
@@ -142,7 +142,7 @@ pub(crate) fn set_default_colors_from_startup_probe(
|
||||
imp::set_default_colors_from_startup_probe(colors);
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(test)))]
|
||||
#[cfg(any(all(unix, not(test)), windows))]
|
||||
mod imp {
|
||||
use super::DefaultColors;
|
||||
use std::sync::Mutex;
|
||||
@@ -211,70 +211,6 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod imp {
|
||||
use super::DefaultColors;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
struct Cache<T> {
|
||||
attempted: bool,
|
||||
value: Option<T>,
|
||||
}
|
||||
|
||||
impl<T> Default for Cache<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
attempted: false,
|
||||
value: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> Cache<T> {
|
||||
fn get_or_init_with(&mut self, mut init: impl FnMut() -> Option<T>) -> Option<T> {
|
||||
if !self.attempted {
|
||||
self.value = init();
|
||||
self.attempted = true;
|
||||
}
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
fn default_colors_cache() -> &'static Mutex<Cache<DefaultColors>> {
|
||||
static CACHE: OnceLock<Mutex<Cache<DefaultColors>>> = OnceLock::new();
|
||||
CACHE.get_or_init(|| Mutex::new(Cache::default()))
|
||||
}
|
||||
|
||||
pub(super) fn default_colors() -> Option<DefaultColors> {
|
||||
let cache = default_colors_cache();
|
||||
let mut cache = cache.lock().ok()?;
|
||||
cache.get_or_init_with(query_default_colors)
|
||||
}
|
||||
|
||||
pub(super) fn set_default_colors_from_startup_probe(
|
||||
colors: Option<crate::terminal_probe::DefaultColors>,
|
||||
) {
|
||||
if let Ok(mut cache) = default_colors_cache().lock() {
|
||||
cache.value = colors.map(|colors| DefaultColors {
|
||||
fg: colors.fg,
|
||||
bg: colors.bg,
|
||||
});
|
||||
cache.attempted = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn query_default_colors() -> Option<DefaultColors> {
|
||||
crate::terminal_probe::default_colors(crate::terminal_probe::DEFAULT_TIMEOUT)
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|colors| DefaultColors {
|
||||
fg: colors.fg,
|
||||
bg: colors.bg,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(all(unix, not(test)), windows)))]
|
||||
mod imp {
|
||||
use super::DefaultColors;
|
||||
|
||||
Reference in New Issue
Block a user