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

Alias completion #393

Closed
hauleth opened this issue Nov 17, 2012 · 47 comments
Closed

Alias completion #393

hauleth opened this issue Nov 17, 2012 · 47 comments
Milestone

Comments

@hauleth
Copy link
Contributor

@hauleth hauleth commented Nov 17, 2012

It will be nice if we can make completion work for aliases too. I.e.

function g; git $argv; end
completion -c g --alias git

And now everything that will be completed in git <tab> will work also in g <tab>.

@zanchey
Copy link
Member

@zanchey zanchey commented Nov 17, 2012

see also #165

@stestagg
Copy link
Contributor

@stestagg stestagg commented Nov 18, 2012

It may be simpler to add an argument to the 'function' builtin, that allows you to specify that the function 'completes like'.

Alias can then provide this argument by default.

An example:

alias gp="git push"

would result in

function --completes-like="git push" gp; git push $argv; end

The completer then will just virtually substitute 'git push' for gp when it needs to.

This may be simpler than parsing the function body every time

@hauleth
Copy link
Contributor Author

@hauleth hauleth commented Nov 18, 2012

@stestagg the way what it will be done is left to the creator, but I also think that manually setting completition is better than parsing body function. But using completion function to alias completion also can be useful i.e. to alias pacman completion to yaourt.

@gustafj
Copy link
Contributor

@gustafj gustafj commented Nov 20, 2012

An argument to the function builtin would be enough for all cases, and would have the benefit of being defined in the same place as the function which needs it.
As opposed to a argument to complete which could be defined anywhere.

The pacman example could also use this syntax (since functions has priority over commands) (but it gets a bit repetitive...) ex:
function --completes-like="pacman" yaourt; command yaourt; end

@JeanMertz
Copy link

@JeanMertz JeanMertz commented Nov 26, 2012

I just found out about this "missing feature" as well.

function gco
  git checkout $argv
end

This won't auto-complete the available branches/tags, which is really a shame. To implement this myself I had to c/p the relevant parts from shared/completions/git.fish

@gf3
Copy link

@gf3 gf3 commented Jan 9, 2013

This is a big one for me, too.

@mgsk
Copy link

@mgsk mgsk commented Jan 23, 2013

For the love of all that is fishy, make it so!

@maxfl
Copy link
Contributor

@maxfl maxfl commented Jan 24, 2013

Before alias completion is supported you can use this function to produce alias completion:

function make_completion --argument-names alias command
    echo "
    function __alias_completion_$alias
        set -l cmd (commandline -o)
        set -e cmd[1]
        complete -C\"$command \$cmd\"
    end
    " | .
    complete -c $alias -a "(__alias_completion_$alias)"
end

use it as follows:
make_completion pacs 'pacman -S'
for alias pacs for command 'pacman -S'

@maxfl
Copy link
Contributor

@maxfl maxfl commented Jan 25, 2013

Or another implementation, without creating intermediate function. It can be added to the 'alias' definition.

function make_completion --argument alias command
    complete -c $alias -a "(
        set -l cmd (commandline -op);
        set -e cmd[1];
        complete -C\"$command \$cmd\";
    )"
end
@mgsk
Copy link

@mgsk mgsk commented Jan 25, 2013

Wonderful! This is how I've used it:

function make_completion --argument-names alias command
    echo "                                             
    function __alias_completion_$alias                 
        set -l cmd (commandline -o)                    
        set -e cmd[1]                                  
        complete -C\"$command \$cmd\"                  
    end                                                
    " | .                                              
    complete -c $alias -a "(__alias_completion_$alias)"
end                                                    

function aptin; sudo apt-get install $argv; end;

make_completion aptin 'apt-get install'

On Thu, Jan 24, 2013 at 03:06:52AM -0800, maxfl wrote:

Before alias completion is supported you can use this function to produce alias completion:

function make_completion --argument-names alias command
    echo "
    function __alias_completion_$alias
        set -l cmd (commandline -o)
        set -e cmd[1]
        complete -C\"$command \$cmd\"
    end
    " | .
    complete -c $alias -a "(__alias_completion_$alias)"
end

use it as follows:
make_completion pacs 'pacman -S'
for alias pacs for command 'pacman -S'


Reply to this email directly or view it on GitHub:
#393 (comment)

@hauleth
Copy link
Contributor Author

@hauleth hauleth commented Jan 25, 2013

It is almost great except that if I alias git with g and try to complete:

$ g checkout <tab>

this still doesn't work.

@maxfl
Copy link
Contributor

@maxfl maxfl commented Jan 25, 2013

I see. The problem is that 'commandline -o' looses the trailing space. Here is the solution.

function make_completion --argument alias command
    complete -c $alias -xa "(
        set -l cmd (commandline -pc | sed -e 's/^ *\S\+ *//' );
        complete -C\"$command \$cmd\";
    )"
end

Since now we do not split the commandline output, we have to use sed to replace the command. I've also changed '-a' to '-xa' option, because the filename completions should be added by nested 'complete' command.

@ridiculousfish
Copy link
Member

@ridiculousfish ridiculousfish commented Jan 26, 2013

