mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2026-08-24 10:14:12 -05:00
feat(shell): support vimode segment in fish
Extend the existing `vimode` segment to fish. When a config contains a `vimode` segment and the active shell is fish, Oh My Posh enables an `_omp_enable_vimode` hook that registers an `--on-variable fish_bind_mode` handler. The handler mirrors fish's bind mode into `POSH_VI_MODE` (translated to the keymap names the segment already understands: `default` -> `vicmd`, `insert` -> `viins`, `replace`/`replace_one` -> `replace`, `visual` passthrough) and re-renders the prompt on every mode change. The hook only activates when vi or hybrid key bindings are in use, and it overrides fish's built-in `fish_mode_prompt` so the mode is shown solely by the segment. The segment implementation itself is unchanged. Related #5438 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
committed by
Jan De Dobbeleer
co-authored by
Claude Opus 4.8
parent
36a96bbde3
commit
302c3df9c4
@@ -211,7 +211,7 @@ func (cfg *Config) Features(env runtime.Environment) shell.Features {
|
||||
}
|
||||
}
|
||||
|
||||
if segment.Type == VIMODE && slices.Contains([]string{shell.ZSH, shell.PWSH}, env.Shell()) {
|
||||
if segment.Type == VIMODE && slices.Contains([]string{shell.ZSH, shell.PWSH, shell.FISH}, env.Shell()) {
|
||||
log.Debug("vi mode tracking enabled")
|
||||
feats |= shell.VIMode
|
||||
}
|
||||
|
||||
@@ -212,6 +212,11 @@ func TestFeaturesVIMode(t *testing.T) {
|
||||
Shell: shell.PWSH,
|
||||
ExpectedFeats: shell.VIMode,
|
||||
},
|
||||
{
|
||||
Case: "fish enables vi mode tracking",
|
||||
Shell: shell.FISH,
|
||||
ExpectedFeats: shell.VIMode,
|
||||
},
|
||||
{
|
||||
Case: "bash does not enable vi mode tracking",
|
||||
Shell: shell.BASH,
|
||||
|
||||
+3
-1
@@ -29,7 +29,9 @@ func (f Features) Fish() Code {
|
||||
return unixUpgrade
|
||||
case Notice:
|
||||
return unixNotice
|
||||
case RPrompt, PoshGit, Azure, LineError, Jobs, Async, KeyHandlers, VIMode:
|
||||
case VIMode:
|
||||
return "_omp_enable_vimode"
|
||||
case RPrompt, PoshGit, Azure, LineError, Jobs, Async, KeyHandlers:
|
||||
fallthrough
|
||||
default:
|
||||
return ""
|
||||
|
||||
@@ -19,6 +19,7 @@ set --global _omp_ftcs_marks 1
|
||||
set --global _omp_prompt_mark 1
|
||||
set --global _omp_cursor_positioning 1
|
||||
set --global _omp_enable_streaming 1
|
||||
_omp_enable_vimode
|
||||
set --global _omp_transient_rprompt 1`
|
||||
|
||||
assert.Equal(t, want, got)
|
||||
|
||||
@@ -747,3 +747,38 @@ function omp_repaint_prompt
|
||||
set --global _omp_new_prompt 1
|
||||
commandline --function repaint
|
||||
end
|
||||
|
||||
# vi mode tracking — mirror the active fish bind mode into POSH_VI_MODE and
|
||||
# re-render the prompt whenever it changes. Enabled through the vimode segment.
|
||||
function _omp_enable_vimode
|
||||
# only track when vi (or hybrid) key bindings are active
|
||||
contains -- "$fish_key_bindings" fish_vi_key_bindings fish_hybrid_key_bindings
|
||||
or return
|
||||
|
||||
# translate fish's bind mode into the keymap names the vimode segment expects
|
||||
function _omp_set_vimode
|
||||
switch $fish_bind_mode
|
||||
case default
|
||||
set --global --export POSH_VI_MODE vicmd
|
||||
case replace replace_one
|
||||
set --global --export POSH_VI_MODE replace
|
||||
case insert
|
||||
set --global --export POSH_VI_MODE viins
|
||||
case '*'
|
||||
set --global --export POSH_VI_MODE $fish_bind_mode
|
||||
end
|
||||
end
|
||||
|
||||
# re-render the prompt on every mode change
|
||||
function _omp_render_vimode --on-variable fish_bind_mode
|
||||
_omp_set_vimode
|
||||
omp_repaint_prompt
|
||||
end
|
||||
|
||||
# oh-my-posh renders the mode through the vimode segment, so silence fish's
|
||||
# built-in mode indicator to avoid a duplicate
|
||||
function fish_mode_prompt
|
||||
end
|
||||
|
||||
_omp_set_vimode
|
||||
end
|
||||
|
||||
@@ -7,12 +7,15 @@ sidebar_label: Vi mode
|
||||
## What
|
||||
|
||||
Display the current Vi mode (insert / normal / visual …) in the prompt. Useful
|
||||
when using ZSH [keymaps][zsh-vi-mode] via `bindkey -v` or PowerShell PSReadLine
|
||||
`-EditMode Vi` so you can tell at a glance which mode you are in.
|
||||
when using ZSH [keymaps][zsh-vi-mode] via `bindkey -v`, PowerShell PSReadLine
|
||||
`-EditMode Vi`, or fish [vi key bindings][fish-vi-mode] so you can tell at a
|
||||
glance which mode you are in.
|
||||
|
||||
In ZSH, adding this segment automatically registers a `zle-keymap-select` hook.
|
||||
In PowerShell, it registers a PSReadLine [Vi mode change handler][pwsh-vi-mode].
|
||||
Both re-render the prompt every time the active mode changes.
|
||||
In fish, it registers an [`--on-variable fish_bind_mode`][fish-bind-mode] handler
|
||||
(only when vi or hybrid key bindings are active). All of them re-render the
|
||||
prompt every time the active mode changes.
|
||||
|
||||
:::caution PowerShell cursor indicator
|
||||
|
||||
@@ -22,6 +25,15 @@ segment in the prompt instead.
|
||||
|
||||
:::
|
||||
|
||||
:::caution fish mode prompt
|
||||
|
||||
fish support overrides `fish_mode_prompt` with an empty function so fish's
|
||||
built-in `[N]` / `[I]` mode indicator does not show up next to the mode
|
||||
rendered by this segment. Make sure vi key bindings are enabled (e.g.
|
||||
`fish_vi_key_bindings`) for the segment to display.
|
||||
|
||||
:::
|
||||
|
||||
## Sample Configuration
|
||||
|
||||
import Config from "@site/src/components/Config.js";
|
||||
@@ -51,9 +63,11 @@ import Config from "@site/src/components/Config.js";
|
||||
| Name | Type | Description |
|
||||
| --------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `.Mode` | `string` | the normalized mode: `insert`, `normal`, `visual`, `viopp`, `replace`, or the raw keymap when unmapped |
|
||||
| `.Keymap` | `string` | the raw mode value ([`$KEYMAP`][zsh-keymap] in ZSH, e.g. `main`, `viins`, `vicmd`, `visual`, `viopp`; `viins` or `vicmd` in PowerShell PSReadLine) |
|
||||
| `.Keymap` | `string` | the raw mode value ([`$KEYMAP`][zsh-keymap] in ZSH, e.g. `main`, `viins`, `vicmd`, `visual`, `viopp`; `viins` or `vicmd` in PowerShell PSReadLine; `viins`, `vicmd`, `visual` or `replace` in fish) |
|
||||
|
||||
[templates]: /docs/configuration/templates
|
||||
[zsh-vi-mode]: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Keymaps
|
||||
[zsh-keymap]: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#index-KEYMAP
|
||||
[pwsh-vi-mode]: https://learn.microsoft.com/en-us/powershell/module/psreadline/set-psreadlineoption#-vimodechangehandler
|
||||
[fish-vi-mode]: https://fishshell.com/docs/current/interactive.html#vi-mode-commands
|
||||
[fish-bind-mode]: https://fishshell.com/docs/current/language.html#the-fish-bind-mode-variable
|
||||
|
||||
Reference in New Issue
Block a user