2019-05-26 08:54:41 +02:00
|
|
|
use crate::prelude::*;
|
|
|
|
use derive_new::new;
|
2019-05-18 04:30:57 +02:00
|
|
|
use rustyline::completion::Completer;
|
|
|
|
use rustyline::completion::{self, FilenameCompleter};
|
2019-05-16 23:43:36 +02:00
|
|
|
use rustyline::line_buffer::LineBuffer;
|
|
|
|
|
2019-05-26 08:54:41 +02:00
|
|
|
#[derive(new)]
|
2019-05-18 04:30:57 +02:00
|
|
|
crate struct NuCompleter {
|
|
|
|
pub file_completer: FilenameCompleter,
|
2019-05-26 08:54:41 +02:00
|
|
|
pub commands: indexmap::IndexMap<String, Arc<dyn Command>>,
|
2019-05-18 04:30:57 +02:00
|
|
|
}
|
2019-05-16 23:43:36 +02:00
|
|
|
|
|
|
|
impl Completer for NuCompleter {
|
2019-05-18 04:30:57 +02:00
|
|
|
type Candidate = completion::Pair;
|
2019-05-16 23:43:36 +02:00
|
|
|
|
|
|
|
fn complete(
|
|
|
|
&self,
|
2019-05-18 04:30:57 +02:00
|
|
|
line: &str,
|
|
|
|
pos: usize,
|
|
|
|
context: &rustyline::Context,
|
|
|
|
) -> rustyline::Result<(usize, Vec<completion::Pair>)> {
|
2019-05-26 08:54:41 +02:00
|
|
|
let commands: Vec<String> = self.commands.keys().cloned().collect();
|
2019-05-18 04:30:57 +02:00
|
|
|
|
|
|
|
let mut completions = self.file_completer.complete(line, pos, context)?.1;
|
|
|
|
|
|
|
|
let line_chars: Vec<_> = line.chars().collect();
|
|
|
|
let mut replace_pos = pos;
|
|
|
|
while replace_pos > 0 {
|
|
|
|
if line_chars[replace_pos - 1] == ' ' {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
replace_pos -= 1;
|
|
|
|
}
|
|
|
|
|
2019-05-18 16:06:01 +02:00
|
|
|
for command in commands.iter() {
|
|
|
|
let mut pos = replace_pos;
|
|
|
|
let mut matched = true;
|
|
|
|
if pos < line_chars.len() {
|
|
|
|
for chr in command.chars() {
|
|
|
|
if line_chars[pos] != chr {
|
|
|
|
matched = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pos += 1;
|
|
|
|
if pos == line_chars.len() {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if matched {
|
|
|
|
completions.push(completion::Pair {
|
2019-06-09 19:52:56 +02:00
|
|
|
display: command.clone(),
|
|
|
|
replacement: command.clone(),
|
2019-05-18 16:06:01 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-18 04:30:57 +02:00
|
|
|
Ok((replace_pos, completions))
|
2019-05-16 23:43:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn update(&self, line: &mut LineBuffer, start: usize, elected: &str) {
|
|
|
|
let end = line.pos();
|
|
|
|
line.replace(start..end, elected)
|
|
|
|
}
|
|
|
|
}
|