Rendering buffer in stdout using crossterm
⚓ Rust 📅 2025-05-15 👤 surdeus 👁️ 9pub fn draw(&self) -> anyhow::Result<()> {
let mut stdout = self.stdout.borrow_mut();
let mut lines = self.text.lines_at(self.y_offset);
eprintln!("first line: {:#?}", lines.clone().next());
eprintln!("size.1: {}", self.size.1);
for i in 0..self.size.1 - 1 {
let line = lines.next().unwrap_or("".into());
let str = format!("{line:<width$}", width = self.size.0 as usize);
if i < 3 {
eprintln!("Line {}: len={}, content={:?}", i, str.len(), str);
}
stdout.queue(cursor::MoveTo(0, i))?.queue(Print(str))?;
}
stdout
.queue(cursor::MoveTo(0, 40))?
.queue(Print("AAAAAAAAAAAAAAAAAAA"))?;
let cursor = self.cursor.head();
stdout.queue(cursor::MoveTo(cursor.0, cursor.1))?;
stdout.flush()?;
Ok(())
}
Here's snippet of function used to render a visible part of buffer into stdout.
I'm redirecting stderr to another tty so i'm using eprintln!.
I'm using ropey::Rope as buffer
line and self.y_offset are always correct. Checked them several times.
lines in if i < 3 are correct to render.
Incrementing self.y_offset is working as well.
That's the only function that interacts with stdout besides 1 stdout.flush() in the caller function. (I'm not even sure if it is needed there)
height of terminal (`self.size.1') is 41, but actual visible height is 40.
I have 2 questions:
- Why i can't use
for i in 0..self.size.1? If i use it, lines below will be copied on the line above with each rerender even if i don't changeself.y_offset. So after 40 rerenders the bottom line will overlap the first one. That also means i cant use 40th line to render buffer there. - Why if i use
for i in 0..self.size.1 - 1it will draw correct while i don't changeself.y_offset, and when i change it will copy all lines to line aboves, but instead of doing so every rerender it actually only make it once.
My guess was i didn't overwrite previous buffer and those lines were overwriting new ones if new ones had less length, but that's not the case because i create padding equal to terminal width. And rendering each line in a loop means new line will overwrite the padding if it was too big.
3 posts - 2 participants
🏷️ rust_feed