From d0cc6078df6886bd40643ee3f542c7cd0862d929 Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Tue, 11 Aug 2020 17:22:39 -0700 Subject: [PATCH] deps: Update dependencies, drop MSRV Update dependencies to most recent versions if applicable. Refactor to deal with breaking changes. Drop MSRV due to dependency issues, just support stable and later. --- .travis.yml | 14 +-- CHANGELOG.md | 4 + CONTRIBUTING.md | 2 +- Cargo.lock | 39 +++--- Cargo.toml | 13 +- README.md | 9 +- src/canvas.rs | 27 ++-- src/canvas/canvas_colours.rs | 2 +- src/canvas/dialogs/dd_dialog.rs | 114 +++++++++-------- src/canvas/dialogs/help_dialog.rs | 26 ++-- src/canvas/widgets/basic_table_arrows.rs | 14 ++- src/canvas/widgets/battery_display.rs | 88 ++++++------- src/canvas/widgets/cpu_basic.rs | 19 +-- src/canvas/widgets/cpu_graph.rs | 43 +++---- src/canvas/widgets/disk_table.rs | 40 +++--- src/canvas/widgets/mem_basic.rs | 11 +- src/canvas/widgets/mem_graph.rs | 50 ++++---- src/canvas/widgets/network_basic.rs | 18 ++- src/canvas/widgets/network_graph.rs | 53 ++++---- src/canvas/widgets/process_table.rs | 153 ++++++++++++----------- src/canvas/widgets/temp_table.rs | 43 ++++--- src/main.rs | 2 + 22 files changed, 408 insertions(+), 376 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05dab58e..cd472ce2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ language: rust rust: - # MSRV; though I only want to test if it builds. - - 1.40.0 - stable - beta os: @@ -13,8 +11,6 @@ jobs: exclude: - if: tag IS present rust: beta - - if: tag IS present - rust: 1.40.0 branches: only: - master @@ -34,15 +30,9 @@ before_script: - rustup target add $TARGET - rustup component add clippy script: - - | - if [[ $TRAVIS_RUST_VERSION != "1.40.0" ]]; then - cargo clippy -- -D clippy::all - fi + - cargo clippy -- -D clippy::all - cargo build --verbose --target $TARGET - - | - if [[ $TRAVIS_RUST_VERSION != "1.40.0" ]]; then - cargo test --verbose --target $TARGET; - fi + - cargo test --verbose --target $TARGET - cargo install --path . --target $TARGET --locked --force before_cache: diff --git a/CHANGELOG.md b/CHANGELOG.md index 57ad01fa..386738a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [179](https://github.com/ClementTsang/bottom/pull/179): Show full command/process path as an option. +### Changes + +- Changed to just support stable (and newer) Rust, due to library incompatibilities. + ## [0.4.5] - 2020-07-08 - No changes here, just an uptick for Crates.io using the wrong Cargo.lock. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d85b28d2..124edecd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ For reports/suggestions that don't fit the definition of a feature or bug, try t If you want to help contribute by submitting a PR, by all means, I'm open! In regards to the development process: - I develop primarily using _stable_ Rust. That is, whatever is the most up-to-date stable version you can get via running - `rustup update stable`. However, as of writing, I do support a MSRV of 1.40.0. + `rustup update stable`. - Note that `cargo test` will fail on anything lower than 1.43.0 due to it using a then-introduced env variable. diff --git a/Cargo.lock b/Cargo.lock index dbb3bff4..a89748a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,6 +135,7 @@ dependencies = [ "assert_cmd", "backtrace", "battery", + "cargo-husky", "chrono", "clap", "crossterm", @@ -157,6 +158,12 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "cargo-husky" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" + [[package]] name = "cassowary" version = "0.3.0" @@ -177,9 +184,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" dependencies = [ "num-integer", "num-traits", @@ -188,9 +195,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.1" +version = "2.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" +checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48" dependencies = [ "ansi_term", "atty", @@ -348,21 +355,19 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" [[package]] name = "dirs" -version = "2.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff" dependencies = [ - "cfg-if", "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" dependencies = [ - "cfg-if", "libc", "redox_users", "winapi 0.3.8", @@ -1273,9 +1278,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bbf8e10fc10b83e71bc19f4374ce17209d45c7c4c99b5067ac554aba3bfd08" +checksum = "f597c00e6548b9ddd54c11b8e8534fc11223f28509d57e021f01797b50ca5ca1" dependencies = [ "cfg-if", "doc-comment", @@ -1340,24 +1345,22 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "tui" -version = "0.9.5" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e" +checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95" dependencies = [ "bitflags", "cassowary", "crossterm", - "either", - "itertools", "unicode-segmentation", "unicode-width", ] [[package]] name = "typed-builder" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fc4459191c621a53ef6c6ca5642e6e0e5ccc61f3e5b8ad6b6ab5317f0200fb" +checksum = "d942c3f63d40f62b3fece2ab34a5bfc0d427ef148010fa732f5d56da0ac6d6ec" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 748447ad..10106589 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,22 +23,22 @@ codegen-units = 1 [dependencies] battery = "0.7.5" crossterm = "0.17" -chrono = "0.4.11" -clap = "2.33.1" -dirs = "2.0.2" +chrono = "0.4.13" +clap = "2.33.2" +dirs = "3.0.1" futures = "0.3.5" heim = "0.0.10" itertools = "0.9.0" regex = "1.3" -sysinfo = "0.14.2" +sysinfo = "0.15.0" toml = "0.5.6" -typed-builder = "0.6.0" +typed-builder = "0.7.0" lazy_static = "1.4.0" backtrace = "0.3" serde = {version = "1.0", features = ["derive"] } unicode-segmentation = "1.6.0" unicode-width = "0.1.7" -tui = {version = "0.9", features = ["crossterm"], default-features = false } +tui = {version = "0.10.0", features = ["crossterm"], default-features = false } # For debugging only... fern = "0.6.0" @@ -50,6 +50,7 @@ winapi = "0.3.8" [dev-dependencies] assert_cmd = "1.0" predicates = "1" +cargo-husky = "1" [package.metadata.deb] section = "utils" diff --git a/README.md b/README.md index 6b1dee99..c6ccd190 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A cross-platform graphical process/system monitor with a customizable interface ## Table of Contents - [Installation](#installation) - - [Manual](#manual) + - [Manually](#manually) - [Cargo](#cargo) - [AUR](#aur) - [Debian (and Debian-based)](#debian) @@ -59,9 +59,9 @@ Note that bottom is: As such, support beyond that is not guaranteed. -### Manual +### [Manually] -There are a few ways to go about doing this. Note that the MSRV is 1.40.0. For example: +There are a few ways to go about doing this manually. If you do so, please build using the current stable release of Rust. For example: ```bash # If required, update Rust on the stable channel @@ -84,6 +84,9 @@ cargo install --path . ### Cargo ```bash +# If required, update Rust on the stable channel +rustup update stable + cargo install bottom # OR, --locked may be required due to how cargo install works diff --git a/src/canvas.rs b/src/canvas.rs index f67e23a2..cb6dc819 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, - widgets::Text, + text::{Span, Spans}, Frame, Terminal, }; @@ -55,7 +55,7 @@ pub struct Painter { pub colours: CanvasColours, height: u16, width: u16, - styled_help_text: Vec>, + styled_help_text: Vec>, is_mac_os: bool, row_constraints: Vec, col_constraints: Vec>, @@ -139,14 +139,14 @@ impl Painter { colours: CanvasColours::default(), height: 0, width: 0, - styled_help_text: Vec::new(), + styled_help_text: Vec::default(), is_mac_os: false, row_constraints, col_constraints, col_row_constraints, layout_constraints, widget_layout, - derived_widget_draw_locs: Vec::new(), + derived_widget_draw_locs: Vec::default(), table_height_offset: 4 + table_gap, } } @@ -155,34 +155,35 @@ impl Painter { /// This is to set some remaining styles and text. pub fn complete_painter_init(&mut self) { self.is_mac_os = cfg!(target_os = "macos"); + let mut styled_help_spans = Vec::new(); // Init help text: (*HELP_TEXT).iter().enumerate().for_each(|(itx, section)| { if itx == 0 { - self.styled_help_text.extend( + styled_help_spans.extend( section .iter() - .map(|&text| Text::Styled(text.into(), self.colours.text_style)) + .map(|&text| Span::styled(text, self.colours.text_style)) .collect::>(), ); } else { // Not required check but it runs only a few times... so whatever ig, prevents me from // being dumb and leaving a help text section only one line long. if section.len() > 1 { - self.styled_help_text.push(Text::Raw("\n\n".into())); - self.styled_help_text.push(Text::Styled( - section[0].into(), - self.colours.table_header_style, - )); - self.styled_help_text.extend( + styled_help_spans.push(Span::from("\n\n")); + styled_help_spans + .push(Span::styled(section[0], self.colours.table_header_style)); + styled_help_spans.extend( section[1..] .iter() - .map(|&text| Text::Styled(text.into(), self.colours.text_style)) + .map(|&text| Span::styled(text, self.colours.text_style)) .collect::>(), ); } } }); + + self.styled_help_text = styled_help_spans.into_iter().map(Spans::from).collect(); } pub fn draw_data( diff --git a/src/canvas/canvas_colours.rs b/src/canvas/canvas_colours.rs index d7724568..5d0e6584 100644 --- a/src/canvas/canvas_colours.rs +++ b/src/canvas/canvas_colours.rs @@ -85,7 +85,7 @@ impl CanvasColours { } pub fn set_table_header_colour(&mut self, colour: &str) -> error::Result<()> { - self.table_header_style = get_style_from_config(colour)?.modifier(Modifier::BOLD); + self.table_header_style = get_style_from_config(colour)?.add_modifier(Modifier::BOLD); Ok(()) } diff --git a/src/canvas/dialogs/dd_dialog.rs b/src/canvas/dialogs/dd_dialog.rs index cb123df2..8a63a6e6 100644 --- a/src/canvas/dialogs/dd_dialog.rs +++ b/src/canvas/dialogs/dd_dialog.rs @@ -2,7 +2,8 @@ use tui::{ backend::Backend, layout::{Alignment, Rect}, terminal::Frame, - widgets::{Block, Borders, Paragraph, Text}, + text::{Span, Spans, Text}, + widgets::{Block, Borders, Paragraph, Wrap}, }; use crate::{app::App, canvas::Painter}; @@ -24,60 +25,67 @@ impl KillDialog for Painter { ) -> bool { if let Some(to_kill_processes) = app_state.get_to_delete_processes() { if let Some(first_pid) = to_kill_processes.1.first() { - let dd_text = vec![ - if app_state.is_grouped(app_state.current_widget.widget_id) { - if to_kill_processes.1.len() != 1 { - Text::raw(format!( - "\nKill {} processes with the name \"{}\"?", - to_kill_processes.1.len(), - to_kill_processes.0 - )) + let dd_text = Text::from(vec![ + Spans::from(vec![]), + Spans::from(vec![ + if app_state.is_grouped(app_state.current_widget.widget_id) { + if to_kill_processes.1.len() != 1 { + Span::from(format!( + "\nKill {} processes with the name \"{}\"?", + to_kill_processes.1.len(), + to_kill_processes.0 + )) + } else { + Span::from(format!( + "\nKill 1 process with the name \"{}\"?", + to_kill_processes.0 + )) + } } else { - Text::raw(format!( - "\nKill 1 process with the name \"{}\"?", - to_kill_processes.0 + Span::from(format!( + "\nKill process \"{}\" with PID {}?", + to_kill_processes.0, first_pid )) - } - } else { - Text::raw(format!( - "\nKill process \"{}\" with PID {}?", - to_kill_processes.0, first_pid - )) - }, - Text::raw("\n\n"), - if app_state.delete_dialog_state.is_on_yes { - Text::styled("Yes", self.colours.currently_selected_text_style) - } else { - Text::raw("Yes") - }, - Text::raw(" "), - if app_state.delete_dialog_state.is_on_yes { - Text::raw("No") - } else { - Text::styled("No", self.colours.currently_selected_text_style) - }, - ]; + }, + ]), + Spans::from(vec![]), + Spans::from(vec![ + if app_state.delete_dialog_state.is_on_yes { + Span::styled("Yes", self.colours.currently_selected_text_style) + } else { + Span::from("Yes") + }, + Span::from(" "), + if app_state.delete_dialog_state.is_on_yes { + Span::from("No") + } else { + Span::styled("No", self.colours.currently_selected_text_style) + }, + ]), + ]); - let dd_title = format!( - " Confirm Kill Process ─{}─ Esc to close ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2) - ) + let dd_title = Span::styled( + format!( + " Confirm Kill Process ─{}─ Esc to close ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2) + ) + ), + self.colours.border_style, ); f.render_widget( - Paragraph::new(dd_text.iter()) + Paragraph::new(dd_text) .block( Block::default() - .title(&dd_title) - .title_style(self.colours.border_style) + .title(dd_title) .style(self.colours.border_style) .borders(Borders::ALL) .border_style(self.colours.border_style), ) .style(self.colours.text_style) .alignment(Alignment::Center) - .wrap(true), + .wrap(Wrap { trim: true }), draw_loc, ); @@ -92,31 +100,33 @@ impl KillDialog for Painter { } fn draw_dd_error_dialog(&self, f: &mut Frame<'_, B>, dd_err: &str, draw_loc: Rect) { - let dd_text = [Text::raw(format!( + let dd_text = Span::from(format!( "\nFailure to properly kill the process - {}", dd_err - ))]; + )); - let error_title = format!( - " Error ─{}─ Esc to close ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(DD_ERROR_BASE.chars().count() + 2) - ) + let error_title = Span::styled( + format!( + " Error ─{}─ Esc to close ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(DD_ERROR_BASE.chars().count() + 2) + ) + ), + self.colours.border_style, ); f.render_widget( - Paragraph::new(dd_text.iter()) + Paragraph::new(dd_text) .block( Block::default() - .title(&error_title) - .title_style(self.colours.border_style) + .title(error_title) .style(self.colours.border_style) .borders(Borders::ALL) .border_style(self.colours.border_style), ) .style(self.colours.text_style) .alignment(Alignment::Center) - .wrap(true), + .wrap(Wrap { trim: true }), draw_loc, ); } diff --git a/src/canvas/dialogs/help_dialog.rs b/src/canvas/dialogs/help_dialog.rs index d0156d1a..ae7d85b6 100644 --- a/src/canvas/dialogs/help_dialog.rs +++ b/src/canvas/dialogs/help_dialog.rs @@ -4,7 +4,8 @@ use tui::{ backend::Backend, layout::{Alignment, Rect}, terminal::Frame, - widgets::{Block, Borders, Paragraph}, + text::Span, + widgets::{Block, Borders, Paragraph, Wrap}, }; use crate::{app::App, canvas::Painter, constants}; @@ -21,9 +22,14 @@ impl HelpDialog for Painter { fn draw_help_dialog( &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, ) { - let help_title = format!( - " Help ─{}─ Esc to close ", - "─".repeat(usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2)) + let help_title = Span::styled( + format!( + " Help ─{}─ Esc to close ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2) + ) + ), + self.colours.border_style, ); if app_state.is_force_redraw { @@ -89,24 +95,24 @@ impl HelpDialog for Painter { } f.render_widget( - Paragraph::new(self.styled_help_text.iter()) + Paragraph::new(self.styled_help_text.clone()) .block( Block::default() - .title(&help_title) - .title_style(self.colours.border_style) + .title(help_title) .style(self.colours.border_style) .borders(Borders::ALL) .border_style(self.colours.border_style), ) .style(self.colours.text_style) .alignment(Alignment::Left) - .wrap(true) - .scroll( + .wrap(Wrap { trim: true }) + .scroll(( app_state .help_dialog_state .scroll_state .current_scroll_index, - ), + 0, + )), draw_loc, ); } diff --git a/src/canvas/widgets/basic_table_arrows.rs b/src/canvas/widgets/basic_table_arrows.rs index 1b309cb1..5e5c306c 100644 --- a/src/canvas/widgets/basic_table_arrows.rs +++ b/src/canvas/widgets/basic_table_arrows.rs @@ -10,7 +10,8 @@ use tui::{ backend::Backend, layout::{Constraint, Layout, Rect}, terminal::Frame, - widgets::{Block, Paragraph, Text}, + text::{Span, Spans}, + widgets::{Block, Paragraph}, }; pub trait BasicTableArrows { @@ -58,9 +59,12 @@ impl BasicTableArrows for Painter { usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len()); let arrow_text = vec![ - Text::Styled(format!("\n◄ {}", left_name).into(), self.colours.text_style), - Text::Raw(" ".repeat(num_spaces).into()), - Text::Styled(format!("{} ►", right_name).into(), self.colours.text_style), + Spans::from(Span::from(String::default())), + Spans::from(vec![ + Span::styled(format!("◄ {}", left_name), self.colours.text_style), + Span::from(" ".repeat(num_spaces)), + Span::styled(format!("{} ►", right_name), self.colours.text_style), + ]), ]; let margined_draw_loc = Layout::default() @@ -69,7 +73,7 @@ impl BasicTableArrows for Painter { .split(draw_loc); f.render_widget( - Paragraph::new(arrow_text.iter()).block(Block::default()), + Paragraph::new(arrow_text).block(Block::default()), margined_draw_loc[0], ); } diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs index 0b378247..d716b53e 100644 --- a/src/canvas/widgets/battery_display.rs +++ b/src/canvas/widgets/battery_display.rs @@ -8,7 +8,8 @@ use tui::{ backend::Backend, layout::{Constraint, Rect}, terminal::Frame, - widgets::{Block, Borders, Paragraph, Row, Table, Tabs, Text}, + text::{Span, Spans}, + widgets::{Block, Borders, Paragraph, Row, Table, Tabs}, }; pub trait BatteryDisplayWidget { @@ -27,32 +28,31 @@ impl BatteryDisplayWidget for Painter { app_state.battery_state.widget_states.get_mut(&widget_id) { let is_on_widget = widget_id == app_state.current_widget.widget_id; - let title = if app_state.is_expanded { - const TITLE_BASE: &str = " Battery ── Esc to go back "; - format!( - " Battery ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ) - } else { - " Battery ".to_string() - }; - let border_and_title_style = if is_on_widget { self.colours.highlighted_border_style } else { self.colours.border_style }; + let title = if app_state.is_expanded { + const TITLE_BASE: &str = " Battery ── Esc to go back "; + Span::styled( + format!( + " Battery ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) + ), + border_and_title_style, + ) + } else { + Span::styled(" Battery ".to_string(), self.colours.widget_title_style) + }; + let battery_block = if draw_border { Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - border_and_title_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { @@ -63,6 +63,23 @@ impl BatteryDisplayWidget for Painter { Block::default().borders(Borders::NONE) }; + f.render_widget( + Tabs::new( + (app_state + .canvas_data + .battery_data + .iter() + .map(|battery| Spans::from(battery.battery_name.clone()))) + .collect::>(), + ) + .block(battery_block.clone()) + .divider(tui::symbols::line::VERTICAL) + .style(self.colours.text_style) + .highlight_style(self.colours.currently_selected_text_style) + .select(battery_widget_state.currently_selected_battery_index), + draw_loc, + ); + if let Some(battery_details) = app_state .canvas_data .battery_data @@ -117,44 +134,21 @@ impl BatteryDisplayWidget for Painter { // Draw f.render_widget( Table::new([""].iter(), battery_rows) - .block(battery_block) + .block(battery_block.clone()) .header_style(self.colours.table_header_style) .widths([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()), draw_loc, ); } else { f.render_widget( - Paragraph::new( - [Text::Styled( - "No data found for this battery".into(), - self.colours.text_style, - )] - .iter(), - ) + Paragraph::new(Spans::from(Span::styled( + "No data found for this battery", + self.colours.text_style, + ))) .block(battery_block), draw_loc, ); } - // if app_state.canvas_data.battery_data.len() > 1 { - f.render_widget( - Tabs::default() - .block(battery_block) - .titles( - (app_state - .canvas_data - .battery_data - .iter() - .map(|battery| &battery.battery_name)) - .collect::>() - .as_ref(), - ) - .divider(tui::symbols::line::VERTICAL) - .style(self.colours.text_style) - .highlight_style(self.colours.currently_selected_text_style) - .select(battery_widget_state.currently_selected_battery_index), - draw_loc, - ); - // } } } } diff --git a/src/canvas/widgets/cpu_basic.rs b/src/canvas/widgets/cpu_basic.rs index baa6adbf..c8db2f33 100644 --- a/src/canvas/widgets/cpu_basic.rs +++ b/src/canvas/widgets/cpu_basic.rs @@ -11,7 +11,8 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - widgets::{Block, Paragraph, Text}, + text::{Span, Spans}, + widgets::{Block, Paragraph}, }; pub trait CpuBasicWidget { @@ -76,10 +77,10 @@ impl CpuBasicWidget for Painter { let num_bars = calculate_basic_use_bars(use_percentage, bar_length); format!( - "{:3}[{}{}{:3.0}%]\n", + "{:3}[{}{}{:3.0}%]", if app_state.app_config_fields.show_average_cpu { if cpu_index == 0 { - "AVG".to_string() + " AVG".to_string() } else { (cpu_index - 1).to_string() } @@ -106,13 +107,13 @@ impl CpuBasicWidget for Painter { ); row_counter -= how_many_cpus; let end_index = min(start_index + how_many_cpus, num_cpus); - let cpu_column: Vec> = (start_index..end_index) + let cpu_column = (start_index..end_index) .map(|cpu_index| { - Text::Styled( - (&cpu_bars[cpu_index]).into(), - self.colours.cpu_colour_styles + Spans::from(Span { + content: (&cpu_bars[cpu_index]).into(), + style: self.colours.cpu_colour_styles [cpu_index % self.colours.cpu_colour_styles.len()], - ) + }) }) .collect::>(); @@ -125,7 +126,7 @@ impl CpuBasicWidget for Painter { .split(*chunk); f.render_widget( - Paragraph::new(cpu_column.iter()).block(Block::default()), + Paragraph::new(cpu_column).block(Block::default()), margined_loc[0], ); } diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs index e6800f91..097d91b8 100644 --- a/src/canvas/widgets/cpu_graph.rs +++ b/src/canvas/widgets/cpu_graph.rs @@ -17,6 +17,7 @@ use tui::{ layout::{Constraint, Direction, Layout, Rect}, symbols::Marker, terminal::Frame, + text::Span, widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table}, }; @@ -103,9 +104,12 @@ impl CpuGraphWidget for Painter { if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&widget_id) { let cpu_data: &mut [ConvertedCpuData] = &mut app_state.canvas_data.cpu_data; - let display_time_labels = [ - format!("{}s", cpu_widget_state.current_display_time / 1000), - "0s".to_string(), + let display_time_labels = vec![ + Span::styled( + format!("{}s", cpu_widget_state.current_display_time / 1000), + self.colours.graph_style, + ), + Span::styled("0s".to_string(), self.colours.graph_style), ]; let x_axis = if app_state.app_config_fields.hide_time @@ -120,8 +124,7 @@ impl CpuGraphWidget for Painter { Axis::default() .bounds([-(cpu_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) - .labels(&display_time_labels) + .labels(display_time_labels) } else { cpu_widget_state.autohide_timer = None; Axis::default().bounds([-(cpu_widget_state.current_display_time as f64), 0.0]) @@ -132,16 +135,17 @@ impl CpuGraphWidget for Painter { Axis::default() .bounds([-(cpu_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) - .labels(&display_time_labels) + .labels(display_time_labels) }; // Note this is offset as otherwise the 0 value is not drawn! let y_axis = Axis::default() .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) .bounds([-0.5, 100.5]) - .labels(&["0%", "100%"]); + .labels(vec![ + Span::styled("0%", self.colours.graph_style), + Span::styled("100%", self.colours.graph_style), + ]); let use_dot = app_state.app_config_fields.use_dot; let show_avg_cpu = app_state.app_config_fields.show_average_cpu; @@ -189,30 +193,28 @@ impl CpuGraphWidget for Painter { vec![] }; - let title = " CPU ".to_string(); - let border_style = if app_state.current_widget.widget_id == widget_id { self.colours.highlighted_border_style } else { self.colours.border_style }; + let title = if app_state.is_expanded { + Span::styled(" CPU ".to_string(), border_style) + } else { + Span::styled(" CPU ".to_string(), self.colours.widget_title_style) + }; + f.render_widget( - Chart::default() + Chart::new(dataset_vector) .block( Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - border_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(border_style), ) .x_axis(x_axis) - .y_axis(y_axis) - .datasets(&dataset_vector), + .y_axis(y_axis), draw_loc, ); } @@ -296,7 +298,6 @@ impl CpuGraphWidget for Painter { Table::new(CPU_LEGEND_HEADER.iter(), cpu_rows) .block( Block::default() - .title_style(border_and_title_style) .borders(Borders::ALL) .border_style(border_and_title_style), ) diff --git a/src/canvas/widgets/disk_table.rs b/src/canvas/widgets/disk_table.rs index 64839869..5b31314e 100644 --- a/src/canvas/widgets/disk_table.rs +++ b/src/canvas/widgets/disk_table.rs @@ -4,6 +4,7 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, + text::Span, widgets::{Block, Borders, Row, Table}, }; @@ -67,20 +68,6 @@ impl DiskTableWidget for Painter { get_variable_intrinsic_widths(width as u16, &width_ratios, &DISK_HEADERS_LENS); let intrinsic_widths = &variable_intrinsic_results.0[0..variable_intrinsic_results.1]; - let title = if app_state.is_expanded { - const TITLE_BASE: &str = " Disk ── Esc to go back "; - format!( - " Disk ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ) - } else if app_state.app_config_fields.use_basic_mode { - String::new() - } else { - " Disk ".to_string() - }; - let (border_and_title_style, highlight_style) = if is_on_widget { ( self.colours.highlighted_border_style, @@ -90,14 +77,27 @@ impl DiskTableWidget for Painter { (self.colours.border_style, self.colours.text_style) }; + let title = if app_state.is_expanded { + const TITLE_BASE: &str = " Disk ── Esc to go back "; + Span::styled( + format!( + " Disk ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) + ), + border_and_title_style, + ) + } else if app_state.app_config_fields.use_basic_mode { + Span::from(String::new()) + } else { + Span::styled(" Disk ".to_string(), self.colours.widget_title_style) + }; + let disk_block = if draw_border { Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - border_and_title_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { diff --git a/src/canvas/widgets/mem_basic.rs b/src/canvas/widgets/mem_basic.rs index 05c7c39a..e3abe7ad 100644 --- a/src/canvas/widgets/mem_basic.rs +++ b/src/canvas/widgets/mem_basic.rs @@ -8,7 +8,8 @@ use tui::{ backend::Backend, layout::{Constraint, Layout, Rect}, terminal::Frame, - widgets::{Block, Paragraph, Text}, + text::{Span, Spans}, + widgets::{Block, Paragraph}, }; pub trait MemBasicWidget { @@ -65,13 +66,13 @@ impl MemBasicWidget for Painter { swap_use_percentage.round(), ); - let mem_text: Vec> = vec![ - Text::Styled(mem_label.into(), self.colours.ram_style), - Text::Styled(swap_label.into(), self.colours.swap_style), + let mem_text = vec![ + Spans::from(Span::styled(mem_label, self.colours.ram_style)), + Spans::from(Span::styled(swap_label, self.colours.swap_style)), ]; f.render_widget( - Paragraph::new(mem_text.iter()).block(Block::default()), + Paragraph::new(mem_text).block(Block::default()), margined_loc[0], ); } diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs index 40f711d3..24717dab 100644 --- a/src/canvas/widgets/mem_graph.rs +++ b/src/canvas/widgets/mem_graph.rs @@ -5,6 +5,7 @@ use tui::{ layout::{Constraint, Rect}, symbols::Marker, terminal::Frame, + text::Span, widgets::{Axis, Block, Borders, Chart, Dataset}, }; @@ -22,9 +23,12 @@ impl MemGraphWidget for Painter { let mem_data: &[(f64, f64)] = &app_state.canvas_data.mem_data; let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data; - let display_time_labels = [ - format!("{}s", mem_widget_state.current_display_time / 1000), - "0s".to_string(), + let display_time_labels = vec![ + Span::styled( + format!("{}s", mem_widget_state.current_display_time / 1000), + self.colours.graph_style, + ), + Span::styled("0s".to_string(), self.colours.graph_style), ]; let x_axis = if app_state.app_config_fields.hide_time || (app_state.app_config_fields.autohide_time @@ -38,8 +42,7 @@ impl MemGraphWidget for Painter { Axis::default() .bounds([-(mem_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) - .labels(&display_time_labels) + .labels(display_time_labels) } else { mem_widget_state.autohide_timer = None; Axis::default().bounds([-(mem_widget_state.current_display_time as f64), 0.0]) @@ -50,16 +53,17 @@ impl MemGraphWidget for Painter { Axis::default() .bounds([-(mem_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) - .labels(&display_time_labels) + .labels(display_time_labels) }; // Offset as the zero value isn't drawn otherwise... - let y_axis: Axis<'_, &str> = Axis::default() + let y_axis = Axis::default() .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) .bounds([-0.5, 100.5]) - .labels(&["0%", "100%"]); + .labels(vec![ + Span::styled("0%", self.colours.graph_style), + Span::styled("100%", self.colours.graph_style), + ]); let mut mem_canvas_vec: Vec> = vec![]; @@ -91,26 +95,25 @@ impl MemGraphWidget for Painter { let title = if app_state.is_expanded { const TITLE_BASE: &str = " Memory ── Esc to go back "; - format!( - " Memory ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) - ) + Span::styled( + format!( + " Memory ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) + ), + self.colours.highlighted_border_style, ) } else { - " Memory ".to_string() + Span::styled(" Memory ".to_string(), self.colours.widget_title_style) }; f.render_widget( - Chart::default() + Chart::new(mem_canvas_vec) .block( Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - self.colours.highlighted_border_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(if app_state.current_widget.widget_id == widget_id { self.colours.highlighted_border_style @@ -120,7 +123,6 @@ impl MemGraphWidget for Painter { ) .x_axis(x_axis) .y_axis(y_axis) - .datasets(&mem_canvas_vec) .hidden_legend_constraints((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))), draw_loc, ); diff --git a/src/canvas/widgets/network_basic.rs b/src/canvas/widgets/network_basic.rs index 30c4e189..c5c7b6fa 100644 --- a/src/canvas/widgets/network_basic.rs +++ b/src/canvas/widgets/network_basic.rs @@ -4,7 +4,8 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - widgets::{Block, Paragraph, Text}, + text::{Span, Spans}, + widgets::{Block, Paragraph}, }; pub trait NetworkBasicWidget { @@ -49,22 +50,19 @@ impl NetworkBasicWidget for Painter { let total_tx_label = format!("Total TX: {}", &app_state.canvas_data.total_tx_display); let net_text = vec![ - Text::Styled(rx_label.into(), self.colours.rx_style), - Text::Styled(tx_label.into(), self.colours.tx_style), + Spans::from(Span::styled(rx_label, self.colours.rx_style)), + Spans::from(Span::styled(tx_label, self.colours.tx_style)), ]; let total_net_text = vec![ - Text::Styled(total_rx_label.into(), self.colours.total_rx_style), - Text::Styled(total_tx_label.into(), self.colours.total_tx_style), + Spans::from(Span::styled(total_rx_label, self.colours.total_rx_style)), + Spans::from(Span::styled(total_tx_label, self.colours.total_tx_style)), ]; - f.render_widget( - Paragraph::new(net_text.iter()).block(Block::default()), - net_loc[0], - ); + f.render_widget(Paragraph::new(net_text).block(Block::default()), net_loc[0]); f.render_widget( - Paragraph::new(total_net_text.iter()).block(Block::default()), + Paragraph::new(total_net_text).block(Block::default()), total_loc[0], ); } diff --git a/src/canvas/widgets/network_graph.rs b/src/canvas/widgets/network_graph.rs index 07146eaa..27a464d8 100644 --- a/src/canvas/widgets/network_graph.rs +++ b/src/canvas/widgets/network_graph.rs @@ -12,6 +12,7 @@ use tui::{ layout::{Constraint, Direction, Layout, Rect}, symbols::Marker, terminal::Frame, + text::Span, widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table}, }; @@ -71,9 +72,12 @@ impl NetworkGraphWidget for Painter { let network_data_rx: &[(f64, f64)] = &app_state.canvas_data.network_data_rx; let network_data_tx: &[(f64, f64)] = &app_state.canvas_data.network_data_tx; - let display_time_labels = [ - format!("{}s", network_widget_state.current_display_time / 1000), - "0s".to_string(), + let display_time_labels = vec![ + Span::styled( + format!("{}s", network_widget_state.current_display_time / 1000), + self.colours.graph_style, + ), + Span::styled("0s".to_string(), self.colours.graph_style), ]; let x_axis = if app_state.app_config_fields.hide_time || (app_state.app_config_fields.autohide_time @@ -87,8 +91,7 @@ impl NetworkGraphWidget for Painter { Axis::default() .bounds([-(network_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) - .labels(&display_time_labels) + .labels(display_time_labels) } else { network_widget_state.autohide_timer = None; Axis::default() @@ -100,27 +103,35 @@ impl NetworkGraphWidget for Painter { Axis::default() .bounds([-(network_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) - .labels(&display_time_labels) + .labels(display_time_labels) }; // 0 is offset. - let y_axis: Axis<'_, &str> = Axis::default() + let y_axis_labels = vec![ + Span::styled("0B", self.colours.graph_style), + Span::styled("1KiB", self.colours.graph_style), + Span::styled("1MiB", self.colours.graph_style), + Span::styled("1GiB", self.colours.graph_style), + ]; + let y_axis = Axis::default() .style(self.colours.graph_style) - .labels_style(self.colours.graph_style) .bounds([-0.5, 30_f64]) - .labels(&["0B", "1KiB", "1MiB", "1GiB"]); + .labels(y_axis_labels); let title = if app_state.is_expanded { const TITLE_BASE: &str = " Network ── Esc to go back "; - format!( - " Network ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) - ) + Span::styled( + format!( + " Network ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) + ), + self.colours.highlighted_border_style, ) } else { - " Network ".to_string() + Span::styled(" Network ".to_string(), self.colours.widget_title_style) }; let legend_constraints = if hide_legend { @@ -209,15 +220,10 @@ impl NetworkGraphWidget for Painter { }; f.render_widget( - Chart::default() + Chart::new(dataset) .block( Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - self.colours.highlighted_border_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(if app_state.current_widget.widget_id == widget_id { self.colours.highlighted_border_style @@ -227,7 +233,6 @@ impl NetworkGraphWidget for Painter { ) .x_axis(x_axis) .y_axis(y_axis) - .datasets(&dataset) .hidden_legend_constraints(legend_constraints), draw_loc, ); diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs index 5ceb8b28..3faab2ba 100644 --- a/src/canvas/widgets/process_table.rs +++ b/src/canvas/widgets/process_table.rs @@ -13,7 +13,8 @@ use tui::{ backend::Backend, layout::{Alignment, Constraint, Direction, Layout, Rect}, terminal::Frame, - widgets::{Block, Borders, Paragraph, Row, Table, Text}, + text::{Span, Spans}, + widgets::{Block, Borders, Paragraph, Row, Table, Wrap}, }; use unicode_segmentation::{GraphemeIndices, UnicodeSegmentation}; @@ -202,12 +203,12 @@ impl ProcessTableWidget for Painter { // TODO: This is a ugly work-around for now. let width_ratios = if proc_widget_state.is_grouped { if proc_widget_state.is_using_full_path { - vec![0.1, 0.7, 0.05, 0.05, 0.025, 0.025, 0.025, 0.025] + vec![0.05, 0.7, 0.05, 0.05, 0.0375, 0.0375, 0.0375, 0.0375] } else { vec![0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.15, 0.15] } } else if proc_widget_state.is_using_full_path { - vec![0.1, 0.7, 0.05, 0.05, 0.02, 0.02, 0.02, 0.02, 0.02] + vec![0.05, 0.7, 0.05, 0.05, 0.03, 0.03, 0.03, 0.03] } else { vec![0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] }; @@ -219,28 +220,6 @@ impl ProcessTableWidget for Painter { let intrinsic_widths = &(variable_intrinsic_results.0)[0..variable_intrinsic_results.1]; - let title = if draw_border { - if app_state.is_expanded - && !proc_widget_state - .process_search_state - .search_state - .is_enabled - { - const TITLE_BASE: &str = " Processes ── Esc to go back "; - format!( - " Processes ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ) - } else { - " Processes ".to_string() - } - } else { - String::default() - }; - let (border_and_title_style, highlight_style) = if is_on_widget { ( self.colours.highlighted_border_style, @@ -250,14 +229,34 @@ impl ProcessTableWidget for Painter { (self.colours.border_style, self.colours.text_style) }; + let title = if draw_border { + if app_state.is_expanded + && !proc_widget_state + .process_search_state + .search_state + .is_enabled + { + const TITLE_BASE: &str = " Processes ── Esc to go back "; + Span::styled( + format!( + " Processes ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) + ), + border_and_title_style, + ) + } else { + Span::styled(" Processes ".to_string(), self.colours.widget_title_style) + } + } else { + Span::from(String::default()) + }; + let process_block = if draw_border { Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - border_and_title_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { @@ -304,7 +303,7 @@ impl ProcessTableWidget for Painter { is_on_widget: bool, grapheme_indices: GraphemeIndices<'a>, start_position: usize, cursor_position: usize, query: &str, currently_selected_text_style: tui::style::Style, text_style: tui::style::Style, - ) -> Vec> { + ) -> Vec> { let mut current_grapheme_posn = 0; if is_on_widget { @@ -316,9 +315,9 @@ impl ProcessTableWidget for Painter { None } else { let styled = if grapheme.0 == cursor_position { - Text::styled(grapheme.1, currently_selected_text_style) + Span::styled(grapheme.1, currently_selected_text_style) } else { - Text::styled(grapheme.1, text_style) + Span::styled(grapheme.1, text_style) }; Some(styled) } @@ -326,20 +325,21 @@ impl ProcessTableWidget for Painter { .collect::>(); if cursor_position >= query.len() { - res.push(Text::styled(" ", currently_selected_text_style)) + res.push(Span::styled(" ", currently_selected_text_style)) } res } else { // This is easier - we just need to get a range of graphemes, rather than // dealing with possibly inserting a cursor (as none is shown!) + grapheme_indices .filter_map(|grapheme| { current_grapheme_posn += UnicodeWidthStr::width(grapheme.1); if current_grapheme_posn <= start_position { None } else { - let styled = Text::styled(grapheme.1, text_style); + let styled = Span::styled(grapheme.1, text_style); Some(styled) } }) @@ -372,17 +372,10 @@ impl ProcessTableWidget for Painter { app_state.is_force_redraw, ); - let mut search_text = vec![Text::styled( - search_title, - if is_on_widget { - self.colours.table_header_style - } else { - self.colours.text_style - }, - )]; let query = proc_widget_state.get_current_search_query().as_str(); let grapheme_indices = UnicodeSegmentation::grapheme_indices(query, true); - let query_with_cursor: Vec> = build_query( + + let query_with_cursor = build_query( is_on_widget, grapheme_indices, start_position, @@ -392,6 +385,19 @@ impl ProcessTableWidget for Painter { self.colours.text_style, ); + let mut search_text = vec![Spans::from({ + let mut search_vec = vec![Span::styled( + search_title, + if is_on_widget { + self.colours.table_header_style + } else { + self.colours.text_style + }, + )]; + search_vec.extend(query_with_cursor); + search_vec + })]; + // Text options shamelessly stolen from VS Code. let case_style = if !proc_widget_state.process_search_state.is_ignoring_case { self.colours.currently_selected_text_style @@ -417,41 +423,36 @@ impl ProcessTableWidget for Painter { self.colours.text_style }; - let option_text = vec![ - Text::raw("\n"), - Text::styled( + let option_text = Spans::from(vec![ + Span::styled( format!("Case({})", if self.is_mac_os { "F1" } else { "Alt+C" }), case_style, ), - Text::raw(" "), - Text::styled( + Span::from(" "), + Span::styled( format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" }), whole_word_style, ), - Text::raw(" "), - Text::styled( + Span::from(" "), + Span::styled( format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" }), regex_style, ), - ]; + ]); - search_text.extend(query_with_cursor); - search_text.push(Text::styled( - format!( - "\n{}", - if let Some(err) = &proc_widget_state - .process_search_state - .search_state - .error_message - { - err.as_str() - } else { - "" - } - ), + search_text.push(Spans::from(Span::styled( + if let Some(err) = &proc_widget_state + .process_search_state + .search_state + .error_message + { + err.as_str() + } else { + "" + }, self.colours.invalid_query_style, - )); - search_text.extend(option_text); + ))); + search_text.push(option_text); let current_border_style = if proc_widget_state .process_search_state @@ -470,15 +471,17 @@ impl ProcessTableWidget for Painter { let repeat_num = usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2); - format!("{} Esc to close ", "─".repeat(repeat_num)) + Span::styled( + format!("{} Esc to close ", "─".repeat(repeat_num)), + current_border_style, + ) } else { - String::new() + Span::from(String::new()) }; let process_search_block = if draw_border { Block::default() - .title(&title) - .title_style(current_border_style) + .title(title) .borders(Borders::ALL) .border_style(current_border_style) } else if is_on_widget { @@ -496,11 +499,11 @@ impl ProcessTableWidget for Painter { .split(draw_loc); f.render_widget( - Paragraph::new(search_text.iter()) + Paragraph::new(search_text) .block(process_search_block) .style(self.colours.text_style) .alignment(Alignment::Left) - .wrap(false), + .wrap(Wrap { trim: false }), margined_draw_loc[0], ); } diff --git a/src/canvas/widgets/temp_table.rs b/src/canvas/widgets/temp_table.rs index 18bc855d..0b5bd42f 100644 --- a/src/canvas/widgets/temp_table.rs +++ b/src/canvas/widgets/temp_table.rs @@ -5,6 +5,7 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, + text::Span, widgets::{Block, Borders, Row, Table}, }; @@ -67,20 +68,6 @@ impl TempTableWidget for Painter { get_variable_intrinsic_widths(width as u16, &width_ratios, &TEMP_HEADERS_LENS); let intrinsic_widths = &(variable_intrinsic_results.0)[0..variable_intrinsic_results.1]; - let title = if app_state.is_expanded { - const TITLE_BASE: &str = " Temperatures ── Esc to go back "; - format!( - " Temperatures ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ) - } else if app_state.app_config_fields.use_basic_mode { - String::new() - } else { - " Temperatures ".to_string() - }; - let (border_and_title_style, highlight_style) = if is_on_widget { ( self.colours.highlighted_border_style, @@ -90,14 +77,30 @@ impl TempTableWidget for Painter { (self.colours.border_style, self.colours.text_style) }; + let title = if app_state.is_expanded { + const TITLE_BASE: &str = " Temperatures ── Esc to go back "; + Span::styled( + format!( + " Temperatures ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) + ), + border_and_title_style, + ) + } else if app_state.app_config_fields.use_basic_mode { + Span::from(String::new()) + } else { + Span::styled( + " Temperatures ".to_string(), + self.colours.widget_title_style, + ) + }; + let temp_block = if draw_border { Block::default() - .title(&title) - .title_style(if app_state.is_expanded { - border_and_title_style - } else { - self.colours.widget_title_style - }) + .title(title) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { diff --git a/src/main.rs b/src/main.rs index e4871563..e8721bf0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -365,6 +365,8 @@ fn create_config(flag_config_location: Option<&str>) -> error::Result { } } else if let Some(home_path) = dirs::home_dir() { let mut path = home_path; + // TODO: This should not be done like this IMO... it should be based on the defaults set by dirs rather than home_dir + // This WILL cause breaking changes on macOS though, warning! path.push(DEFAULT_UNIX_CONFIG_FILE_PATH); path.into_os_string() } else {