Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom fuzzy completion for commands that are not first in the pipeline ($LBUFFER) #4074

Closed
4 of 10 tasks
balta2ar opened this issue Nov 1, 2024 · 3 comments
Closed
4 of 10 tasks

Comments

@balta2ar
Copy link

balta2ar commented Nov 1, 2024

Checklist

  • I have read through the manual page (man fzf)
  • I have searched through the existing issues
  • For bug reports, I have checked if the bug is reproducible in the latest version of fzf

Output of fzf --version

0.56.0 (ff16877)

OS

  • Linux
  • macOS
  • Windows
  • Etc.

Shell

  • bash
  • zsh
  • fish

Problem / Steps to reproduce

This must have been discussed somewhere during the fzf history, but I can't seem to find any relevant issues or a clear statement that it's not possible in man or on github or wiki (https://github.com/junegunn/fzf/wiki/Examples-(completion)#writing-custom-fuzzy-completion) 😞

I'm trying to make a custom completion for llm command to complete available LLM models:

git di | llm -m **<cursor>

A naive handler is simply not triggered:

_fzf_complete_llm() {
  ARGS="$@"
  if [[ $ARGS == 'llm'* ]]; then
...

or to be more precise, instead, git handler is triggered (which I have a custom handler for):

_fzf_complete_git() {
    ARGS="$@"
...

so it looks like everything that has to do with that type of completion works under the assumption that the command we're completing is the first one? So how can I have a handler for command that is not the first one in the pipeline? Is that possible at all?

I guess I could in that specific case override my git handler, make it more smart at parsing the whole line and check where the "cursor" is, but what if it's a different command I don't have a handler for, e.g.:

xclip -o -selection clibboard | llm --system "translate to english" -m **<cursor>
@LangLangBart
Copy link
Contributor

It does work correctly in bash.

command env -i HOME=$HOME TERM=$TERM USER=$USER PATH=$PATH bash --norc
eval "$(fzf --bash)"

_fzf_complete_doge() {
  _fzf_complete --multi --reverse --prompt="doge> " -- "$@" < <(
    echo very
    echo wow
    echo such
    echo doge
  )
}
complete -F _fzf_complete_doge -o default -o bashdefault doge

[cmd1] | doge **

In zsh, the issue lies in the __fzf_extract_command function, which processes commands from left to right until the first command meets the requirement.

fzf/shell/completion.zsh

Lines 123 to 135 in d938fdc

# Extract the name of the command. e.g. foo=1 bar baz**<tab>
__fzf_extract_command() {
local token tokens
tokens=(${(z)1})
for token in $tokens; do
token=${(Q)token}
if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then
echo "$token"
return
fi
done
echo "${tokens[1]}"
}

As a workaround, you could try using process substitution so your intended command is placed first.

# process substitution
paste -sd ","  <(seq 15 -5 1)  
# 15,10,5

# process substitution with redirection
paste -sd "," - < <(seq 15 -5 1)
# 15,10,5

PS: Your reported issue is still valid, don't close it.

@LangLangBart
Copy link
Contributor

PS: Your reported issue is still valid, don't close it.

Based on the description from OP, I didn't search for other tickets until I clicked on the bug icon added by the maintainer to see open bug issues. Now, I would argue to close it as a duplicate of #1992.

@junegunn
Copy link
Owner

junegunn commented Nov 4, 2024

@LangLangBart Oh, thanks for pointing it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants