Bind fuzzy history search to Ctrl-R

This commit is contained in:
Pirmin Kalberer 2019-09-16 22:48:22 +02:00
parent 44b7e07569
commit 1e3549571c
5 changed files with 25 additions and 8 deletions

7
Cargo.lock generated
View file

@ -1566,6 +1566,7 @@ dependencies = [
"serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
"shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sublime_fuzzy 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"surf 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "surf 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2443,6 +2444,11 @@ name = "strsim"
version = "0.8.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sublime_fuzzy"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "subprocess" name = "subprocess"
version = "0.1.18" version = "0.1.18"
@ -3247,6 +3253,7 @@ dependencies = [
"checksum stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4725650978235083241fab0fdc8e694c3de37821524e7534a1a9061d1068af" "checksum stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4725650978235083241fab0fdc8e694c3de37821524e7534a1a9061d1068af"
"checksum static_assertions 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4f8de36da215253eb5f24020bfaa0646613b48bf7ebe36cdfa37c3b3b33b241" "checksum static_assertions 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4f8de36da215253eb5f24020bfaa0646613b48bf7ebe36cdfa37c3b3b33b241"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum sublime_fuzzy 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97bd7ad698ea493a3a7f60c2ffa117c234f341e09f8cc2d39cef10cdde077acf"
"checksum subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "28fc0f40f0c0da73339d347aa7d6d2b90341a95683a47722bc4eebed71ff3c00" "checksum subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "28fc0f40f0c0da73339d347aa7d6d2b90341a95683a47722bc4eebed71ff3c00"
"checksum surf 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "018eed64aede455beb88505d50c5c64882bebbe0996d4b660c272e3d8bb6f883" "checksum surf 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "018eed64aede455beb88505d50c5c64882bebbe0996d4b660c272e3d8bb6f883"
"checksum syn 0.15.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ee06ea4b620ab59a2267c6b48be16244a3389f8bfa0986bdd15c35b890b00af3" "checksum syn 0.15.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ee06ea4b620ab59a2267c6b48be16244a3389f8bfa0986bdd15c35b890b00af3"

View file

@ -73,6 +73,7 @@ num-bigint = { version = "0.2.3", features = ["serde"] }
bigdecimal = { version = "0.1.0", features = ["serde"] } bigdecimal = { version = "0.1.0", features = ["serde"] }
natural = "0.3.0" natural = "0.3.0"
serde_urlencoded = "0.6.1" serde_urlencoded = "0.6.1"
sublime_fuzzy = "0.5"
neso = { version = "0.5.0", optional = true } neso = { version = "0.5.0", optional = true }
crossterm = { version = "0.10.2", optional = true } crossterm = { version = "0.10.2", optional = true }

View file

@ -10,6 +10,7 @@ use crate::context::Context;
use crate::data::Value; use crate::data::Value;
pub(crate) use crate::errors::ShellError; pub(crate) use crate::errors::ShellError;
use crate::git::current_branch; use crate::git::current_branch;
use crate::histsearch;
use crate::parser::registry::Signature; use crate::parser::registry::Signature;
use crate::parser::{hir, CallNode, Pipeline, PipelineElement, TokenNode}; use crate::parser::{hir, CallNode, Pipeline, PipelineElement, TokenNode};
use crate::prelude::*; use crate::prelude::*;
@ -333,6 +334,12 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
rl.set_edit_mode(edit_mode); rl.set_edit_mode(edit_mode);
// Register Ctrl-r for history fuzzy search
// rustyline doesn't support custom commands, so we override Ctrl-D (EOF)
rl.bind_sequence(rustyline::KeyPress::Ctrl('R'), rustyline::Cmd::EndOfFile);
// Redefine Ctrl-D to same command as Ctrl-C
rl.bind_sequence(rustyline::KeyPress::Ctrl('D'), rustyline::Cmd::Interrupt);
let readline = rl.readline(&format!( let readline = rl.readline(&format!(
"{}{}> ", "{}{}> ",
cwd, cwd,
@ -347,6 +354,12 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
rl.add_history_entry(line.clone()); rl.add_history_entry(line.clone());
} }
LineResult::SearchHist => {
let hist = std::fs::read_to_string("history.txt").expect("Cannot open history.txt");
let lines = hist.lines().rev().collect();
histsearch::select_from_list(&lines);
}
LineResult::CtrlC => { LineResult::CtrlC => {
if ctrlcbreak { if ctrlcbreak {
std::process::exit(0); std::process::exit(0);
@ -390,6 +403,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
enum LineResult { enum LineResult {
Success(String), Success(String),
SearchHist,
Error(String, ShellError), Error(String, ShellError),
CtrlC, CtrlC,
Break, Break,
@ -517,7 +531,7 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
LineResult::Success(line.clone()) LineResult::Success(line.clone())
} }
Err(ReadlineError::Interrupted) => LineResult::CtrlC, Err(ReadlineError::Interrupted) => LineResult::CtrlC,
Err(ReadlineError::Eof) => LineResult::Break, Err(ReadlineError::Eof) => LineResult::SearchHist, // Override LineResult::Break
Err(err) => { Err(err) => {
println!("Error: {:?}", err); println!("Error: {:?}", err);
LineResult::Break LineResult::Break

View file

@ -3,7 +3,7 @@ use crossterm::{cursor, terminal, ClearType, InputEvent, KeyEvent, RawScreen};
use std::io::Write; use std::io::Write;
use sublime_fuzzy::best_match; use sublime_fuzzy::best_match;
fn select_from_list(lines: &Vec<&str>) { pub fn select_from_list(lines: &Vec<&str>) {
const MAX_RESULTS: usize = 5; const MAX_RESULTS: usize = 5;
#[derive(PartialEq)] #[derive(PartialEq)]
enum State { enum State {
@ -163,9 +163,3 @@ fn paint_selection_list(lines: &Vec<&str>, selected: usize) {
// Clear additional lines from previous selection // Clear additional lines from previous selection
terminal().clear(ClearType::FromCursorDown).unwrap(); terminal().clear(ClearType::FromCursorDown).unwrap();
} }
fn main() {
let hist = std::fs::read_to_string("history.txt").expect("Cannot open history.txt");
let lines = hist.lines().rev().collect();
select_from_list(&lines);
}

View file

@ -13,6 +13,7 @@ mod errors;
mod evaluate; mod evaluate;
mod format; mod format;
mod git; mod git;
mod histsearch;
mod parser; mod parser;
mod plugin; mod plugin;
mod shell; mod shell;