Support vicmd_symbol in fish-shell (#254)
This commit is contained in:
parent
4eb7beca48
commit
3dd035056d
|
@ -122,13 +122,13 @@ can do this in two ways: by changing color (red/green) or by changing its shape
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ----------------------- | ------- | --------------------------------------------------------------------------------- |
|
| ----------------------- | ------- | ----------------------------------------------------------------------------------- |
|
||||||
| `symbol` | `"❯"` | The symbol used before the text input in the prompt. |
|
| `symbol` | `"❯"` | The symbol used before the text input in the prompt. |
|
||||||
| `error_symbol` | `"✖"` | The symbol used before text input if the previous command failed. |
|
| `error_symbol` | `"✖"` | The symbol used before text input if the previous command failed. |
|
||||||
| `use_symbol_for_status` | `false` | Indicate error status by changing the symbol. |
|
| `use_symbol_for_status` | `false` | Indicate error status by changing the symbol. |
|
||||||
| `vicmd_symbol` | `"❮"` | The symbol used before the text input in the prompt if zsh is in vim normal mode. |
|
| `vicmd_symbol` | `"❮"` | The symbol used before the text input in the prompt if shell is in vim normal mode. |
|
||||||
| `disabled` | `false` | Disables the `character` module. |
|
| `disabled` | `false` | Disables the `character` module. |
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
|
|
|
@ -255,11 +255,18 @@ export STARSHIP_SHELL="zsh"
|
||||||
|
|
||||||
const FISH_INIT: &str = r##"
|
const FISH_INIT: &str = r##"
|
||||||
function fish_prompt
|
function fish_prompt
|
||||||
|
switch "$fish_key_bindings"
|
||||||
|
case fish_hybrid_key_bindings fish_vi_key_bindings
|
||||||
|
set keymap "$fish_bind_mode"
|
||||||
|
case '*'
|
||||||
|
set keymap insert
|
||||||
|
end
|
||||||
set -l exit_code $status
|
set -l exit_code $status
|
||||||
# Account for changes in variable name between v2.7 and v3.0
|
# Account for changes in variable name between v2.7 and v3.0
|
||||||
set -l CMD_DURATION "$CMD_DURATION$cmd_duration"
|
set -l CMD_DURATION "$CMD_DURATION$cmd_duration"
|
||||||
set -l starship_duration (math --scale=0 "$CMD_DURATION / 1000")
|
set -l starship_duration (math --scale=0 "$CMD_DURATION / 1000")
|
||||||
## STARSHIP ## prompt --status=$exit_code --cmd-duration=$starship_duration --jobs=(count (jobs -p))
|
## STARSHIP ## prompt --status=$exit_code --keymap=$keymap --cmd-duration=$starship_duration --jobs=(count (jobs -p))
|
||||||
end
|
end
|
||||||
|
function fish_mode_prompt; end
|
||||||
export STARSHIP_SHELL="fish"
|
export STARSHIP_SHELL="fish"
|
||||||
"##;
|
"##;
|
||||||
|
|
|
@ -48,8 +48,8 @@ fn main() {
|
||||||
.short("k")
|
.short("k")
|
||||||
.long("keymap")
|
.long("keymap")
|
||||||
.value_name("KEYMAP")
|
.value_name("KEYMAP")
|
||||||
// zsh only
|
// fish/zsh only
|
||||||
.help("The keymap of zsh")
|
.help("The keymap of fish/zsh")
|
||||||
.takes_value(true);
|
.takes_value(true);
|
||||||
|
|
||||||
let jobs_arg = Arg::with_name("jobs")
|
let jobs_arg = Arg::with_name("jobs")
|
||||||
|
|
|
@ -13,6 +13,12 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
const SUCCESS_CHAR: &str = "❯";
|
const SUCCESS_CHAR: &str = "❯";
|
||||||
const FAILURE_CHAR: &str = "✖";
|
const FAILURE_CHAR: &str = "✖";
|
||||||
const VICMD_CHAR: &str = "❮";
|
const VICMD_CHAR: &str = "❮";
|
||||||
|
enum ShellEditMode {
|
||||||
|
Normal,
|
||||||
|
Insert,
|
||||||
|
};
|
||||||
|
const ASSUMED_MODE: ShellEditMode = ShellEditMode::Insert;
|
||||||
|
// TODO: extend config to more modes
|
||||||
|
|
||||||
let color_success = Color::Green.bold();
|
let color_success = Color::Green.bold();
|
||||||
let color_failure = Color::Red.bold();
|
let color_failure = Color::Red.bold();
|
||||||
|
@ -25,16 +31,28 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
.config_value_bool("use_symbol_for_status")
|
.config_value_bool("use_symbol_for_status")
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
let exit_success = arguments.value_of("status_code").unwrap_or("0") == "0";
|
let exit_success = arguments.value_of("status_code").unwrap_or("0") == "0";
|
||||||
|
let shell = std::env::var("STARSHIP_SHELL").unwrap_or_default();
|
||||||
let keymap = arguments.value_of("keymap").unwrap_or("viins");
|
let keymap = arguments.value_of("keymap").unwrap_or("viins");
|
||||||
|
|
||||||
|
// Match shell "keymap" names to normalized vi modes
|
||||||
|
// NOTE: in vi mode, fish reports normal mode as "default".
|
||||||
|
// Unfortunately, this is also the name of the non-vi default mode.
|
||||||
|
// We do some environment detection in src/init.rs to translate.
|
||||||
|
// The result: in non-vi fish, keymap is always reported as "insert"
|
||||||
|
let mode = match (shell.as_str(), keymap) {
|
||||||
|
("fish", "default") | ("zsh", "vicmd") => ShellEditMode::Normal,
|
||||||
|
_ => ASSUMED_MODE,
|
||||||
|
};
|
||||||
|
|
||||||
/* If an error symbol is set in the config, use symbols to indicate
|
/* If an error symbol is set in the config, use symbols to indicate
|
||||||
success/failure, in addition to color */
|
success/failure, in addition to color */
|
||||||
let symbol = if use_symbol && !exit_success {
|
let symbol = if use_symbol && !exit_success {
|
||||||
module.new_segment("error_symbol", FAILURE_CHAR)
|
module.new_segment("error_symbol", FAILURE_CHAR)
|
||||||
} else if keymap == "vicmd" {
|
|
||||||
module.new_segment("vicmd_symbol", VICMD_CHAR)
|
|
||||||
} else {
|
} else {
|
||||||
module.new_segment("symbol", SUCCESS_CHAR)
|
match mode {
|
||||||
|
ShellEditMode::Normal => module.new_segment("vicmd_symbol", VICMD_CHAR),
|
||||||
|
ShellEditMode::Insert => module.new_segment("symbol", SUCCESS_CHAR),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if exit_success {
|
if exit_success {
|
||||||
|
|
|
@ -74,35 +74,77 @@ fn char_module_symbolyes_status() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn char_module_vicmd_keymap() -> io::Result<()> {
|
fn char_module_zsh_keymap() -> io::Result<()> {
|
||||||
let expected_vicmd = format!("{} ", Color::Green.bold().paint("❮"));
|
let expected_vicmd = "❮";
|
||||||
let expected_specified = format!("{} ", Color::Green.bold().paint("N"));
|
// TODO make this less... well, stupid when ANSI escapes can be mocked out
|
||||||
let expected_other = format!("{} ", Color::Green.bold().paint("❯"));
|
let expected_specified = "I HIGHLY DOUBT THIS WILL SHOW UP IN OTHER OUTPUT";
|
||||||
|
let expected_other = "❯";
|
||||||
|
|
||||||
// zle keymap is vicmd
|
// zle keymap is vicmd
|
||||||
let output = common::render_module("character")
|
let output = common::render_module("character")
|
||||||
|
.env("STARSHIP_SHELL", "zsh")
|
||||||
.arg("--keymap=vicmd")
|
.arg("--keymap=vicmd")
|
||||||
.output()?;
|
.output()?;
|
||||||
let actual = String::from_utf8(output.stdout).unwrap();
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
assert_eq!(expected_vicmd, actual);
|
assert!(actual.contains(&expected_vicmd));
|
||||||
|
|
||||||
// specified vicmd character
|
// specified vicmd character
|
||||||
let output = common::render_module("character")
|
let output = common::render_module("character")
|
||||||
.use_config(toml::toml! {
|
.use_config(toml::toml! {
|
||||||
[character]
|
[character]
|
||||||
vicmd_symbol = "N"
|
vicmd_symbol = "I HIGHLY DOUBT THIS WILL SHOW UP IN OTHER OUTPUT"
|
||||||
})
|
})
|
||||||
|
.env("STARSHIP_SHELL", "zsh")
|
||||||
.arg("--keymap=vicmd")
|
.arg("--keymap=vicmd")
|
||||||
.output()?;
|
.output()?;
|
||||||
let actual = String::from_utf8(output.stdout).unwrap();
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
assert_eq!(expected_specified, actual);
|
assert!(actual.contains(&expected_specified));
|
||||||
|
|
||||||
// zle keymap is other
|
// zle keymap is other
|
||||||
let output = common::render_module("character")
|
let output = common::render_module("character")
|
||||||
|
.env("STARSHIP_SHELL", "zsh")
|
||||||
.arg("--keymap=visual")
|
.arg("--keymap=visual")
|
||||||
.output()?;
|
.output()?;
|
||||||
let actual = String::from_utf8(output.stdout).unwrap();
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
assert_eq!(expected_other, actual);
|
assert!(actual.contains(&expected_other));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn char_module_fish_keymap() -> io::Result<()> {
|
||||||
|
let expected_vicmd = "❮";
|
||||||
|
// TODO make this less... well, stupid when ANSI escapes can be mocked out
|
||||||
|
let expected_specified = "I HIGHLY DOUBT THIS WILL SHOW UP IN OTHER OUTPUT";
|
||||||
|
let expected_other = "❯";
|
||||||
|
|
||||||
|
// fish keymap is default
|
||||||
|
let output = common::render_module("character")
|
||||||
|
.env("STARSHIP_SHELL", "fish")
|
||||||
|
.arg("--keymap=default")
|
||||||
|
.output()?;
|
||||||
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
|
assert!(actual.contains(&expected_vicmd));
|
||||||
|
|
||||||
|
// specified vicmd character
|
||||||
|
let output = common::render_module("character")
|
||||||
|
.use_config(toml::toml! {
|
||||||
|
[character]
|
||||||
|
vicmd_symbol = "I HIGHLY DOUBT THIS WILL SHOW UP IN OTHER OUTPUT"
|
||||||
|
})
|
||||||
|
.env("STARSHIP_SHELL", "fish")
|
||||||
|
.arg("--keymap=default")
|
||||||
|
.output()?;
|
||||||
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
|
assert!(actual.contains(&expected_specified));
|
||||||
|
|
||||||
|
// fish keymap is other
|
||||||
|
let output = common::render_module("character")
|
||||||
|
.env("STARSHIP_SHELL", "fish")
|
||||||
|
.arg("--keymap=visual")
|
||||||
|
.output()?;
|
||||||
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
|
assert!(actual.contains(&expected_other));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue