Skip to content

Commit

Permalink
Merge pull request #259 from damymetzke/fuzzy-select-vim
Browse files Browse the repository at this point in the history
Add vim mode to `FuzzySelect`
  • Loading branch information
pksunkara committed May 21, 2023
2 parents d77d5cd + 4165fcb commit c8cdaf3
Showing 1 changed file with 36 additions and 9 deletions.
45 changes: 36 additions & 9 deletions src/prompts/fuzzy_select.rs
Expand Up @@ -38,6 +38,7 @@ pub struct FuzzySelect<'a> {
report: bool,
clear: bool,
highlight_matches: bool,
enable_vim_mode: bool,
max_length: Option<usize>,
theme: &'a dyn Theme,
/// Search string that a fuzzy search with start with.
Expand Down Expand Up @@ -118,6 +119,17 @@ impl FuzzySelect<'_> {
self
}

/// Indicated whether to allow the use of vim mode
///
/// Vim mode can be entered by pressing Escape.
/// This then allows the user to navigate using hjkl.
///
/// The default is to disable vim mode.
pub fn vim_mode(mut self, val: bool) -> Self {
self.enable_vim_mode = val;
self
}

/// Sets the maximum number of visible options.
///
/// The default is the height of the terminal minus 2.
Expand Down Expand Up @@ -209,6 +221,8 @@ impl FuzzySelect<'_> {

term.hide_cursor()?;

let mut vim_mode = false;

loop {
render.clear()?;
render.fuzzy_select_prompt(self.prompt.as_str(), &search_term, position)?;
Expand Down Expand Up @@ -240,16 +254,24 @@ impl FuzzySelect<'_> {
}
term.flush()?;

match (term.read_key()?, sel) {
(Key::Escape, _) if allow_quit => {
match (term.read_key()?, sel, vim_mode) {
(Key::Escape, _, false) if self.enable_vim_mode => {
vim_mode = true;
}
(Key::Escape, _, false) | (Key::Char('q'), _, true) if allow_quit => {
if self.clear {
render.clear()?;
term.flush()?;
}
term.show_cursor()?;
return Ok(None);
}
(Key::ArrowUp | Key::BackTab, _) if !filtered_list.is_empty() => {
(Key::Char('i' | 'a'), _, true) => {
vim_mode = false;
}
(Key::ArrowUp | Key::BackTab, _, _) | (Key::Char('k'), _, true)
if !filtered_list.is_empty() =>
{
if sel == Some(0) {
starting_row =
filtered_list.len().max(visible_term_rows) - visible_term_rows;
Expand All @@ -266,7 +288,9 @@ impl FuzzySelect<'_> {
};
term.flush()?;
}
(Key::ArrowDown | Key::Tab, _) if !filtered_list.is_empty() => {
(Key::ArrowDown | Key::Tab, _, _) | (Key::Char('j'), _, true)
if !filtered_list.is_empty() =>
{
sel = match sel {
None => Some(0),
Some(sel) => {
Expand All @@ -280,15 +304,17 @@ impl FuzzySelect<'_> {
}
term.flush()?;
}
(Key::ArrowLeft, _) if position > 0 => {
(Key::ArrowLeft, _, _) | (Key::Char('h'), _, true) if position > 0 => {
position -= 1;
term.flush()?;
}
(Key::ArrowRight, _) if position < search_term.len() => {
(Key::ArrowRight, _, _) | (Key::Char('l'), _, true)
if position < search_term.len() =>
{
position += 1;
term.flush()?;
}
(Key::Enter, Some(sel)) if !filtered_list.is_empty() => {
(Key::Enter, Some(sel), _) if !filtered_list.is_empty() => {
if self.clear {
render.clear()?;
}
Expand All @@ -305,12 +331,12 @@ impl FuzzySelect<'_> {
term.show_cursor()?;
return Ok(sel_string_pos_in_items);
}
(Key::Backspace, _) if position > 0 => {
(Key::Backspace, _, _) if position > 0 => {
position -= 1;
search_term.remove(position);
term.flush()?;
}
(Key::Char(chr), _) if !chr.is_ascii_control() => {
(Key::Char(chr), _, _) if !chr.is_ascii_control() => {
search_term.insert(position, chr);
position += 1;
term.flush()?;
Expand Down Expand Up @@ -349,6 +375,7 @@ impl<'a> FuzzySelect<'a> {
report: true,
clear: true,
highlight_matches: true,
enable_vim_mode: false,
max_length: None,
theme,
initial_text: "".into(),
Expand Down

0 comments on commit c8cdaf3

Please sign in to comment.