1
0
mirror of https://github.com/bobwen-dev/hunter synced 2025-04-12 00:55:41 +02:00

handle long lines in status/footer

This commit is contained in:
rabite 2019-03-20 13:58:59 +01:00
parent c2297ab494
commit 9a711bbe96
6 changed files with 53 additions and 20 deletions

View File

@ -60,6 +60,10 @@ impl Coordinates {
(self.position.0).1 = y; (self.position.0).1 = y;
} }
pub fn xsize_u(&self) -> usize {
self.size.size_u().0
}
pub fn xsize(&self) -> u16 { pub fn xsize(&self) -> u16 {
self.size.xsize() self.size.xsize()
} }
@ -115,7 +119,7 @@ impl Size {
} }
pub fn size_u(&self) -> (usize, usize) { pub fn size_u(&self) -> (usize, usize) {
let (xsize, ysize) = self.0; let (xsize, ysize) = self.0;
(xsize as usize, ysize as usize) ((xsize-1) as usize, (ysize-1) as usize)
} }
pub fn xsize(&self) -> u16 { pub fn xsize(&self) -> u16 {
(self.0).0 (self.0).0
@ -131,7 +135,7 @@ impl Position {
} }
pub fn position_u(&self) -> (usize, usize) { pub fn position_u(&self) -> (usize, usize) {
let (xpos, ypos) = self.0; let (xpos, ypos) = self.0;
(xpos as usize, ypos as usize) ((xpos-1) as usize, (ypos-1) as usize)
} }
pub fn x(&self) -> u16 { pub fn x(&self) -> u16 {
(self.0).0 (self.0).0

View File

@ -69,9 +69,14 @@ pub enum HError {
WidgetUndefinedKeyError{key: Key}, WidgetUndefinedKeyError{key: Key},
#[fail(display = "Terminal has been resized!")] #[fail(display = "Terminal has been resized!")]
TerminalResizedError, TerminalResizedError,
#[fail(display = "{}", _0)]
Log(String)
} }
impl HError { impl HError {
pub fn log(log: String) -> HResult<()> {
Err(HError::Log(log))
}
pub fn quit() -> HResult<()> { pub fn quit() -> HResult<()> {
Err(HError::Quit) Err(HError::Quit)
} }

View File

@ -44,15 +44,21 @@ impl Foldable for LogEntry {
impl From<&HError> for LogEntry { impl From<&HError> for LogEntry {
fn from(from: &HError) -> LogEntry { fn from(from: &HError) -> LogEntry {
let time: DateTime<Local> = Local::now(); let time: DateTime<Local> = Local::now();
let logcolor = match from {
HError::Log(_) => term::normal_color(),
_ => term::color_red()
};
let description = format!("{}{}{}: {}", let description = format!("{}{}{}: {}",
term::color_green(), term::color_green(),
time.format("%F %R"), time.format("%F %R"),
term::color_red(), logcolor,
from).lines().take(1).collect(); from).lines().take(1).collect();
let mut content = format!("{}{}{}: {}\n", let mut content = format!("{}{}{}: {}\n",
term::color_green(), term::color_green(),
time.format("%F %R"), time.format("%F %R"),
term::color_red(), logcolor,
from); from);
@ -93,7 +99,7 @@ impl FoldableWidgetExt for ListView<Vec<LogEntry>> {
fn render_header(&self) -> HResult<String> { fn render_header(&self) -> HResult<String> {
let (xsize, _) = self.core.coordinates.size_u(); 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 num = self.content.len();
let hint = format!("{} / {}", current, num); let hint = format!("{} / {}", current, num);
let hint_xpos = xsize - hint.len(); let hint_xpos = xsize - hint.len();
@ -118,12 +124,17 @@ impl FoldableWidgetExt for ListView<Vec<LogEntry>> {
let hint_xpos = xsize - line_hint.len(); let hint_xpos = xsize - line_hint.len();
let hint_ypos = ysize + ypos + 1; let hint_ypos = ysize + ypos + 1;
let footer = format!("LogEntry: {}{}{}{}{}", let sized_description = term::sized_string_u(&description,
description, xsize
- (line_hint.len()+2));
let footer = format!("{}{}{}{}{}",
sized_description,
term::reset(), term::reset(),
term::status_bg(), term::status_bg(),
term::goto_xy_u(hint_xpos, hint_ypos), term::goto_xy_u(hint_xpos, hint_ypos),
line_hint); line_hint);
Ok(footer) Ok(footer)
} else { Ok("No log entries".to_string()) } } else { Ok("No log entries".to_string()) }
} }

View File

@ -12,6 +12,7 @@ use crate::listview::{Listable, ListView};
use crate::textview::TextView; use crate::textview::TextView;
use crate::widget::{Widget, Events, WidgetCore}; use crate::widget::{Widget, Events, WidgetCore};
use crate::coordinates::Coordinates; use crate::coordinates::Coordinates;
use crate::dirty::Dirtyable;
use crate::hbox::HBox; use crate::hbox::HBox;
use crate::preview::WillBeWidget; use crate::preview::WillBeWidget;
use crate::fail::{HResult, HError, ErrorLog}; use crate::fail::{HResult, HError, ErrorLog};
@ -90,12 +91,11 @@ impl Process {
format!("{}{}", term::color_red(), proc_status) format!("{}{}", term::color_red(), proc_status)
}; };
let status = format!("Process: {}:{} exited {}{}{} with status: {}", let status = format!("Process: {}:{} exited {}{} with status: {}",
cmd, cmd,
pid, pid,
color_success, color_success,
term::reset(), term::normal_color(),
term::status_bg(),
color_status); color_status);
sender.send(Events::Status(status))?; sender.send(Events::Status(status))?;
} }
@ -113,6 +113,10 @@ impl Listable for ListView<Vec<Process>> {
self.render_proc(proc).unwrap() self.render_proc(proc).unwrap()
}).collect() }).collect()
} }
fn on_refresh(&mut self) -> HResult<()> {
self.core.set_dirty();
Ok(())
}
} }
impl ListView<Vec<Process>> { impl ListView<Vec<Process>> {
@ -385,6 +389,7 @@ impl Widget for ProcView {
fn render_footer(&self) -> HResult<String> { fn render_footer(&self) -> HResult<String> {
let listview = self.get_listview(); let listview = self.get_listview();
let selection = listview.get_selection(); let selection = listview.get_selection();
let xsize = self.core.coordinates.xsize_u();
if let Some(proc) = listview.content.get(selection) { if let Some(proc) = listview.content.get(selection) {
let cmd = &proc.cmd; let cmd = &proc.cmd;
@ -409,7 +414,7 @@ impl Widget for ProcView {
} }
} else { "wtf".to_string() }; } else { "wtf".to_string() };
let procinfo = format!("Process: {}:{} exited {}{}{} with status: {}", let procinfo = format!("{}:{} exited {}{}{} with status: {}",
cmd, cmd,
pid, pid,
color_success, color_success,
@ -419,7 +424,7 @@ impl Widget for ProcView {
procinfo procinfo
} else { "still running".to_string() }; } else { "still running".to_string() };
let footer = format!("{}: {}", cmd, procinfo); let footer = term::sized_string_u(&procinfo, xsize);
Ok(footer) Ok(footer)
} else { Ok("No proccesses".to_string()) } } else { Ok("No proccesses".to_string()) }

View File

@ -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 { fn ansi_len_at(ansi_pos: &Vec<(usize, usize)>, char_pos: &usize) -> usize {
ansi_pos.iter().fold(0, |len, (start, end)| { ansi_pos.iter().fold(0, |len, (start, end)| {
if char_pos >= end { if char_pos >= start && char_pos <= end {
len + (end-start) len + (char_pos - start)
} else { len } } 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()) (m.start(), m.end())
}).collect(); }).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 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 acc
} else { } else {
acc + &ch.to_string() 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); let padded = format!("{:padding$}", sized, padding=xsize + ansi_len + 1);
padded padded
} }

View File

@ -373,9 +373,12 @@ pub trait Widget {
} }
fn show_status(&self, status: &str) -> HResult<()> { 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()?; 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()?; self.draw_status()?;
Ok(()) Ok(())