mirror of
https://github.com/ratatui/ratatui.git
synced 2025-09-29 22:11:34 +00:00
fix(backend): move the cursor when first diff is on second cell
Both termion and crossterm backends were not moving the cursor if the first diff to draw was on the second cell. The condition triggering the cursor move has been updated to fix this. In addition, two tests have been added to avoid future regressions.
This commit is contained in:
parent
641f391137
commit
ecb482f297
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -47,6 +47,8 @@ jobs:
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
env:
|
||||
RUST_BACKTRACE: full
|
||||
- name: "Clippy"
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
@ -75,3 +77,5 @@ jobs:
|
||||
with:
|
||||
command: test
|
||||
args: --no-default-features --features=crossterm --tests --examples
|
||||
env:
|
||||
RUST_BACKTRACE: full
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
## To be released
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix incorrect output when the first diff to draw is on the second cell of the terminal (#347).
|
||||
|
||||
## v0.10.0 - 2020-07-17
|
||||
|
||||
### Breaking changes
|
||||
|
@ -58,16 +58,13 @@ where
|
||||
let mut fg = Color::Reset;
|
||||
let mut bg = Color::Reset;
|
||||
let mut modifier = Modifier::empty();
|
||||
let mut last_y = 0;
|
||||
let mut last_x = 0;
|
||||
|
||||
map_error(queue!(string, MoveTo(0, 0)))?;
|
||||
let mut last_pos: Option<(u16, u16)> = None;
|
||||
for (x, y, cell) in content {
|
||||
if y != last_y || x != last_x + 1 {
|
||||
// Move the cursor if the previous location was not (x - 1, y)
|
||||
if !matches!(last_pos, Some(p) if x == p.0 + 1 && y == p.1) {
|
||||
map_error(queue!(string, MoveTo(x, y)))?;
|
||||
}
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
last_pos = Some((x, y));
|
||||
if cell.modifier != modifier {
|
||||
let diff = ModifierDiff {
|
||||
from: modifier,
|
||||
|
@ -1,13 +1,13 @@
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
|
||||
use super::Backend;
|
||||
use crate::{
|
||||
buffer::Cell,
|
||||
layout::Rect,
|
||||
style::{Color, Modifier},
|
||||
};
|
||||
use std::{
|
||||
fmt,
|
||||
io::{self, Write},
|
||||
};
|
||||
|
||||
pub struct TermionBackend<W>
|
||||
where
|
||||
@ -82,15 +82,13 @@ where
|
||||
let mut fg = Color::Reset;
|
||||
let mut bg = Color::Reset;
|
||||
let mut modifier = Modifier::empty();
|
||||
let mut last_y = 0;
|
||||
let mut last_x = 0;
|
||||
write!(string, "{}", termion::cursor::Goto(1, 1)).unwrap();
|
||||
let mut last_pos: Option<(u16, u16)> = None;
|
||||
for (x, y, cell) in content {
|
||||
if y != last_y || x != last_x + 1 {
|
||||
// Move the cursor if the previous location was not (x - 1, y)
|
||||
if !matches!(last_pos, Some(p) if x == p.0 + 1 && y == p.1) {
|
||||
write!(string, "{}", termion::cursor::Goto(x + 1, y + 1)).unwrap();
|
||||
}
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
last_pos = Some((x, y));
|
||||
if cell.modifier != modifier {
|
||||
write!(
|
||||
string,
|
||||
|
63
tests/backend_termion.rs
Normal file
63
tests/backend_termion.rs
Normal file
@ -0,0 +1,63 @@
|
||||
#[cfg(feature = "termion")]
|
||||
#[test]
|
||||
fn backend_termion_should_only_write_diffs() -> Result<(), Box<dyn std::error::Error>> {
|
||||
use std::{fmt::Write, io::Cursor};
|
||||
|
||||
let mut bytes = Vec::new();
|
||||
let mut stdout = Cursor::new(&mut bytes);
|
||||
{
|
||||
use tui::{
|
||||
backend::TermionBackend, layout::Rect, widgets::Paragraph, Terminal, TerminalOptions,
|
||||
Viewport,
|
||||
};
|
||||
let backend = TermionBackend::new(&mut stdout);
|
||||
let area = Rect::new(0, 0, 3, 1);
|
||||
let mut terminal = Terminal::with_options(
|
||||
backend,
|
||||
TerminalOptions {
|
||||
viewport: Viewport::fixed(area),
|
||||
},
|
||||
)?;
|
||||
terminal.draw(|f| {
|
||||
f.render_widget(Paragraph::new("a"), area);
|
||||
})?;
|
||||
terminal.draw(|f| {
|
||||
f.render_widget(Paragraph::new("ab"), area);
|
||||
})?;
|
||||
terminal.draw(|f| {
|
||||
f.render_widget(Paragraph::new("abc"), area);
|
||||
})?;
|
||||
}
|
||||
|
||||
let expected = {
|
||||
use termion::{color, cursor, style};
|
||||
let mut s = String::new();
|
||||
// First draw
|
||||
write!(s, "{}", cursor::Goto(1, 1))?;
|
||||
s.push_str("a");
|
||||
write!(s, "{}", color::Fg(color::Reset))?;
|
||||
write!(s, "{}", color::Bg(color::Reset))?;
|
||||
write!(s, "{}", style::Reset)?;
|
||||
write!(s, "{}", cursor::Hide)?;
|
||||
// Second draw
|
||||
write!(s, "{}", cursor::Goto(2, 1))?;
|
||||
s.push_str("b");
|
||||
write!(s, "{}", color::Fg(color::Reset))?;
|
||||
write!(s, "{}", color::Bg(color::Reset))?;
|
||||
write!(s, "{}", style::Reset)?;
|
||||
write!(s, "{}", cursor::Hide)?;
|
||||
// Third draw
|
||||
write!(s, "{}", cursor::Goto(3, 1))?;
|
||||
s.push_str("c");
|
||||
write!(s, "{}", color::Fg(color::Reset))?;
|
||||
write!(s, "{}", color::Bg(color::Reset))?;
|
||||
write!(s, "{}", style::Reset)?;
|
||||
write!(s, "{}", cursor::Hide)?;
|
||||
// Terminal drop
|
||||
write!(s, "{}", cursor::Show)?;
|
||||
s
|
||||
};
|
||||
assert_eq!(std::str::from_utf8(&bytes)?, expected);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user