Does anyone have any thoughts on how commandline ought to be handled? For example, if I write alias gb 'git branch'. The git completion wants to only return completions for the relevant subcommand, which it uses builtin commandline to parse out. Since it won't be able to parse it out of the actual commandline, this will fail.

One possibility would be to make commandline lie and return something with the alias replaced, i.e.

alias gb 'git branch'
gb fi<tab>

Within the completion, commandline would return "git branch fi" instead of "gb fi".

Another possibility is to replace the ad-hoc use of commandline with true subcommand support (so you could write a completion specifically for 'git branch').

@gf3
Copy link

@gf3 gf3 commented Jan 26, 2013

Maybe we should check out how ZSH does it? It's able to complete things like shell aliases as well as aliases set in .gitconfig.

@maxfl
Copy link
Contributor

@maxfl maxfl commented Jan 31, 2013

@ridiculousfish, there is another way to look at it: it's not an issue of the 'commandline', but an issue of the 'complete':

  1. commandline should be as transparent as possible. It returns the command lines as is and doesn't distinguish between commands and aliases.
  2. 'complete' can have something like modes, or a possibility to use the completion for another command:
    complete -c gb -C 'git branch' # to tell fish to complete gb as if it were 'git branch'
    It's a thing that is done by that script two posts above, but script is ugly since it requires calling another commands.
  3. [a bit offtopic here] complete can have some 'mode' or 'preset' option to provide a set of completions which can be reused by several commands:
    like:
    complete --preset vim -l longcommand1 -s s1 -d desc 1
    complete --preset vim -l longcommand2 -s s2 -d desc 2
    complete -c vim --use-preset vim
    complete -c gvim --use-preset vim
@dag
Copy link
Contributor

@dag dag commented Feb 10, 2013

However you solve this I'd like it if the solution works also for functions, not just aliases. @maxfi's suggestion in the comment above would seem to qualify, for example. Making alias special on the other hand, seems to not qualify.

@dag
Copy link
Contributor

@dag dag commented May 6, 2013

BTW if this becomes a reality we also need a way to escape it. Consider alias git hub; you want to keep the git completions, not use the non-existent hub completions. I wonder how zsh deals with that...

@gustafj gustafj mentioned this issue May 12, 2013
@Gonzih
Copy link
Contributor

@Gonzih Gonzih commented May 18, 2013

Just migrated to fish from zsh and that issue is now bothering me.

@sjl
Copy link

@sjl sjl commented Oct 31, 2013

I agree that this should be a feature of complete. "Complete this command like this other one" seems like a decent way to solve this problem.

Also @maxfl's make_completion is not working for me, not exactly sure why.

@ghost
Copy link

@ghost ghost commented Nov 1, 2013

I think that #731 would fix this.

@tomxtobin
Copy link

@tomxtobin tomxtobin commented Nov 1, 2013

Having aliases automatically expand as I type (as per the abbreviations feature in #731) would be a huge turn-off. I'm very sensitive to anything that changes what I'm typing out from under me.

@dag
Copy link
Contributor

@dag dag commented Nov 1, 2013

Note that abbreviations only expand when you hit enter or space. Try it and you might be surprised at how non-invasive it actually is. Or maybe you're not impressed at all – people are different!

I certainly do think we need some way to "redirect" completions, regardless of aliases and abbreviations. This should probably be a feature of complete because it's the most general solution, and not all "aliases" are in the shell (for example egrep).

@stestagg
Copy link
Contributor

@stestagg stestagg commented Nov 1, 2013

I'm not keen on this at all, bash does something similar with tilda
expansion when pressing TAB, and it's annoying and makes editing previous
commands harder.

Thanks

Steve

On Fri, Nov 1, 2013 at 10:53 AM, Dag Odenhall notifications@github.comwrote:

Note that abbreviations only expand when you hit enter or space. Try it
and you might be surprised at how non-invasive it actually is. Or maybe
you're not impressed at all – people are different!

I certainly do think we need some way to "redirect" completions,
regardless of aliases and abbreviations. This should probably be a feature
of complete because it's the most general solution, and not all "aliases"
are in the shell (for example egrep).


Reply to this email directly or view it on GitHubhttps://github.com//issues/393#issuecomment-27558448
.

@Rameshv
Copy link

@Rameshv Rameshv commented Nov 1, 2013

+1

@xfix
Copy link
Member

@xfix xfix commented Nov 2, 2013

complete --command egrep --like grep
complete --command egrep --erase --short-option E --long-option extended-regexp

Just thinking. Needs better name than --like, but I like this.

@hauleth
Copy link
Contributor Author

@hauleth hauleth commented Nov 2, 2013

For me --like looks good enough.

@ridiculousfish
Copy link
Member

@ridiculousfish ridiculousfish commented Nov 2, 2013

@dag "Function signature" is a misnomer. I should have called it command signature. You can set one on a function in its declaration, on external commands, and builtins will have them too.

@xixixao
Copy link

@xixixao xixixao commented Dec 20, 2013

This is a real must! For me, the tab completion is the killer feature of fish, but I need to be able to easily add it to my aliases (functions).#393 (comment) works for me.

@ahti
Copy link
Contributor

@ahti ahti commented Jul 7, 2014

This is really something where complete is lacking, which also leads to more complicated completion files.

For an example see the completion for pacman, pacsrv, yaourt, ...

All of the completion files for these tools just call __fish_complete_pacman which is not even defined inside the completions folder but in the functions directory. This is a very non-generic way to deal with this problem.

If you take a look into /share/functions, you will find a bunch of functions starting with __fish_complete_, which is also a little code duplication and (imho) a very inelegant way to solve this problem.

This could be easily solved with a --like. The original tool (pacman in this case) contains the "real" completion, yaourt, pacsrv, et. al. just contain a complete yaourt --like pacman.

@melekes
Copy link

@melekes melekes commented Jul 14, 2014

+1. Feature is critical for me as well.

@tonatiuh
Copy link

@tonatiuh tonatiuh commented Jul 14, 2014

+1. This is also very important to me, it bothers me to have to write the full command name.

Btw other things from fish are very cool : )

