Home / End

This commit is contained in:
Thomas Forgione 2023-10-24 16:57:24 +02:00
parent cd867b6c87
commit 692d38869a
2 changed files with 60 additions and 100 deletions

View File

@ -114,6 +114,18 @@ impl<W: Write> Multiview<W> {
tile.scroll_up();
}
/// Scrolls down to the bottom of the current selected tile.
pub fn scroll_full_down(&mut self) {
let tile = self.tile_mut(self.selected);
tile.scroll_full_down();
}
/// Scrolls up to the top the current selected tile.
pub fn scroll_full_up(&mut self) {
let tile = self.tile_mut(self.selected);
tile.scroll_full_up();
}
/// Push a string into a tile's stdout.
pub fn push_stdout(&mut self, (i, j): (u16, u16), content: String) {
let tile = self.tile_mut((i, j));
@ -149,6 +161,12 @@ pub enum Msg {
/// Scroll down one line.
ScrollDown,
/// Scroll to the top of the log.
ScrollFullUp,
/// Scroll to the bottom of the log.
ScrollFullDown,
/// The program was asked to exit.
Exit,
}
@ -217,6 +235,8 @@ pub fn main() -> io::Result<()> {
Event::Key(Key::Char('q')) => sender.send(Msg::Exit).unwrap(),
Event::Key(Key::Down) => sender.send(Msg::ScrollDown).unwrap(),
Event::Key(Key::Up) => sender.send(Msg::ScrollUp).unwrap(),
Event::Key(Key::End) => sender.send(Msg::ScrollFullDown).unwrap(),
Event::Key(Key::Home) => sender.send(Msg::ScrollFullUp).unwrap(),
Event::Mouse(MouseEvent::Press(p, x, y)) => match p {
MouseButton::WheelUp => sender.send(Msg::ScrollUp).unwrap(),
MouseButton::WheelDown => sender.send(Msg::ScrollDown).unwrap(),
@ -236,6 +256,8 @@ pub fn main() -> io::Result<()> {
Ok(Msg::Click(x, y)) => multiview.select_tile((x, y), term_size),
Ok(Msg::ScrollDown) => multiview.scroll_down(),
Ok(Msg::ScrollUp) => multiview.scroll_up(),
Ok(Msg::ScrollFullDown) => multiview.scroll_full_down(),
Ok(Msg::ScrollFullUp) => multiview.scroll_full_up(),
Ok(Msg::Exit) => break,
Err(_) => (),
}

View File

@ -91,7 +91,6 @@ impl TileBuilder {
inner_size: (w - 4, h - 5),
sender: self.sender?,
stdout: String::new(),
cursor: None,
len: 0,
scroll: 0,
number_lines: 1,
@ -112,11 +111,6 @@ pub struct Tile {
/// We put both stdout and stderr here to avoid dealing with order between stdout and stderr.
pub stdout: String,
/// The cursor where stdout should write.
///
/// If None, stdout should push at the end of the string.
pub cursor: Option<usize>,
/// The number of chars in stdout.
pub len: usize,
@ -248,106 +242,27 @@ impl Tile {
/// Push content into the stdout of the tile.
pub fn push_stdout(&mut self, content: String) {
let mut clear_line_counter = 0;
for c in content.chars() {
// Check if we're running into \x1b[K
clear_line_counter = match (c, clear_line_counter) {
('\x1b', _) => {
self.counting = false;
1
}
('[', 1) => 2,
('K', 2) => 3,
_ => 0,
};
if let (3, Some(cursor)) = (clear_line_counter, self.cursor) {
// Find the size of the string until the next '\n' or end
let mut counter = 0;
loop {
counter += 1;
// TODO fix utf8
if self.stdout.len() <= counter + cursor
|| &self.stdout[cursor + counter..cursor + counter + 1] == "\n"
{
break;
}
}
self.stdout
.replace_range((cursor - 2)..(cursor + counter), "");
self.len -= 2 + counter;
self.cursor = None;
self.counting = true;
continue;
if c == '\x1b' {
self.counting = false;
}
if c == '\r' {
// Set cursor at the right place
let mut index = self.len;
let mut reverse = self.stdout.chars().rev();
if c == '\n' {
self.stdout.push(c);
self.len += 1;
self.column_number = 0;
loop {
match reverse.next() {
Some('\n') | None => break,
_ => index -= 1,
self.number_lines += 1;
} else {
// TODO fix utf8
self.stdout.push(c);
if self.counting {
self.column_number += 1;
if self.column_number == self.inner_size.0 + 1 {
self.column_number = 0;
self.number_lines += 1;
}
}
self.cursor = Some(index);
} else {
let new_cursor = match self.cursor {
Some(index) => {
if c == '\n' {
self.stdout.push(c);
self.len += 1;
self.column_number = 0;
self.number_lines += 1;
None
} else {
// TODO fix utf8
if index >= self.stdout.len() {
self.stdout.push(c);
if self.counting {
self.column_number += 1;
if self.column_number == self.inner_size.0 + 1 {
self.column_number = 0;
self.number_lines += 1;
}
}
self.len += 1;
None
} else {
self.stdout.replace_range(index..index + 1, &c.to_string());
Some(index + 1)
}
}
}
None => {
self.stdout.push(c);
if c == '\n' {
self.column_number = 0;
self.number_lines += 1;
} else {
if self.counting {
self.column_number += 1;
if self.column_number == self.inner_size.0 + 1 {
self.column_number = 0;
self.number_lines += 1;
}
}
}
self.len += 1;
None
}
};
self.cursor = new_cursor;
self.len += 1;
}
if c == 'm' {
@ -461,6 +376,16 @@ impl Tile {
}
}
'\r' => {
current_char_index = 0;
if line_index >= scroll && line_index <= h + scroll {
buffer.push(format!(
"{}",
cursor::Goto(x, y + line_index as u16 - scroll)
));
}
}
_ => {
if line_index >= scroll && line_index <= h + scroll {
if counting {
@ -518,4 +443,17 @@ impl Tile {
self.scroll += 1;
}
}
/// Scrolls up one line.
pub fn scroll_full_up(&mut self) {
self.scroll = 0;
}
/// Scrolls down one line.
pub fn scroll_full_down(&mut self) {
self.scroll = self.number_lines - self.inner_size.1 as isize - 1;
if self.scroll < 0 {
self.scroll = 0;
}
}
}