From d21400a4784e17b7a4afe110155c01717f835388 Mon Sep 17 00:00:00 2001 From: Vivek Malneedi Date: Sat, 27 Feb 2021 13:55:27 -0500 Subject: [PATCH] feat: add support for tcsh (#2288) * feat: add support for tcsh * add tcsh to install.sh install message * list tcsh in bug_report.rs and main.rs * quote starship path Co-authored-by: David Knaack * fix job count * add tcsh support to shell module * fix STARSHIP_START_TIME undefined error * preserve existing user precmd and postcmd, remove jobs support * remove unnecessary parentheses * minor script improvement * removes parens from install script message * Update docs/config/README.md Co-authored-by: Thomas O'Donnell Co-authored-by: David Knaack Co-authored-by: Thomas O'Donnell --- README.md | 10 ++++++++++ docs/README.md | 10 ++++++++++ docs/config/README.md | 7 +++++++ install/install.sh | 5 +++++ src/bug_report.rs | 1 + src/configs/shell.rs | 2 ++ src/context.rs | 2 ++ src/init/mod.rs | 10 ++++++++++ src/init/starship.tcsh | 9 +++++++++ src/main.rs | 2 +- src/module.rs | 1 + src/modules/shell.rs | 1 + src/print.rs | 7 +++++++ src/utils.rs | 4 ++++ 14 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/init/starship.tcsh diff --git a/README.md b/README.md index 83405d67..5674067a 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,16 @@ shown below. Can't see yours? Have a look at the [extra platform instructions](h eval (starship init elvish) ``` + #### Tcsh + + Add the following to the end of `~/.tcshrc`: + + ```sh + # ~/.tcshrc + + eval "`starship init tcsh`" + ``` + ## 🤝 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). diff --git a/docs/README.md b/docs/README.md index 5fdedb9c..6a7435b0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -115,3 +115,13 @@ description: Starship is the minimal, blazing fast, and extremely customizable p eval (starship init elvish) ``` + #### Tcsh + + Add the following to the end of `~/.tcshrc`: + + ```sh + # ~/.tcshrc + + eval "`starship init tcsh`" + ``` + diff --git a/docs/config/README.md b/docs/config/README.md index 9502d0dd..b00a3e92 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -1408,6 +1408,12 @@ The module will be shown only if there are background jobs running. The module will show the number of jobs running if there is more than 1 job, or more than the `threshold` config value, if it exists. +::: warning + +This module is not supported on tcsh. + +::: + ### Options | Option | Default | Description | @@ -2284,6 +2290,7 @@ To enable it, set `disabled` to `false` in your configuration file. | `powershell_indicator` | `psh` | A format string used to represent powershell. | | `ion_indicator` | `ion` | A format string used to represent ion. | | `elvish_indicator` | `esh` | A format string used to represent elvish. | +| `tcsh_indicator` | `tsh` | A format string used to represent tcsh. | | `format` | `$indicator ` | The format for the module. | | `disabled` | `true` | Disables the `shell` module. | diff --git a/install/install.sh b/install/install.sh index 891cf108..2263df2f 100755 --- a/install/install.sh +++ b/install/install.sh @@ -432,4 +432,9 @@ info "Please follow the steps for your shell to complete the installation: Add the following to the end of ${BOLD}~/.config/ion/initrc${NO_COLOR}: eval \$(starship init ion) + + ${BOLD}${UNDERLINE}Tcsh${NO_COLOR} + Add the following to the end of ${BOLD}~/.tcshrc${NO_COLOR}: + + eval "`starship init tcsh`" " diff --git a/src/bug_report.rs b/src/bug_report.rs index d93fcc80..943a146f 100644 --- a/src/bug_report.rs +++ b/src/bug_report.rs @@ -205,6 +205,7 @@ fn get_config_path(shell: &str) -> Option { } "zsh" => Some(".zshrc"), "elvish" => Some(".elvish/rc.elv"), + "tcsh" => Some(".tcshrc"), _ => None, } .map(|path| home_dir.join(path)) diff --git a/src/configs/shell.rs b/src/configs/shell.rs index 24551df9..4b56189c 100644 --- a/src/configs/shell.rs +++ b/src/configs/shell.rs @@ -11,6 +11,7 @@ pub struct ShellConfig<'a> { pub powershell_indicator: &'a str, pub ion_indicator: &'a str, pub elvish_indicator: &'a str, + pub tcsh_indicator: &'a str, pub disabled: bool, } @@ -24,6 +25,7 @@ impl<'a> RootModuleConfig<'a> for ShellConfig<'a> { powershell_indicator: "psh", ion_indicator: "ion", elvish_indicator: "esh", + tcsh_indicator: "tsh", disabled: true, } } diff --git a/src/context.rs b/src/context.rs index 251e5e33..807f3d18 100644 --- a/src/context.rs +++ b/src/context.rs @@ -251,6 +251,7 @@ impl<'a> Context<'a> { "powershell" => Shell::PowerShell, "zsh" => Shell::Zsh, "elvish" => Shell::Elvish, + "tcsh" => Shell::Tcsh, _ => Shell::Unknown, } } @@ -486,6 +487,7 @@ pub enum Shell { PowerShell, Zsh, Elvish, + Tcsh, Unknown, } diff --git a/src/init/mod.rs b/src/init/mod.rs index a06bf32d..be1d228f 100644 --- a/src/init/mod.rs +++ b/src/init/mod.rs @@ -173,6 +173,13 @@ fi"#, ); Some(script) } + Some("tcsh") => { + let script = format!( + r#"eval "`("{}" init tcsh --print-full-init)`""#, + starship.sprint_posix()? + ); + Some(script) + } None => { println!( "Invalid shell name provided: {}\\n\ @@ -212,6 +219,7 @@ pub fn init_main(shell_name: &str) -> io::Result<()> { "powershell" => print_script(PWSH_INIT, &starship_path.sprint()?), "ion" => print_script(ION_INIT, &starship_path.sprint()?), "elvish" => print_script(ELVISH_INIT, &starship_path.sprint_posix()?), + "tcsh" => print_script(TCSH_INIT, &starship_path.sprint_posix()?), _ => { println!( "printf \"Shell name detection failed on phase two init.\\n\ @@ -255,3 +263,5 @@ const PWSH_INIT: &str = include_str!("starship.ps1"); const ION_INIT: &str = include_str!("starship.ion"); const ELVISH_INIT: &str = include_str!("starship.elv"); + +const TCSH_INIT: &str = include_str!("starship.tcsh"); diff --git a/src/init/starship.tcsh b/src/init/starship.tcsh new file mode 100644 index 00000000..7d4b4b9a --- /dev/null +++ b/src/init/starship.tcsh @@ -0,0 +1,9 @@ +setenv STARSHIP_SHELL tcsh; +setenv STARSHIP_SESSION_KEY `::STARSHIP:: session`; +set USER_PRECMD = "`alias precmd`"; +set USER_POSTCMD = "`alias postcmd`"; +set STARSHIP_PRECMD = 'set STARSHIP_CMD_STATUS = $status;set STARSHIP_PATH = ::STARSHIP::;set STARSHIP_END_TIME = `$STARSHIP_PATH time`;set STARSHIP_DURATION = 0;if ( $STARSHIP_START_TIME != -1 ) @ STARSHIP_DURATION = $STARSHIP_END_TIME - $STARSHIP_START_TIME;set prompt = "`$STARSHIP_PATH prompt --status $STARSHIP_CMD_STATUS --cmd-duration $STARSHIP_DURATION`";set STARSHIP_START_TIME = -1'; +set STARSHIP_POSTCMD = 'set STARSHIP_START_TIME = `::STARSHIP:: time`'; +alias precmd "$STARSHIP_PRECMD;$USER_PRECMD"; +alias postcmd "$STARSHIP_POSTCMD;$USER_POSTCMD"; +set STARSHIP_START_TIME = `::STARSHIP:: time`; diff --git a/src/main.rs b/src/main.rs index 2701b21f..977f9941 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,7 @@ fn main() { let shell_arg = Arg::with_name("shell") .value_name("SHELL") .help( - "The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion, elvish", + "The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion, elvish, tcsh", ) .required(true); diff --git a/src/module.rs b/src/module.rs index e222ef2e..7a6961be 100644 --- a/src/module.rs +++ b/src/module.rs @@ -144,6 +144,7 @@ impl<'a> Module<'a> { match shell { Shell::Bash => ansi_strings_modified(ansi_strings, shell), Shell::Zsh => ansi_strings_modified(ansi_strings, shell), + Shell::Tcsh => ansi_strings_modified(ansi_strings, shell), _ => ansi_strings, } } diff --git a/src/modules/shell.rs b/src/modules/shell.rs index fe90b2e8..fc51b52f 100644 --- a/src/modules/shell.rs +++ b/src/modules/shell.rs @@ -23,6 +23,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { Shell::PowerShell => Some(config.powershell_indicator), Shell::Ion => Some(config.ion_indicator), Shell::Elvish => Some(config.elvish_indicator), + Shell::Tcsh => Some(config.tcsh_indicator), Shell::Unknown => None, }, _ => None, diff --git a/src/print.rs b/src/print.rs index 78e67694..0330af07 100644 --- a/src/print.rs +++ b/src/print.rs @@ -87,6 +87,13 @@ pub fn get_prompt(context: Context) -> String { } write!(buf, "{}", ANSIStrings(&module_strings)).unwrap(); + // escape \n and ! characters for tcsh + if let Shell::Tcsh = context.shell { + buf = buf.replace('!', "\\!"); + // space is required before newline + buf = buf.replace('\n', " \\n"); + } + buf } diff --git a/src/utils.rs b/src/utils.rs index c9d076ae..d1a3025c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -226,6 +226,8 @@ pub fn wrap_seq_for_shell( const BASH_END: &str = "\u{5c}\u{5d}"; // \] const ZSH_BEG: &str = "\u{25}\u{7b}"; // %{ const ZSH_END: &str = "\u{25}\u{7d}"; // %} + const TCSH_BEG: &str = "\u{25}\u{7b}"; // %{ + const TCSH_END: &str = "\u{25}\u{7d}"; // %} // ANSI escape codes cannot be nested, so we can keep track of whether we're // in an escape or not with a single boolean variable @@ -238,6 +240,7 @@ pub fn wrap_seq_for_shell( match shell { Shell::Bash => format!("{}{}", BASH_BEG, escape_begin), Shell::Zsh => format!("{}{}", ZSH_BEG, escape_begin), + Shell::Tcsh => format!("{}{}", TCSH_BEG, escape_begin), _ => x.to_string(), } } else if x == escape_end && escaped { @@ -245,6 +248,7 @@ pub fn wrap_seq_for_shell( match shell { Shell::Bash => format!("{}{}", escape_end, BASH_END), Shell::Zsh => format!("{}{}", escape_end, ZSH_END), + Shell::Tcsh => format!("{}{}", escape_end, TCSH_END), _ => x.to_string(), } } else {