@@ -3,15 +3,16 @@ use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
33use helix_core::Position;
44use helix_view::Editor;
55use helix_view::Theme;
6+use std::borrow::Cow;
67use std::string::String;
78
89pub struct Prompt {
910 pub prompt: String,
1011 pub line: String,
1112 pub cursor: usize,
12− pub completion: Vec<String>,
13+ pub completion: Vec<Cow<'static, str>>,
1314 pub completion_selection_index: Option<usize>,
14− completion_fn: Box<dyn FnMut(&str) -> Vec<String>>,
15+ completion_fn: Box<dyn FnMut(&str) -> Vec<Cow<'static, str>>>,
1516 callback_fn: Box<dyn FnMut(&mut Editor, &str, PromptEvent)>,
1617}
1718
@@ -28,7 +29,7 @@ pub enum PromptEvent {
2829impl Prompt {
2930 pub fn new(
3031 prompt: String,
31− mut completion_fn: impl FnMut(&str) -> Vec<String> + 'static,
32+ mut completion_fn: impl FnMut(&str) -> Vec<Cow<'static, str>> + 'static,
3233 callback_fn: impl FnMut(&mut Editor, &str, PromptEvent) + 'static,
3334 ) -> Prompt {
3435 Prompt {
@@ -83,7 +84,19 @@ impl Prompt {
8384 let index =
8485 self.completion_selection_index.map(|i| i + 1).unwrap_or(0) % self.completion.len();
8586 self.completion_selection_index = Some(index);
86− self.line = self.completion[index].clone();
87+
88+ let item = &self.completion[index];
89+
90+ // replace the last arg
91+ if let Some(pos) = self.line.rfind(' ') {
92+ self.line.replace_range(pos + 1.., item);
93+ } else {
94+ // need toowned_clone_into nightly feature to reuse allocation
95+ self.line = item.to_string();
96+ }
97+
98+ self.move_end();
99+ // TODO: recalculate completion when completion item is accepted, (Enter)
87100 }
88101 pub fn exit_selection(&mut self) {
89102 self.completion_selection_index = None;
@@ -175,9 +188,14 @@ impl Component for Prompt {
175188 )));
176189
177190 match event {
191+ // char or shift char
178192 KeyEvent {
179193 code: KeyCode::Char(c),
180194 modifiers: KeyModifiers::NONE,
195+ }
196+ | KeyEvent {
197+ code: KeyCode::Char(c),
198+ modifiers: KeyModifiers::SHIFT,
181199 } => {
182200 self.insert_char(c);
183201 (self.callback_fn)(cx.editor, &self.line, PromptEvent::Update);