Keep a forward slash when autocomplete on Windows

When autocomplete path with `/` on Windows, paths remains with slash
instead of backslash(`\`).

If mixed both, path completion uses a last path seperator.
This commit is contained in:
Lyuha 2024-07-06 02:07:14 +09:00
parent 0178295363
commit 656975e15a
No known key found for this signature in database
GPG Key ID: 31F39D559E4A0754
2 changed files with 55 additions and 9 deletions

View File

@ -10,9 +10,7 @@ use nu_protocol::{
levenshtein_distance, Span,
};
use nu_utils::get_ls_colors;
use std::path::{
is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR,
};
use std::path::{is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP};
use super::SortBy;
@ -93,16 +91,16 @@ enum OriginalCwd {
}
impl OriginalCwd {
fn apply(&self, mut p: PathBuiltFromString) -> String {
fn apply(&self, mut p: PathBuiltFromString, path_separator: char) -> String {
match self {
Self::None => {}
Self::Home => p.parts.insert(0, "~".to_string()),
Self::Prefix(s) => p.parts.insert(0, s.clone()),
};
let mut ret = p.parts.join(MAIN_SEPARATOR_STR);
let mut ret = p.parts.join(&path_separator.to_string());
if p.isdir {
ret.push(SEP);
ret.push(path_separator);
}
ret
}
@ -133,6 +131,14 @@ pub fn complete_item(
) -> Vec<(nu_protocol::Span, String, Option<Style>)> {
let partial = surround_remove(partial);
let isdir = partial.ends_with(is_separator);
#[cfg(unix)]
let path_separator = SEP;
#[cfg(windows)]
let path_separator = partial
.chars()
.rfind(|c: &char| is_separator(*c))
.unwrap_or(SEP);
let cwd_pathbuf = Path::new(cwd).to_path_buf();
let ls_colors = (engine_state.config.use_ls_colors_completions
&& engine_state.config.use_ansi_coloring)
@ -195,7 +201,7 @@ pub fn complete_item(
)
.into_iter()
.map(|p| {
let path = original_cwd.apply(p);
let path = original_cwd.apply(p, path_separator);
let style = ls_colors.as_ref().map(|lsc| {
lsc.style_for_path_with_metadata(
&path,

View File

@ -32,7 +32,6 @@ fn completer() -> NuCompleter {
fn completer_strings() -> NuCompleter {
// Create a new engine
let (dir, _, mut engine, mut stack) = new_engine();
// Add record value as example
let record = r#"def animals [] { ["cat", "dog", "eel" ] }
def my-command [animal: string@animals] { print $animal }"#;
@ -258,6 +257,20 @@ fn file_completions() {
folder(dir.join(".hidden_folder")),
];
#[cfg(windows)]
{
let separator = '/';
let target_dir = format!("cp {dir_str}{separator}");
let slash_suggestions = completer.complete(&target_dir, target_dir.len());
let expected_slash_paths = expected_paths
.iter()
.map(|s| s.replace('\\', "/"))
.collect();
match_suggestions(expected_slash_paths, slash_suggestions);
}
// Match the results
match_suggestions(expected_paths, suggestions);
@ -272,12 +285,25 @@ fn file_completions() {
match_suggestions(expected_paths, suggestions);
// Test completions for hidden files
let target_dir = format!("ls {}/.", folder(dir.join(".hidden_folder")));
let target_dir = format!("ls {}{MAIN_SEPARATOR}.", folder(dir.join(".hidden_folder")));
let suggestions = completer.complete(&target_dir, target_dir.len());
let expected_paths: Vec<String> =
vec![file(dir.join(".hidden_folder").join(".hidden_subfile"))];
#[cfg(windows)]
{
let target_dir = format!("ls {}/.", folder(dir.join(".hidden_folder")));
let slash_suggestions = completer.complete(&target_dir, target_dir.len());
let expected_slash = expected_paths
.iter()
.map(|s| s.replace('\\', "/"))
.collect();
match_suggestions(expected_slash, slash_suggestions)
}
// Match the results
match_suggestions(expected_paths, suggestions);
}
@ -464,6 +490,7 @@ fn command_ls_with_filecompletion() {
match_suggestions(expected_paths, suggestions)
}
#[test]
fn command_open_with_filecompletion() {
let (_, _, engine, stack) = new_engine();
@ -794,6 +821,19 @@ fn folder_with_directorycompletions() {
folder(dir.join(".hidden_folder")),
];
#[cfg(windows)]
{
let target_dir = format!("cd {dir_str}/");
let slash_suggestions = completer.complete(&target_dir, target_dir.len());
let expected_slash_paths = expected_paths
.iter()
.map(|s| s.replace('\\', "/"))
.collect();
match_suggestions(expected_slash_paths, slash_suggestions);
}
// Match the results
match_suggestions(expected_paths, suggestions);
}