ChrisJohnsen / tmux-MacOSX-pasteboard

Notes and workarounds for accessing the Mac OS X pasteboard in tmux sessions. Note: The pu branch (“Proposed Updates”) may be rewound without notice.
BSD 2-Clause "Simplified" License
2.38k stars 84 forks source link

zsh prompt char disappears with `set-option -g default-command "reattach-to-user-namespace -l zsh` #48

Open srustamo opened 8 years ago

srustamo commented 8 years ago

I'm using pure prompt with this .zshrc.

Adding set-option -g default-command "reattach-to-user-namespace -l zsh to my .tmux.conf makes the prompt char disappear in tmux zsh session.

There is no problem with the prompt outside of tmux. Why would this happen?

OSX 10.9.5, zsh 5.2 (x86_64-apple-darwin13.4.0)

ChrisJohnsen commented 8 years ago

I could not reproduce anything like that until I did a git init in my testing directory. I suspect your problem has to do with the asynchronous redrawing of the branch+status (and prompt) that “pure” does. It does not seem to have anything to do with tmux or reattach-to-user-namespace though: I can produce the (same?) effect by just starting a plain zsh (using a pared down version of your configuration) while in a dirty Git directory (unstaged and/or untracked changes).

Using script to capture the escape sequences, you can see the prompt being printed multiple times (once as normal, once more due to your zle-line-init hook, and again when “pure” decides to redraw its prompt). You probably only see the last of these since each erases the one before it and they happen fairly quickly. The first and last prompt redraws happen with an unset KEYMAP, which is probably the ultimate cause of your disappearing prompt (the debugging version of your PROMPT that I use helps to spot this by including the unmodified value in the prompt itself).

PROMPT='[KEYMAP:${KEYMAP-<<unset>>}]%(?.%F{green}.%F{red})${${KEYMAP/vicmd/❮}/(main|viins)/❯}%f '

I found that the problems does not occur with /bin/zsh (5.0.8 from 10.11.4), but does for my /opt/local/bin/zsh (5.1.1 from MacPorts). Maybe it is a bug or adverse interaction only present in newer versions of zsh?

Overall, relying on KEYMAP in PROMPT seems likely to be pretty fragile since KEYMAP only seems to be set in contexts created by zle. You kind of force that with your zle .reset-prompt in zle-line-init, but that also seems to be fragile in the case of whatever “pure” does to cause prompt redrawing.

srustamo commented 8 years ago

Not sure why I see this in tmux only and not outside it. I referenced the issue in pure issues, I hope you don't mind.

srustamo commented 8 years ago

Barring a clean solution, I can make use of fine-grained solution options detailed in Usage.md to access pasteboard from within tmux.

However, anything launched from within it, vim, for instance, don't have access to clipboard. I might of course launch these with reattach-to-user-namespace from within tmux, but that seems to be too convoluted.

Edit: this would avoid having set-option -g default-command "reattach-to-user-namespace -l zsh in .tmux.conf, without which there is no problem, on my system at least. Which, admittedly, you don't seem to think is the problem.

Edit 2: incidentally, if I'm in a git controlled dir in tmux, I don’t see the disappearing char. i.e. I never see [KEYMAP:<<unset>>] outside tmux or in a git controlled dir inside tmux.

ChrisJohnsen commented 8 years ago

Odd. Being in a tmux session never made a difference for me (with or without launching the shell through the wrapper). The only thing that triggered the problem for me was being in a “dirty” Git working tree and running zsh 5.1.1. Any of 1) being outside a Git working tree, 2) being inside a clean Git working tree, or 3) running zsh 5.0.8 avoided the problem that I was able to reproduce.

Are you sure that you are using the same zsh version in all your contexts? When I use this prompt:

PROMPT='[ZV:$ZSH_VERSION,KEYMAP:${KEYMAP-<<unset>>}]%(?.%F{green}.%F{red})${${KEYMAP/vicmd/❮}/(main|viins)/❯}%f '

I see [ZV:5.1.1,KEYMAP:<<unset>>] when in a dirty Git working tree, but I have never been able to trigger [ZV:5.0.8,KEYMAP:<<unset>>].

Playing around a bit more, I found something else that fixes the problem in my replication setup: replacing prompt pure with setopt promptsubst. The fact that this fixes the basic prompt in all situations points to a bad interaction with “pure” (i.e. KEYMAP is not set when it redraws a changed prompt after one of its async jobs finishes). The resulting configuration is missing the “pure” cwd and branch+status prefix line, but KEYMAP is always set (for the last prompt printing) and the “prompt character” never disappears.

Can you put together a minimal configuration (e.g. .tmux.conf and .zshrc with just your prompt and “pure”) that exhibits the problem? You might find ZDOTDIR helpful for keeping such a test configuration separate from your normal configuration.

# put minimal .zshrc and .tmux.conf in ~/tmp/48/ (also the fpath bits for “pure” in a subdir)

# test outside tmux
ZDOTDIR=$HOME/tmp/48 zsh -l

# test inside tmux
ZDOTDIR=$HOME/tmp/48 tmux -L issue48 -f $HOME/tmp/48/.tmux.conf
srustamo commented 8 years ago

Over at 'pure' issue tracker, your first reply here resulted in the following, which seems to fix the problem:

VIM_PROMPT="❯"
PROMPT='%(?.%F{green}.%F{red})${VIM_PROMPT}%f '

function zle-line-init zle-keymap-select { 
    VIM_PROMPT=${(S%%)${KEYMAP/vicmd/❮}/(main|viins)/❯} # Expand string in place
    zle .reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select 

Do you see any issues with such a solution?

ChrisJohnsen commented 8 years ago

That seems like a good workaround. It fixes the problem that I was able to reproduce.

When using zsh 5.1.1, KEYMAP is still unset during pure’s async-triggered multi-line redraw, but the intermediate zle-line-init-triggered prompt redraw saves the appropriate value for VIM_PROMPT for the KEYMAP-less redrawing to use.

srustamo commented 8 years ago

Thank you for you help!

srustamo commented 8 years ago

I just noticed that I lost visual select mode when in normal mode. I can yank word object and paste it, but not visually select some parts of a line and yank. Could that be due to the prompt related code?

ChrisJohnsen commented 8 years ago

Is that something to do with zle’s vi mode? I do not use that. What key strokes (or mouse actions?) do you use? It is reproducible in a minimal configuration that I can easily setup in an alternate ZDOTDIR?

And no, I would not expect normally expect the PROMPT to affect editing modes.

srustamo commented 8 years ago

Yes, it is related to zle's vi mode.

Following your advice, I created .zshenv with ZDOTDIR=$HOME/tmp/48 zsh -l in it. In that dir, I created a minimal .zshrc.

Also, in ZDOTDIR=$HOME/tmp/48/bare_zshrc I created a .zshrc with just this line bindkey -v.

With this last bare_zshrc I don't see zle's visual select at all (as well as with the one in 48 dir). I probably need more sleep, but I'm vaguely sure that I did see this available on my system before fiddling with prompt. I also thought that terminal's theming maybe to blame, tried different themes without luck. Also no go is the OSX standard Terminal app.

A bit of investigation led me to this in zle manual, which might confirm that I was not seeing things:

_The parameter zle_highlight is also used by the line editor; see Character Highlighting. Highlighting of special characters and the region between the cursor and the mark (as set with set-mark-command in Emacs mode, or by visual-mode in Vi mode) is enabled by default; consult this reference for more information. Irascible conservatives will wish to know that all highlighting may be disabled by the following setting: zlehighlight=(none)

There's also discussion of vi visual mode in zsh-syntax-highlighting.

I understand that I'm totally off the original subject, and appreciate your help.