jeffreytse / zsh-vi-mode

💻 A better and friendly vi(vim) mode plugin for ZSH.
MIT License
3.07k stars 107 forks source link

Prompt got eaten and move up a line on certain actions #124

Open jeffreytse opened 2 years ago

jeffreytse commented 2 years ago

General information

Please report the following information as possible as you can:

Basic examination

Problem description

The prompt jumps up, deleting whatever line came before it. In the below case, use a two-line prompt, and both lines in the prompt jump up to delete the line of output before them.

To illustrate, the terminal looks like this:

Last login: Wed Sep  8 14:38:23 on ttys004
╭─ ~                                                                      ✔
╰─ echo "output to be clobbered by the next prompt"
output to be clobbered by the next prompt
╭─ ~                                                                      ✔
╰─

Then, I hit S and my terminal looks like this:

Last login: Wed Sep  8 14:38:23 on ttys004
╭─ ~                                                                       ✔
╰─ echo "output to be clobbered by the next prompt"
╭─ ~                                                                       ✔
╰─

Notice that the line of output following the echo got eaten, and the prompt is now one line higher in the terminal than it started at.

Reproduction steps

  1. Either open a new terminal or just hit to get a fresh prompt.
  2. Type <ESC>S or <ESC>R<ESC>

Expected behavior

The prompt should keep at the same line rather than moving up a line.

jeffreytse commented 2 years ago

This issue is introduced by 1549325615a5da5ec570289dfa08687cece1c5f6 and c1480b4a96dfe9ff5ca28f482a7417db25bdd797.

ecbaldwin commented 2 years ago

I've updated to the latest version and it does fix the issue in almost every case. I still see it occasionally on a fresh terminal if S is the first thing I do and it has also happened 2-3 times in other situations. I might have to give it some time to see exactly what actions lead to it still occurring.

For now, this seems like a big improvement and is enough to get me to switch from softmoth/zsh-vim-mode

trmckay commented 2 years ago

I am still experiencing this issue, but only under tmux.

Steps to reproduce:

  1. Load tmux session with default config.
  2. Press enter a few times.
  3. Switch between normal and insert mode a few times.

The prompts will get clobbered.

jeffreytse commented 2 years ago

@trmckay Thanks! Could you provide me some more details of your environment? Such as ZSH framework, theme and so on.

trmckay commented 2 years ago

@jeffreytse Of course, here is my zshrc. In short, I am using zplug with a few plugins and the starship prompt.

#!/bin/zsh

source $HOME/.aliases

setopt correct

HISTFILE=$HOME/.zsh_history
HISTSIZE=2000
SAVEHIST=1000

# Directory navigation
setopt autocd autopushd pushdignoredups

# Starship prompt
eval "$(starship init zsh)"
export STARSHIP_CONFIG=~/.config/starship.toml

source /usr/share/zsh/scripts/zplug/init.zsh

zplug "jeffreytse/zsh-vi-mode"
zplug "mdumitru/fancy-ctrl-z"
zplug "zsh-users/zsh-syntax-highlighting"
zplug "mdumitru/git-aliases"
zplug "zpm-zsh/tmux"
zplug "zsh-users/zsh-completions"
zplug "unixorn/fzf-zsh-plugin"

TMUX_AUTOSTART=false
TMUX_MOTD=false

export KEYTIMEOUT=1

zplug load

