Improve tab completion behaviour (#2916)

* Improve tab completion behaviour

* Fix clippy issue

* Add test cases
This commit is contained in:
Coen Fox 2021-01-13 15:04:29 +11:00 committed by GitHub
parent ad26adc3e3
commit 495d2ebd70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -51,7 +51,27 @@ impl rustyline::completion::Completer for Helper {
}
fn update(&self, line: &mut rustyline::line_buffer::LineBuffer, start: usize, elected: &str) {
let end = line.pos();
let end = start
+ match line
.as_str()
.chars()
.into_iter()
.skip(start)
.zip(elected.chars().into_iter())
.enumerate()
.find(|(_, (line, replace))| line != replace)
{
Some((index, (_, _))) => index,
None => line.pos(),
};
let mut end = end.max(line.pos());
let remaining = &line.as_str()[end..];
if remaining.starts_with('"') {
end += 1;
}
line.replace(start..end, elected)
}
}
@ -144,3 +164,49 @@ fn vec_tag<T>(input: Vec<Tagged<T>>) -> Option<Tag> {
}
impl rustyline::Helper for Helper {}
#[cfg(test)]
mod tests {
use super::*;
use nu_engine::basic_evaluation_context;
use rustyline::completion::Completer;
use rustyline::line_buffer::LineBuffer;
#[test]
fn closing_quote_should_replaced() {
let text = "cd \"folder with spaces\\subdirectory\\\"";
let replacement = "\"folder with spaces\\subdirectory\\subsubdirectory\\\"";
let mut buffer = LineBuffer::with_capacity(256);
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 1);
let helper = Helper::new(basic_evaluation_context().unwrap(), None);
helper.update(&mut buffer, "cd ".len(), &replacement);
assert_eq!(
buffer.as_str(),
"cd \"folder with spaces\\subdirectory\\subsubdirectory\\\""
);
}
#[test]
fn replacement_with_cursor_in_text() {
let text = "cd \"folder with spaces\\subdirectory\\\"";
let replacement = "\"folder with spaces\\subdirectory\\subsubdirectory\\\"";
let mut buffer = LineBuffer::with_capacity(256);
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 30);
let helper = Helper::new(basic_evaluation_context().unwrap(), None);
helper.update(&mut buffer, "cd ".len(), &replacement);
assert_eq!(
buffer.as_str(),
"cd \"folder with spaces\\subdirectory\\subsubdirectory\\\""
);
}
}