JanDeDobbeleer / oh-my-posh

The most customisable and low-latency cross platform/shell prompt renderer
https://ohmyposh.dev
MIT License
17.4k stars 2.38k forks source link

Show current mode in ZSH Vi mode #5438

Open stepanzak opened 3 months ago

stepanzak commented 3 months ago

Code of Conduct

What would you like to see added?

In ZSH, you can enable Vi mode with bindkey -v. Powerlevel10k has (had) a feature that shows current mode (normal/insert/replace etc.) and immediately updates it on change. I would love to be able to do the same in omp, since it's really annoying to use the Vi mode whilst not being able to tell whether I'm in insert mode or not.

gwojan commented 2 months ago

Is there any way this feature could be added to bash Vi mode and pwsh for that matter? For PowerShell/PSReadLine I currently have a ViModeChangeHandler configured and it would be easy to set an environment variable that oh-my-posh could read.

JanDeDobbeleer commented 1 month ago

@stepanzak I was playing around with this and adding the following snippet already enables this. Currently thinking about how to enable that from the configuration.

.zshrc

bindkey -v

_omp_redraw-prompt() {
  local precmd
  for precmd in $precmd_functions; do
    $precmd
  done

  zle .reset-prompt
}

function _omp_zle-keymap-select() {
    if [ "${KEYMAP}" = 'vicmd' ]; then
        export POSH_VI_MODE="command"
    else
        export POSH_VI_MODE="insert"
    fi

    _omp_redraw-prompt
}
_omp_create_widget zle-keymap-select _omp_zle-keymap-select

# reset to default mode at the end of line input reading
function _omp_zle-line-finish() {
    export POSH_VI_MODE="insert"
}
_omp_create_widget zle-line-finish _omp_zle-line-finish

# Fix a bug when you C-c in CMD mode, you'd be prompted with CMD mode indicator
# while in fact you would be in INS mode.
# Fixed by catching SIGINT (C-c), set mode to INS and repropagate the SIGINT,
# so if anything else depends on it, we will not break it.
TRAPINT() {
    export POSH_VI_MODE="insert"
    return $(( 128 + $1 ))
}

And use the following code block to display this:

mytheme.omp.json

{
  "type": "text",
  "style": "plain",
  "template": "{{ if .Env.POSH_VI_MODE }}({{ .Env.POSH_VI_MODE }}) {{ end }}"
}
NovaViper commented 1 week ago

Hey, would it be possible for you to also make it where the prompt symbol can change based on what mode we're in? Possibly integrate with the zsh-vi-mode plugin as an additional nicety!

JanDeDobbeleer commented 1 week ago

integrate with the zsh-vi-mode plugin as an additional nicety!

@NovaViper that's not something we do, but changing the icon is rather straightforward with the use of a template

NovaViper commented 5 days ago

@JanDeDobbeleer Ah ok! I was wondering because I can't consistently get the variable to display in the prompt. I can get it to show insert but oddly can't get command to appear when I hit the escape key to enter normal mode; even with the zsh-vi-mode plugin removed. What happens is when I first load up the terminal, the variable is empty (not taking into account the current mode when I start up is in viins). And when I hit enter, it shows insert; but command under any circumstance does not show at all.

This is my zshrc (I'm using NixOS with Home-Manager to setup zsh), https://gist.github.com/NovaViper/6eeb096936b0c52290632986a3a18d38