Open jsirex opened 6 years ago
I pushed a failing spec to fixes/kill-multiple-words
multiple words killed with `backward-kill-word`
can be yanked back with `yank` (FAILED - 1)
Failures:
1) multiple words killed with `backward-kill-word` can be yanked back with `yank`
Failure/Error: wait_for { session.content }.to eq('echo first second')
expected: "echo first second"
got: "echo first"
(compared using ==)
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/handler.rb:13:in `block (2 levels) in handle_matcher'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/handler.rb:10:in `loop'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/handler.rb:10:in `block in handle_matcher'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/handler.rb:9:in `handle_matcher'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/target.rb:30:in `block in to'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/target.rb:44:in `block in with_wait'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait.rb:28:in `with_wait'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/target.rb:44:in `with_wait'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/target.rb:30:in `to'
# ./spec/integrations/kill_word_spec.rb:12:in `block (2 levels) in <top (required)>'
# ./spec/spec_helper.rb:19:in `block (2 levels) in <top (required)>'
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait.rb:46:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# Timeout::Error:
# execution expired
# /usr/local/bundle/gems/rspec-wait-0.0.9/lib/rspec/wait/handler.rb:16:in `sleep'
Finished in 2.15 seconds (files took 0.24763 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/integrations/kill_word_spec.rb:10 # multiple words killed with `backward-kill-word` can be yanked back with `yank`
Looks like this behavior can be reproduced by simply wrapping backward-kill-word
in a user-defined widget.
% my-backward-kill-word() { zle backward-kill-word }
% zle -N my-backward-kill-word
% bindkey ^W my-backward-kill-word
The functionality where cut text is concatenated to be yanked in combined form later seems to be dependent on the two built-in cutting widgets running one directly after the other.
Some interesting places in the upstream code:
backward-kill-word
has flag ZLE_KILL
which flags it as a "kill" type command.ZLE_KILL
flag set. If it didn't, it will start a new buffer and thus not concatenate the text cut this time with the text cut last time.lastcmd
flags are reset to zero here when the user-defined widget finishes running.So the flow when using my-backward-kill-word
twice is something like:
1) backward-kill-word
built in finishes: from now on lastcmd
was a kill command
2) my-backward-kill-word
widget finishes: from now on lastcmd
was not a kill command
3) backward-kill-word
built in finishes: from now on lastcmd
was a kill command
4) my-backward-kill-word
widget finishes: from now on lastcmd
was not a kill command
Because the kill commands aren't coming one after another, the text is not concatenated for yanking.
Compare with the flow when using built-in backward-kill-word
:
1) backward-kill-word
built in finishes: from now on lastcmd
was a kill command
2) backward-kill-word
built in finishes: from now on lastcmd
was a kill command
Not sure how this could be fixed. Next step is probably an email to the mailing list.
Actually... there's a pretty easy fix if you're ok with not fetching suggestions after backward-kill-word
is executed.
Add backward-kill-word
to the list of ignore widgets in your zshrc:
# After sourcing zsh-autosuggestions.zsh
ZSH_AUTOSUGGEST_IGNORE_WIDGETS+=(backward-kill-word)
Also found this related issue in zsh-syntax-highlighting: https://github.com/zsh-users/zsh-syntax-highlighting/issues/150
Looks like it hasn't been merged yet, but there's a commit https://github.com/danielshahaf/zsh-syntax-highlighting/commit/bfa71c983fa6c3b43cc657276223410123d5c145 that uses zle -f
(only available in zsh >=5.2) to set the "kill" flag on the user-defined widgets wrapping the builtin kill widgets.
Here is a patch based on @ericfreese comment and the solution he has linked
I ran into this issue on and @ericfreese's hack worked for me. Would be great to get a long term fix for this merged in. Thanks for all of the great work on this plugin!
The issue with the proposed workaround is that it leaves the suggestion while this is not valid.
@macdems Maybe you could start a pull request with your suggestion? I think you need to somehow put the list of widgets into a specific variable, like this is done for ZSH_AUTOSUGGEST_IGNORE_WIDGETS
. If you don't have time, I can do that for you.
@vincentbernat I can do this, but next week the earliest (no I am almost fully offline with no access to any computer).
I have created a pull request. In my system yanking does not leave the suggestion, so it also seems to solve #526.
I have created a pull request. In my system yanking does not leave the suggestion, so it also seems to solve #526.
I tried applying this patch on top of upstream. Ctrl-w Ctrl-y is still broken for me after that.
Has anyone gotten the normal behavior of select-word-style bash
to actually work while zsh-autosuggestions
is enabled?
I've been seeing broken behavior where Ctrl+w will gobble up the entire line always into the cut buffer, no matter that WORDCHARS
had been set to (e.g. so as to not include spaces). Then Ctrl+y shows what is there by "yanking" (pasting) that entire line out, not just the last word. When I use the ZSH_AUTOSUGGEST_IGNORE_WIDGETS
workaround, and disable select-word-style bash
, then normal Zsh behavior for backward-kill-word
is restored where one word at a time can be deleted backwards via Ctrl+w, then pasted back with Ctrl+y. Yet, then I can't set it up like bash
word behavior because Zsh defaults to not include /
and '
separators as "words".
I've tried out the change in PR #551, but behavior is still the same unless I add backward-kill-word
, and backward-kill-word-match
to the ZSH_AUTOSUGGEST_IGNORE_WIDGETS
array, and disable select-word-style bash
entirely. So my choices seem to be: use zsh-autosuggestions
but be forced to have Zsh default Ctrl+w word behavior, OR disable zsh-autosuggestions
and then get select-word-style bash
behavior working.
The only way I've been able to get normal select-word-style bash
behavior is to not load zsh-autosuggestions
plugin at all! 🤷
@trinitronx I just tried out PR #551 with zsh 5.9 and it works for me, though it also need a little fix for yank-pop
as noted by @vincentbernat which I've added in another PR #795
Given command:
echo first second
I want to cut two wordsfirst second
by typing CTRL+WW .But then when I try to paste it with CTRL+Y I'm getting only one word:
first
.I'm using oh-my-zsh: