@@ -3,16 +3,15 @@ use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
33use helix_core::Position;
44use helix_view::Editor;
55use helix_view::Theme;
6−use std::borrow::Cow;
7−use std::string::String;
6+use std::{borrow::Cow, ops::RangeFrom};
87
98pub struct Prompt {
109 prompt: String,
1110 pub line: String,
1211 cursor: usize,
13− completion: Vec<Cow<'static, str>>,
12+ completion: Vec<(RangeFrom<usize>, Cow<'static, str>)>,
1413 completion_selection_index: Option<usize>,
15− completion_fn: Box<dyn FnMut(&str) -> Vec<Cow<'static, str>>>,
14+ completion_fn: Box<dyn FnMut(&str) -> Vec<(RangeFrom<usize>, Cow<'static, str>)>>,
1615 callback_fn: Box<dyn FnMut(&mut Editor, &str, PromptEvent)>,
1716}
1817
@@ -29,7 +28,7 @@ pub enum PromptEvent {
2928impl Prompt {
3029 pub fn new(
3130 prompt: String,
32− mut completion_fn: impl FnMut(&str) -> Vec<Cow<'static, str>> + 'static,
31+ mut completion_fn: impl FnMut(&str) -> Vec<(RangeFrom<usize>, Cow<'static, str>)> + 'static,
3332 callback_fn: impl FnMut(&mut Editor, &str, PromptEvent) + 'static,
3433 ) -> Prompt {
3534 Prompt {
@@ -85,15 +84,9 @@ impl Prompt {
8584 self.completion_selection_index.map(|i| i + 1).unwrap_or(0) % self.completion.len();
8685 self.completion_selection_index = Some(index);
8786
88− let item = &self.completion[index];
87+ let (range, item) = &self.completion[index];
8988
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− }
89+ self.line.replace_range(range.clone(), item);
9790
9891 self.move_end();
9992 // TODO: recalculate completion when completion item is accepted, (Enter)
@@ -135,7 +128,7 @@ impl Prompt {
135128 Rect::new(0, area.height - col_height - 2, area.width, col_height),
136129 theme.get("ui.statusline"),
137130 );
138− for (i, command) in self.completion.iter().enumerate() {
131+ for (i, (_range, completion)) in self.completion.iter().enumerate() {
139132 let color = if self.completion_selection_index.is_some()
140133 && i == self.completion_selection_index.unwrap()
141134 {
@@ -146,7 +139,7 @@ impl Prompt {
146139 surface.set_stringn(
147140 1 + col * BASE_WIDTH,
148141 area.height - col_height - 2 + row,
149− &command,
142+ &completion,
150143 BASE_WIDTH as usize - 1,
151144 color,
152145 );