Process selected command

This commit is contained in:
Pirmin Kalberer 2019-09-18 00:21:39 +02:00
parent 1e3549571c
commit 1c95bf05dc
2 changed files with 41 additions and 19 deletions

View File

@ -340,26 +340,47 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
// 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 prompt = &format!(
"{}{}> ",
cwd,
match current_branch() {
Some(s) => format!("({})", s),
None => "".to_string(),
}
));
);
let mut initial_command = Some(String::new());
let mut readline = Err(ReadlineError::Eof);
while let Some(ref cmd) = initial_command {
readline = rl.readline_with_initial(prompt, (&cmd, ""));
if let Err(ReadlineError::Eof) = &readline {
// Fuzzy search in history
let hist = std::fs::read_to_string("history.txt").expect("Cannot open history.txt");
let lines = hist.lines().rev().collect();
let selection = histsearch::select_from_list(&lines); // Clears last line with prompt
match selection {
histsearch::SelectionResult::Selected(line) => {
println!("{}{}", &prompt, &line); // TODO: colorize prompt
readline = Ok(line.clone());
initial_command = None;
}
histsearch::SelectionResult::Edit(line) => {
initial_command = Some(line);
}
histsearch::SelectionResult::NoSelection => {
readline = Ok("".to_string());
initial_command = None;
}
}
} else {
initial_command = None;
}
}
match process_line(readline, &mut context).await {
LineResult::Success(line) => {
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 => {
if ctrlcbreak {
std::process::exit(0);
@ -403,7 +424,6 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
enum LineResult {
Success(String),
SearchHist,
Error(String, ShellError),
CtrlC,
Break,
@ -531,7 +551,7 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
LineResult::Success(line.clone())
}
Err(ReadlineError::Interrupted) => LineResult::CtrlC,
Err(ReadlineError::Eof) => LineResult::SearchHist, // Override LineResult::Break
Err(ReadlineError::Eof) => LineResult::Break,
Err(err) => {
println!("Error: {:?}", err);
LineResult::Break

View File

@ -3,7 +3,13 @@ use crossterm::{cursor, terminal, ClearType, InputEvent, KeyEvent, RawScreen};
use std::io::Write;
use sublime_fuzzy::best_match;
pub fn select_from_list(lines: &Vec<&str>) {
pub enum SelectionResult {
Selected(String),
Edit(String),
NoSelection,
}
pub fn select_from_list(lines: &Vec<&str>) -> SelectionResult {
const MAX_RESULTS: usize = 5;
#[derive(PartialEq)]
enum State {
@ -70,7 +76,7 @@ pub fn select_from_list(lines: &Vec<&str>) {
cursor.move_up(selected_lines.len() as u16);
}
let (_x, y) = cursor.pos();
let _ = cursor.goto(0, y);
let _ = cursor.goto(0, y - 1);
let _ = cursor.show();
let _ = RawScreen::disable_raw_mode();
@ -79,13 +85,9 @@ pub fn select_from_list(lines: &Vec<&str>) {
terminal.clear(ClearType::FromCursorDown).unwrap();
match state {
State::Selected(idx) => {
print!("{}", lines[idx]);
}
State::Edit(idx) => {
print!("{}", lines[idx]);
}
_ => {}
State::Selected(idx) => SelectionResult::Selected(lines[idx].to_string()),
State::Edit(idx) => SelectionResult::Edit(lines[idx].to_string()),
_ => SelectionResult::NoSelection,
}
}