From e8f7aaccef9c39ca5ba0d2696202f964fc35c6d2 Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Tue, 5 Apr 2022 05:59:01 +0200 Subject: [PATCH] Add compact mode (#288) --- atuin-client/src/settings.rs | 14 ++++++ src/command/search.rs | 91 ++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/atuin-client/src/settings.rs b/atuin-client/src/settings.rs index 08715ca..ef6752f 100644 --- a/atuin-client/src/settings.rs +++ b/atuin-client/src/settings.rs @@ -41,9 +41,22 @@ impl From for chrono_english::Dialect { } } +#[derive(Clone, Debug, Deserialize, Copy)] +pub enum Style { + #[serde(rename = "auto")] + Auto, + + #[serde(rename = "full")] + Full, + + #[serde(rename = "compact")] + Compact, +} + #[derive(Clone, Debug, Deserialize)] pub struct Settings { pub dialect: Dialect, + pub style: Style, pub auto_sync: bool, pub sync_address: String, pub sync_frequency: String, @@ -134,6 +147,7 @@ impl Settings { .set_default("sync_address", "https://api.atuin.sh")? .set_default("search_mode", "prefix")? .set_default("session_token", "")? + .set_default("style", "auto")? .add_source(Environment::with_prefix("atuin").separator("_")); config_builder = if config_file.exists() { diff --git a/src/command/search.rs b/src/command/search.rs index 6e7ec25..a28b154 100644 --- a/src/command/search.rs +++ b/src/command/search.rs @@ -86,6 +86,7 @@ impl State { &mut self, f: &mut tui::Frame, r: tui::layout::Rect, + b: tui::widgets::Block, ) { let durations = self.durations(); let max_length = durations.iter().fold(0, |largest, i| { @@ -153,7 +154,7 @@ impl State { .collect(); let results = List::new(results) - .block(Block::default().borders(Borders::ALL).title("History")) + .block(b) .start_corner(Corner::BottomLeft) .highlight_symbol(">> "); @@ -321,9 +322,13 @@ fn draw(f: &mut Frame<'_, T>, history_count: i64, app: &mut State) { f.render_widget(title, top_left_chunks[0]); f.render_widget(help, top_left_chunks[1]); - - app.render_results(f, chunks[1]); f.render_widget(stats, top_right_chunks[0]); + + app.render_results( + f, + chunks[1], + Block::default().borders(Borders::ALL).title("History"), + ); f.render_widget(input, chunks[2]); f.set_cursor( @@ -334,6 +339,70 @@ fn draw(f: &mut Frame<'_, T>, history_count: i64, app: &mut State) { ); } +#[allow(clippy::cast_possible_truncation)] +fn draw_compact(f: &mut Frame<'_, T>, history_count: i64, app: &mut State) { + let chunks = Layout::default() + .direction(Direction::Vertical) + .margin(0) + .horizontal_margin(1) + .constraints( + [ + Constraint::Length(1), + Constraint::Min(1), + Constraint::Length(1), + ] + .as_ref(), + ) + .split(f.size()); + + let header_chunks = Layout::default() + .direction(Direction::Horizontal) + .constraints( + [ + Constraint::Ratio(1, 3), + Constraint::Ratio(1, 3), + Constraint::Ratio(1, 3), + ] + .as_ref(), + ) + .split(chunks[0]); + + let title = Paragraph::new(Text::from(Span::styled( + format!("Atuin v{}", VERSION), + Style::default().fg(Color::DarkGray), + ))); + + let help = Paragraph::new(Text::from(Spans::from(vec![ + Span::styled("Esc", Style::default().add_modifier(Modifier::BOLD)), + Span::raw(" to exit"), + ]))) + .style(Style::default().fg(Color::DarkGray)) + .alignment(Alignment::Center); + + let stats = Paragraph::new(Text::from(Span::raw(format!( + "history count: {}", + history_count, + )))) + .style(Style::default().fg(Color::DarkGray)) + .alignment(Alignment::Right); + + let input = Paragraph::new(format!("] {}", app.input.clone())).block(Block::default()); + + f.render_widget(title, header_chunks[0]); + f.render_widget(help, header_chunks[1]); + f.render_widget(stats, header_chunks[2]); + + app.render_results(f, chunks[1], Block::default()); + f.render_widget(input, chunks[2]); + + f.set_cursor( + // Put cursor past the end of the input text + chunks[2].x + app.input.width() as u16 + 2, + // Move one line down, from the border to the input line + chunks[2].y + 1, + ); +} + // this is a big blob of horrible! clean it up! // for now, it works. But it'd be great if it were more easily readable, and // modular. I'd like to add some more stats and stuff at some point @@ -341,6 +410,7 @@ fn draw(f: &mut Frame<'_, T>, history_count: i64, app: &mut State) { async fn select_history( query: &[String], search_mode: SearchMode, + style: atuin_client::settings::Style, db: &mut (impl Database + Send + Sync), ) -> Result { let stdout = stdout().into_raw_mode()?; @@ -369,7 +439,18 @@ async fn select_history( } } - terminal.draw(|f| draw(f, history_count, &mut app))?; + let compact = match style { + atuin_client::settings::Style::Auto => { + terminal.size().map(|size| size.height < 14).unwrap_or(true) + } + atuin_client::settings::Style::Compact => true, + atuin_client::settings::Style::Full => false, + }; + if compact { + terminal.draw(|f| draw_compact(f, history_count, &mut app))?; + } else { + terminal.draw(|f| draw(f, history_count, &mut app))?; + } } } @@ -405,7 +486,7 @@ pub async fn run( }; if interactive { - let item = select_history(query, settings.search_mode, db).await?; + let item = select_history(query, settings.search_mode, settings.style, db).await?; eprintln!("{}", item); } else { let results = db