Support ~ (home directory) in completions.

This requires a bit of a hack in command completions, since we don't expand `~`
for the replacement, just long enough to get child entries.
This commit is contained in:
Jason Gedge 2020-09-01 18:10:29 -04:00 committed by Andrés N. Robalino
parent 569345e1d4
commit f9acb7a7a5
2 changed files with 31 additions and 5 deletions

View File

@ -1,5 +1,5 @@
use std::iter::FromIterator; use std::iter::FromIterator;
use std::path::Path; use std::path::{Path, PathBuf};
use indexmap::set::IndexSet; use indexmap::set::IndexSet;
@ -36,7 +36,24 @@ impl Completer {
let path_completer = crate::completion::path::Completer; let path_completer = crate::completion::path::Completer;
let path_results = path_completer.complete(ctx, partial); let path_results = path_completer.complete(ctx, partial);
suggestions.extend(path_results.into_iter().filter(|suggestion| { suggestions.extend(path_results.into_iter().filter(|suggestion| {
let path = Path::new(&suggestion.replacement); // TODO better path abstractions to avoid a mess like this
let path = {
#[cfg(feature = "directories")]
{
let home_prefix = format!("~{}", std::path::MAIN_SEPARATOR);
if let Some(mut home) = dirs::home_dir() {
home.push(suggestion.replacement.replacen(&home_prefix, "", 1));
home
} else {
PathBuf::from(&suggestion.replacement)
}
}
#[cfg(not(feature = "directories"))]
{
PathBuf::from(&suggestion.replacement)
}
};
path.is_dir() || is_executable(&path) path.is_dir() || is_executable(&path)
})); }));
} }

View File

@ -1,4 +1,4 @@
use std::path::Path; use std::path::PathBuf;
use crate::completion::{Context, Suggestion}; use crate::completion::{Context, Suggestion};
@ -17,9 +17,18 @@ impl Completer {
}; };
let base_dir = if base_dir_name == "" { let base_dir = if base_dir_name == "" {
Path::new(".") PathBuf::from(".")
} else if base_dir_name == format!("~{}", SEP) {
#[cfg(feature = "directories")]
{
dirs::home_dir().unwrap_or_else(|| PathBuf::from("~"))
}
#[cfg(not(feature = "directories"))]
{
PathBuf::from("~")
}
} else { } else {
Path::new(base_dir_name) PathBuf::from(base_dir_name)
}; };
if let Ok(result) = base_dir.read_dir() { if let Ok(result) = base_dir.read_dir() {