Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show current mode in ZSH Vi mode #5438

Open
1 task done
stepanzak opened this issue Aug 9, 2024 · 7 comments
Open
1 task done

Show current mode in ZSH Vi mode #5438

stepanzak opened this issue Aug 9, 2024 · 7 comments
Assignees
Labels
🚀 feat New feature

Comments

@stepanzak
Copy link

Code of Conduct

  • I agree to follow this project's 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
Copy link

gwojan commented Sep 10, 2024

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
Copy link
Owner

JanDeDobbeleer commented Sep 29, 2024

@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
Copy link

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
Copy link
Owner

JanDeDobbeleer commented Nov 3, 2024

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
Copy link

NovaViper commented Nov 7, 2024

@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

@Frestein
Copy link

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!

My solution:
image
image
image
image
image

# OMP zsh-vi-mode integration
_omp_redraw-prompt() {
  local precmd
  for precmd in "${precmd_functions[@]}"; do
    "$precmd"
  done

  zle .reset-prompt
}

export POSH_VI_MODE="I"

function zvm_after_select_vi_mode() {
  case $ZVM_MODE in
  $ZVM_MODE_NORMAL)
    POSH_VI_MODE="N"
    ;;
  $ZVM_MODE_INSERT)
    POSH_VI_MODE="I"
    ;;
  $ZVM_MODE_VISUAL)
    POSH_VI_MODE="V"
    ;;
  $ZVM_MODE_VISUAL_LINE)
    POSH_VI_MODE="V-L"
    ;;
  $ZVM_MODE_REPLACE)
    POSH_VI_MODE="R"
    ;;
  esac
  _omp_redraw-prompt
}
[[blocks.segments]]
leading_diamond = ''
trailing_diamond = ''
template = '{{ if .Env.POSH_VI_MODE }}{{ .Env.POSH_VI_MODE }}{{ end }}'
foreground = 'red'
background = '#3C3836'
type = 'text'
style = 'diamond'
foreground_templates = [
  "{{if contains \"N\" .Env.POSH_VI_MODE}}blue{{end}}",
  "{{if contains \"I\" .Env.POSH_VI_MODE}}magenta{{end}}",
  "{{if contains \"V\" .Env.POSH_VI_MODE}}cyan{{end}}",
  "{{if contains \"V-L\" .Env.POSH_VI_MODE}}cyan{{end}}",
  "{{if contains \"R\" .Env.POSH_VI_MODE}}yellow{{end}}",
]

@NovaViper
Copy link

NovaViper commented Nov 21, 2024

@Frestein Thanks! I took your example and further modified it to allow for the prompt character to change!

# OMP zsh-vi-mode integration
_omp_redraw-prompt() {
  local precmd
  for precmd in "${precmd_functions[@]}"; do
    "$precmd"
  done
  zle && zle reset-prompt
}

export POSH_VI_MODE="$(printf '\u276F')"

function zvm_after_select_vi_mode() {
  case $ZVM_MODE in
  $ZVM_MODE_NORMAL)
    POSH_VI_MODE="$(printf '\u276E')"
    ;;
  $ZVM_MODE_INSERT)
    POSH_VI_MODE="$(printf '\u276F')"
    ;;
  $ZVM_MODE_VISUAL)
    POSH_VI_MODE="$(printf '\u2164')"
    ;;
  $ZVM_MODE_VISUAL_LINE)
    POSH_VI_MODE="$(printf '\u2164')"
    ;;
  $ZVM_MODE_REPLACE)
    POSH_VI_MODE="$(printf '\u25B6')"
    ;;
  esac
  _omp_redraw-prompt
}

This is translated from my json file that my NixOS configuration generates, may not work exactly as intended.

[var]
PromptChar = "❯"

[[blocks]]
type = "prompt"
newline = "true"
alignment = "left"
    [[blocks.segments]]
    background = "transparent"
    foreground_templates = [
        "{{if gt .Code 0}}1{{end}}",
        "{{if eq .Code 0}}10{{end}}"
    ]
    style = "plain"
    template = "{{ if .Env.POSH_VI_MODE }}{{ .Env.POSH_VI_MODE }}{{ else }}{{.Var.PromptChar}}{{ end }}"
    type = "text"

Quick Edit: Here's a reference of the commit for anyone who needs it for their own NixOS setup! NovaViper/NixConfig@13e0d01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚀 feat New feature
Projects
None yet
Development

No branches or pull requests

5 participants