summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@elliehuxtable.com>2022-04-22 21:05:02 +0100
committerGitHub <noreply@github.com>2022-04-22 21:05:02 +0100
commit508d4f476157384b0d454bee3dd6e9256560561b (patch)
tree9eb2fbc5a9a51d3419e9e684a01fe5a2106e77c9 /src
parent02c70deecba955c1b01f661ed7a709038e90addc (diff)
History filter (#329)
* Add history filters, and hotkey toggle Switch between different search modes to narrow down the history you want - global search for all history, host for all history from your current machine, session for the current shell session, and directory for the current directory The default can be configured via `filter_mode` * Update docs * Add context
Diffstat (limited to 'src')
-rw-r--r--src/command/client/history.rs6
-rw-r--r--src/command/client/search.rs74
-rw-r--r--src/command/client/stats.rs8
3 files changed, 75 insertions, 13 deletions
diff --git a/src/command/client/history.rs b/src/command/client/history.rs
index b2f68f932..994cbfd55 100644
--- a/src/command/client/history.rs
+++ b/src/command/client/history.rs
@@ -6,7 +6,7 @@ use clap::Subcommand;
use eyre::Result;
use tabwriter::TabWriter;
-use atuin_client::database::Database;
+use atuin_client::database::{current_context, Database};
use atuin_client::history::History;
use atuin_client::settings::Settings;
use atuin_client::sync;
@@ -97,6 +97,8 @@ impl Cmd {
settings: &Settings,
db: &mut (impl Database + Send + Sync),
) -> Result<()> {
+ let context = current_context();
+
match self {
Self::Start { command: words } => {
let command = words.join(" ");
@@ -168,7 +170,7 @@ impl Cmd {
};
let history = match (session, cwd) {
- (None, None) => db.list(None, false).await?,
+ (None, None) => db.list(settings.filter_mode, &context, None, false).await?,
(None, Some(cwd)) => {
let query = format!("select * from history where cwd = '{}';", cwd);
db.query_history(&query).await?
diff --git a/src/command/client/search.rs b/src/command/client/search.rs
index a1dc5aa9c..a913e161d 100644
--- a/src/command/client/search.rs
+++ b/src/command/client/search.rs
@@ -1,6 +1,7 @@
use chrono::Utc;
use clap::Parser;
use eyre::Result;
+use std::env;
use std::{io::stdout, ops::Sub, time::Duration};
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen};
use tui::{
@@ -14,9 +15,11 @@ use tui::{
use unicode_width::UnicodeWidthStr;
use atuin_client::{
+ database::current_context,
+ database::Context,
database::Database,
history::History,
- settings::{SearchMode, Settings},
+ settings::{FilterMode, SearchMode, Settings},
};
use super::event::{Event, Events};
@@ -91,9 +94,13 @@ impl Cmd {
struct State {
input: String,
+ filter_mode: FilterMode,
+
results: Vec<History>,
results_state: ListState,
+
+ context: Context,
}
impl State {
@@ -233,8 +240,14 @@ async fn query_results(
db: &mut (impl Database + Send + Sync),
) -> Result<()> {
let results = match app.input.as_str() {
- "" => db.list(Some(200), true).await?,
- i => db.search(Some(200), search_mode, i).await?,
+ "" => {
+ db.list(app.filter_mode, &app.context, Some(200), true)
+ .await?
+ }
+ i => {
+ db.search(Some(200), search_mode, app.filter_mode, &app.context, i)
+ .await?
+ }
};
app.results = results;
@@ -300,6 +313,16 @@ async fn key_handler(
app.input = String::from("");
query_results(app, search_mode, db).await.unwrap();
}
+ Key::Ctrl('r') => {
+ app.filter_mode = match app.filter_mode {
+ FilterMode::Global => FilterMode::Host,
+ FilterMode::Host => FilterMode::Session,
+ FilterMode::Session => FilterMode::Directory,
+ FilterMode::Directory => FilterMode::Global,
+ };
+
+ query_results(app, search_mode, db).await.unwrap();
+ }
Key::Down | Key::Ctrl('n') => {
let i = match app.results_state.selected() {
Some(i) => {
@@ -376,8 +399,15 @@ fn draw<T: Backend>(f: &mut Frame<'_, T>, history_count: i64, app: &mut State) {
let help = Text::from(Spans::from(help));
let help = Paragraph::new(help);
+ let filter_mode = match app.filter_mode {
+ FilterMode::Global => "GLOBAL",
+ FilterMode::Host => "HOST",
+ FilterMode::Session => "SESSION",
+ FilterMode::Directory => "DIRECTORY",
+ };
+
let input = Paragraph::new(app.input.clone())
- .block(Block::default().borders(Borders::ALL).title("Query"));
+ .block(Block::default().borders(Borders::ALL).title(filter_mode));
let stats = Paragraph::new(Text::from(Span::raw(format!(
"history count: {}",
@@ -451,7 +481,15 @@ fn draw_compact<T: Backend>(f: &mut Frame<'_, T>, history_count: i64, app: &mut
.style(Style::default().fg(Color::DarkGray))
.alignment(Alignment::Right);
- let input = Paragraph::new(format!("] {}", app.input.clone())).block(Block::default());
+ let filter_mode = match app.filter_mode {
+ FilterMode::Global => "GLOBAL",
+ FilterMode::Host => "HOST",
+ FilterMode::Session => "SESSION",
+ FilterMode::Directory => "DIRECTORY",
+ };
+
+ let input =
+ Paragraph::new(format!("{}] {}", filter_mode, app.input.clone())).block(Block::default());
f.render_widget(title, header_chunks[0]);
f.render_widget(help, header_chunks[1]);
@@ -460,9 +498,11 @@ fn draw_compact<T: Backend>(f: &mut Frame<'_, T>, history_count: i64, app: &mut
app.render_results(f, chunks[1], Block::default());
f.render_widget(input, chunks[2]);
+ let extra_width = app.input.width() + filter_mode.len();
+
f.set_cursor(
// Put cursor past the end of the input text
- chunks[2].x + app.input.width() as u16 + 2,
+ chunks[2].x + extra_width as u16 + 2,
// Move one line down, from the border to the input line
chunks[2].y + 1,
);
@@ -475,6 +515,7 @@ fn draw_compact<T: Backend>(f: &mut Frame<'_, T>, history_count: i64, app: &mut
async fn select_history(
query: &[String],
search_mode: SearchMode,
+ filter_mode: FilterMode,
style: atuin_client::settings::Style,
db: &mut (impl Database + Send + Sync),
) -> Result<String> {
@@ -491,6 +532,8 @@ async fn select_history(
input: query.join(" "),
results: Vec::new(),
results_state: ListState::default(),
+ context: current_context(),
+ filter_mode,
};
query_results(&mut app, search_mode, db).await?;
@@ -551,11 +594,26 @@ pub async fn run(
};
if interactive {
- let item = select_history(query, settings.search_mode, settings.style, db).await?;
+ let item = select_history(
+ query,
+ settings.search_mode,
+ settings.filter_mode,
+ settings.style,
+ db,
+ )
+ .await?;
eprintln!("{}", item);
} else {
+ let context = current_context();
+
let results = db
- .search(None, settings.search_mode, query.join(" ").as_str())
+ .search(
+ None,
+ settings.search_mode,
+ settings.filter_mode,
+ &context,
+ query.join(" ").as_str(),
+ )
.await?;
// TODO: This filtering would be better done in the SQL query, I just
diff --git a/src/command/client/stats.rs b/src/command/client/stats.rs
index 6d342c196..85c58cc05 100644
--- a/src/command/client/stats.rs
+++ b/src/command/client/stats.rs
@@ -8,9 +8,9 @@ use clap::Parser;
use cli_table::{format::Justify, print_stdout, Cell, Style, Table};
use eyre::{bail, Result};
-use atuin_client::database::Database;
+use atuin_client::database::{current_context, Database};
use atuin_client::history::History;
-use atuin_client::settings::Settings;
+use atuin_client::settings::{FilterMode, Settings};
#[derive(Parser)]
#[clap(infer_subcommands = true)]
@@ -71,6 +71,8 @@ impl Cmd {
db: &mut (impl Database + Send + Sync),
settings: &Settings,
) -> Result<()> {
+ let context = current_context();
+
match self {
Self::Day { words } => {
let words = if words.is_empty() {
@@ -90,7 +92,7 @@ impl Cmd {
}
Self::All => {
- let history = db.list(None, false).await?;
+ let history = db.list(FilterMode::Global, &context, None, false).await?;
compute_stats(&history)?;