|
|
@ -422,6 +422,47 @@ pub mod completers {
|
|
|
|
Accept,
|
|
|
|
Accept,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn best_match(opt1: &str, opt2: &str, input: &str) -> std::cmp::Ordering {
|
|
|
|
|
|
|
|
let min_len = std::cmp::min(std::cmp::min(opt1.len(), opt2.len()), input.len());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut opt1vals = (0, false);
|
|
|
|
|
|
|
|
let mut opt2vals = (0, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i in 0..min_len {
|
|
|
|
|
|
|
|
if opt1vals.1 && opt2vals.1 {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !opt1vals.1 {
|
|
|
|
|
|
|
|
if opt1[i..=i] == input[i..=i] {
|
|
|
|
|
|
|
|
opt1vals.0 += 1;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
opt1vals.1 = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !opt2vals.1 {
|
|
|
|
|
|
|
|
if opt2[i..=i] == input[i..=i] {
|
|
|
|
|
|
|
|
opt2vals.0 += 1;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
opt2vals.1 = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let ord = opt2vals.0.cmp(&opt1vals.0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ord == std::cmp::Ordering::Equal {
|
|
|
|
|
|
|
|
if opt1.len() < opt2.len() {
|
|
|
|
|
|
|
|
return std::cmp::Ordering::Less;
|
|
|
|
|
|
|
|
} else if opt1.len() > opt2.len() {
|
|
|
|
|
|
|
|
return std::cmp::Ordering::Greater;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ord
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: we could return an iter/lazy thing so it can fetch as many as it needs.
|
|
|
|
// TODO: we could return an iter/lazy thing so it can fetch as many as it needs.
|
|
|
|
fn filename_impl<F>(
|
|
|
|
fn filename_impl<F>(
|
|
|
|
_editor: &Editor,
|
|
|
|
_editor: &Editor,
|
|
|
@ -437,6 +478,10 @@ pub mod completers {
|
|
|
|
use ignore::WalkBuilder;
|
|
|
|
use ignore::WalkBuilder;
|
|
|
|
use std::path::Path;
|
|
|
|
use std::path::Path;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let input_filename = input
|
|
|
|
|
|
|
|
.split(std::path::MAIN_SEPARATOR)
|
|
|
|
|
|
|
|
.last()
|
|
|
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
let is_tilde = input == "~";
|
|
|
|
let is_tilde = input == "~";
|
|
|
|
let path = helix_stdx::path::expand_tilde(Path::new(input));
|
|
|
|
let path = helix_stdx::path::expand_tilde(Path::new(input));
|
|
|
|
|
|
|
|
|
|
|
@ -509,12 +554,15 @@ pub mod completers {
|
|
|
|
// if empty, return a list of dirs and files in current dir
|
|
|
|
// if empty, return a list of dirs and files in current dir
|
|
|
|
if let Some(file_name) = file_name {
|
|
|
|
if let Some(file_name) = file_name {
|
|
|
|
let range = (input.len().saturating_sub(file_name.len()))..;
|
|
|
|
let range = (input.len().saturating_sub(file_name.len()))..;
|
|
|
|
fuzzy_match(&file_name, files, true)
|
|
|
|
let mut files: Vec<_> = fuzzy_match(&file_name, files, true)
|
|
|
|
.into_iter()
|
|
|
|
.into_iter()
|
|
|
|
.map(|(name, _)| (range.clone(), name))
|
|
|
|
.map(|(name, _)| (range.clone(), name))
|
|
|
|
.collect()
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: complete to longest common match
|
|
|
|
files.sort_unstable_by(|(_, path1), (_, path2)| {
|
|
|
|
|
|
|
|
best_match(path1, path2, input_filename)
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
files
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
let mut files: Vec<_> = files.map(|file| (end.clone(), file)).collect();
|
|
|
|
let mut files: Vec<_> = files.map(|file| (end.clone(), file)).collect();
|
|
|
|
files.sort_unstable_by(|(_, path1), (_, path2)| path1.cmp(path2));
|
|
|
|
files.sort_unstable_by(|(_, path1), (_, path2)| path1.cmp(path2));
|
|
|
|