Skip to content

Commit

Permalink
Support vendor and user completions
Browse files Browse the repository at this point in the history
  • Loading branch information
jcgruenhage committed Dec 22, 2023
1 parent 109f629 commit 6b93bb2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/nu-path/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dirs-next = "2.0"

[target.'cfg(windows)'.dependencies]
omnipath = "0.1"
winapi = "0.3"
dirs-sys-next = "0.1"

[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))'.dependencies]
pwd = "1.3"
36 changes: 36 additions & 0 deletions crates/nu-path/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,42 @@ pub fn config_dir() -> Option<PathBuf> {
dirs_next::config_dir()
}

pub fn vendor_completions_dirs() -> Vec<PathBuf> {
let vendor_completions_fn = |mut path: PathBuf| {
path.push("nushell");
path.push("completions");
path
};
let mut dirs = Vec::new();

// default global directory
#[cfg(not(target_os = "windows"))]
let global_default = Some(PathBuf::from("/usr/share"));
#[cfg(target_os = "windows")]
let global_default = dirs_sys_next::known_folder(&winapi::um::knownfolders::FOLDERID_ProgramData);

// global directory
if let Some(global) = std::env::var("NU_VENDOR_COMPLETIONS_DIR")
.ok()
.or(option_env!("NU_VENDOR_COMPLETIONS_DIR").map(String::from))
.map(PathBuf::from)
.or(global_default.map(vendor_completions_fn))
{
dirs.push(global);
}

// local directory of the current user
if let Some(data_dir) = std::env::var("NU_COMPLETIONS_DIR")
.ok()
.map(PathBuf::from)
.or_else(|| dirs_next::data_dir().map(vendor_completions_fn))
{
dirs.push(data_dir);
}

dirs
}

#[cfg(windows)]
pub fn canonicalize(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
path.canonicalize()?.to_winuser_path()
Expand Down
2 changes: 1 addition & 1 deletion crates/nu-path/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ mod tilde;
mod util;

pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path};
pub use helpers::{config_dir, home_dir};
pub use helpers::{config_dir, home_dir, vendor_completions_dirs};
pub use tilde::expand_tilde;
pub use util::trim_trailing_slash;
19 changes: 19 additions & 0 deletions crates/nu-utils/src/sample_config/default_env.nu
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,25 @@ $env.ENV_CONVERSIONS = {
}
}

# Completions distributed by package managers are sourced from a global vendor
# completions directory If you want to override the default, you can do so like
# this:
#
# $env.NU_VENDOR_COMPLETIONS_DIR = ...
#
# The default is /usr/share/nushell/vendor_completions.d on Linux and MacOS,
# and %ProgramData%\nushell\vendor_completions.d on Windows
#
# There's a similar path for completions installed by the user, which can be
# overridden like so:
#
# $env.NU_COMPLETIONS_DIR = ...
#
# The default here is $XDG_DATA_HOME/nushell/vendor_completions.d on Linux,
# falling back to $HOME/.local/share for $XDG_DATA_HOME if it's not set,
# $HOME/Library/Application Support/nushell/vendor_completions.d on MacOS,
# and %RoamingAppData%\nushell\vendor_completions.d on Windows.

# Directories to search for scripts when calling source or use
# The default for this is $nu.default-config-dir/scripts
$env.NU_LIB_DIRS = [
Expand Down
18 changes: 18 additions & 0 deletions src/config_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) fn read_config_file(
config_file: Option<Spanned<String>>,
is_env_config: bool,
) {
read_vendor_completions(engine_state, stack);
// Load config startup file
if let Some(file) = config_file {
let working_set = StateWorkingSet::new(engine_state);
Expand Down Expand Up @@ -123,6 +124,23 @@ pub(crate) fn read_loginshell_file(engine_state: &mut EngineState, stack: &mut S
info!("read_loginshell_file {}:{}:{}", file!(), line!(), column!());
}

pub(crate) fn read_vendor_completions(engine_state: &mut EngineState, stack: &mut Stack) {
nu_path::vendor_completions_dirs()
.into_iter()
.filter_map(|dir| dir.read_dir().ok())
.flatten()
.filter_map(|entry| entry.ok())
.map(|entry| entry.path())
.filter(|entry| entry.is_file())
.filter(|entry| {
entry
.extension()
.filter(|extension| extension.to_str() == Some("nu"))
.is_some()
})
.for_each(|entry| eval_config_contents(entry, engine_state, stack));
}

pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut Stack) {
let config_file = get_default_env();
eval_source(
Expand Down

0 comments on commit 6b93bb2

Please sign in to comment.