cargo_plugin_utils/
scrolling.rs1use std::io::Write;
4
5use anyhow::Context;
6use console::Term;
7
8pub fn get_terminal_size() -> anyhow::Result<(u16, u16)> {
10 let term = Term::stdout();
11 term.size_checked().context("Failed to get terminal size")
12}
13
14pub fn set_scrolling_region(top: u16, bottom: u16) -> anyhow::Result<()> {
19 let mut stderr = std::io::stderr();
22 write!(stderr, "\x1b[{};{}r", top, bottom).context("Failed to set scrolling region")?;
23 stderr.flush().context("Failed to flush stdout")?;
24 Ok(())
25}
26
27pub fn reset_scrolling_region() -> anyhow::Result<()> {
31 let mut stderr = std::io::stderr();
33 write!(stderr, "\x1b[r").context("Failed to reset scrolling region")?;
34 stderr.flush().context("Failed to flush stdout")?;
35 Ok(())
36}
37
38pub fn clear_scrolling_region() -> anyhow::Result<()> {
42 let mut stderr = std::io::stderr();
48 write!(stderr, "\x1b[J").context("Failed to clear scrolling region")?;
52 stderr.flush().context("Failed to flush stdout")?;
53 Ok(())
54}
55
56pub fn move_cursor_to_line(line: u16) -> anyhow::Result<()> {
58 let mut stderr = std::io::stderr();
61 write!(stderr, "\x1b[{};1H", line).context("Failed to move cursor to line")?;
62 stderr.flush().context("Failed to flush stdout")?;
63 Ok(())
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_get_terminal_size() {
72 let _size = get_terminal_size();
75 }
76
77 #[test]
78 fn test_set_scrolling_region() {
79 let _ = set_scrolling_region(1u16, 10u16);
82 }
83
84 #[test]
85 fn test_reset_scrolling_region() {
86 let _ = reset_scrolling_region();
88 }
89
90 #[test]
91 fn test_clear_scrolling_region() {
92 let _ = clear_scrolling_region();
94 }
95
96 #[test]
97 fn test_move_cursor_to_line() {
98 let _ = move_cursor_to_line(5u16);
100 }
101
102 #[test]
103 fn test_scrolling_region_sequence() {
104 let _ = set_scrolling_region(1u16, 5u16);
106 let _ = move_cursor_to_line(1u16);
107 let _ = clear_scrolling_region();
108 let _ = reset_scrolling_region();
109 }
110}