-
-
Save nornagon/11a79d7a1f2e98aa129fedb4abccc530 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::io::{self, stdout}; | |
| use crossterm::{ | |
| event::{read, Event, KeyCode, KeyEventKind}, | |
| terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, | |
| ExecutableCommand, | |
| }; | |
| use ratatui::{ | |
| backend::CrosstermBackend, | |
| layout::Rect, | |
| style::{Color, Style}, | |
| text::{Line, Span}, | |
| widgets::{Block, Borders, Paragraph, Widget}, | |
| Terminal, | |
| }; | |
| fn main() -> io::Result<()> { | |
| // Set up terminal | |
| enable_raw_mode()?; | |
| stdout().execute(EnterAlternateScreen)?; | |
| let backend = CrosstermBackend::new(stdout()); | |
| let mut terminal = Terminal::new(backend)?; | |
| // Simple helper to wait for a key | |
| let mut wait_key = || -> io::Result<()> { | |
| loop { | |
| match read()? { | |
| Event::Key(k) if k.kind == KeyEventKind::Press => break, | |
| _ => {} | |
| } | |
| } | |
| Ok(()) | |
| }; | |
| // Frame 1: baseline | |
| terminal.draw(|f| { | |
| let area = f.size(); | |
| draw_baseline(area, f); | |
| // write 'ab' | |
| let p = Paragraph::new("ab"); | |
| p.render(Rect::new(2, 5, 10, 1), f.buffer_mut()); | |
| draw_instructions(f, "1/3: Showing 'ab'. Press any key to overwrite with 🤷"); | |
| })?; | |
| wait_key()?; | |
| // Frame 2: overwrite with a regular double-width emoji (🤷) | |
| terminal.draw(|f| { | |
| let area = f.size(); | |
| draw_baseline(area, f); | |
| let p = Paragraph::new("🤷"); | |
| p.render(Rect::new(2, 5, 10, 1), f.buffer_mut()); | |
| draw_instructions( | |
| f, | |
| "2/3: Overwrote with 🤷. If you see 'b', trailing cell did not clear. Press any key.", | |
| ); | |
| })?; | |
| wait_key()?; | |
| // Frame 3: show 'ab' again to exactly replicate the sequence before VS16 case | |
| terminal.draw(|f| { | |
| let area = f.size(); | |
| draw_baseline(area, f); | |
| let p = Paragraph::new("ab"); | |
| p.render(Rect::new(2, 5, 10, 1), f.buffer_mut()); | |
| draw_instructions( | |
| f, | |
| "3/4: Showing 'ab' again. Press any key to overwrite with ⌨️", | |
| ); | |
| })?; | |
| wait_key()?; | |
| // Frame 4: overwrite with keyboard emoji using VS16 (⌨️) | |
| terminal.draw(|f| { | |
| let area = f.size(); | |
| draw_baseline(area, f); | |
| let p = Paragraph::new("⌨️"); | |
| p.render(Rect::new(2, 5, 10, 1), f.buffer_mut()); | |
| draw_instructions( | |
| f, | |
| "4/4: Overwrote with ⌨️. Some terminals fail here; look for leftover 'b'. Press any key to exit.", | |
| ); | |
| })?; | |
| wait_key()?; | |
| // Restore terminal | |
| stdout().execute(LeaveAlternateScreen)?; | |
| disable_raw_mode()?; | |
| Ok(()) | |
| } | |
| fn draw_baseline(area: Rect, f: &mut ratatui::Frame<'_>) { | |
| // Ruler line and a border to provide context | |
| let mut ruler = String::from("0123456789"); | |
| while ruler.len() < area.width as usize { ruler.push_str("0123456789"); } | |
| let ruler = &ruler[..area.width as usize]; | |
| Paragraph::new(Line::from(vec![Span::styled(ruler, Style::default().fg(Color::DarkGray))])) | |
| .render(Rect::new(0, 4, area.width, 1), f.buffer_mut()); | |
| Block::new().borders(Borders::ALL).render(area, f.buffer_mut()); | |
| } | |
| fn draw_instructions(f: &mut ratatui::Frame<'_>, message: &str) { | |
| let area = f.size(); | |
| Paragraph::new(message).render(Rect::new(1, area.height.saturating_sub(2), area.width - 2, 1), f.buffer_mut()); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment