mirror of
https://github.com/atuinsh/atuin.git
synced 2025-08-19 11:20:13 +02:00
This reverts commit cd5d337b52
.
This commit is contained in:
@@ -49,7 +49,7 @@ use ratatui::{
|
|||||||
const TAB_TITLES: [&str; 2] = ["Search", "Inspect"];
|
const TAB_TITLES: [&str; 2] = ["Search", "Inspect"];
|
||||||
|
|
||||||
pub enum InputAction {
|
pub enum InputAction {
|
||||||
Accept(History),
|
Accept(usize),
|
||||||
Copy(usize),
|
Copy(usize),
|
||||||
Delete(usize),
|
Delete(usize),
|
||||||
ReturnOriginal,
|
ReturnOriginal,
|
||||||
@@ -110,14 +110,13 @@ impl State {
|
|||||||
settings: &Settings,
|
settings: &Settings,
|
||||||
input: &Event,
|
input: &Event,
|
||||||
w: &mut W,
|
w: &mut W,
|
||||||
results: &[History],
|
|
||||||
) -> Result<InputAction>
|
) -> Result<InputAction>
|
||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
{
|
{
|
||||||
execute!(w, EnableMouseCapture)?;
|
execute!(w, EnableMouseCapture)?;
|
||||||
let r = match input {
|
let r = match input {
|
||||||
Event::Key(k) => self.handle_key_input(settings, k, results),
|
Event::Key(k) => self.handle_key_input(settings, k),
|
||||||
Event::Mouse(m) => self.handle_mouse_input(*m),
|
Event::Mouse(m) => self.handle_mouse_input(*m),
|
||||||
Event::Paste(d) => self.handle_paste_input(d),
|
Event::Paste(d) => self.handle_paste_input(d),
|
||||||
_ => InputAction::Continue,
|
_ => InputAction::Continue,
|
||||||
@@ -199,12 +198,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_key_input(
|
fn handle_key_input(&mut self, settings: &Settings, input: &KeyEvent) -> InputAction {
|
||||||
&mut self,
|
|
||||||
settings: &Settings,
|
|
||||||
input: &KeyEvent,
|
|
||||||
results: &[History],
|
|
||||||
) -> InputAction {
|
|
||||||
if input.kind == event::KeyEventKind::Release {
|
if input.kind == event::KeyEventKind::Release {
|
||||||
return InputAction::Continue;
|
return InputAction::Continue;
|
||||||
}
|
}
|
||||||
@@ -229,23 +223,13 @@ impl State {
|
|||||||
KeyCode::Char('c' | 'g') if ctrl => Some(InputAction::ReturnOriginal),
|
KeyCode::Char('c' | 'g') if ctrl => Some(InputAction::ReturnOriginal),
|
||||||
KeyCode::Esc if esc_allow_exit => Some(Self::handle_key_exit(settings)),
|
KeyCode::Esc if esc_allow_exit => Some(Self::handle_key_exit(settings)),
|
||||||
KeyCode::Char('[') if ctrl && esc_allow_exit => Some(Self::handle_key_exit(settings)),
|
KeyCode::Char('[') if ctrl && esc_allow_exit => Some(Self::handle_key_exit(settings)),
|
||||||
KeyCode::Tab => {
|
KeyCode::Tab => Some(InputAction::Accept(self.results_state.selected())),
|
||||||
let selected = self.results_state.selected();
|
KeyCode::Right if cursor_at_end_of_line && settings.keys.accept_past_line_end => {
|
||||||
if !results.is_empty() && selected < results.len() {
|
Some(InputAction::Accept(self.results_state.selected()))
|
||||||
Some(InputAction::Accept(results[selected].clone()))
|
|
||||||
} else {
|
|
||||||
Some(InputAction::ReturnQuery)
|
|
||||||
}
|
}
|
||||||
|
KeyCode::Left if cursor_at_start_of_line && settings.keys.exit_past_line_start => {
|
||||||
|
Some(Self::handle_key_exit(settings))
|
||||||
}
|
}
|
||||||
KeyCode::Right if cursor_at_end_of_line => {
|
|
||||||
let selected = self.results_state.selected();
|
|
||||||
if !results.is_empty() && selected < results.len() {
|
|
||||||
Some(InputAction::Accept(results[selected].clone()))
|
|
||||||
} else {
|
|
||||||
Some(InputAction::ReturnQuery)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
KeyCode::Left if cursor_at_start_of_line => Some(Self::handle_key_exit(settings)),
|
|
||||||
KeyCode::Char('o') if ctrl => {
|
KeyCode::Char('o') if ctrl => {
|
||||||
self.tab_index = (self.tab_index + 1) % TAB_TITLES.len();
|
self.tab_index = (self.tab_index + 1) % TAB_TITLES.len();
|
||||||
Some(InputAction::Continue)
|
Some(InputAction::Continue)
|
||||||
@@ -261,7 +245,7 @@ impl State {
|
|||||||
|
|
||||||
// handle tab-specific input
|
// handle tab-specific input
|
||||||
let action = match self.tab_index {
|
let action = match self.tab_index {
|
||||||
0 => self.handle_search_input(settings, input, results),
|
0 => self.handle_search_input(settings, input),
|
||||||
|
|
||||||
1 => super::inspector::input(self, settings, self.results_state.selected(), input),
|
1 => super::inspector::input(self, settings, self.results_state.selected(), input),
|
||||||
|
|
||||||
@@ -298,26 +282,16 @@ impl State {
|
|||||||
self.handle_search_scroll_one_line(settings, enable_exit, !settings.invert)
|
self.handle_search_scroll_one_line(settings, enable_exit, !settings.invert)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_search_accept(&mut self, settings: &Settings, results: &[History]) -> InputAction {
|
fn handle_search_accept(&mut self, settings: &Settings) -> InputAction {
|
||||||
if settings.enter_accept {
|
if settings.enter_accept {
|
||||||
self.accept = true;
|
self.accept = true;
|
||||||
}
|
}
|
||||||
let selected = self.results_state.selected();
|
InputAction::Accept(self.results_state.selected())
|
||||||
if !results.is_empty() && selected < results.len() {
|
|
||||||
InputAction::Accept(results[selected].clone())
|
|
||||||
} else {
|
|
||||||
InputAction::ReturnQuery
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
fn handle_search_input(
|
fn handle_search_input(&mut self, settings: &Settings, input: &KeyEvent) -> InputAction {
|
||||||
&mut self,
|
|
||||||
settings: &Settings,
|
|
||||||
input: &KeyEvent,
|
|
||||||
results: &[History],
|
|
||||||
) -> InputAction {
|
|
||||||
let ctrl = input.modifiers.contains(KeyModifiers::CONTROL);
|
let ctrl = input.modifiers.contains(KeyModifiers::CONTROL);
|
||||||
let alt = input.modifiers.contains(KeyModifiers::ALT);
|
let alt = input.modifiers.contains(KeyModifiers::ALT);
|
||||||
|
|
||||||
@@ -408,20 +382,14 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match input.code {
|
match input.code {
|
||||||
KeyCode::Enter => return self.handle_search_accept(settings, results),
|
KeyCode::Enter => return self.handle_search_accept(settings),
|
||||||
KeyCode::Char('m') if ctrl => return self.handle_search_accept(settings, results),
|
KeyCode::Char('m') if ctrl => return self.handle_search_accept(settings),
|
||||||
KeyCode::Char('y') if ctrl => {
|
KeyCode::Char('y') if ctrl => {
|
||||||
return InputAction::Copy(self.results_state.selected());
|
return InputAction::Copy(self.results_state.selected());
|
||||||
}
|
}
|
||||||
KeyCode::Char(c @ '1'..='9') if modfr => {
|
KeyCode::Char(c @ '1'..='9') if modfr => {
|
||||||
let selected = self.results_state.selected();
|
|
||||||
return c.to_digit(10).map_or(InputAction::Continue, |c| {
|
return c.to_digit(10).map_or(InputAction::Continue, |c| {
|
||||||
let new_index = selected + c as usize;
|
InputAction::Accept(self.results_state.selected() + c as usize)
|
||||||
if !results.is_empty() && new_index < results.len() {
|
|
||||||
InputAction::Accept(results[new_index].clone())
|
|
||||||
} else {
|
|
||||||
InputAction::ReturnQuery
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
KeyCode::Left if ctrl => self
|
KeyCode::Left if ctrl => self
|
||||||
@@ -1173,11 +1141,8 @@ pub async fn history(
|
|||||||
event_ready = event_ready => {
|
event_ready = event_ready => {
|
||||||
if event_ready?? {
|
if event_ready?? {
|
||||||
loop {
|
loop {
|
||||||
match app.handle_input(settings, &event::read()?, &mut std::io::stdout(), &results)? {
|
match app.handle_input(settings, &event::read()?, &mut std::io::stdout())? {
|
||||||
InputAction::Continue => {
|
InputAction::Continue => {},
|
||||||
// Redraw the UI to keep it in sync with the selection state
|
|
||||||
terminal.draw(|f| app.draw(f, &results, stats.clone(), settings, theme))?;
|
|
||||||
},
|
|
||||||
InputAction::Delete(index) => {
|
InputAction::Delete(index) => {
|
||||||
if results.is_empty() {
|
if results.is_empty() {
|
||||||
break;
|
break;
|
||||||
@@ -1229,12 +1194,8 @@ pub async fn history(
|
|||||||
stats = if app.tab_index == 0 {
|
stats = if app.tab_index == 0 {
|
||||||
None
|
None
|
||||||
} else if !results.is_empty() {
|
} else if !results.is_empty() {
|
||||||
let selected = app.results_state.selected();
|
let selected = results[app.results_state.selected()].clone();
|
||||||
if selected < results.len() {
|
Some(db.stats(&selected).await?)
|
||||||
Some(db.stats(&results[selected]).await?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -1247,26 +1208,29 @@ pub async fn history(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
InputAction::Accept(history) => {
|
InputAction::Accept(index) if index < results.len() => {
|
||||||
let mut command = history.command;
|
let mut command = results.swap_remove(index).command;
|
||||||
if accept
|
if accept
|
||||||
&& (utils::is_zsh() || utils::is_fish() || utils::is_bash() || utils::is_xonsh())
|
&& (utils::is_zsh() || utils::is_fish() || utils::is_bash() || utils::is_xonsh())
|
||||||
{
|
{
|
||||||
command = String::from("__atuin_accept__:") + &command;
|
command = String::from("__atuin_accept__:") + &command;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have the actual history entry, so use it directly
|
// index is in bounds so we return that entry
|
||||||
Ok(command)
|
Ok(command)
|
||||||
}
|
}
|
||||||
InputAction::ReturnOriginal => Ok(String::new()),
|
InputAction::ReturnOriginal => Ok(String::new()),
|
||||||
InputAction::Copy(index) => {
|
InputAction::Copy(index) => {
|
||||||
if !results.is_empty() && index < results.len() {
|
let cmd = results.swap_remove(index).command;
|
||||||
let cmd = results[index].command.clone();
|
|
||||||
set_clipboard(cmd);
|
set_clipboard(cmd);
|
||||||
}
|
|
||||||
Ok(String::new())
|
Ok(String::new())
|
||||||
}
|
}
|
||||||
InputAction::ReturnQuery => Ok(app.search.input.into_inner()),
|
InputAction::ReturnQuery | InputAction::Accept(_) => {
|
||||||
|
// Either:
|
||||||
|
// * index == RETURN_QUERY, in which case we should return the input
|
||||||
|
// * out of bounds -> usually implies no selected entry so we return the input
|
||||||
|
Ok(app.search.input.into_inner())
|
||||||
|
}
|
||||||
InputAction::Continue | InputAction::Redraw | InputAction::Delete(_) => {
|
InputAction::Continue | InputAction::Redraw | InputAction::Delete(_) => {
|
||||||
unreachable!("should have been handled!")
|
unreachable!("should have been handled!")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user