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

wrap more than just the command (e.g `git checkout`) #1976

Closed
despairblue opened this Issue Mar 9, 2015 · 31 comments

Comments

Projects
None yet
@despairblue
Copy link

despairblue commented Mar 9, 2015

Is this possible?:

function gco --wraps 'git checkout'
  git checkout $argv
end

I would expect this to auto complete like git checkout, though it does not.

@ridiculousfish

This comment has been minimized.

Copy link
Member

ridiculousfish commented Mar 10, 2015

Not yet. That looks for a command git\ checkout, i.e. with an embedded space.

Today commands can only wrap other commands. The reason is that I wasn't sure how far to take it - can you also wrap commands with subcommands, redirections, unclosed quotes, etc? Taken to extremes you wind up with something like zsh's no-holds-barred global aliases.

I think your use case is very reasonable. If you want to think through the issues and come up with a proposal for how it should behave, I'd sure appreciate it. An example of what I mean: what should cmd --wraps 'foo > bar' do?

You might also try an abbreviation here.

@despairblue

This comment has been minimized.

Copy link

despairblue commented Mar 10, 2015

yeah I found out about the abbreviations in a related issue. I tried them
and they suit this use case actually pretty well. Is there any ETA when
they will be released?

On Tue, Mar 10, 2015, 07:38 ridiculousfish notifications@github.com wrote:

Not yet. That looks for a command git\ checkout, i.e. with an embedded
space.

Today commands can only wrap other commands. The reason is that I wasn't
sure how far to take it - can you also wrap commands with subcommands,
redirections, unclosed quotes, etc? Taken to extremes you wind up with
something like zsh's no-holds-barred global aliases.

I think your use case is very reasonable. If you want to think through the
issues and come up with a proposal for how it should behave, I'd sure
appreciate it.

You might also try an abbreviation here.


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

@zanchey

This comment has been minimized.

Copy link
Member

zanchey commented Mar 12, 2015

Not yet.

@simnalamburt

This comment has been minimized.

Copy link

simnalamburt commented Jan 3, 2016

+1 for this issue. I'm former zsh user and trying to migrate to the fish shell, but blocked by this. I lived with tons of git aliases, and now I have serious problem with using them. I desperately need this feature.

alias g='git'

alias ga='git add'
alias gaa='git add --all'
alias gapa='git add --patch'

alias gb='git branch'
alias gba='git branch -a'
alias gbl='git blame -b -w'
alias gbnm='git branch --no-merged'
alias gbr='git branch --remote'
alias gbs='git bisect'
...
@pickfire

This comment has been minimized.

Copy link
Contributor

pickfire commented Jan 3, 2016

@simnalamburt You can use abbr too, it will automatically lengthen it.

abbr -a g git
@krader1961

This comment has been minimized.

Copy link
Contributor

krader1961 commented Jan 4, 2016

@simnalamburt for aliases meant only for interactive use you're probably better served by the abbr command.

@simnalamburt

This comment has been minimized.

Copy link

simnalamburt commented Jan 4, 2016

I used to make about 200 aliases. I tried to change all those aliases into abbr but it made fish too slow.

https://github.com/simnalamburt/pkg-cgitc/blob/master/init.fish

@faho

This comment has been minimized.

Copy link
Member

faho commented Jan 4, 2016

@simnalamburt: Too slow to start or slow while running?

@simnalamburt

This comment has been minimized.

Copy link

simnalamburt commented Jan 4, 2016

Too slow to start

@faho

This comment has been minimized.

Copy link
Member

faho commented Jan 4, 2016

In that case, I've noticed abbr.fish taking a while. I'll try to take a look.

@pickfire

This comment has been minimized.

Copy link
Contributor

pickfire commented Jan 4, 2016

@faho, nice. Try to open it in a new issue.

@faho

This comment has been minimized.

Copy link
Member

faho commented Jan 4, 2016

@simnalamburt: You may want to try one of two things:

  • Set the abbreviations once and remove the abbr calls from your config file

This is because abbreviations are stored in a universal (by default) variable shared among fish instances, so you don't need to set them up each time fish starts. You could also keep the calls in your config file but guard them with

if set -q fish_initialized
   set -U fish_initialized
   abbr so wow
   #...
end

This is only a speedup of about 1/3 in the common case (abbrs already written) and depends on a git master fish (because of the string builtin), but maybe it's enough for you?

@faho faho changed the title wrap `git checkout` wrap more than just the command (e.g `git checkout`) Jan 14, 2016

@simnalamburt

This comment has been minimized.

Copy link

simnalamburt commented Jan 20, 2016

@faho Thanks. Greatly settled with below:

if not set -q cgitc_initialized
  set -U cgitc_initialized

  # Abbrs
end

simnalamburt added a commit to simnalamburt/cgitc that referenced this issue Jan 20, 2016

@zanchey

This comment has been minimized.

Copy link
Member

zanchey commented May 21, 2016

I think abbreviations are the right answer here - I don't know that there's much more to do. Thoughts?

@faho

This comment has been minimized.

