fix(fish): add proper vi mode detection for fish shell (#3839)

* add proper vi mode detection for fish shell

* update tests

* fix test

* update config-schema.json

* update docs

* add warning about symbols only supported in fish
This commit is contained in:
Mat Jones 2022-06-04 10:41:24 +00:00 committed by GitHub
parent 1e2bc8477e
commit 146976351e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 10 deletions

View File

@ -122,7 +122,10 @@
"error_symbol": "[](bold red)",
"format": "$symbol ",
"success_symbol": "[](bold green)",
"vicmd_symbol": "[](bold green)"
"vicmd_symbol": "[](bold green)",
"vimcmd_replace_one_symbol": "[](bold purple)",
"vimcmd_replace_symbol": "[](bold purple)",
"vimcmd_visual_symbol": "[](bold yellow)"
},
"allOf": [
{
@ -1784,6 +1787,18 @@
"default": "[](bold green)",
"type": "string"
},
"vimcmd_visual_symbol": {
"default": "[](bold yellow)",
"type": "string"
},
"vimcmd_replace_symbol": {
"default": "[](bold purple)",
"type": "string"
},
"vimcmd_replace_one_symbol": {
"default": "[](bold purple)",
"type": "string"
},
"disabled": {
"default": false,
"type": "boolean"

View File

@ -572,18 +572,23 @@ look at [this example](#with-custom-error-shape).
::: warning
`vicmd_symbol` is only supported in cmd, fish and zsh.
`vimcmd_replace_one_symbol`, `vimcmd_replace_symbol`, and `vimcmd_visual_symbol`
are only supported in fish due to [upstream issues with mode detection in zsh](https://github.com/starship/starship/issues/625#issuecomment-732454148).
:::
### Options
| Option | Default | Description |
| ---------------- | ------------------- | -------------------------------------------------------------------------------- |
| `format` | `"$symbol "` | The format string used before the text input. |
| `success_symbol` | `"[](bold green)"` | The format string used before the text input if the previous command succeeded. |
| `error_symbol` | `"[](bold red)"` | The format string used before the text input if the previous command failed. |
| `vicmd_symbol` | `"[](bold green)"` | The format string used before the text input if the shell is in vim normal mode. |
| `disabled` | `false` | Disables the `character` module. |
| Option | Default | Description |
| -------------------------- | -------------------- | --------------------------------------------------------------------------------------- |
| `format` | `"$symbol "` | The format string used before the text input. |
| `success_symbol` | `"[](bold green)"` | The format string used before the text input if the previous command succeeded. |
| `error_symbol` | `"[](bold red)"` | The format string used before the text input if the previous command failed. |
| `vicmd_symbol` | `"[](bold green)"` | The format string used before the text input if the shell is in vim normal mode. |
| `vicmd_replace_one_symbol` | `"[](bold purple)"` | The format string used before the text input if the shell is in vim `replace_one` mode. |
| `vimcmd_replace_symbol` | `"[](bold purple)"` | The format string used before the text input if the shell is in vim replace mode. |
| `vimcmd_visual_symbol` | `"[](bold yellow)"` | The format string used before the text input if the shell is in vim replace mode. |
| `disabled` | `false` | Disables the `character` module. |
### Variables

View File

@ -8,6 +8,9 @@ pub struct CharacterConfig<'a> {
pub success_symbol: &'a str,
pub error_symbol: &'a str,
pub vicmd_symbol: &'a str,
pub vimcmd_visual_symbol: &'a str,
pub vimcmd_replace_symbol: &'a str,
pub vimcmd_replace_one_symbol: &'a str,
pub disabled: bool,
}
@ -18,6 +21,9 @@ impl<'a> Default for CharacterConfig<'a> {
success_symbol: "[](bold green)",
error_symbol: "[](bold red)",
vicmd_symbol: "[](bold green)",
vimcmd_visual_symbol: "[](bold yellow)",
vimcmd_replace_symbol: "[](bold purple)",
vimcmd_replace_one_symbol: "[](bold purple)",
disabled: false,
}
}

View File

@ -4,7 +4,7 @@ use crate::formatter::StringFormatter;
/// Creates a module for the prompt character
///
/// The character segment prints an arrow character in a color dependant on the
/// The character segment prints an arrow character in a color dependent on the
/// exit-code of the last executed command:
/// - If the exit-code was "0", it will be formatted with `success_symbol`
/// (green arrow by default)
@ -13,6 +13,9 @@ use crate::formatter::StringFormatter;
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
enum ShellEditMode {
Normal,
Visual,
Replace,
ReplaceOne,
Insert,
}
const ASSUMED_MODE: ShellEditMode = ShellEditMode::Insert;
@ -35,11 +38,17 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
(Shell::Fish, "default") | (Shell::Zsh, "vicmd") | (Shell::Cmd, "vi") => {
ShellEditMode::Normal
}
(Shell::Fish, "visual") => ShellEditMode::Visual,
(Shell::Fish, "replace") => ShellEditMode::Replace,
(Shell::Fish, "replace_one") => ShellEditMode::ReplaceOne,
_ => ASSUMED_MODE,
};
let symbol = match mode {
ShellEditMode::Normal => config.vicmd_symbol,
ShellEditMode::Visual => config.vimcmd_visual_symbol,
ShellEditMode::Replace => config.vimcmd_replace_symbol,
ShellEditMode::ReplaceOne => config.vimcmd_replace_one_symbol,
ShellEditMode::Insert => {
if exit_success {
config.success_symbol
@ -168,6 +177,9 @@ mod test {
fn fish_keymap() {
let expected_vicmd = Some(format!("{} ", Color::Green.bold().paint("")));
let expected_specified = Some(format!("{} ", Color::Green.bold().paint("V")));
let expected_visual = Some(format!("{} ", Color::Yellow.bold().paint("")));
let expected_replace = Some(format!("{} ", Color::Purple.bold().paint("")));
let expected_replace_one = expected_replace.clone();
let expected_other = Some(format!("{} ", Color::Green.bold().paint("")));
// fish keymap is default
@ -188,11 +200,32 @@ mod test {
.collect();
assert_eq!(expected_specified, actual);
// fish keymap is other
// fish keymap is visual
let actual = ModuleRenderer::new("character")
.shell(Shell::Fish)
.keymap("visual")
.collect();
assert_eq!(expected_visual, actual);
// fish keymap is replace
let actual = ModuleRenderer::new("character")
.shell(Shell::Fish)
.keymap("replace")
.collect();
assert_eq!(expected_replace, actual);
// fish keymap is replace_one
let actual = ModuleRenderer::new("character")
.shell(Shell::Fish)
.keymap("replace_one")
.collect();
assert_eq!(expected_replace_one, actual);
// fish keymap is other
let actual = ModuleRenderer::new("character")
.shell(Shell::Fish)
.keymap("other")
.collect();
assert_eq!(expected_other, actual);
}