function post_init() {
    # Start a tmux session.
    function start_tmux {
        session=$(tmux ls 2> /dev/null | fzf --print-query | cut -d':' -f1)
        exists=$(echo $session | wc -l)
        if [ $exists -ne 2 ]; then
            session=$(echo $session | head -1)
            if [ "$session" == "" ]; then
                return 1
            fi
            cd "$(fd -t d '.*' . | fzf)" || return 1
        else
            session=$(echo $session | tail -1)
        fi
        tmux new-session -A -s "$session" || return 1
    }
    bindkey -s '^n' 'start_tmux^M'

    # Open a file in nvim.
    bindkey -s '^o' 'nvim $(fzf)^M'

    [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
}

zvm_after_init_commands+=('post_init')

eval "$(zoxide init zsh)"

### oh-my-zsh completion

# Handle completions insecurities (i.e., completion-dependent directories with
# insecure ownership or permissions) by:
#
# * Human-readably notifying the user of these insecurities.
function handle_completion_insecurities() {
  # List of the absolute paths of all unique insecure directories, split on
  # newline from compaudit()'s output resembling:
  #
  #     There are insecure directories:
  #     /usr/share/zsh/site-functions
  #     /usr/share/zsh/5.0.6/functions
  #     /usr/share/zsh
  #     /usr/share/zsh/5.0.6
  #
  # Since the ignorable first line is printed to stderr and thus not captured,
  # stderr is squelched to prevent this output from leaking to the user.
  local -aU insecure_dirs
  insecure_dirs=( ${(f@):-"$(compaudit 2>/dev/null)"} )

  # If no such directories exist, get us out of here.
  [[ -z "${insecure_dirs}" ]] && return

  # List ownership and permissions of all insecure directories.
  ls -ld ${(@)insecure_dirs}
}

# fixme - the load process here seems a bit bizarre
zmodload -i zsh/complist

WORDCHARS=''

unsetopt menu_complete   # do not autoselect the first completion entry
unsetopt flowcontrol
setopt auto_menu         # show completion menu on successive tab press
setopt complete_in_word
setopt always_to_end

# should this be in keybindings?
bindkey -M menuselect '^o' accept-and-infer-next-history
zstyle ':completion:*:*:*:*:*' menu select

# case insensitive (all), partial-word and substring completion
if [[ "$CASE_SENSITIVE" = true ]]; then
  zstyle ':completion:*' matcher-list 'r:|=*' 'l:|=* r:|=*'
else
  if [[ "$HYPHEN_INSENSITIVE" = true ]]; then
    zstyle ':completion:*' matcher-list 'm:{a-zA-Z-_}={A-Za-z_-}' 'r:|=*' 'l:|=* r:|=*'
  else
    zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
  fi
fi
unset CASE_SENSITIVE HYPHEN_INSENSITIVE

# Complete . and .. special directories
zstyle ':completion:*' special-dirs true

zstyle ':completion:*' list-colors ''
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'

if [[ "$OSTYPE" = solaris* ]]; then
  zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm"
else
  zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm -w -w"
fi

# disable named-directories autocompletion
zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories

# Use caching so that commands like apt and dpkg complete are useable
zstyle ':completion:*' use-cache yes
zstyle ':completion:*' cache-path $ZSH_CACHE_DIR

# Don't complete uninteresting users
zstyle ':completion:*:*:*:users' ignored-patterns \
        adm amanda apache at avahi avahi-autoipd beaglidx bin cacti canna \
        clamav daemon dbus distcache dnsmasq dovecot fax ftp games gdm \
        gkrellmd gopher hacluster haldaemon halt hsqldb ident junkbust kdm \
        ldap lp mail mailman mailnull man messagebus  mldonkey mysql nagios \
        named netdump news nfsnobody nobody nscd ntp nut nx obsrun openvpn \
        operator pcap polkitd postfix postgres privoxy pulse pvm quagga radvd \
        rpc rpcuser rpm rtkit scard shutdown squid sshd statd svn sync tftp \
        usbmux uucp vcsa wwwrun xfs '_*'

# ... unless we really want to.
zstyle '*' single-ignored show

if [[ $COMPLETION_WAITING_DOTS = true ]]; then
  expand-or-complete-with-dots() {
    print -Pn "%F{red}…%f"
    zle expand-or-complete
    zle redisplay
  }
  zle -N expand-or-complete-with-dots
  # Set the function as the default tab completion widget
  bindkey -M emacs "^I" expand-or-complete-with-dots
  bindkey -M viins "^I" expand-or-complete-with-dots
  bindkey -M vicmd "^I" expand-or-complete-with-dots
fi

# automatically load bash completion functions
autoload -U +X bashcompinit && bashcompinit

zstyle ':completion:*:approximate:*' max-errors 2
zstyle ':completion:*:ssh:*' hosts off

source $HOME/.local.zsh

I've also since found that the issue only occurs with the starship prompt.

jeffreytse commented 2 years ago

@trmckay You mean that this issue will disappear without the starship?

trmckay commented 2 years ago

@jeffreytse Yeah. I looked through their issues and couldn't find anything relevant. I think maybe this is specific to multiline prompts, not starship itself. But, I can do more testing later.

jeffreytse commented 2 years ago

@trmckay Thank you for your kindly testing, once you got any progress, you are welcome to touch me. : )

trmckay commented 2 years ago

@jeffreytse some info for you. This issue is now specific to starship and affects multi- and single-line prompts. There are no issues being tracked in the starship repo. Let me know if I can help you solve this.

jeffreytse commented 2 years ago

Hi @trmckay

Thanks for your following up, could you provide me a minimum .zshrc file which can reproduce the issue in your environment? I will try to settle with your minimum .zshrc file. And you're welcome to contribute to this project if you have any idea on this issue with the source code.

Thanks and Regards

trmckay commented 2 years ago

@jeffreytse with starship, tmux, and zplug installed:

eval "$(starship init zsh)"
export STARSHIP_CONFIG=~/.config/starship.toml
source /usr/share/zsh/scripts/zplug/init.zsh
zplug "jeffreytse/zsh-vi-mode"
zplug load

Pinning to a version without the bug:

eval "$(starship init zsh)"
export STARSHIP_CONFIG=~/.config/starship.toml
source /usr/share/zsh/scripts/zplug/init.zsh
zplug "jeffreytse/zsh-vi-mode", at:v0.8.4
zplug load
tymcauley commented 2 years ago

I have also noticed this same behavior in the following environment:

For me, the critical ingredients appear to be the following:

So, this .zshrc appears to be enough to trigger the issue:

source ~/powerlevel10k/powerlevel10k.zsh-theme
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
source ~/.zsh-vi-mode/zsh-vi-mode.plugin.zsh

If you don't have a ~/.p10k.zsh config file, the config wizard will guide you through setting up a prompt, I use a dual-line prompt with a blank line in between each prompt.

Then, run tmux to start a new tmux session. Hit Enter to add in a few new lines, hit Esc to enter vi normal mode, and then each time you hit Esc, the prompt will move up and eat a line on the screen.

jeffreytse commented 2 years ago

Hi @trmckay @tymcauley

Thanks for the helpful information, once I get progress, I will let you know. : )

Thanks and Regards

slacksystem commented 2 years ago

I'm having this issue too with oh-my-zsh with several plugins enabled, and zsh-vi-mode. Happens only in tmux, and only with multiline prompt. It also happens when using tab completion

EDIT: I don't know what starship is but I do not believe I have it

tmmgeekette commented 2 years ago

I just spent 2 days trying to fix this problem. I didn't realize there was a bug report on it.

This is happening for me on macos. I've got. Zsh, starship, vi mode. It happens after I hit ESC to go into vi command mode. The first key I type in command mode (no matter what it is) the prompt eats 2 lines above it. Tmux or no tmux.

Is there a fix available for this yet?

tmmgeekette commented 2 years ago

Fixed my problem 3 different ways.

1 deleting zle-keymap-select widget altogether solves this for me.

2 sticking the following into my .zshrc , also solves the problem.

function zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}"
    RPS2=$RPS1
    zle reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select

3 And lastly, I discovered I was initializing starship twice in my .zshrc. Removing one of the two init lines fixes it as well.

julianKatz commented 2 years ago

I am also experiencing this bug, but I'm running this as my theme:

zplug 'romkatv/powerlevel10k', as:theme, depth:1

I'm also running on tmux. This tmux is running on a linux machine which I've connected to over ssh from a mac. My prompt is multi-line as well.

❯ zsh --version
zsh 5.8 (x86_64-debian-linux-gnu)
❯ tmux -V
Alias tip: tm -V
tmux 3.2a
piersolenski commented 2 years ago

Also getting this with Starship regardless of whether in tmux or not...

scresante commented 2 years ago

@jeffreytse some info for you. This issue is now specific to starship and affects multi- and single-line prompts. There are no issues being tracked in the starship repo. Let me know if I can help you solve this.

It's not specific to starship. I don't use starship, and I still have this issue.

slacksystem commented 2 years ago

I don't use starship either and was having this issue. PR #180 seems to have fixed it for me

nwaywood commented 2 years ago

I needed to use PR #180 AND do point 2 here https://github.com/jeffreytse/zsh-vi-mode/issues/124#issuecomment-1021410225 to fix it.

Note that I use pure prompt

julianKatz commented 1 year ago

Any update here? Would love to see this fixed.

jeffreytse commented 1 year ago

Any update here? Would love to see this fixed.

Hi @julianKatz, the PR #180 has been merged, hope this helpful. : )

diminutivesloop commented 1 year ago

I'm seeing this after updating to 0.10.0. I don't remember encountering this issue before today which is weird because it's such a long-standing issue.

jeffreytse commented 1 year ago

@diminutivesloop, could you provide minimum reproduce steps for your seeing, so that I can have a further check for you. Thank you! : )

jeffreytse commented 1 year ago

@diminutivesloop Could you try again with the latest update? If you're using zsh-syntax-highlighting plugin, it should fix the issue. : )

diminutivesloop commented 1 year ago

@diminutivesloop I'm already on 0.10.0 and the issue is still present and I don't see any newer version that's been released. I also don't have zsh-syntax-highlighting installed so that wouldn't be causing the issue. I can look at producing a minimal reproduction.

jeffreytse commented 1 year ago

@diminutivesloop Thanks for your update, could you try with the latest update 4d778df, which means you clone this repository directly.

diminutivesloop commented 1 year ago

So I was actually able to try the latest version by running brew install zsh-vi-mode --HEAD, and from my testing this issue appears to be fixed.

mxstbr commented 7 months ago

I just installed the latest version from GitHub together with Sindre's Pure prompt and it always deletes the latest line when I switch between insert mode and visual mode.

Video recording: https://s.stl8.co/TSLCLRZV

mxstbr commented 7 months ago

The exact commands I ran from history:

CleanShot 2024-01-11 at 12 16 17@2x
juliusbachnick commented 4 days ago

I experience the same isse using Sindre's pure prompt together with zsh-vi-mode. Without this plugin (using bindkey -v), lines are not eaten away.