feat: add support for xonsh (#2807)

* feat: add support for xonsh

* xonsh: add STARSHIP_SESSION_KEY

* xonsh: implement STARSHIP_SESSION_KEY in xonsh

* docs: mention tcsh, elvish, and nu in more places

* xonsh: change STARSHIP_SESSION_KEY implementation

See https://github.com/starship/starship/pull/2807#discussion_r667064149

* xonsh: fix jobs implementation

* xonsh: do not silently discard stderr from starship
This commit is contained in:
Jeremy Schlatter 2021-07-16 12:25:01 -07:00 committed by GitHub
parent 1eaf996a36
commit b1dcd5aecd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 99 additions and 5 deletions

View File

@ -251,6 +251,15 @@ shown below. Can't see yours? Have a look at the [extra platform instructions](h
# ~/.tcshrc # ~/.tcshrc
eval `starship init tcsh` eval `starship init tcsh`
#### Xonsh
Add the following to the end of `~/.xonshrc`:
```sh
# ~/.xonshrc
execx($(starship init xonsh))
``` ```
#### Nushell #### Nushell

View File

@ -50,13 +50,13 @@ module.exports = {
head: [ head: [
["link", { rel: "icon", href: "/icon.png" }], ["link", { rel: "icon", href: "/icon.png" }],
["meta", { property: "og:title", content: "Starship: Cross-Shell Prompt" }], ["meta", { property: "og:title", content: "Starship: Cross-Shell Prompt" }],
["meta", { property: "og:description", content: "Starship is the minimal, blazing fast, and extremely customizable prompt for any shell! Shows the information you need, while staying sleek and minimal. Quick installation available for Bash, Fish, ZSH, Ion, and Powershell."}], ["meta", { property: "og:description", content: "Starship is the minimal, blazing fast, and extremely customizable prompt for any shell! Shows the information you need, while staying sleek and minimal. Quick installation available for Bash, Fish, ZSH, Ion, Tcsh, Elvish, Nu, Xonsh, and Powershell."}],
["meta", { property: "og:type", content: "website" }], ["meta", { property: "og:type", content: "website" }],
["meta", { property: "og:url", content: "https://starship.rs/" }], ["meta", { property: "og:url", content: "https://starship.rs/" }],
["meta", { property: "og:image", content: "https://starship.rs/icon.png" }], ["meta", { property: "og:image", content: "https://starship.rs/icon.png" }],
["meta", { name: "twitter:card", content: "summary"}], ["meta", { name: "twitter:card", content: "summary"}],
["meta", { name: "twitter:title", content: "Starship: Cross-Shell Prompt"}], ["meta", { name: "twitter:title", content: "Starship: Cross-Shell Prompt"}],
["meta", { name: "twitter:description", content: "Starship is the minimal, blazing fast, and extremely customizable prompt for any shell! Shows the information you need, while staying sleek and minimal. Quick installation available for Bash, Fish, ZSH, Ion, and Powershell."}], ["meta", { name: "twitter:description", content: "Starship is the minimal, blazing fast, and extremely customizable prompt for any shell! Shows the information you need, while staying sleek and minimal. Quick installation available for Bash, Fish, ZSH, Ion, Tcsh, Elvish, Nu, Xonsh, and Powershell."}],
["meta", { name: "twitter:image", content: "https://starship.rs/icon.png"}], ["meta", { name: "twitter:image", content: "https://starship.rs/icon.png"}],
["meta", { name: "twitter:alt", content: "Starship: Cross-Shell Prompt"}], ["meta", { name: "twitter:alt", content: "Starship: Cross-Shell Prompt"}],
], ],

View File

@ -16,7 +16,7 @@ footer: ISC Licensed | Copyright © 2019-present Starship Contributors
# Used for the description meta tag, for SEO # Used for the description meta tag, for SEO
metaTitle: "Starship: Cross-Shell Prompt" metaTitle: "Starship: Cross-Shell Prompt"
description: Starship is the minimal, blazing fast, and extremely customizable prompt for any shell! Shows the information you need, while staying sleek and minimal. Quick installation available for Bash, Fish, ZSH, Ion, and PowerShell. description: Starship is the minimal, blazing fast, and extremely customizable prompt for any shell! Shows the information you need, while staying sleek and minimal. Quick installation available for Bash, Fish, ZSH, Ion, Tcsh, Elvish, Nu, Xonsh, and PowerShell.
--- ---
<div class="center"> <div class="center">
@ -106,6 +106,7 @@ description: Starship is the minimal, blazing fast, and extremely customizable p
eval $(starship init ion) eval $(starship init ion)
``` ```
#### Elvish #### Elvish
::: warning ::: warning
@ -130,7 +131,7 @@ description: Starship is the minimal, blazing fast, and extremely customizable p
eval `starship init tcsh` eval `starship init tcsh`
``` ```
#### Nushell #### Nushell
::: warning ::: warning
This will change in the future. This will change in the future.
@ -147,3 +148,13 @@ description: Starship is the minimal, blazing fast, and extremely customizable p
] ]
prompt = "starship_prompt" prompt = "starship_prompt"
``` ```
#### Xonsh
Add the following to the end of `~/.xonshrc`:
```sh
# ~/.xonshrc
execx($(starship init xonsh))
```

View File

@ -2587,6 +2587,7 @@ To enable it, set `disabled` to `false` in your configuration file.
| `ion_indicator` | `ion` | A format string used to represent ion. | | `ion_indicator` | `ion` | A format string used to represent ion. |
| `elvish_indicator` | `esh` | A format string used to represent elvish. | | `elvish_indicator` | `esh` | A format string used to represent elvish. |
| `tcsh_indicator` | `tsh` | A format string used to represent tcsh. | | `tcsh_indicator` | `tsh` | A format string used to represent tcsh. |
| `xonsh_indicator` | `xsh` | A format string used to represent xonsh. |
| `unknown_indicator` | | The default value to be displayed when the shell is unknown. | | `unknown_indicator` | | The default value to be displayed when the shell is unknown. |
| `format` | `$indicator ` | The format for the module. | | `format` | `$indicator ` | The format for the module. |
| `disabled` | `true` | Disables the `shell` module. | | `disabled` | `true` | Disables the `shell` module. |

View File

@ -456,4 +456,10 @@ info "Please follow the steps for your shell to complete the installation:
Add the following to the end of ${BOLD}~/.tcshrc${NO_COLOR}: Add the following to the end of ${BOLD}~/.tcshrc${NO_COLOR}:
eval \`starship init tcsh\` eval \`starship init tcsh\`
${BOLD}${UNDERLINE}Xonsh${NO_COLOR}
Add the following to the end of ${BOLD}~/.xonshrc${NO_COLOR}:
execx($(starship init xonsh))
" "

View File

@ -42,6 +42,12 @@ description: |
`Invoke-Expression (&starship init powershell)` `Invoke-Expression (&starship init powershell)`
### Xonsh
Add the following to the end of ~/.xonshrc:
execx($(starship init xonsh))
grade: stable grade: stable
confinement: strict confinement: strict

View File

@ -212,6 +212,7 @@ fn get_config_path(shell: &str) -> Option<PathBuf> {
"zsh" => Some(".zshrc"), "zsh" => Some(".zshrc"),
"elvish" => Some(".elvish/rc.elv"), "elvish" => Some(".elvish/rc.elv"),
"tcsh" => Some(".tcshrc"), "tcsh" => Some(".tcshrc"),
"xonsh" => Some(".xonshrc"),
_ => None, _ => None,
} }
.map(|path| home_dir.join(path)) .map(|path| home_dir.join(path))

View File

@ -14,6 +14,7 @@ pub struct ShellConfig<'a> {
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 nu_indicator: &'a str,
pub xonsh_indicator: &'a str,
pub unknown_indicator: &'a str, pub unknown_indicator: &'a str,
pub disabled: bool, pub disabled: bool,
} }
@ -30,6 +31,7 @@ impl<'a> Default for ShellConfig<'a> {
elvish_indicator: "esh", elvish_indicator: "esh",
tcsh_indicator: "tsh", tcsh_indicator: "tsh",
nu_indicator: "nu", nu_indicator: "nu",
xonsh_indicator: "xsh",
unknown_indicator: "", unknown_indicator: "",
disabled: true, disabled: true,
} }

View File

@ -257,6 +257,7 @@ impl<'a> Context<'a> {
"elvish" => Shell::Elvish, "elvish" => Shell::Elvish,
"tcsh" => Shell::Tcsh, "tcsh" => Shell::Tcsh,
"nu" => Shell::Nu, "nu" => Shell::Nu,
"xonsh" => Shell::Xonsh,
_ => Shell::Unknown, _ => Shell::Unknown,
} }
} }
@ -494,6 +495,7 @@ pub enum Shell {
Elvish, Elvish,
Tcsh, Tcsh,
Nu, Nu,
Xonsh,
Unknown, Unknown,
} }

View File

@ -168,6 +168,10 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
starship.sprint_posix()? starship.sprint_posix()?
), ),
"nu" => print_script(NU_INIT, &StarshipPath::init()?.sprint_posix()?), "nu" => print_script(NU_INIT, &StarshipPath::init()?.sprint_posix()?),
"xonsh" => print!(
r#"execx($({} init xonsh --print-full-init))"#,
starship.sprint_posix()?
),
_ => { _ => {
let quoted_arg = shell_words::quote(shell_basename); let quoted_arg = shell_words::quote(shell_basename);
println!( println!(
@ -181,6 +185,7 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
* tcsh\\n\ * tcsh\\n\
* zsh\\n\ * zsh\\n\
* nu\\n\ * nu\\n\
* xonsh\\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}",
@ -204,6 +209,7 @@ pub fn init_main(shell_name: &str) -> io::Result<()> {
"ion" => print_script(ION_INIT, &starship_path.sprint()?), "ion" => print_script(ION_INIT, &starship_path.sprint()?),
"elvish" => print_script(ELVISH_INIT, &starship_path.sprint_posix()?), "elvish" => print_script(ELVISH_INIT, &starship_path.sprint_posix()?),
"tcsh" => print_script(TCSH_INIT, &starship_path.sprint_posix()?), "tcsh" => print_script(TCSH_INIT, &starship_path.sprint_posix()?),
"xonsh" => print_script(XONSH_INIT, &starship_path.sprint_posix()?),
_ => { _ => {
println!( println!(
"printf \"Shell name detection failed on phase two init.\\n\ "printf \"Shell name detection failed on phase two init.\\n\
@ -251,6 +257,8 @@ const TCSH_INIT: &str = include_str!("starship.tcsh");
const NU_INIT: &str = include_str!("starship.nu"); const NU_INIT: &str = include_str!("starship.nu");
const XONSH_INIT: &str = include_str!("starship.xsh");
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

17
src/init/starship.xsh Normal file
View File

@ -0,0 +1,17 @@
import uuid
def starship_prompt():
last_cmd = __xonsh__.history[-1] if __xonsh__.history else None
status = last_cmd.rtn if last_cmd else 0
# I believe this is equivalent to xonsh.jobs.get_next_job_number() for our purposes,
# but we can't use that function because of https://gitter.im/xonsh/xonsh?at=60e8832d82dd9050f5e0c96a
jobs = sum(1 for job in __xonsh__.all_jobs.values() if job['obj'] and job['obj'].poll() is None)
duration = round((last_cmd.ts[1] - last_cmd.ts[0]) * 1000) if last_cmd else 0
# The `| cat` is a workaround for https://github.com/xonsh/xonsh/issues/3786. See https://github.com/starship/starship/pull/2807#discussion_r667316323.
return $(::STARSHIP:: prompt --status=@(status) --jobs=@(jobs) --cmd-duration=@(duration) | cat)
$PROMPT = starship_prompt
$STARSHIP_SHELL = "xonsh"
$STARSHIP_SESSION_KEY = uuid.uuid4().hex

View File

@ -43,7 +43,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, nu", "The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion, elvish, tcsh, nu, xonsh",
) )
.required(true); .required(true);

View File

@ -25,6 +25,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
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::Nu => Some(config.nu_indicator),
Shell::Xonsh => Some(config.xonsh_indicator),
Shell::Unknown => Some(config.unknown_indicator), Shell::Unknown => Some(config.unknown_indicator),
}, },
_ => None, _ => None,
@ -37,6 +38,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
"ion_indicator" => Some(Ok(config.ion_indicator)), "ion_indicator" => Some(Ok(config.ion_indicator)),
"elvish_indicator" => Some(Ok(config.elvish_indicator)), "elvish_indicator" => Some(Ok(config.elvish_indicator)),
"tcsh_indicator" => Some(Ok(config.tcsh_indicator)), "tcsh_indicator" => Some(Ok(config.tcsh_indicator)),
"xonsh_indicator" => Some(Ok(config.xonsh_indicator)),
"unknown_indicator" => Some(Ok(config.unknown_indicator)), "unknown_indicator" => Some(Ok(config.unknown_indicator)),
_ => None, _ => None,
}) })
@ -279,6 +281,35 @@ mod tests {
assert_eq!(expected, actual); assert_eq!(expected, actual);
} }
#[test]
fn test_xonsh_default_format() {
let expected = Some(format!("{} ", "xsh"));
let actual = ModuleRenderer::new("shell")
.shell(Shell::Xonsh)
.config(toml::toml! {
[shell]
disabled = false
})
.collect();
assert_eq!(expected, actual);
}
#[test]
fn test_xonsh_custom_format() {
let expected = Some(format!("{} ", Color::Cyan.bold().paint("xonsh")));
let actual = ModuleRenderer::new("shell")
.shell(Shell::Xonsh)
.config(toml::toml! {
[shell]
xonsh_indicator = "[xonsh](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"));