Copy link
Member

faho commented May 22, 2016

@zanchey: I don't think so. That wouldn't work for commands that wrap other commands, for one, and sometimes you have a function that can take the exact same arguments as something else, but you don't want it to show up fully in the commandline.

@faho

This comment has been minimized.

Copy link
Member

faho commented May 22, 2016

For example, I have this function:

function duthis
    set -q argv[1]; or set argv * .*
        du -sch $argv | sort -h
end

Of course since the arguments are passed to du -sch, it should be completed like du -sch. But I don't want that thing as an abbr instead (and currently it wouldn't actually work as an abbr since it would put the cursor after the sort call).

(Currently, wrapping du -sch would behave the same as wrapping du, but that's because of #1315).

An example of what I mean: what should cmd --wraps 'foo > bar' do?

@ridiculousfish: This is only about completions, right? Those aren't affected by redirections. Basically what I think would solve this completely is to use the argument to "--wraps" as the fake commandline and pass that to the completions, just like if complete -C were called.

@ridiculousfish

This comment has been minimized.

Copy link
Member

ridiculousfish commented May 24, 2016

The tricky part is that we have to figure out whose completion to invoke - for example, the du completions. This means we have to expand and parse the command line again, after substituting in the wrapped command. This is doable, it's just a bit of work.

@inflation

This comment has been minimized.

Copy link

inflation commented Jan 27, 2017

Hi, I'm facing the same issue here. For a single abbr, it is too long for expansion. And when I have lots of these kind of aliases, I don't have the time to write completion for each of them if I define them as functions.

abbr gwip 'git add -A; git rm (git ls-files --deleted) 2> /dev/null; git commit --no-verify -m "--wip-- [skip ci]"'
@krader1961

This comment has been minimized.

Copy link
Contributor

krader1961 commented Mar 23, 2017

Personally I recommend using an abbreviation for simple situations like the one in the original problem statement. This is the simplest solution to the problem and works well for me. For example, I have these git related abbreviations:

abbr gc 'git commit'
abbr gca 'git commit --amend'
abbr gco 'git checkout'
abbr gcm 'git checkout master'
abbr gd 'git diff'
abbr gs 'git status'
abbr gsb 'git show-branch'
abbr gam 'hub am -3'
abbr gb 'git branch'

I can type any of them followed by a space and the subsequent completions work as expected. It is not at all clear how completions should work if the example by @inflation were instead an alias/function.

dsbonev added a commit to dsbonev/dotfiles that referenced this issue Apr 5, 2017

Use fish abbreviations to autocomplete branch names
Workaround a fish issue of not being able to autocomplete aliased
commands having arguments.

fish-shell/fish-shell#1976
@simnalamburt

This comment has been minimized.

Copy link

simnalamburt commented Apr 25, 2017

I had created super fast git abbreviation plugin by hacking the abbr function. @xnuk found that it becomes much more faster if you update fish_user_abbreviations variable directly.

Reference
@jacobsa

This comment has been minimized.

Copy link

jacobsa commented May 10, 2017

FWIW, I also would really like support for the "git checkout" case, except for a command that doesn't support aliases itself as git does. Abbreviations work, but are suboptimal because the expanded form is really verbose and ugly.

@despairblue

This comment has been minimized.

Copy link

despairblue commented May 10, 2017

As the person who opened this issue, I have to say that abbreviations seem to me better usability-wise. I've been using them since shortly after opening this issue and they have two main advantages:

  1. I don't forgot what I'm abbreviating. When I'm on another machine I still know how the command works since abbreviations are more like autocomplete: I know what I want, but I only type it partially.

  2. People see what they execute before they do it. When someone is using my machine and we share the same alias and they use it, no harm done. But if for some reason I alias sudo rm -rf / to gco we have a problem. When they know that I use fish they start to look for what it expands to. That's something that highly confuses me when using someone else's bash or zsh setup (typing an alias and not seeing it expanded).

@krader1961

This comment has been minimized.

Copy link
Contributor

krader1961 commented Aug 14, 2017

@simnalamburt, Note that fish 3.0.0 will have much faster abbreviations. See issue #4048. That change, however, means that the fish_user_abbreviations no longer has any meaning.

@timothywlewis

This comment has been minimized.

Copy link

timothywlewis commented Dec 28, 2017

I have an git alias dsf (for https://github.com/so-fancy/diff-so-fancy) that should autocomplete the same as git diff. Here's the relevant piece of my ~/.gitconfig:

[alias]
	dsf = "!f() { [ -z \"$GIT_PREFIX\" ] || cd \"$GIT_PREFIX\" && git diff --color \"$@\" | diff-so-fancy  | less --tabs=4 -RFX; }; f"

My current approach is to clone the '### diff' section of https://github.com/fish-shell/fish-shell/blob/master/share/completions/git.fish into my own ~/.config/fish/completions/git.fish:

# source shared git completions for __fish_git_needs_command and __fish_git_using_command
source $__fish_datadir/completions/git.fish

### dsf is an alias that wraps diff -- https://github.com/so-fancy/diff-so-fancy
###  cloned from 'diff' section in /usr/local/Cellar/fish/2.6.0/share/fish/completions/git.fish
complete -c git -n '__fish_git_needs_command' -a dsf -d 'Show changes between commits, commit and working tree, etc'
complete -c git -n '__fish_git_using_command dsf' -a '(__fish_git_ranges)' -d 'Branch'
complete -c git -n '__fish_git_using_command dsf' -l cached -d 'Show diff of changes in the index'
complete -c git -n '__fish_git_using_command dsf' -l no-index -d 'Compare two paths on the filesystem'
# TODO options

Is this the cleanest way to do it? Or is there a cleaner way to inherit all the completions defined for git diff?

@zanchey

This comment has been minimized.

Copy link
Member

zanchey commented Jan 9, 2018

That's probably as good as it gets.

@faho faho referenced this issue Feb 18, 2018

Closed

Alias completion #4729

ridiculousfish added a commit to ridiculousfish/fish-shell that referenced this issue Feb 27, 2018

Wrapping completions to allow injecting arguments
This enables some limited use of arguments for wrapping completions. The
simplest example is that complete gco -w 'git checkout' now works like
you would want: `gco <tab>` now invokes git's completions with the
`checkout` argument prepended.

Fixes fish-shell#1976

@ridiculousfish ridiculousfish modified the milestones: fish-future, fish-3.0 Feb 27, 2018

@ridiculousfish

This comment has been minimized.

Copy link
Member

ridiculousfish commented Feb 27, 2018

This should be working much better in bb7b649. Please give it a try and let me know if any aliases aren't behaving properly.

flskif added a commit to flskif/dotfiles that referenced this issue Jun 2, 2018

Use abbreviations instead of aliases in Fish
I need git subcommands to autocomplete, but it's not working with
aliases, so I've switched to abbreviations.

For more details, see
fish-shell/fish-shell#2277 (comment)
fish-shell/fish-shell#1976

@gabebw gabebw referenced this issue Aug 25, 2018

Open

Check out fish shell #140

4 of 6 tasks complete
@Siilwyn

This comment has been minimized.

Copy link

Siilwyn commented Jan 9, 2019

@ridiculousfish not sure if I should create a new issue or reply here... this doesn't seem to work with npm subcommands.

For example alias npr='npm run' and typing npr gives me completion for all npm commands instead of what just the npm scripts that I do get if I type npm run.

@faho

This comment has been minimized.

Copy link
Member

faho commented Jan 9, 2019

@Siilwyn: Are you sure you are running fish 3.0.0?

@Siilwyn

This comment has been minimized.

Copy link

Siilwyn commented Jan 9, 2019

Sorry about that, I figured since this issue was closed a while ago I would be running a version that includes that fix but I'm still on 2.7.

@timothywlewis

This comment has been minimized.

Copy link

timothywlewis commented Jan 10, 2019

So now in fish 3.0.0 can I get git diff completions for my git alias? I'd like to get git dsf <tab> to have the identical completions as git diff <tab>.

# this didn't work
complete -c 'git dsf' -w 'git diff'
# and neither did this
complete -c git -n '__fish_seen_subcommand_from dsf' -w 'git diff'

The closest I can get to it is a function that wraps it:

function gdsf -w 'git diff'
    git dsf $argv;
end

Thanks!

I have an git alias dsf (for https://github.com/so-fancy/diff-so-fancy) that should autocomplete the same as git diff. Here's the relevant piece of my ~/.gitconfig:

[alias]
	dsf = "!f() { [ -z \"$GIT_PREFIX\" ] || cd \"$GIT_PREFIX\" && git diff --color \"$@\" | diff-so-fancy  | less --tabs=4 -RFX; }; f"

My current approach is to clone the '### diff' section of https://github.com/fish-shell/fish-shell/blob/master/share/completions/git.fish into my own ~/.config/fish/completions/git.fish:

# source shared git completions for __fish_git_needs_command and __fish_git_using_command
source $__fish_datadir/completions/git.fish

### dsf is an alias that wraps diff -- https://github.com/so-fancy/diff-so-fancy
###  cloned from 'diff' section in /usr/local/Cellar/fish/2.6.0/share/fish/completions/git.fish
complete -c git -n '__fish_git_needs_command' -a dsf -d 'Show changes between commits, commit and working tree, etc'
complete -c git -n '__fish_git_using_command dsf' -a '(__fish_git_ranges)' -d 'Branch'
complete -c git -n '__fish_git_using_command dsf' -l cached -d 'Show diff of changes in the index'
complete -c git -n '__fish_git_using_command dsf' -l no-index -d 'Compare two paths on the filesystem'
# TODO options

Is this the cleanest way to do it? Or is there a cleaner way to inherit all the completions defined for git diff?

@zanchey

This comment has been minimized.

Copy link
Member

zanchey commented Jan 10, 2019

fish will complete aliases that only use internal git functions, but not those that start shell pipelines; your current method is probably the cleanest for now.

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