refactor(terminal): cleanup deprecated flush logic (#6373)

Removes flush logic that was leftover to test against ratatui's flush
Cleaned up the flush logic so it's a bit more intent revealing.
DrawCommand now owns the Cells that it draws as this works around a
borrow checker problem.
This commit is contained in:
Josh McKinney
2025-11-07 15:54:07 -08:00
committed by GitHub
parent db408b9e62
commit 9fba811764
3 changed files with 48 additions and 40 deletions

13
codex-rs/Cargo.lock generated
View File

@@ -1455,6 +1455,7 @@ dependencies = [
"codex-windows-sandbox",
"color-eyre",
"crossterm",
"derive_more 2.0.1",
"diffy",
"dirs",
"dunce",
@@ -1658,6 +1659,15 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "convert_case"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -2003,7 +2013,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [
"convert_case",
"convert_case 0.6.0",
"proc-macro2",
"quote",
"syn 2.0.104",
@@ -2016,6 +2026,7 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"convert_case 0.7.1",
"proc-macro2",
"quote",
"syn 2.0.104",

View File

@@ -42,6 +42,7 @@ codex-ollama = { workspace = true }
codex-protocol = { workspace = true }
color-eyre = { workspace = true }
crossterm = { workspace = true, features = ["bracketed-paste", "event-stream"] }
derive_more = { workspace = true, features = ["is_variant"] }
diffy = { workspace = true }
dirs = { workspace = true }
dunce = { workspace = true }

View File

@@ -33,6 +33,7 @@ use crossterm::style::SetBackgroundColor;
use crossterm::style::SetColors;
use crossterm::style::SetForegroundColor;
use crossterm::terminal::Clear;
use derive_more::IsVariant;
use ratatui::backend::Backend;
use ratatui::backend::ClearType;
use ratatui::buffer::Buffer;
@@ -120,8 +121,6 @@ where
/// Last known position of the cursor. Used to find the new area when the viewport is inlined
/// and the terminal resized.
pub last_known_cursor_pos: Position,
use_custom_flush: bool,
}
impl<B> Drop for Terminal<B>
@@ -151,16 +150,12 @@ where
let cursor_pos = backend.get_cursor_position()?;
Ok(Self {
backend,
buffers: [
Buffer::empty(Rect::new(0, 0, 0, 0)),
Buffer::empty(Rect::new(0, 0, 0, 0)),
],
buffers: [Buffer::empty(Rect::ZERO), Buffer::empty(Rect::ZERO)],
current: 0,
hidden_cursor: false,
viewport_area: Rect::new(0, cursor_pos.y, 0, 0),
last_known_screen_size: screen_size,
last_known_cursor_pos: cursor_pos,
use_custom_flush: true,
})
}
@@ -173,11 +168,26 @@ where
}
}
/// Gets the current buffer as a reference.
fn current_buffer(&self) -> &Buffer {
&self.buffers[self.current]
}
/// Gets the current buffer as a mutable reference.
pub fn current_buffer_mut(&mut self) -> &mut Buffer {
fn current_buffer_mut(&mut self) -> &mut Buffer {
&mut self.buffers[self.current]
}
/// Gets the previous buffer as a reference.
fn previous_buffer(&self) -> &Buffer {
&self.buffers[1 - self.current]
}
/// Gets the previous buffer as a mutable reference.
fn previous_buffer_mut(&mut self) -> &mut Buffer {
&mut self.buffers[1 - self.current]
}
/// Gets the backend
pub const fn backend(&self) -> &B {
&self.backend
@@ -191,26 +201,12 @@ where
/// Obtains a difference between the previous and the current buffer and passes it to the
/// current backend for drawing.
pub fn flush(&mut self) -> io::Result<()> {
let previous_buffer = &self.buffers[1 - self.current];
let current_buffer = &self.buffers[self.current];
if self.use_custom_flush {
let updates = diff_buffers(previous_buffer, current_buffer);
if let Some(DrawCommand::Put { x, y, .. }) = updates
.iter()
.rev()
.find(|cmd| matches!(cmd, DrawCommand::Put { .. }))
{
self.last_known_cursor_pos = Position { x: *x, y: *y };
}
draw(&mut self.backend, updates.into_iter())
} else {
let updates = previous_buffer.diff(current_buffer);
if let Some((x, y, _)) = updates.last() {
self.last_known_cursor_pos = Position { x: *x, y: *y };
}
self.backend.draw(updates.into_iter())
let updates = diff_buffers(self.previous_buffer(), self.current_buffer());
let last_put_command = updates.iter().rfind(|command| command.is_put());
if let Some(&DrawCommand::Put { x, y, .. }) = last_put_command {
self.last_known_cursor_pos = Position { x, y };
}
draw(&mut self.backend, updates.into_iter())
}
/// Updates the Terminal so that internal buffers match the requested area.
@@ -224,8 +220,8 @@ where
/// Sets the viewport area.
pub fn set_viewport_area(&mut self, area: Rect) {
self.buffers[self.current].resize(area);
self.buffers[1 - self.current].resize(area);
self.current_buffer_mut().resize(area);
self.previous_buffer_mut().resize(area);
self.viewport_area = area;
}
@@ -337,7 +333,7 @@ where
self.swap_buffers();
ratatui::backend::Backend::flush(&mut self.backend)?;
Backend::flush(&mut self.backend)?;
Ok(())
}
@@ -381,13 +377,13 @@ where
.set_cursor_position(self.viewport_area.as_position())?;
self.backend.clear_region(ClearType::AfterCursor)?;
// Reset the back buffer to make sure the next update will redraw everything.
self.buffers[1 - self.current].reset();
self.previous_buffer_mut().reset();
Ok(())
}
/// Clears the inactive buffer and swaps it with the current buffer
pub fn swap_buffers(&mut self) {
self.buffers[1 - self.current].reset();
self.previous_buffer_mut().reset();
self.current = 1 - self.current;
}
@@ -400,13 +396,13 @@ where
use ratatui::buffer::Cell;
use unicode_width::UnicodeWidthStr;
#[derive(Debug)]
enum DrawCommand<'a> {
Put { x: u16, y: u16, cell: &'a Cell },
#[derive(Debug, IsVariant)]
enum DrawCommand {
Put { x: u16, y: u16, cell: Cell },
ClearToEnd { x: u16, y: u16, bg: Color },
}
fn diff_buffers<'a>(a: &'a Buffer, b: &'a Buffer) -> Vec<DrawCommand<'a>> {
fn diff_buffers(a: &Buffer, b: &Buffer) -> Vec<DrawCommand> {
let previous_buffer = &a.content;
let next_buffer = &b.content;
@@ -455,7 +451,7 @@ fn diff_buffers<'a>(a: &'a Buffer, b: &'a Buffer) -> Vec<DrawCommand<'a>> {
updates.push(DrawCommand::Put {
x,
y,
cell: &next_buffer[i],
cell: next_buffer[i].clone(),
});
}
}
@@ -468,9 +464,9 @@ fn diff_buffers<'a>(a: &'a Buffer, b: &'a Buffer) -> Vec<DrawCommand<'a>> {
updates
}
fn draw<'a, I>(writer: &mut impl Write, commands: I) -> io::Result<()>
fn draw<I>(writer: &mut impl Write, commands: I) -> io::Result<()>
where
I: Iterator<Item = DrawCommand<'a>>,
I: Iterator<Item = DrawCommand>,
{
let mut fg = Color::Reset;
let mut bg = Color::Reset;