mirror of
https://github.com/nushell/nushell.git
synced 2025-04-09 21:28:55 +02:00
fix(completion): dotnu_completion dir with space, expand tilde (#14983)
# Description This PR closes #14956, only one known issue on that list remains. # User-Facing Changes # Tests + Formatting new cases added # After Submitting
This commit is contained in:
parent
63fa6a6df7
commit
5291f978c2
@ -1,4 +1,5 @@
|
|||||||
use crate::completions::{file_path_completion, Completer, CompletionOptions};
|
use crate::completions::{file_path_completion, Completer, CompletionOptions};
|
||||||
|
use nu_path::expand_tilde;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
engine::{Stack, StateWorkingSet},
|
engine::{Stack, StateWorkingSet},
|
||||||
Span,
|
Span,
|
||||||
@ -28,7 +29,10 @@ impl Completer for DotNuCompletion {
|
|||||||
_pos: usize,
|
_pos: usize,
|
||||||
options: &CompletionOptions,
|
options: &CompletionOptions,
|
||||||
) -> Vec<SemanticSuggestion> {
|
) -> Vec<SemanticSuggestion> {
|
||||||
let prefix_str = String::from_utf8_lossy(prefix).replace('`', "");
|
let prefix_str = String::from_utf8_lossy(prefix);
|
||||||
|
let start_with_backquote = prefix_str.starts_with('`');
|
||||||
|
let end_with_backquote = prefix_str.ends_with('`');
|
||||||
|
let prefix_str = prefix_str.replace('`', "");
|
||||||
let mut search_dirs: Vec<PathBuf> = vec![];
|
let mut search_dirs: Vec<PathBuf> = vec![];
|
||||||
|
|
||||||
// If prefix_str is only a word we want to search in the current dir
|
// If prefix_str is only a word we want to search in the current dir
|
||||||
@ -46,12 +50,8 @@ impl Completer for DotNuCompletion {
|
|||||||
lib_dirs
|
lib_dirs
|
||||||
.as_list()
|
.as_list()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|it| {
|
.flat_map(|it| it.iter().filter_map(|x| x.to_path().ok()))
|
||||||
it.iter().map(|x| {
|
.map(expand_tilde)
|
||||||
x.to_path()
|
|
||||||
.expect("internal error: failed to convert lib path")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
@ -78,13 +78,12 @@ impl Completer for DotNuCompletion {
|
|||||||
|
|
||||||
// Fetch the files filtering the ones that ends with .nu
|
// Fetch the files filtering the ones that ends with .nu
|
||||||
// and transform them into suggestions
|
// and transform them into suggestions
|
||||||
|
|
||||||
let completions = file_path_completion(
|
let completions = file_path_completion(
|
||||||
span,
|
span,
|
||||||
partial,
|
partial,
|
||||||
&search_dirs
|
&search_dirs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| d.to_str().unwrap_or_default())
|
.filter_map(|d| d.to_str())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
options,
|
options,
|
||||||
working_set.permanent_state,
|
working_set.permanent_state,
|
||||||
@ -93,20 +92,35 @@ impl Completer for DotNuCompletion {
|
|||||||
completions
|
completions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
// Different base dir, so we list the .nu files or folders
|
// Different base dir, so we list the .nu files or folders
|
||||||
.filter(|it| it.path.ends_with(".nu") || it.path.ends_with(SEP))
|
.filter(|it| {
|
||||||
|
// for paths with spaces in them
|
||||||
|
let path = it.path.trim_end_matches('`');
|
||||||
|
path.ends_with(".nu") || path.ends_with(SEP)
|
||||||
|
})
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
let append_whitespace = x.path.ends_with(".nu");
|
let append_whitespace =
|
||||||
|
x.path.ends_with(".nu") && (!start_with_backquote || end_with_backquote);
|
||||||
// Re-calculate the span to replace
|
// Re-calculate the span to replace
|
||||||
let span_offset = if base_dir == "." {
|
let mut span_offset = 0;
|
||||||
0
|
let mut value = x.path.to_string();
|
||||||
} else {
|
// Complete only the last path component
|
||||||
base_dir.len() + 1
|
if base_dir != "." {
|
||||||
} + prefix.iter().take_while(|c| **c == b'`').count();
|
span_offset = base_dir.len() + 1
|
||||||
|
}
|
||||||
|
// Retain only one '`'
|
||||||
|
if start_with_backquote {
|
||||||
|
value = value.trim_start_matches('`').to_string();
|
||||||
|
span_offset += 1;
|
||||||
|
}
|
||||||
|
// Add the backquote back
|
||||||
|
if end_with_backquote && !value.ends_with('`') {
|
||||||
|
value.push('`');
|
||||||
|
}
|
||||||
let end = x.span.end - offset;
|
let end = x.span.end - offset;
|
||||||
let start = std::cmp::min(end, x.span.start - offset + span_offset);
|
let start = std::cmp::min(end, x.span.start - offset + span_offset);
|
||||||
SemanticSuggestion {
|
SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
value: x.path,
|
value,
|
||||||
style: x.style,
|
style: x.style,
|
||||||
span: reedline::Span { start, end },
|
span: reedline::Span { start, end },
|
||||||
append_whitespace,
|
append_whitespace,
|
||||||
|
@ -275,12 +275,30 @@ fn dotnu_completions() {
|
|||||||
|
|
||||||
// Test nested nu script
|
// Test nested nu script
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let completion_str = "use .\\dir_module\\sub_module\\".to_string();
|
let completion_str = "use `.\\dir_module\\".to_string();
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let completion_str = "use ./dir_module/sub_module/".to_string();
|
let completion_str = "use `./dir_module/".to_string();
|
||||||
let suggestions = completer.complete(&completion_str, completion_str.len());
|
let suggestions = completer.complete(&completion_str, completion_str.len());
|
||||||
|
|
||||||
match_suggestions(&vec!["sub.nu".into()], &suggestions);
|
match_suggestions(
|
||||||
|
&vec![
|
||||||
|
"mod.nu".into(),
|
||||||
|
#[cfg(windows)]
|
||||||
|
"sub module\\`".into(),
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
"sub module/`".into(),
|
||||||
|
],
|
||||||
|
&suggestions,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test nested nu script, with ending '`'
|
||||||
|
#[cfg(windows)]
|
||||||
|
let completion_str = "use `.\\dir_module\\sub module\\`".to_string();
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
let completion_str = "use `./dir_module/sub module/`".to_string();
|
||||||
|
let suggestions = completer.complete(&completion_str, completion_str.len());
|
||||||
|
|
||||||
|
match_suggestions(&vec!["sub.nu`".into()], &suggestions);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
"asdf.nu".into(),
|
"asdf.nu".into(),
|
||||||
|
Loading…
Reference in New Issue
Block a user