Skip to content

Commit 2a65ebc

Browse files
committed
Make Completion a stateful API
1 parent de90b1a commit 2a65ebc

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

examples/completion.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use dialoguer::{theme::ColorfulTheme, Completion, Input};
33
fn main() {
44
println!("Use the Right arrow or Tab to complete your command");
55

6-
let completion = MyCompletion::default();
6+
let mut completion = MyCompletion::default();
77

88
Input::<String>::with_theme(&ColorfulTheme::default())
99
.with_prompt("dialoguer")
10-
.completion_with(&completion)
10+
.completion_with(&mut completion)
1111
.interact_text()
1212
.unwrap();
1313
}
@@ -30,7 +30,7 @@ impl Default for MyCompletion {
3030

3131
impl Completion for MyCompletion {
3232
/// Simple completion implementation based on substring
33-
fn get(&self, input: &str) -> Option<String> {
33+
fn next(&mut self, input: &str, _completion_modified: bool) -> Option<String> {
3434
let matches = self
3535
.options
3636
.iter()

src/completion.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/// Trait for completion handling.
2-
pub trait Completion {
3-
fn get(&self, input: &str) -> Option<String>;
2+
pub trait Completion: Send {
3+
fn next(&mut self, input: &str, completion_modified: bool) -> Option<String>;
44
}

src/prompts/input.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ pub struct Input<'a, T> {
6464
#[cfg(feature = "history")]
6565
history: Option<Arc<Mutex<&'a mut dyn History<T>>>>,
6666
#[cfg(feature = "completion")]
67-
completion: Option<&'a dyn Completion>,
67+
completion: Option<Arc<Mutex<&'a mut dyn Completion>>>,
68+
#[cfg(feature = "completion")]
69+
completion_modified: bool,
6870
}
6971

7072
impl<T> Default for Input<'static, T> {
@@ -164,6 +166,8 @@ impl<'a, T> Input<'a, T> {
164166
history: None,
165167
#[cfg(feature = "completion")]
166168
completion: None,
169+
#[cfg(feature = "completion")]
170+
completion_modified: false,
167171
}
168172
}
169173

@@ -219,11 +223,11 @@ impl<'a, T> Input<'a, T> {
219223

220224
/// Enable completion
221225
#[cfg(feature = "completion")]
222-
pub fn completion_with<C>(mut self, completion: &'a C) -> Self
226+
pub fn completion_with<C>(mut self, completion: &'a mut C) -> Self
223227
where
224228
C: Completion,
225229
{
226-
self.completion = Some(completion);
230+
self.completion = Some(Arc::new(Mutex::new(completion)));
227231
self
228232
}
229233
}
@@ -354,6 +358,11 @@ where
354358
}
355359

356360
term.flush()?;
361+
362+
#[cfg(feature = "completion")]
363+
if self.completion.is_some() {
364+
self.completion_modified = true;
365+
}
357366
}
358367
Key::Char(chr) if !chr.is_ascii_control() => {
359368
chars.insert(position, chr);
@@ -363,6 +372,11 @@ where
363372
term.write_str(&tail)?;
364373
term.move_cursor_left(tail.chars().count() - 1)?;
365374
term.flush()?;
375+
376+
#[cfg(feature = "completion")]
377+
if self.completion.is_some() {
378+
self.completion_modified = true;
379+
}
366380
}
367381
Key::ArrowLeft if position > 0 => {
368382
if (position + prompt_len) % term.size().1 as usize == 0 {
@@ -473,9 +487,13 @@ where
473487
}
474488
#[cfg(feature = "completion")]
475489
Key::ArrowRight | Key::Tab => {
476-
if let Some(completion) = &self.completion {
490+
if let Some(completion) = &mut self.completion {
477491
let input: String = chars.clone().into_iter().collect();
478-
if let Some(x) = completion.get(&input) {
492+
if let Some(x) = completion
493+
.lock()
494+
.unwrap()
495+
.next(&input, self.completion_modified)
496+
{
479497
term.clear_chars(chars.len())?;
480498
chars.clear();
481499
position = 0;
@@ -486,6 +504,8 @@ where
486504
term.write_str(&x)?;
487505
term.flush()?;
488506
}
507+
508+
self.completion_modified = false;
489509
}
490510
}
491511
#[cfg(feature = "history")]

0 commit comments

Comments
 (0)