mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 00:13:21 +01:00
add $nu.data-dir
for completions and $nu.cache-dir
for other uses (#13122)
# Description This PR is an attempt to add a standard location for people to put completions in. I saw this topic come up again recently and IIRC we decided to create a standard location. I used the dirs-next crate to dictate where these locations are. I know some people won't like that but at least this gets the ball rolling in a direction that has a standard directory. This is what the default NU_LIB_DIRS looks like now in the default_env.nu. It should also be like this when starting nushell with `nu -n` ```nushell $env.NU_LIB_DIRS = [ ($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts ($nu.data-dir | path join 'completions') # default home for nushell completions ] ``` I also added these default folders to the `$nu` variable so now there is `$nu.data-path` and `$nu.cache-path`. ## Data Dir Default ![image](https://github.com/nushell/nushell/assets/343840/aeeb7cd6-17b4-43e8-bb6f-986a0c7fce23) While I was in there, I also decided to add a cache dir ## Cache Dir Default ![image](https://github.com/nushell/nushell/assets/343840/87dead66-4911-4f67-bfb2-acb16f386674) ### This is what the default looks like in Ubuntu. ![image](https://github.com/nushell/nushell/assets/343840/bca8eae8-8c18-47e8-b64f-3efe34f0004f) ### This is what it looks like with XDG_CACHE_HOME and XDG_DATA_HOME overridden ```nushell XDG_DATA_HOME=/tmp/data_home XDG_CACHE_HOME=/tmp/cache_home cargo r ``` ![image](https://github.com/nushell/nushell/assets/343840/fae86d50-9821-41f1-868e-3814eca3730b) ### This is what the defaults look like in Windows (username scrubbed to protect the innocent) ![image](https://github.com/nushell/nushell/assets/343840/3ebdb5cd-0150-448c-aff5-c57053e4788a) How my NU_LIB_DIRS is set in the images above ```nushell $env.NU_LIB_DIRS = [ ($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts '/Users/fdncred/src/nu_scripts' ($nu.config-path | path dirname) ($nu.data-dir | path join 'completions') # default home for nushell completions ] ``` Let the debate begin. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
b0d1b4b182
commit
0372e8c53c
@ -195,6 +195,7 @@ reedline = { workspace = true, features = ["bashisms", "sqlite"] }
|
|||||||
|
|
||||||
crossterm = { workspace = true }
|
crossterm = { workspace = true }
|
||||||
ctrlc = { workspace = true }
|
ctrlc = { workspace = true }
|
||||||
|
dirs-next = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
miette = { workspace = true, features = ["fancy-no-backtrace", "fancy"] }
|
miette = { workspace = true, features = ["fancy-no-backtrace", "fancy"] }
|
||||||
mimalloc = { version = "0.1.42", default-features = false, optional = true }
|
mimalloc = { version = "0.1.42", default-features = false, optional = true }
|
||||||
|
@ -763,11 +763,13 @@ fn variables_completions() {
|
|||||||
// Test completions for $nu
|
// Test completions for $nu
|
||||||
let suggestions = completer.complete("$nu.", 4);
|
let suggestions = completer.complete("$nu.", 4);
|
||||||
|
|
||||||
assert_eq!(15, suggestions.len());
|
assert_eq!(17, suggestions.len());
|
||||||
|
|
||||||
let expected: Vec<String> = vec![
|
let expected: Vec<String> = vec![
|
||||||
|
"cache-dir".into(),
|
||||||
"config-path".into(),
|
"config-path".into(),
|
||||||
"current-exe".into(),
|
"current-exe".into(),
|
||||||
|
"data-dir".into(),
|
||||||
"default-config-dir".into(),
|
"default-config-dir".into(),
|
||||||
"env-path".into(),
|
"env-path".into(),
|
||||||
"history-enabled".into(),
|
"history-enabled".into(),
|
||||||
|
@ -6,18 +6,36 @@ pub fn home_dir() -> Option<PathBuf> {
|
|||||||
dirs_next::home_dir()
|
dirs_next::home_dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the data directory for the current platform or XDG_DATA_HOME if specified.
|
||||||
|
pub fn data_dir() -> Option<PathBuf> {
|
||||||
|
match std::env::var("XDG_DATA_HOME").map(PathBuf::from) {
|
||||||
|
Ok(xdg_data) if xdg_data.is_absolute() => Some(canonicalize(&xdg_data).unwrap_or(xdg_data)),
|
||||||
|
_ => get_canonicalized_path(dirs_next::data_dir()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the cache directory for the current platform or XDG_CACHE_HOME if specified.
|
||||||
|
pub fn cache_dir() -> Option<PathBuf> {
|
||||||
|
match std::env::var("XDG_CACHE_HOME").map(PathBuf::from) {
|
||||||
|
Ok(xdg_cache) if xdg_cache.is_absolute() => {
|
||||||
|
Some(canonicalize(&xdg_cache).unwrap_or(xdg_cache))
|
||||||
|
}
|
||||||
|
_ => get_canonicalized_path(dirs_next::cache_dir()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the config directory for the current platform or XDG_CONFIG_HOME if specified.
|
||||||
pub fn config_dir() -> Option<PathBuf> {
|
pub fn config_dir() -> Option<PathBuf> {
|
||||||
match std::env::var("XDG_CONFIG_HOME").map(PathBuf::from) {
|
match std::env::var("XDG_CONFIG_HOME").map(PathBuf::from) {
|
||||||
Ok(xdg_config) if xdg_config.is_absolute() => {
|
Ok(xdg_config) if xdg_config.is_absolute() => {
|
||||||
Some(canonicalize(&xdg_config).unwrap_or(xdg_config))
|
Some(canonicalize(&xdg_config).unwrap_or(xdg_config))
|
||||||
}
|
}
|
||||||
_ => config_dir_old(),
|
_ => get_canonicalized_path(dirs_next::config_dir()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the old default config directory. Outside of Linux, this will ignore `XDG_CONFIG_HOME`
|
pub fn get_canonicalized_path(path: Option<PathBuf>) -> Option<PathBuf> {
|
||||||
pub fn config_dir_old() -> Option<PathBuf> {
|
let path = path?;
|
||||||
let path = dirs_next::config_dir()?;
|
|
||||||
Some(canonicalize(&path).unwrap_or(path))
|
Some(canonicalize(&path).unwrap_or(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,6 @@ mod trailing_slash;
|
|||||||
|
|
||||||
pub use components::components;
|
pub use components::components;
|
||||||
pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs};
|
pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs};
|
||||||
pub use helpers::{config_dir, config_dir_old, home_dir};
|
pub use helpers::{cache_dir, config_dir, data_dir, get_canonicalized_path, home_dir};
|
||||||
pub use tilde::expand_tilde;
|
pub use tilde::expand_tilde;
|
||||||
pub use trailing_slash::{has_trailing_slash, strip_trailing_slash};
|
pub use trailing_slash::{has_trailing_slash, strip_trailing_slash};
|
||||||
|
@ -149,6 +149,38 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
record.push(
|
||||||
|
"data-dir",
|
||||||
|
if let Some(path) = nu_path::data_dir() {
|
||||||
|
let mut canon_data_path = canonicalize_path(engine_state, &path);
|
||||||
|
canon_data_path.push("nushell");
|
||||||
|
Value::string(canon_data_path.to_string_lossy(), span)
|
||||||
|
} else {
|
||||||
|
Value::error(
|
||||||
|
ShellError::IOError {
|
||||||
|
msg: "Could not get data path".into(),
|
||||||
|
},
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
record.push(
|
||||||
|
"cache-dir",
|
||||||
|
if let Some(path) = nu_path::cache_dir() {
|
||||||
|
let mut canon_cache_path = canonicalize_path(engine_state, &path);
|
||||||
|
canon_cache_path.push("nushell");
|
||||||
|
Value::string(canon_cache_path.to_string_lossy(), span)
|
||||||
|
} else {
|
||||||
|
Value::error(
|
||||||
|
ShellError::IOError {
|
||||||
|
msg: "Could not get cache path".into(),
|
||||||
|
},
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
record.push("temp-path", {
|
record.push("temp-path", {
|
||||||
let canon_temp_path = canonicalize_path(engine_state, &std::env::temp_dir());
|
let canon_temp_path = canonicalize_path(engine_state, &std::env::temp_dir());
|
||||||
Value::string(canon_temp_path.to_string_lossy(), span)
|
Value::string(canon_temp_path.to_string_lossy(), span)
|
||||||
|
@ -77,6 +77,7 @@ $env.ENV_CONVERSIONS = {
|
|||||||
# The default for this is $nu.default-config-dir/scripts
|
# The default for this is $nu.default-config-dir/scripts
|
||||||
$env.NU_LIB_DIRS = [
|
$env.NU_LIB_DIRS = [
|
||||||
($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts
|
($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts
|
||||||
|
($nu.data-dir | path join 'completions') # default home for nushell completions
|
||||||
]
|
]
|
||||||
|
|
||||||
# Directories to search for plugin binaries when calling register
|
# Directories to search for plugin binaries when calling register
|
||||||
|
19
src/main.rs
19
src/main.rs
@ -104,7 +104,9 @@ fn main() -> Result<()> {
|
|||||||
default: nushell_config_path.display().to_string(),
|
default: nushell_config_path.display().to_string(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else if let Some(old_config) = nu_path::config_dir_old().map(|p| p.join("nushell")) {
|
} else if let Some(old_config) =
|
||||||
|
nu_path::get_canonicalized_path(dirs_next::config_dir()).map(|p| p.join("nushell"))
|
||||||
|
{
|
||||||
let xdg_config_empty = nushell_config_path
|
let xdg_config_empty = nushell_config_path
|
||||||
.read_dir()
|
.read_dir()
|
||||||
.map_or(true, |mut dir| dir.next().is_none());
|
.map_or(true, |mut dir| dir.next().is_none());
|
||||||
@ -125,13 +127,22 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let default_nushell_completions_path = if let Some(mut path) = nu_path::data_dir() {
|
||||||
|
path.push("nushell");
|
||||||
|
path.push("completions");
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
std::path::PathBuf::new()
|
||||||
|
};
|
||||||
|
|
||||||
let mut default_nu_lib_dirs_path = nushell_config_path.clone();
|
let mut default_nu_lib_dirs_path = nushell_config_path.clone();
|
||||||
default_nu_lib_dirs_path.push("scripts");
|
default_nu_lib_dirs_path.push("scripts");
|
||||||
engine_state.add_env_var(
|
engine_state.add_env_var(
|
||||||
"NU_LIB_DIRS".to_string(),
|
"NU_LIB_DIRS".to_string(),
|
||||||
Value::test_list(vec![Value::test_string(
|
Value::test_list(vec![
|
||||||
default_nu_lib_dirs_path.to_string_lossy(),
|
Value::test_string(default_nu_lib_dirs_path.to_string_lossy()),
|
||||||
)]),
|
Value::test_string(default_nushell_completions_path.to_string_lossy()),
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut default_nu_plugin_dirs_path = nushell_config_path;
|
let mut default_nu_plugin_dirs_path = nushell_config_path;
|
||||||
|
Loading…
Reference in New Issue
Block a user