diff --git a/src/list/state.rs b/src/list/state.rs index 53fe07c4..76392d1c 100644 --- a/src/list/state.rs +++ b/src/list/state.rs @@ -1,7 +1,9 @@ use anyhow::{Context, Result}; use crossterm::{ cursor::{MoveTo, MoveToNextLine}, - style::{Attribute, Color, ResetColor, SetAttribute, SetBackgroundColor, SetForegroundColor}, + style::{ + Attribute, Attributes, Color, ResetColor, SetAttribute, SetAttributes, SetForegroundColor, + }, terminal::{self, BeginSynchronizedUpdate, Clear, ClearType, EndSynchronizedUpdate}, QueueableCommand, }; @@ -19,6 +21,9 @@ use crate::{ use super::scroll_state::ScrollState; const COL_SPACING: usize = 2; +const SELECTED_ROW_ATTRIBUTES: Attributes = Attributes::none() + .with(Attribute::Reverse) + .with(Attribute::Bold); fn next_ln(stdout: &mut StdoutLock) -> io::Result<()> { stdout @@ -41,6 +46,7 @@ pub struct ListState<'a> { app_state: &'a mut AppState, scroll_state: ScrollState, name_col_padding: Vec, + path_col_padding: Vec, filter: Filter, term_width: u16, term_height: u16, @@ -52,13 +58,18 @@ impl<'a> ListState<'a> { stdout.queue(Clear(ClearType::All))?; let name_col_title_len = 4; - let name_col_width = app_state - .exercises() - .iter() - .map(|exercise| exercise.name.len()) - .max() - .map_or(name_col_title_len, |max| max.max(name_col_title_len)); + let path_col_title_len = 4; + let (name_col_width, path_col_width) = app_state.exercises().iter().fold( + (name_col_title_len, path_col_title_len), + |(name_col_width, path_col_width), exercise| { + ( + name_col_width.max(exercise.name.len()), + path_col_width.max(exercise.path.len()), + ) + }, + ); let name_col_padding = vec![b' '; name_col_width + COL_SPACING]; + let path_col_padding = vec![b' '; path_col_width]; let filter = Filter::None; let n_rows_with_filter = app_state.exercises().len(); @@ -73,6 +84,7 @@ impl<'a> ListState<'a> { app_state, scroll_state, name_col_padding, + path_col_padding, filter, // Set by `set_term_size` term_width: 0, @@ -119,7 +131,7 @@ impl<'a> ListState<'a> { writer.write_str(pre_highlight)?; writer.stdout.queue(SetForegroundColor(Color::Magenta))?; writer.write_str(highlight)?; - writer.stdout.queue(ResetColor)?; + writer.stdout.queue(SetForegroundColor(Color::Reset))?; return writer.write_str(post_highlight); } } @@ -143,14 +155,12 @@ impl<'a> ListState<'a> { let mut writer = MaxLenWriter::new(stdout, self.term_width as usize); if self.scroll_state.selected() == Some(row_offset + n_displayed_rows) { - writer.stdout.queue(SetBackgroundColor(Color::Rgb { - r: 40, - g: 40, - b: 40, - }))?; // The crab emoji has the width of two ascii chars. writer.add_to_len(2); writer.stdout.write_all("🦀".as_bytes())?; + writer + .stdout + .queue(SetAttributes(SELECTED_ROW_ATTRIBUTES))?; } else { writer.write_ascii(b" ")?; } @@ -164,12 +174,13 @@ impl<'a> ListState<'a> { if exercise.done { writer.stdout.queue(SetForegroundColor(Color::Green))?; - writer.write_ascii(b"DONE ")?; + writer.write_ascii(b"DONE ")?; } else { writer.stdout.queue(SetForegroundColor(Color::Yellow))?; - writer.write_ascii(b"PENDING ")?; + writer.write_ascii(b"PENDING")?; } writer.stdout.queue(SetForegroundColor(Color::Reset))?; + writer.write_ascii(b" ")?; self.draw_exericse_name(&mut writer, exercise)?; @@ -183,6 +194,8 @@ impl<'a> ListState<'a> { exercise.terminal_file_link(&mut writer)?; } + writer.write_ascii(&self.path_col_padding[exercise.path.len()..])?; + next_ln(stdout)?; stdout.queue(ResetColor)?; n_displayed_rows += 1; diff --git a/src/watch/state.rs b/src/watch/state.rs index 47978aba..c27dedf3 100644 --- a/src/watch/state.rs +++ b/src/watch/state.rs @@ -20,6 +20,10 @@ use crate::{ use super::{terminal_event::terminal_event_handler, InputPauseGuard, WatchEvent}; +const HEADING_ATTRIBUTES: Attributes = Attributes::none() + .with(Attribute::Bold) + .with(Attribute::Underlined); + #[derive(PartialEq, Eq)] enum DoneStatus { DoneWithSolution(String), @@ -209,9 +213,7 @@ impl<'a> WatchState<'a> { if self.show_hint { stdout - .queue(SetAttributes( - Attributes::from(Attribute::Bold).with(Attribute::Underlined), - ))? + .queue(SetAttributes(HEADING_ATTRIBUTES))? .queue(SetForegroundColor(Color::Cyan))?; stdout.write_all(b"Hint")?; stdout.queue(ResetColor)?;