From 9a711bbe96d753d0dbf70007adc0ff89823aa9ad Mon Sep 17 00:00:00 2001 From: rabite Date: Wed, 20 Mar 2019 13:58:59 +0100 Subject: handle long lines in status/footer --- src/coordinates.rs | 8 ++++++-- src/fail.rs | 5 +++++ src/foldview.rs | 21 ++++++++++++++++----- src/proclist.rs | 15 ++++++++++----- src/term.rs | 19 ++++++++++++------- src/widget.rs | 5 ++++- 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/coordinates.rs b/src/coordinates.rs index 735286a..6453ad9 100644 --- a/src/coordinates.rs +++ b/src/coordinates.rs @@ -60,6 +60,10 @@ impl Coordinates { (self.position.0).1 = y; } + pub fn xsize_u(&self) -> usize { + self.size.size_u().0 + } + pub fn xsize(&self) -> u16 { self.size.xsize() } @@ -115,7 +119,7 @@ impl Size { } pub fn size_u(&self) -> (usize, usize) { let (xsize, ysize) = self.0; - (xsize as usize, ysize as usize) + ((xsize-1) as usize, (ysize-1) as usize) } pub fn xsize(&self) -> u16 { (self.0).0 @@ -131,7 +135,7 @@ impl Position { } pub fn position_u(&self) -> (usize, usize) { let (xpos, ypos) = self.0; - (xpos as usize, ypos as usize) + ((xpos-1) as usize, (ypos-1) as usize) } pub fn x(&self) -> u16 { (self.0).0 diff --git a/src/fail.rs b/src/fail.rs index 97cbd62..580aad1 100644 --- a/src/fail.rs +++ b/src/fail.rs @@ -69,9 +69,14 @@ pub enum HError { WidgetUndefinedKeyError{key: Key}, #[fail(display = "Terminal has been resized!")] TerminalResizedError, + #[fail(display = "{}", _0)] + Log(String) } impl HError { + pub fn log(log: String) -> HResult<()> { + Err(HError::Log(log)) + } pub fn quit() -> HResult<()> { Err(HError::Quit) } diff --git a/src/foldview.rs b/src/foldview.rs index 74c8f9e..d45eff6 100644 --- a/src/foldview.rs +++ b/src/foldview.rs @@ -44,15 +44,21 @@ impl Foldable for LogEntry { impl From<&HError> for LogEntry { fn from(from: &HError) -> LogEntry { let time: DateTime = Local::now(); + + let logcolor = match from { + HError::Log(_) => term::normal_color(), + _ => term::color_red() + }; + let description = format!("{}{}{}: {}", term::color_green(), time.format("%F %R"), - term::color_red(), + logcolor, from).lines().take(1).collect(); let mut content = format!("{}{}{}: {}\n", term::color_green(), time.format("%F %R"), - term::color_red(), + logcolor, from); @@ -93,7 +99,7 @@ impl FoldableWidgetExt for ListView> { fn render_header(&self) -> HResult { let (xsize, _) = self.core.coordinates.size_u(); - let current = self.current_fold().unwrap_or(0); + let current = self.current_fold().map(|n| n+1).unwrap_or(0); let num = self.content.len(); let hint = format!("{} / {}", current, num); let hint_xpos = xsize - hint.len(); @@ -118,12 +124,17 @@ impl FoldableWidgetExt for ListView> { let hint_xpos = xsize - line_hint.len(); let hint_ypos = ysize + ypos + 1; - let footer = format!("LogEntry: {}{}{}{}{}", - description, + let sized_description = term::sized_string_u(&description, + xsize + - (line_hint.len()+2)); + + let footer = format!("{}{}{}{}{}", + sized_description, term::reset(), term::status_bg(), term::goto_xy_u(hint_xpos, hint_ypos), line_hint); + Ok(footer) } else { Ok("No log entries".to_string()) } } diff --git a/src/proclist.rs b/src/proclist.rs index bab9394..a841b44 100644 --- a/src/proclist.rs +++ b/src/proclist.rs @@ -12,6 +12,7 @@ use crate::listview::{Listable, ListView}; use crate::textview::TextView; use crate::widget::{Widget, Events, WidgetCore}; use crate::coordinates::Coordinates; +use crate::dirty::Dirtyable; use crate::hbox::HBox; use crate::preview::WillBeWidget; use crate::fail::{HResult, HError, ErrorLog}; @@ -90,12 +91,11 @@ impl Process { format!("{}{}", term::color_red(), proc_status) }; - let status = format!("Process: {}:{} exited {}{}{} with status: {}", + let status = format!("Process: {}:{} exited {}{} with status: {}", cmd, pid, color_success, - term::reset(), - term::status_bg(), + term::normal_color(), color_status); sender.send(Events::Status(status))?; } @@ -113,6 +113,10 @@ impl Listable for ListView> { self.render_proc(proc).unwrap() }).collect() } + fn on_refresh(&mut self) -> HResult<()> { + self.core.set_dirty(); + Ok(()) + } } impl ListView> { @@ -385,6 +389,7 @@ impl Widget for ProcView { fn render_footer(&self) -> HResult { let listview = self.get_listview(); let selection = listview.get_selection(); + let xsize = self.core.coordinates.xsize_u(); if let Some(proc) = listview.content.get(selection) { let cmd = &proc.cmd; @@ -409,7 +414,7 @@ impl Widget for ProcView { } } else { "wtf".to_string() }; - let procinfo = format!("Process: {}:{} exited {}{}{} with status: {}", + let procinfo = format!("{}:{} exited {}{}{} with status: {}", cmd, pid, color_success, @@ -419,7 +424,7 @@ impl Widget for ProcView { procinfo } else { "still running".to_string() }; - let footer = format!("{}: {}", cmd, procinfo); + let footer = term::sized_string_u(&procinfo, xsize); Ok(footer) } else { Ok("No proccesses".to_string()) } diff --git a/src/term.rs b/src/term.rs index abedbba..81c1feb 100644 --- a/src/term.rs +++ b/src/term.rs @@ -163,9 +163,13 @@ fn is_ansi(ansi_pos: &Vec<(usize, usize)>, char_pos: &usize) -> bool { fn ansi_len_at(ansi_pos: &Vec<(usize, usize)>, char_pos: &usize) -> usize { ansi_pos.iter().fold(0, |len, (start, end)| { - if char_pos >= end { - len + (end-start) - } else { len } + if char_pos >= start && char_pos <= end { + len + (char_pos - start) + } else if char_pos >= end { + len + (end - start) + } else { + len + } }) } @@ -174,18 +178,19 @@ pub fn sized_string_u(string: &str, xsize: usize) -> String { (m.start(), m.end()) }).collect(); - let sized = string.chars().enumerate().fold("".to_string(), |acc, (i, ch)| { + let sized = string.chars().fold(String::new(), |acc, ch| { let width: usize = unicode_width::UnicodeWidthStr::width_cjk(acc.as_str()); - let ansi_len = ansi_len_at(&ansi_pos, &i); + let ansi_len = ansi_len_at(&ansi_pos, &acc.len()); + let unprinted = acc.len() - width; - if width >= xsize as usize + ansi_len { + if width + unprinted >= xsize + ansi_len + 1{ acc } else { acc + &ch.to_string() } }); - let ansi_len = ansi_len_at(&ansi_pos, &(sized.len().saturating_sub(1))); + let ansi_len = ansi_len_at(&ansi_pos, &sized.len()); let padded = format!("{:padding$}", sized, padding=xsize + ansi_len + 1); padded } diff --git a/src/widget.rs b/src/widget.rs index 1610596..28e58e6 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -373,9 +373,12 @@ pub trait Widget { } fn show_status(&self, status: &str) -> HResult<()> { + let xsize = self.get_core()?.coordinates.xsize_u(); + let sized_status = term::sized_string_u(status, xsize); + HError::log(status.to_string()).log(); { let mut status_content = self.get_core()?.status_bar_content.lock()?; - *status_content = Some(status.to_string()); + *status_content = Some(sized_status); } self.draw_status()?; Ok(()) -- cgit v1.2.3