@toabi
Copy link

@toabi toabi commented Aug 6, 2014

+1. That's the only thing I miss since moving from (oh-my)-zsh

@ignlg
Copy link

@ignlg ignlg commented Aug 13, 2014

+1. The --like param for complete seems perfect and flexible.

@ridiculousfish
Copy link
Member

@ridiculousfish ridiculousfish commented Aug 16, 2014

This is implemented as 06400b8. The commit message has more details.

In short you can now do this:

complete --command foo --wraps bar

or

function foo --wraps bar
    ...
end

Either way, foo dynamically inherits bar's completions.

I went with -w/--wraps instead of --like because function foo --like bar seemed less clear. I think wraps is also more precise: yaourt wraps pacman in the sense that it includes all of pacman's completions, but also provides its own completions in addition.

I didn't implement support for aliasing to multiple commands, i.e. compete --command gco --wraps 'git checkout' won't work. That use case seems better served by abbreviations to me. zsh allows arbitrarily powerful aliases, e.g. you can write alias haha=''and nowhaha` introduces an unclosed backtick. It's just pure textual substitution. I don't think we want to go that far so I went with something conservative.

Definitely interested in your suggestions or ideas for improvements here.

@ridiculousfish ridiculousfish modified the milestones: fish-future, next-minor Aug 16, 2014
@gglanzani
Copy link

@gglanzani gglanzani commented Aug 26, 2014

So basically there is still no way to have things like gco do completion? Because I don't think I fully understand what abbreviations means in that context (an example would be great).

@terlar
Copy link
Contributor

@terlar terlar commented Aug 26, 2014

set -U fish_user_abbreviations 'gco=git checkout'

Next time you write gco+<enter> or gco+<space> you would get git checkout.

@stestagg
Copy link
Contributor

@stestagg stestagg commented Aug 26, 2014

It would be great if the abbreviations could be seamless (i.e. not expand when entered)

@terlar
Copy link
Contributor

@terlar terlar commented Aug 26, 2014

That is pretty much the point with the abbreviations though, you could just create a function wrapper if you want to keep it unexpanded. I find it much more clear and useful when it expands, barely have any aliases anymore.

@stestagg
Copy link
Contributor

@stestagg stestagg commented Aug 26, 2014

But you can't then get completions wrapped if you do, so the feature looses
a lot of it's functionality

On Tue, Aug 26, 2014 at 7:10 PM, Terje Larsen notifications@github.com
wrote:

That is pretty much the point with the abbreviations though, you could
just create a function wrapper if you want to keep it unexpanded. I find it
much more clear and useful when it expands, barely have any aliases anymore.


Reply to this email directly or view it on GitHub
#393 (comment)
.

@gglanzani
Copy link

@gglanzani gglanzani commented Aug 27, 2014

@terlar Thanks, that works. It's somewhat an undocumented feature (found more info in the issue tracker).

@ridiculousfish
Copy link
Member

@ridiculousfish ridiculousfish commented Aug 29, 2014

It's an incomplete feature - we don't have any real UI for it yet (either in fish_config or command line).

@najamelan
Copy link

@najamelan najamelan commented Feb 12, 2015

For people wondering about git aliases, I can say that it works if you set your alias in .gitconfig instead of in fish configuration.

@niedzielski
Copy link

@niedzielski niedzielski commented Apr 24, 2015

Thanks! This is very convenient! Worth building master for!

@joar
Copy link

@joar joar commented May 13, 2015

This does not seem to solve the issue when you've abbreviated git add to ga.

Using

function --wraps 'git add' ga
    git add $argv;
end

does not help, and using

function --wraps 'git' ga
    git add $argv;
end

gives you completions for git instead of git add. Presumable since the completions for giit sub-commands are defined using conditions, e.g:

complete --no-files \
    --command git \
    --arguments '(__fish_git_add_files)' \
    --condition '__fish_git_using_command add'

(Rambling, hope it's helpful)

@zanchey
Copy link
Member

@zanchey zanchey commented May 21, 2015

Correct, abbreviations only support the token in command position - see #1976 for some discussion.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.