Zsh-autosuggestions: Maybe fix for slow pastes

Created on 9 May 2017  路  15Comments  路  Source: zsh-users/zsh-autosuggestions

Howdy, I think I may have a solution for slow pastes (#141 #219) but I'm not sure if there are problems with it or what the best way to actually implement it is.

I believe that the paste slowdown comes from the additional zle invocation to call the original widget on self-insert. Rather than doing that, if, on disable, we replace self-insert with the original widget and then on enable, we replace it back, things are snappy.

Here is my naive implementation:

# Disable suggestions
_zsh_autosuggest_disable() {
    typeset -g _ZSH_AUTOSUGGEST_DISABLED
    _zsh_autosuggest_clear
    zle -N self-insert url-quote-magic
}

# Enable suggestions
_zsh_autosuggest_enable() {
    unset _ZSH_AUTOSUGGEST_DISABLED
    zle -N self-insert _zsh_autosuggest_bound_1_self-insert

    if [ $#BUFFER -gt 0 ]; then
        _zsh_autosuggest_fetch
    fi
}

Obviously we shouldn't hard-code url-quote-magic or _zsh_autosuggest_bound_1_self-insert but I wasn't sure of the best way to get the right ones in there.

Thoughts? Suggestions? Thanks!

Most helpful comment

Works for me. Thanks again for your help.

For posterity:

# This speeds up pasting w/ autosuggest
# https://github.com/zsh-users/zsh-autosuggestions/issues/238
pasteinit() {
  OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
  zle -N self-insert url-quote-magic # I wonder if you'd need `.url-quote-magic`?
}

pastefinish() {
  zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish

All 15 comments

Thanks for this @aaronjensen. I think it's an interesting idea, but as far as I can tell won't be super-straightforward to implement. I don't think I'll have time to look deeper into this until the fall, but if you're interested, it would probably be good to read through src/bind.zsh. Also see the zle built-in.

I'm curious though- what is your use case for bracketed-paste-magic? Have you considered disabling it?

Edit: You may be able to get something working for your personal config by saving the bound widget to some global variable on paste-init (you can get with ${${(s.:.)widgets[self-insert]}[2,3]}) and restoring on paste-finish, but I wouldn't want to merge that into this plugin because it will break other plugins like zsh-syntax-highlighting.

Maybe something like this?

paste-init() {
  OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
  zle -N self-insert url-quote-magic # I wonder if you'd need `.url-quote-magic`?
}

paste-finish() {
  zle -N self-insert $OLD_SELF_INSERT
}

Thanks for the suggestion, this seems to work on first test.

Do you know why it breaks zsh-syntax-highlighting? FWIW, it doesn't work 100% for me even without this, it's just that with this, it breaks differently.

Without the above fix it strips all of the highlighting:

without

With the above fix it strips one char worth of highlighting for each character that bracketed paste magic adds.

with

Pasting a command that has highlighting behaves the same either way, what is pasted is inverted until you hit something, then the syntax highlighting takes over.

So I think there's actually just a bug between zsh-sytnax-highlighting and bracketed-paste-magic, I'm not sure that your suggested fix above breaks anything further. I'm going to run with it for a while, having the instance paste back is awesome!

By the way, here are paste comparisons:

without

with

@ericfreese FYI, this is still working great for me. What would you think about including this built in?

@aaronjensen

The patch mentioned in #219 should be included as of zsh v5.4, and should make all of this paste-init/paste-finish stuff unnecessary.

Would you mind trying out 5.4 or greater and reporting back?

Unfortunately, it seems that it is the same on zsh 5.4. I'm on develop and:

$ zsh --version
zsh 5.4.2 (x86_64-apple-darwin17.0.0)

zsh54

Your suggested fix above does still work.

afaict, any sort of early return from within _zsh_autosuggest_modify is not enough to speed it up. If I return immediately after _zsh_autosuggest_invoke_original_widget $@ it is still slow.

fwiw removing _zsh_autosuggest_highlight_reset and _zsh_autosuggest_highlight_apply from the widget eval speed things up somewhat, but it's still not as fast as the widget not being there.

Going to close this issue as it seems the paste-init/paste-finish solution posted solves the slow paste issue with bracketed-paste-magic. If there are other problems with this solution, let's create new issues for them.

Works for me. Thanks again for your help.

For posterity:

# This speeds up pasting w/ autosuggest
# https://github.com/zsh-users/zsh-autosuggestions/issues/238
pasteinit() {
  OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
  zle -N self-insert url-quote-magic # I wonder if you'd need `.url-quote-magic`?
}

pastefinish() {
  zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish

@aaronjensen This didn't cut it for me :

I'm not sure what I did wrong and how to fix it.

I was redirected from #351 as I mostly wanted to disable autosuggestions when something is pasted in the shell. e.g. when git clone is already typed in autosuggest suggests the previous repo url, but when pasting another git URL, and pressing the left arrow, the previous suggesstion is appended.

@bric3, I experience this bug as well. The above fix isn't really intended to address that, it's intended to make pasting fast, which it does for me. It seems there could still be an issue with either that fix or with zsh-autosuggestions.

@aaronjensen OK, indeed, it works in that regard !
Anyway applying this trick https://github.com/zsh-users/zsh-autosuggestions/issues/351#issuecomment-472020765 appears to fix my issue, but I'm not sure why.

Where does one use apply this?

Works for me. Thanks again for your help.

For posterity:

# This speeds up pasting w/ autosuggest
# https://github.com/zsh-users/zsh-autosuggestions/issues/238
pasteinit() {
  OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
  zle -N self-insert url-quote-magic # I wonder if you'd need `.url-quote-magic`?
}

pastefinish() {
  zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish

I put mine in my .zshrc

The proposed fix works for me but why is it not added to zsh-autosuggestions and needs to be applied manually?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dragonxlwang picture dragonxlwang  路  3Comments

Kenmmm picture Kenmmm  路  4Comments

raulferras picture raulferras  路  3Comments

OmeGak picture OmeGak  路  3Comments

moritzschaefer picture moritzschaefer  路  5Comments