diff options
author | Azad <49314270+Akmadan23@users.noreply.github.com> | 2024-03-10 20:54:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-10 15:54:39 -0400 |
commit | 8fe75f3bb7fb876f96efb0f215744ee43203f2a2 (patch) | |
tree | 25f01262d85779f9d767eb899ad4f72d38a3e8e8 | |
parent | cc5ed528428a29c64fb6061b02398ab77e734d5e (diff) |
fix: path autocompletion (#502)
-rw-r--r-- | src/ui/views/tui_textfield.rs | 76 |
1 files changed, 21 insertions, 55 deletions
diff --git a/src/ui/views/tui_textfield.rs b/src/ui/views/tui_textfield.rs index 1bc38aa..f3e3588 100644 --- a/src/ui/views/tui_textfield.rs +++ b/src/ui/views/tui_textfield.rs @@ -42,9 +42,9 @@ struct CompletionTracker { } impl CompletionTracker { - pub fn new(pos: usize, candidates: Vec<Pair>, _original: String) -> Self { + pub fn new(index: usize, pos: usize, candidates: Vec<Pair>, _original: String) -> Self { CompletionTracker { - index: 0, + index, pos, _original, candidates, @@ -231,17 +231,19 @@ impl<'a> TuiTextField<'a> { let _ = terminal.hide_cursor(); return None; } - Key::Char('\t') => autocomplete_forward( + Key::Char('\t') => autocomplete( &mut line_buffer, &mut completion_tracker, &completer, listener, + false, ), - Key::BackTab => autocomplete_backwards( + Key::BackTab => autocomplete( &mut line_buffer, &mut completion_tracker, &completer, listener, + true, ), // Current `completion_tracker` should be dropped @@ -316,25 +318,28 @@ impl<'a> TuiTextField<'a> { } } -fn autocomplete_forward( +fn autocomplete( line_buffer: &mut LineBuffer, completion_tracker: &mut Option<CompletionTracker>, completer: &FilenameCompleter, listener: &mut DummyListener, + backwards: bool, ) -> bool { // If we are in the middle of a word, move to the end of it, // so we don't split it with autocompletion. move_to_the_end(line_buffer); - if let Some(ref mut ct) = completion_tracker { - if ct.index + 1 >= ct.candidates.len() { - return false; - } - ct.index += 1; - let candidate = &ct.candidates[ct.index]; + if let Some(ct) = completion_tracker { + ct.index = if backwards { + ct.index.checked_sub(1).unwrap_or(ct.candidates.len() - 1) + } else if ct.index + 1 == ct.candidates.len() { + 0 + } else { + ct.index + 1 + }; let pos = ct.pos; - let first = candidate.display(); + let first = ct.candidates[ct.index].display(); line_buffer.set_pos(pos); line_buffer.kill_buffer(listener); @@ -348,11 +353,10 @@ fn autocomplete_forward( .unwrap_or(std::cmp::Ordering::Less) }); - let mut ct = - CompletionTracker::new(pos, candidates, String::from(line_buffer.as_str())); - ct.index = 0; - let candidate = &ct.candidates[0]; - let first = candidate.display(); + let index = if backwards { candidates.len() - 1 } else { 0 }; + let pos = line_buffer.rfind('/').map(|p| p + 1).unwrap_or(pos); + let ct = CompletionTracker::new(index, pos, candidates, line_buffer.to_string()); + let first = ct.candidates[index].display(); line_buffer.set_pos(pos); line_buffer.kill_buffer(listener); @@ -366,44 +370,6 @@ fn autocomplete_forward( false } -fn autocomplete_backwards( - line_buffer: &mut LineBuffer, - completion_tracker: &mut Option<CompletionTracker>, - completer: &FilenameCompleter, - listener: &mut DummyListener, -) -> bool { - // If we are in the middle of a word, move to the end of it, - // so we don't split it with autocompletion. - move_to_the_end(line_buffer); - - if let Some(ref mut ct) = completion_tracker { - ct.index = ct.index.checked_sub(1).unwrap_or(ct.candidates.len() - 1); - - let candidate = &ct.candidates[ct.index]; - line_buffer.update(candidate.display(), ct.pos, listener); - } else if let Some((pos, mut candidates)) = get_candidates(completer, line_buffer) { - if !candidates.is_empty() { - candidates.sort_by(|x, y| { - x.display() - .partial_cmp(y.display()) - .unwrap_or(std::cmp::Ordering::Less) - }); - - let first_idx = candidates.len() - 1; - let first = candidates[first_idx].display().to_string(); - - let mut ct = - CompletionTracker::new(pos, candidates, String::from(line_buffer.as_str())); - ct.index = first_idx; - - *completion_tracker = Some(ct); - line_buffer.update(&first, pos, listener); - } - } - - false -} - fn moved_to_another_word<F, Any>(line_buffer: &mut LineBuffer, action: F) -> bool where F: FnOnce(&mut LineBuffer) -> Any, |