Skip to content

Commit 9ea2342

Browse files
committed
feat(fish): add vimode segment support
1 parent 161f1d9 commit 9ea2342

8 files changed

Lines changed: 56 additions & 10 deletions

File tree

src/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ func (cfg *Config) Features(env runtime.Environment) shell.Features {
211211
}
212212
}
213213

214-
if segment.Type == VIMODE && slices.Contains([]string{shell.ZSH, shell.PWSH}, env.Shell()) {
214+
if segment.Type == VIMODE && slices.Contains([]string{shell.ZSH, shell.PWSH, shell.FISH}, env.Shell()) {
215215
log.Debug("vi mode tracking enabled")
216216
feats |= shell.VIMode
217217
}

src/config/config_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ func TestFeaturesVIMode(t *testing.T) {
212212
Shell: shell.PWSH,
213213
ExpectedFeats: shell.VIMode,
214214
},
215+
{
216+
Case: "fish enables vi mode tracking",
217+
Shell: shell.FISH,
218+
ExpectedFeats: shell.VIMode,
219+
},
215220
{
216221
Case: "bash does not enable vi mode tracking",
217222
Shell: shell.BASH,

src/segments/vimode.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ func (v *VIMode) Enabled() bool {
2727

2828
func mapVIModeKeymap(keymap string) string {
2929
switch keymap {
30-
case "main", "viins", "emacs":
30+
case "main", "viins", "emacs", "insert":
3131
return "insert"
32-
case "vicmd":
32+
case "vicmd", "default":
3333
return "normal"
3434
case "visual":
3535
return "visual"
36-
case "viopp":
36+
case "viopp", "operator", "f", "F", "t", "T":
3737
return "viopp"
38-
case "replace":
38+
case "replace", "replace_one":
3939
return "replace"
4040
default:
4141
return keymap

src/segments/vimode_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,18 @@ func TestVIMode(t *testing.T) {
2020
{Case: "main keymap maps to insert", Env: "main", ExpectedMode: "insert", ExpectedKeymap: "main", ExpectedEnabled: true},
2121
{Case: "viins keymap maps to insert", Env: "viins", ExpectedMode: "insert", ExpectedKeymap: "viins", ExpectedEnabled: true},
2222
{Case: "emacs keymap maps to insert", Env: "emacs", ExpectedMode: "insert", ExpectedKeymap: "emacs", ExpectedEnabled: true},
23+
{Case: "insert keymap maps is preserved", Env: "insert", ExpectedMode: "insert", ExpectedKeymap: "insert", ExpectedEnabled: true},
2324
{Case: "vicmd keymap maps to normal", Env: "vicmd", ExpectedMode: "normal", ExpectedKeymap: "vicmd", ExpectedEnabled: true},
25+
{Case: "default keymap maps to normal", Env: "default", ExpectedMode: "normal", ExpectedKeymap: "default", ExpectedEnabled: true},
2426
{Case: "visual keymap is preserved", Env: "visual", ExpectedMode: "visual", ExpectedKeymap: "visual", ExpectedEnabled: true},
2527
{Case: "viopp keymap is preserved", Env: "viopp", ExpectedMode: "viopp", ExpectedKeymap: "viopp", ExpectedEnabled: true},
28+
{Case: "operator keymap maps to viopp", Env: "operator", ExpectedMode: "viopp", ExpectedKeymap: "operator", ExpectedEnabled: true},
29+
{Case: "f keymap maps to viopp", Env: "f", ExpectedMode: "viopp", ExpectedKeymap: "f", ExpectedEnabled: true},
30+
{Case: "F keymap maps to viopp", Env: "F", ExpectedMode: "viopp", ExpectedKeymap: "F", ExpectedEnabled: true},
31+
{Case: "t keymap maps to viopp", Env: "t", ExpectedMode: "viopp", ExpectedKeymap: "t", ExpectedEnabled: true},
32+
{Case: "T keymap maps to viopp", Env: "T", ExpectedMode: "viopp", ExpectedKeymap: "T", ExpectedEnabled: true},
2633
{Case: "replace keymap is preserved", Env: "replace", ExpectedMode: "replace", ExpectedKeymap: "replace", ExpectedEnabled: true},
34+
{Case: "replace_one keymap maps to replace", Env: "replace_one", ExpectedMode: "replace", ExpectedKeymap: "replace_one", ExpectedEnabled: true},
2735
{Case: "unknown keymap falls through", Env: "custom", ExpectedMode: "custom", ExpectedKeymap: "custom", ExpectedEnabled: true},
2836
{Case: "empty env disables segment", Env: "", ExpectedEnabled: false},
2937
}

src/shell/fish.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ func (f Features) Fish() Code {
2929
return unixUpgrade
3030
case Notice:
3131
return unixNotice
32-
case RPrompt, PoshGit, Azure, LineError, Jobs, Async, KeyHandlers, VIMode:
32+
case VIMode:
33+
return "_omp_enable_vimode"
34+
case RPrompt, PoshGit, Azure, LineError, Jobs, Async, KeyHandlers:
3335
fallthrough
3436
default:
3537
return ""

src/shell/fish_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ set --global _omp_ftcs_marks 1
1919
set --global _omp_prompt_mark 1
2020
set --global _omp_cursor_positioning 1
2121
set --global _omp_enable_streaming 1
22-
set --global _omp_transient_rprompt 1`
22+
set --global _omp_transient_rprompt 1
23+
_omp_enable_vimode`
2324

2425
assert.Equal(t, want, got)
2526
}

src/shell/scripts/omp.fish

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,25 @@ function enable_poshtooltips
666666
bind \x7f _omp_backspace_key_handler -M insert
667667
end
668668

669+
function _omp_export_bind_mode
670+
if not contains -- "$fish_key_bindings" fish_vi_key_bindings fish_hybrid_key_bindings
671+
set --export --global POSH_VI_MODE "emacs"
672+
else
673+
set --export --global POSH_VI_MODE "$fish_bind_mode"
674+
end
675+
end
676+
677+
function _omp_enable_vimode
678+
_omp_export_bind_mode
679+
# fish calls `fish_mode_prompt` when the bind mode is changed. if it
680+
# produces no output, fish will then call `fish_prompt` so there's no need
681+
# to repaint as long as `fish_mode_prompt` outputs nothing
682+
function fish_mode_prompt
683+
_omp_export_bind_mode
684+
set --global _omp_new_prompt 1
685+
end
686+
end
687+
669688
# transient prompt
670689

671690
function _omp_enter_key_handler

website/docs/segments/system/vimode.mdx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ sidebar_label: Vi mode
77
## What
88

99
Display the current Vi mode (insert / normal / visual …) in the prompt. Useful
10-
when using ZSH [keymaps][zsh-vi-mode] via `bindkey -v` or PowerShell PSReadLine
11-
`-EditMode Vi` so you can tell at a glance which mode you are in.
10+
when using ZSH [keymaps][zsh-vi-mode] via `bindkey -v`, PowerShell PSReadLine
11+
`-EditMode Vi`, or fish [`fish_key_bindings`][fish-key-bindings] so you can
12+
tell at a glance which mode you are in.
1213

1314
In ZSH, adding this segment automatically registers a `zle-keymap-select` hook.
1415
In PowerShell, it registers a PSReadLine [Vi mode change handler][pwsh-vi-mode].
15-
Both re-render the prompt every time the active mode changes.
16+
In fish, it overrides [`fish_mode_prompt`][fish-mode-prompt].
17+
All three re-render the prompt every time the active mode changes.
1618

1719
:::caution PowerShell cursor indicator
1820

@@ -22,6 +24,13 @@ segment in the prompt instead.
2224

2325
:::
2426

27+
:::caution `fish_mode_prompt`
28+
29+
Make sure nothing else in your fish config overrides `fish_mode_prompt`, as
30+
this will interfere with this segment's functionality.
31+
32+
:::
33+
2534
## Sample Configuration
2635

2736
import Config from "@site/src/components/Config.js";
@@ -57,3 +66,5 @@ import Config from "@site/src/components/Config.js";
5766
[zsh-vi-mode]: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Keymaps
5867
[zsh-keymap]: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#index-KEYMAP
5968
[pwsh-vi-mode]: https://learn.microsoft.com/en-us/powershell/module/psreadline/set-psreadlineoption#-vimodechangehandler
69+
[fish-key-bindings]: https://fishshell.com/docs/current/language.html#envvar-fish_key_bindings
70+
[fish-mode-prompt]: https://fishshell.com/docs/current/cmds/fish_mode_prompt.html

0 commit comments

Comments
 (0)