Clear seems working

This commit is contained in:
Thomas Forgione 2023-10-25 15:54:27 +02:00
parent 18bc80ee8e
commit c5d563bea1
3 changed files with 126 additions and 58 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
for i in `seq 1 100`; do for i in `seq 1 100`; do
echo $i
sleep 0.05s sleep 0.05s
echo -en "\n$i"
done done

View File

@ -153,11 +153,10 @@ impl<W: Write> Multiview<W> {
Ok(()) Ok(())
} }
}
impl<W: Write> Drop for Multiview<W> { /// Exits.
fn drop(&mut self) { pub fn exit(&mut self) {
write!(self.stdout, "{}", cursor::Show).unwrap(); write!(self.stdout, "{}", cursor::Show).ok();
for row in &mut self.tiles { for row in &mut self.tiles {
for tile in row { for tile in row {
@ -167,6 +166,12 @@ impl<W: Write> Drop for Multiview<W> {
} }
} }
impl<W: Write> Drop for Multiview<W> {
fn drop(&mut self) {
self.exit();
}
}
/// An event that can be sent in channels. /// An event that can be sent in channels.
pub enum Msg { pub enum Msg {
/// An stdout line arrived. /// An stdout line arrived.
@ -291,7 +296,10 @@ pub fn main() -> io::Result<()> {
Ok(Msg::ScrollUp) => multiview.scroll_up(), Ok(Msg::ScrollUp) => multiview.scroll_up(),
Ok(Msg::ScrollFullDown) => multiview.scroll_full_down(), Ok(Msg::ScrollFullDown) => multiview.scroll_full_down(),
Ok(Msg::ScrollFullUp) => multiview.scroll_full_up(), Ok(Msg::ScrollFullUp) => multiview.scroll_full_up(),
Ok(Msg::Exit) => break, Ok(Msg::Exit) => {
multiview.exit();
break;
}
Err(_) => (), Err(_) => (),
} }

View File

@ -91,7 +91,6 @@ impl TileBuilder {
inner_size: (w - 4, h - 5), inner_size: (w - 4, h - 5),
sender: self.sender?, sender: self.sender?,
stdout: String::new(), stdout: String::new(),
len: 0,
scroll: 0, scroll: 0,
number_lines: 1, number_lines: 1,
counting: true, counting: true,
@ -111,9 +110,6 @@ pub struct Tile {
/// We put both stdout and stderr here to avoid dealing with order between stdout and stderr. /// We put both stdout and stderr here to avoid dealing with order between stdout and stderr.
pub stdout: String, pub stdout: String,
/// The number of chars in stdout.
pub len: usize,
/// The sender for the communication with the multiview. /// The sender for the communication with the multiview.
pub sender: Sender<Msg>, pub sender: Sender<Msg>,
@ -180,24 +176,46 @@ impl Tile {
let coords = coords; let coords = coords;
thread::spawn(move || loop { thread::spawn(move || {
let mut buffer = [0; 4096]; loop {
let result = stdout.read(&mut buffer); let mut buffer = [0; 4096];
let result = stdout.read(&mut buffer);
match result { match result {
Ok(0) => break, Ok(0) => break,
Ok(n) => { Ok(n) => {
sender sender
.send(Msg::Stderr( .send(Msg::Stderr(
coords, coords,
String::from_utf8_lossy(&buffer[0..n]).to_string(), String::from_utf8_lossy(&buffer[0..n]).to_string(),
)) ))
.unwrap(); .unwrap();
}
Err(_) => break,
} }
Err(_) => break,
} }
sender
.send(Msg::Stdout(coords, String::from("\n")))
.unwrap();
let code = 0;
let exit_string = format!(
"{}{}Command exited with return code {}\r{}",
style::Bold,
if code == 0 {
color::Green.fg_str()
} else {
color::Red.fg_str()
},
code,
style::Reset,
);
sender.send(Msg::Stdout(coords, exit_string)).unwrap();
}); });
thread::spawn(move || loop { thread::spawn(move || loop {
@ -229,26 +247,33 @@ impl Tile {
if c == '\x1b' { if c == '\x1b' {
self.counting = false; self.counting = false;
} }
match c {
'\n' => {
self.stdout.push(c);
self.column_number = 0;
self.number_lines += 1;
}
if c == '\n' { '\r' => {
self.stdout.push(c); self.stdout.push(c);
self.len += 1; self.column_number = 0;
self.column_number = 0; }
self.number_lines += 1;
} else { _ => {
// TODO fix utf8 // TODO fix utf8
self.stdout.push(c); self.stdout.push(c);
if self.counting {
self.column_number += 1; if self.counting {
if self.column_number == self.inner_size.0 + 1 { self.column_number += 1;
self.column_number = 0; if self.column_number == self.inner_size.0 + 1 {
self.number_lines += 1; self.column_number = 0;
self.number_lines += 1;
}
} }
} }
self.len += 1;
} }
if c == 'm' { if c == 'm' || c == 'K' {
self.counting = true; self.counting = true;
} }
} }
@ -319,19 +344,45 @@ impl Tile {
let mut buffer = vec![]; let mut buffer = vec![];
let mut counting = true;
let mut line_index = 0; let mut line_index = 0;
let mut last_line_index = 0;
let mut old_current_char_index = 0; let mut old_current_char_index = 0;
let mut current_char_index = 0; let mut current_char_index = 0;
let mut last_char = ' '; let mut max_char_index = 0;
let scroll = self.scroll as u16; let scroll = self.scroll as u16;
buffer.push(format!("{}", cursor::Goto(x, y))); buffer.push(format!("{}", cursor::Goto(x, y)));
for c in self.stdout.chars() { let mut iter = self.stdout.chars();
last_char = c;
loop {
let c = match iter.next() {
Some(c) => c,
None => break,
};
if c == '\x1b' { if c == '\x1b' {
counting = false; let mut subbuffer = String::from(c);
loop {
let next = match iter.next() {
Some(c) => c,
None => break,
};
subbuffer.push(next);
if next == 'm' || next == 'K' {
break;
}
}
match &subbuffer[0..3] {
"\x1b[K" => (),
_ => buffer.push(subbuffer),
}
continue;
} }
if line_index >= scroll && line_index <= h + scroll { if line_index >= scroll && line_index <= h + scroll {
@ -344,6 +395,8 @@ impl Tile {
current_char_index = 0; current_char_index = 0;
if line_index >= scroll && line_index <= h + scroll { if line_index >= scroll && line_index <= h + scroll {
max_char_index = 0;
if old_current_char_index < w { if old_current_char_index < w {
let mut spaces = String::new(); let mut spaces = String::new();
for _ in old_current_char_index..w { for _ in old_current_char_index..w {
@ -356,6 +409,8 @@ impl Tile {
"{}", "{}",
cursor::Goto(x, y + line_index as u16 - scroll) cursor::Goto(x, y + line_index as u16 - scroll)
)); ));
last_line_index = line_index;
} }
} }
@ -366,24 +421,28 @@ impl Tile {
"{}", "{}",
cursor::Goto(x, y + line_index as u16 - scroll) cursor::Goto(x, y + line_index as u16 - scroll)
)); ));
last_line_index = line_index;
} }
} }
_ => { _ => {
if line_index >= scroll && line_index <= h + scroll { if line_index >= scroll && line_index <= h + scroll {
if counting { current_char_index += 1;
current_char_index += 1; max_char_index = std::cmp::max(max_char_index, current_char_index);
}
if current_char_index == w + 1 { if current_char_index == w + 1 {
line_index += 1; line_index += 1;
current_char_index = 1; current_char_index = 1;
max_char_index = 1;
if line_index >= scroll && line_index <= h + scroll { if line_index >= scroll && line_index <= h + scroll {
buffer.push(format!( buffer.push(format!(
"{}", "{}",
cursor::Goto(x, y + line_index as u16 - scroll) cursor::Goto(x, y + line_index as u16 - scroll)
)); ));
last_line_index = line_index;
} }
} }
@ -391,20 +450,21 @@ impl Tile {
} }
} }
} }
if c == 'm' {
counting = true;
}
} }
let index = if last_char == '\n' { // I don't know how to clear this correctly :'(
old_current_char_index // let index = if last_char == '\n' {
} else { // old_current_char_index
current_char_index // } else {
}; // max_char_index;
// };
let mut spaces = String::new(); let mut spaces = format!(
for _ in index..w { "{}",
cursor::Goto(x + max_char_index, y + last_line_index as u16 - scroll)
);
for _ in max_char_index..w {
spaces.push(DELETE_CHAR); spaces.push(DELETE_CHAR);
} }
buffer.push(spaces); buffer.push(spaces);