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 <davidkna@users.noreply.github.com>

* 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 <andytom@users.noreply.github.com>

Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com>
This commit is contained in:
Vivek Malneedi 2021-02-27 13:55:27 -05:00 committed by GitHub
parent ce2f844a2f
commit d21400a478
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 70 additions and 1 deletions

View File

@ -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).

View File

@ -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`"
```

View File

@ -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. |

View File

@ -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`"
"

View File

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

View File

@ -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,
}
}

View File

@ -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,
}

View File

@ -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");

9
src/init/starship.tcsh Normal file
View File

@ -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`;

View File

@ -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);

View File

@ -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,
}
}

View File

@ -23,6 +23,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
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,

View File

@ -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
}

View File

@ -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 {