From 146976351ec804ab1594d5262a1e0dd2d2de4972 Mon Sep 17 00:00:00 2001 From: Mat Jones Date: Sat, 4 Jun 2022 10:41:24 +0000 Subject: [PATCH] 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 --- .github/config-schema.json | 17 ++++++++++++++++- docs/config/README.md | 19 ++++++++++++------- src/configs/character.rs | 6 ++++++ src/modules/character.rs | 37 +++++++++++++++++++++++++++++++++++-- 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/.github/config-schema.json b/.github/config-schema.json index 3ed03d14..16de446c 100644 --- a/.github/config-schema.json +++ b/.github/config-schema.json @@ -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" diff --git a/docs/config/README.md b/docs/config/README.md index 61649ca5..db9c5179 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -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 diff --git a/src/configs/character.rs b/src/configs/character.rs index 91cef60c..eb28f9cd 100644 --- a/src/configs/character.rs +++ b/src/configs/character.rs @@ -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, } } diff --git a/src/modules/character.rs b/src/modules/character.rs index e7b65e2e..39c78b15 100644 --- a/src/modules/character.rs +++ b/src/modules/character.rs @@ -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> { 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> { (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); }