zsh-users / zsh-autosuggestions

Fish-like autosuggestions for zsh
MIT License
30.81k stars 1.85k forks source link

How to bind `tab` / `ctrl + h` key to accept / clear the current suggestion without disappearing the default behavior #633

Closed noraworld closed 2 years ago

noraworld commented 2 years ago

This is a help wanted, not a bug report or a feature request.

How can I bind keys as they meet the following requirements?

I have tried the following, but I realized the default behavior disappears.

bindkey '\t' autosuggest-accept
bindkey '^H' autosuggest-clear

I want to accept auto-suggestion / clear auto-suggestion by pressing tab key / ctrl + h key, but I don’t want to override the existing key bindings.

I have read #532, but I could not resolve the problem.

Any suggestions would be greatly appreciated!

Thank you.

ericfreese commented 2 years ago

If the auto-suggestion is available (when a part of command that I have not typed yet shows up with grey-colored), press the tab key to accept the current suggestion, otherwise the tab key behaves as default

I think you will need to define a custom widget for this. You can probably check if $POSTDISPLAY has non-zero length and if so run autosuggest-accept. Else call your completion widget that you currently have tab bound to. Then bind tab to that widget

If the auto-suggestion is available (when a part of command that I have not typed yet shows up with grey-colored), press the ctrl + h to clear the current suggestion, otherwise the ctrl + h behaves as default (backward-delete-char; it deletes one character)

I would think you can tackle this a similar way. Make a custom widget that calls autosuggest-clear if the POSTDISPLAY is set. Otherwise calls backward-delete-char

noraworld commented 2 years ago

@ericfreese Thank you for your reply!

I understand what you said, but I don’t know how to code them. Would you give me a brief code example? It’s OK even if it’s a pseudo code.

noraworld commented 2 years ago

I took a look at what $POSTDISPLAY is and how to use it after you helped me. Then what I want to do has been finally realized as follow:

function __smart_completion() {
  if [ -n "$POSTDISPLAY" ]; then
    zle autosuggest-accept
  else
    zle expand-or-complete
  fi
}

zle -N __smart_completion
bindkey '\t' __smart_completion

function __smart_backward() {
  if [ -n "$POSTDISPLAY" ]; then
    zle autosuggest-clear
  else
    zle backward-delete-char
  fi
}

zle -N __smart_backward
bindkey '^H' __smart_backward

But... this was different than what I was expecting. The auto-suggestion is so powerful, so I had hard time using the original completion behavior. In addition, deleting a char goes slow because the auto-suggestion shows up every time deleting a char.

I ended up reverting the original auto-suggestion keybindings back 😅 But I learned a lot from what you said. I appreciate it 🙏

Thank you!

loodvn commented 1 year ago

Thanks for the great plugin! As a first time user, I also find tab (when suggestions are available) to be more natural than other keybindings (e.g. when I use VSCode/other IDEs I use tab to apply completion).

I understand there's the clash with zsh's tab behaviour (and the solution of keeping both is great) so just adding another vote towards adding this tab option.