-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Feature request: Allow conditional routing for custom fuzzy completion postprocessing functions #3367
Comments
Good point, it's something I haven't really thought through. In bash, you can access the original command via _fzf_complete_foo() {
_fzf_complete --multi --reverse --header-lines=3 -- "$@" < <(
ls -al
)
}
_fzf_complete_foo_post() {
echo -n "[ ${COMP_WORDS[@]} ]"
awk '{print $NF}'
}
[ -n "$BASH" ] && complete -F _fzf_complete_foo -o default -o bashdefault foo But I guess that's not possible in zsh (not a zsh user myself). If there is no such way to readily do it in zsh, we can consider passing the completion arguments to the post function. |
Ah, looks like _fzf_complete_foo() {
_fzf_complete --multi --reverse --header-lines=3 -- "$@" < <(
ls -al
)
}
_fzf_complete_foo_post() {
echo -n "[ $LBUFFER ]"
awk '{print $NF}'
} |
Thanks for the reply. I've tried to implement what you showed, but I think it indicates a miscommunication. I assumed that what gets passed to the postprocessing function is the verbatim string that the user selects in fzf. So like, in the first example from the README's section on custom fuzzy completion, if the user selects e.g., I confess I don't really see how that is useful, since that command string is already present in the terminal when fzf pastes the selected output. So returning By contrast, passing through the actual selected text seems like it would be vastly more useful. Is that somehow possible? |
Here's what I personally am trying to do, as an example to make it concrete: _fzf_complete_git() {
ARGS="$@"
if [[ "${ARGS}" == "git checkout"* ]]; then
_fzf_complete --prompt="All branches> " -- "${ARGS}" < <(
git branch --no-color --all --format="%(refname:short)" \
| grep -vE ^origin$ \
| sed -E 's/^./LOCAL\t&/' \
| sed 's/LOCAL\torigin\//REMOTE\t/'
)
elif [[ "${ARGS}" == "git rebase -i"* ]]; then
_fzf_complete --prompt="Rebase onto commit> " -- "${ARGS}" < <(
git log --oneline
)
else
eval "zle ${fzf_default_completion:-expand-or-complete}"
fi
}
_fzf_complete_git_post() {
if [[ "${LBUFFER}" == "LOCAL"* || "${LBUFFER}" == "REMOTE"* ]]; then
# git checkout
awk -F "\t" '{print $2}'
else
# git rebase
awk '{print $1}' | sed -E "s/.$/&~/"
fi
} In English: I want one function which works with
The "main" function shown above does everything I want it to, in that it correctly distinguishes Can you advise on what changes I'd need to make to bring about the desired postprocessing behavior? |
Actually, after thinking on it I now realize why having access to But then how can I also get access to my fzf selection in postprocessing? |
Aaaaaaand I just figured it out haha. My functions are now working as intended, including postprocessing, thanks to the magic of At the very minimum, the example in the wiki should be updated to include that variable so that people can tinker with it and figure it out themselves. Better though would be to actually describe what that variable is and how it should be used in postprocessing. Best would be update the API to be more inherently transparent, then update the main README (not just the wiki) to reflect this cool capability. I would also prefer to see a short description of how information is passed between these functions, since it's a little opaque at present, and understanding that would open the door to many more cool and creative uses I'm sure. But anyway, I believe my own immediate needs have now been met. I'll stop blowing up this thread now :) Cheers! |
Yeah, the wiki needs an overhaul. The pages are written by the community, and sadly, there has been no quality control at all. I don't know which ones are working and which ones are not. But I just don't have time to go through the code.
Agreed. It would be even better if the API is consistent across bash and zsh (no COMP_WORDS vs LBUFFER). |
man fzf
)Info
Maybe this is already possible to do, but the current documentation is insufficient for understanding how to implement it.
The wiki shows an example for how to implement a custom fuzzy completion function with some conditional routing (
_fzf_complete_git
). This is useful because it shows how you could, in theory, write a single function that provides different completions for many different subcommands. For example,git checkout
versusgit cherry-pick
, the former presentinggit branch
output and the latter presentinggit cherry-pick
output from which to select. The example in the wiki already gives a good idea for how to implement this usingif
/elif
string matching.However, the postprocessing function that goes with that example (
_fzf_complete_git_post
) does not illustrate how to branch the postprocessing in the same way. For example, say I want thegit cherry-pick
tocut
out just the commit sha column, whereasgit checkout
should just pass branch names through unchanged. I attempted to implement this myself, on the assumption that the input to the postprocessing function is the line selected through fuzzy completion, but I was completely guessing, and ultimately didn't succeed.My point is that either the kind of conditional routing (to handle multiple commands) that is already possible in the "main" completion function should be made possible in the "post" function too, or else if it is already possible, the documentation should be updated to show how to implement it.
The text was updated successfully, but these errors were encountered: