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:
parent
c2297ab494
commit
9a711bbe96
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()) }
|
||||||
}
|
}
|
||||||
|
@ -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()) }
|
||||||
|
19
src/term.rs
19
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 {
|
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
|
||||||
}
|
}
|
||||||
|
@ -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(())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user