feat: add support for nu shell (#2847)
This commit is contained in:
parent
196cc8aa39
commit
cea1a1ceb1
|
@ -1,5 +1,7 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
@ -383,6 +385,16 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "directories-next"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"dirs-sys-next",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -394,16 +406,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs-next"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"dirs-sys-next",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-sys-next"
|
name = "dirs-sys-next"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -1692,7 +1694,7 @@ dependencies = [
|
||||||
"byte-unit",
|
"byte-unit",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"dirs-next",
|
"directories-next",
|
||||||
"gethostname",
|
"gethostname",
|
||||||
"git2",
|
"git2",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
|
|
@ -32,7 +32,7 @@ tls-vendored = ["native-tls/vendored"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.3"
|
clap = "2.33.3"
|
||||||
ansi_term = "0.12.1"
|
ansi_term = "0.12.1"
|
||||||
dirs-next = "2.0.0"
|
directories-next = "2.0.0"
|
||||||
git2 = { version = "0.13.20", default-features = false }
|
git2 = { version = "0.13.20", default-features = false }
|
||||||
toml = { version = "0.5.8", features = ["preserve_order"] }
|
toml = { version = "0.5.8", features = ["preserve_order"] }
|
||||||
rust-ini = "0.17.0"
|
rust-ini = "0.17.0"
|
||||||
|
|
14
README.md
14
README.md
|
@ -253,6 +253,20 @@ shown below. Can't see yours? Have a look at the [extra platform instructions](h
|
||||||
eval `starship init tcsh`
|
eval `starship init tcsh`
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Nushell
|
||||||
|
|
||||||
|
**Warning** This will change in the future. Only nu version v0.33 or higher is supported.
|
||||||
|
Add the following to your nu config file:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
startup = [
|
||||||
|
"mkdir ~/.cache/starship",
|
||||||
|
"starship init nu | save ~/.cache/starship/init.nu",
|
||||||
|
"source ~/.cache/starship/init.nu"
|
||||||
|
]
|
||||||
|
prompt = "starship_prompt"
|
||||||
|
```
|
||||||
|
|
||||||
## 🤝 Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
We are always looking for contributors of **all skill levels**! If you're looking to ease your way into the project, try out a [good first issue](https://github.com/starship/starship/labels/🌱%20good%20first%20issue).
|
We are always looking for contributors of **all skill levels**! If you're looking to ease your way into the project, try out a [good first issue](https://github.com/starship/starship/labels/🌱%20good%20first%20issue).
|
||||||
|
|
|
@ -129,3 +129,20 @@ description: Starship is the minimal, blazing fast, and extremely customizable p
|
||||||
|
|
||||||
eval `starship init tcsh`
|
eval `starship init tcsh`
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Nushell
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
This will change in the future.
|
||||||
|
Only nu version v0.33 or higher is supported.
|
||||||
|
:::
|
||||||
|
Add the following to your nu config file:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
startup = [
|
||||||
|
"mkdir ~/.cache/starship",
|
||||||
|
"starship init nu | save ~/.cache/starship/init.nu",
|
||||||
|
"source ~/.cache/starship/init.nu"
|
||||||
|
]
|
||||||
|
prompt = "starship_prompt"
|
||||||
|
```
|
||||||
|
|
|
@ -413,7 +413,7 @@ look at [this example](#with-custom-error-shape).
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
||||||
`error_symbol` is not supported on elvish shell.
|
`error_symbol` is not supported on elvish and nu shell.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -1487,7 +1487,7 @@ then the module will also show when there are 0 jobs running.
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
||||||
This module is not supported on tcsh.
|
This module is not supported on tcsh and nu.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -2624,7 +2624,7 @@ To enable it, set `disabled` to `false` in your configuration file.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
This module is not supported on elvish shell.
|
This module is not supported on elvish and nu shell.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::shadow;
|
use crate::shadow;
|
||||||
use crate::utils::exec_cmd;
|
use crate::utils::{self, exec_cmd};
|
||||||
|
|
||||||
|
use directories_next::ProjectDirs;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -191,7 +192,12 @@ fn get_terminal_info() -> TerminalInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config_path(shell: &str) -> Option<PathBuf> {
|
fn get_config_path(shell: &str) -> Option<PathBuf> {
|
||||||
dirs_next::home_dir().and_then(|home_dir| {
|
if shell == "nu" {
|
||||||
|
return ProjectDirs::from("org", "nushell", "nu")
|
||||||
|
.map(|project_dirs| project_dirs.config_dir().join("config.toml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::home_dir().and_then(|home_dir| {
|
||||||
match shell {
|
match shell {
|
||||||
"bash" => Some(".bashrc"),
|
"bash" => Some(".bashrc"),
|
||||||
"fish" => Some(".config/fish/config.fish"),
|
"fish" => Some(".config/fish/config.fish"),
|
||||||
|
@ -217,7 +223,7 @@ fn get_starship_config() -> String {
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.ok()
|
.ok()
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
dirs_next::home_dir().map(|mut home_dir| {
|
utils::home_dir().map(|mut home_dir| {
|
||||||
home_dir.push(".config/starship.toml");
|
home_dir.push(".config/starship.toml");
|
||||||
home_dir
|
home_dir
|
||||||
})
|
})
|
||||||
|
@ -276,7 +282,7 @@ mod tests {
|
||||||
fn test_get_config_path() {
|
fn test_get_config_path() {
|
||||||
let config_path = get_config_path("bash");
|
let config_path = get_config_path("bash");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dirs_next::home_dir().unwrap().join(".bashrc"),
|
utils::home_dir().unwrap().join(".bashrc"),
|
||||||
config_path.unwrap()
|
config_path.unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ impl StarshipConfig {
|
||||||
} else {
|
} else {
|
||||||
// Default to using ~/.config/starship.toml
|
// Default to using ~/.config/starship.toml
|
||||||
log::debug!("STARSHIP_CONFIG is not set");
|
log::debug!("STARSHIP_CONFIG is not set");
|
||||||
let config_path = dirs_next::home_dir()?.join(".config/starship.toml");
|
let config_path = utils::home_dir()?.join(".config/starship.toml");
|
||||||
let config_path_str = config_path.to_str()?.to_owned();
|
let config_path_str = config_path.to_str()?.to_owned();
|
||||||
log::debug!("Using default config path: {}", config_path_str);
|
log::debug!("Using default config path: {}", config_path_str);
|
||||||
config_path_str
|
config_path_str
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub struct ShellConfig<'a> {
|
||||||
pub ion_indicator: &'a str,
|
pub ion_indicator: &'a str,
|
||||||
pub elvish_indicator: &'a str,
|
pub elvish_indicator: &'a str,
|
||||||
pub tcsh_indicator: &'a str,
|
pub tcsh_indicator: &'a str,
|
||||||
|
pub nu_indicator: &'a str,
|
||||||
pub unknown_indicator: &'a str,
|
pub unknown_indicator: &'a str,
|
||||||
pub disabled: bool,
|
pub disabled: bool,
|
||||||
}
|
}
|
||||||
|
@ -28,6 +29,7 @@ impl<'a> Default for ShellConfig<'a> {
|
||||||
ion_indicator: "ion",
|
ion_indicator: "ion",
|
||||||
elvish_indicator: "esh",
|
elvish_indicator: "esh",
|
||||||
tcsh_indicator: "tsh",
|
tcsh_indicator: "tsh",
|
||||||
|
nu_indicator: "nu",
|
||||||
unknown_indicator: "",
|
unknown_indicator: "",
|
||||||
disabled: true,
|
disabled: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::process::Command;
|
||||||
|
|
||||||
use crate::config::RootModuleConfig;
|
use crate::config::RootModuleConfig;
|
||||||
use crate::config::StarshipConfig;
|
use crate::config::StarshipConfig;
|
||||||
|
use crate::utils;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use toml::map::Map;
|
use toml::map::Map;
|
||||||
|
@ -178,7 +179,7 @@ fn get_config_path() -> OsString {
|
||||||
if let Some(config_path) = env::var_os("STARSHIP_CONFIG") {
|
if let Some(config_path) = env::var_os("STARSHIP_CONFIG") {
|
||||||
return config_path;
|
return config_path;
|
||||||
}
|
}
|
||||||
dirs_next::home_dir()
|
utils::home_dir()
|
||||||
.expect("couldn't find home directory")
|
.expect("couldn't find home directory")
|
||||||
.join(".config")
|
.join(".config")
|
||||||
.join("starship.toml")
|
.join("starship.toml")
|
||||||
|
|
|
@ -3,8 +3,8 @@ use crate::module::Module;
|
||||||
use crate::utils::{exec_cmd, CommandOutput};
|
use crate::utils::{exec_cmd, CommandOutput};
|
||||||
|
|
||||||
use crate::modules;
|
use crate::modules;
|
||||||
|
use crate::utils::{self, home_dir};
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use dirs_next::home_dir;
|
|
||||||
use git2::{ErrorCode::UnbornBranch, Repository, RepositoryState};
|
use git2::{ErrorCode::UnbornBranch, Repository, RepositoryState};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
@ -168,7 +168,7 @@ impl<'a> Context<'a> {
|
||||||
pub fn expand_tilde(dir: PathBuf) -> PathBuf {
|
pub fn expand_tilde(dir: PathBuf) -> PathBuf {
|
||||||
if dir.starts_with("~") {
|
if dir.starts_with("~") {
|
||||||
let without_home = dir.strip_prefix("~").unwrap();
|
let without_home = dir.strip_prefix("~").unwrap();
|
||||||
return dirs_next::home_dir().unwrap().join(without_home);
|
return utils::home_dir().unwrap().join(without_home);
|
||||||
}
|
}
|
||||||
dir
|
dir
|
||||||
}
|
}
|
||||||
|
@ -256,6 +256,7 @@ impl<'a> Context<'a> {
|
||||||
"zsh" => Shell::Zsh,
|
"zsh" => Shell::Zsh,
|
||||||
"elvish" => Shell::Elvish,
|
"elvish" => Shell::Elvish,
|
||||||
"tcsh" => Shell::Tcsh,
|
"tcsh" => Shell::Tcsh,
|
||||||
|
"nu" => Shell::Nu,
|
||||||
_ => Shell::Unknown,
|
_ => Shell::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,6 +493,7 @@ pub enum Shell {
|
||||||
Zsh,
|
Zsh,
|
||||||
Elvish,
|
Elvish,
|
||||||
Tcsh,
|
Tcsh,
|
||||||
|
Nu,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +623,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn context_constructor_should_fall_back_to_tilde_replacement_when_canonicalization_fails() {
|
fn context_constructor_should_fall_back_to_tilde_replacement_when_canonicalization_fails() {
|
||||||
use dirs_next::home_dir;
|
use utils::home_dir;
|
||||||
|
|
||||||
// Mock navigation to a directory which does not exist on disk
|
// Mock navigation to a directory which does not exist on disk
|
||||||
let test_path = Path::new("~/path_which_does_not_exist").to_path_buf();
|
let test_path = Path::new("~/path_which_does_not_exist").to_path_buf();
|
||||||
|
|
|
@ -168,6 +168,7 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
|
||||||
r#"eval `({} init tcsh --print-full-init)`"#,
|
r#"eval `({} init tcsh --print-full-init)`"#,
|
||||||
starship.sprint_posix()?
|
starship.sprint_posix()?
|
||||||
),
|
),
|
||||||
|
"nu" => print_script(NU_INIT, &StarshipPath::init()?.sprint_posix()?),
|
||||||
_ => {
|
_ => {
|
||||||
let quoted_arg = shell_words::quote(shell_basename);
|
let quoted_arg = shell_words::quote(shell_basename);
|
||||||
println!(
|
println!(
|
||||||
|
@ -180,6 +181,7 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
|
||||||
* powershell\\n\
|
* powershell\\n\
|
||||||
* tcsh\\n\
|
* tcsh\\n\
|
||||||
* zsh\\n\
|
* zsh\\n\
|
||||||
|
* nu\\n\
|
||||||
\\n\
|
\\n\
|
||||||
Please open an issue in the starship repo if you would like to \
|
Please open an issue in the starship repo if you would like to \
|
||||||
see support for %s:\\nhttps://github.com/starship/starship/issues/new\\n\\n\" {0} {0}",
|
see support for %s:\\nhttps://github.com/starship/starship/issues/new\\n\\n\" {0} {0}",
|
||||||
|
@ -248,6 +250,8 @@ const ELVISH_INIT: &str = include_str!("starship.elv");
|
||||||
|
|
||||||
const TCSH_INIT: &str = include_str!("starship.tcsh");
|
const TCSH_INIT: &str = include_str!("starship.tcsh");
|
||||||
|
|
||||||
|
const NU_INIT: &str = include_str!("starship.nu");
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
let-env STARSHIP_SHELL = "nu"
|
||||||
|
let-env STARSHIP_SESSION = (random chars -l 16)
|
||||||
|
|
||||||
|
def starship_prompt [] {
|
||||||
|
# jobs are not supported
|
||||||
|
# status is not supported
|
||||||
|
^::STARSHIP:: prompt --cmd-duration $nu.env.CMD_DURATION_MS
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::utils;
|
||||||
use ansi_term::Color;
|
use ansi_term::Color;
|
||||||
use log::{Level, LevelFilter, Metadata, Record};
|
use log::{Level, LevelFilter, Metadata, Record};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
@ -22,7 +23,7 @@ impl Default for StarshipLogger {
|
||||||
let log_dir = env::var_os("STARSHIP_CACHE")
|
let log_dir = env::var_os("STARSHIP_CACHE")
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
dirs_next::home_dir()
|
utils::home_dir()
|
||||||
.expect("Unable to find home directory")
|
.expect("Unable to find home directory")
|
||||||
.join(".cache/starship")
|
.join(".cache/starship")
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,7 +41,7 @@ fn main() {
|
||||||
let shell_arg = Arg::with_name("shell")
|
let shell_arg = Arg::with_name("shell")
|
||||||
.value_name("SHELL")
|
.value_name("SHELL")
|
||||||
.help(
|
.help(
|
||||||
"The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion, elvish, tcsh",
|
"The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion, elvish, tcsh, nu",
|
||||||
)
|
)
|
||||||
.required(true);
|
.required(true);
|
||||||
|
|
||||||
|
|
|
@ -298,8 +298,8 @@ fn to_fish_style(pwd_dir_length: usize, dir_string: String, truncated_dir_string
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test::ModuleRenderer;
|
use crate::test::ModuleRenderer;
|
||||||
|
use crate::utils::home_dir;
|
||||||
use ansi_term::Color;
|
use ansi_term::Color;
|
||||||
use dirs_next::home_dir;
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
use std::os::unix::fs::symlink;
|
use std::os::unix::fs::symlink;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
Shell::Ion => Some(config.ion_indicator),
|
Shell::Ion => Some(config.ion_indicator),
|
||||||
Shell::Elvish => Some(config.elvish_indicator),
|
Shell::Elvish => Some(config.elvish_indicator),
|
||||||
Shell::Tcsh => Some(config.tcsh_indicator),
|
Shell::Tcsh => Some(config.tcsh_indicator),
|
||||||
|
Shell::Nu => Some(config.nu_indicator),
|
||||||
Shell::Unknown => Some(config.unknown_indicator),
|
Shell::Unknown => Some(config.unknown_indicator),
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -249,6 +250,35 @@ mod tests {
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_nu_default_format() {
|
||||||
|
let expected = Some(format!("{} ", "nu"));
|
||||||
|
let actual = ModuleRenderer::new("shell")
|
||||||
|
.shell(Shell::Nu)
|
||||||
|
.config(toml::toml! {
|
||||||
|
[shell]
|
||||||
|
disabled = false
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_nu_custom_format() {
|
||||||
|
let expected = Some(format!("{} ", Color::Cyan.bold().paint("nu")));
|
||||||
|
let actual = ModuleRenderer::new("shell")
|
||||||
|
.shell(Shell::Nu)
|
||||||
|
.config(toml::toml! {
|
||||||
|
[shell]
|
||||||
|
nu_indicator = "[nu](bold cyan)"
|
||||||
|
disabled = false
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_custom_format_conditional_indicator_match() {
|
fn test_custom_format_conditional_indicator_match() {
|
||||||
let expected = Some(format!("{} ", "B"));
|
let expected = Some(format!("{} ", "B"));
|
||||||
|
|
|
@ -2,7 +2,7 @@ use process_control::{ChildExt, Timeout};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
use std::io::Result;
|
use std::io::Result;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
@ -414,6 +414,10 @@ fn render_time_component((component, suffix): (&u128, &&str)) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn home_dir() -> Option<PathBuf> {
|
||||||
|
directories_next::BaseDirs::new().map(|base_dirs| base_dirs.home_dir().to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Reference in New Issue