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

Support the same tab completion options as zsh #25

Closed
pbrisbin opened this issue Nov 25, 2013 · 15 comments
Closed

Support the same tab completion options as zsh #25

pbrisbin opened this issue Nov 25, 2013 · 15 comments
Assignees

Comments

@pbrisbin
Copy link
Contributor

Completion in general is very lacking compared to ZSH, but I'm not sure we can anything about that.

@georgebrock
Copy link
Collaborator

I don't think there's anything preventing us from implementing all of the git tab completion features that are available in zsh; we based the existing tab completion on git's shell completion code, and given enough time we could port all of it over to gitsh.

What other completion features you're missing from zsh?

@pbrisbin
Copy link
Contributor Author

I thought of that after opening the issue. As far as I can tell the completion system is just a bit naive. It completes all commands/options listed in help all the time, or remote info in some cases?

The zsh completion script is smart about when to complete what options, when to complete remote or local branches, present files, tracked files, indexed files, etc and includes aliases and completes them correctly too.

I'd love to port all of that over, and would be willing to work on it myself.

@georgebrock
Copy link
Collaborator

@pbrisbin I've added tab completion for aliases added in #30. If you want to port over the full zsh completion algorithm, that would be awesome.

@georgebrock georgebrock changed the title Tab complete git aliases Support the same tab completion options as zsh Mar 19, 2014
@alexanderjeurissen
Copy link

First of all, sorry to necro this issue. But i recently made the transition to GitSh and I'd like to explain a usecase that really annoys me when i started using GitSh and it's expanding a path

for example:
current directory: ~/abc/
i want to navigate to: ~/abc/bcd/cde/def/

let's assume the following extra conditions:
the bcd directory contains another directory called efg which contains a directory fgh
leading to the following directory tree:
screen shot 2014-09-28 at 22 16 12

in zsh i can do the following:
cd b/c/d/ <tab> which expands it to: cd bcd/cde/def/

in gitsh and other shells i have to expand the unresolved parts of the path one by one like this:

cd b <tab> > cd bcd/c <tab> > cd bcd/cde/d <tab> > cd bcd/cde/def

This might seem like a minor issue, but if your used to powerful terminal emulators like zsh then it get's annoying real fast.

@georgebrock
Copy link
Collaborator

@alexanderjeurissen I think there are two different issues being discussed here:

  1. The git-specific tab completion options that are available when using git from zsh
  2. The tab completion options that zsh has built in for dealing with files

I think (1) would be very useful for gitsh users, but (2) is a little more tricky: I'm trying to follow the “principle of least astonishment” with gitsh's interface design, but it's hard to see how to apply that here. As a zsh users, you're surprised that cd b/c/d/ <tab> doesn't expand to cd bcd/cde/def/, but as a bash user I'd be surprised if that expansion did happen.

@alexanderjeurissen
Copy link

@georgebrock I understand that you want easy migration to Gitsh from various terminal emulators. However it would be nice to have more advanced tab completion as options or maybe as plugins. Most advanced features for Zsh aren't defaults but have to be toggled on, by enabling the plugin that's responsible for given feature.

@mike-burns
Copy link
Contributor

As a zsh user who does not use the b/c/d -> bcd/cde/def completion, I'd also be surprised if gitsh did this. But if someone submitted a PR for that specifically, with an option to toggle it, then that'd probably be useful.

@lode
Copy link

lode commented Jan 20, 2015

I have a similar experience coming from git-sh. It feels git-sh is smarter about the context of the command.

I personally don't feel comfortable enough with ruby to start implementation, but would love to help getting this further. Would it be a good start to list some specific situations? Or is the current references to zsh and git-sh enough? (Is this a good issue btw, or is there another more generic issue already?)

@mike-burns
Copy link
Contributor

Specifics would be great, pull requests with failing tests would be even better, and pull requests with working code is most ideal.

See https://github.com/thoughtbot/gitsh/blob/master/CONTRIBUTING.md for details on how to get the dev environment running locally. Not too much Ruby knowledge is required for this (you'll need RubyGems and Bundler: apt-get install rubygems bundler). Make sure this runs and passes:

make check

Edit spec/units/completer_spec.rb and copy one of the existing file path tests. Something like:

it 'completes partial paths' do
  with_a_temporary_home_directory do
    completer = build_completer(input: 'add ')
    Dir.chdir do
      FileUtils.mkdir_p(%w(abc def ghi jkl mno))
    end

    expect(completer.call('a/d/g/j/m')).to include 'abc/def/ghi/jkl/mno'
  end
end

Then run the test according to CONTRIBUTING.md:

env TESTS="spec/units/completer_spec" make -e check

If you want to tackle the Ruby after that, look in lib/gitsh/completer.rb, especially the PathCompleter class (line 102-ish). You'll need to modify the #collection method.

@lode
Copy link

lode commented Mar 9, 2015

Thanks for the push into actual coding :) I tried ruby a while back and noticed it costs me a lots of time for small things, so I'll save it for later. Or, at least I'll start with some specific things I'd like to see different. Maybe later or maybe someone else can pick some up.

Some auto completion (via tab) wishes:

  • push would give push origin (with ending space)
  • merge ori would give merge origin/
  • stash pop would give stash pop stash@{ (further auto completion lists the available numbers or even the output of stash list)
  • in general auto complete branch names instead of paths where a branch name can be expected

Often the extra space or slash at the end makes all the difference between fluently continue typing or having to type redundant stuff.

@mike-burns
Copy link
Contributor

Perhaps a DSL for expressing completions would be useful, such that we can express:

push $remote $branch
merge $branch
stash pop $stash

And $remote completes with a space at the end, $branch completes remotes with a slash at the end, and $stash completes from the stash list.

@georgebrock how's that for over-engineered?

@lode
Copy link

lode commented Mar 12, 2015

I'm not sure what exactly you mean with $remote and $branch but note that the ending char differs per command.

push $remote $branch has a space after $remote
merge $remote/$branch has a slash after $remote, unless you see that origin/foobar is a branch-name only? (vs a concatenation of $origin and $branch)

@georgebrock
Copy link
Collaborator

@mike-burns That could be quite a nice way of expressing it.

@lode I'd see origin/foobar as a branch name, rather than an origin and a branch. Most commands that take a branch name work just as well with local branches and remote tracking branches.

@lode
Copy link

lode commented Mar 17, 2015

@georgebrock indeed, than it works perfectly of course.

georgebrock added a commit that referenced this issue Mar 19, 2017
This is a really major change, and therefore a big diff.

Replaces the Parslet-based parsing expression grammar (PEG) with an
RLTK-based context-free grammar (CFG).

The `Gitsh::Parser` (which converted text into a AST) and
`Gitsh::Transformer` (which converted the AST into useful domain objects)
have been replaced with a `Gitsh::Lexer` (which converts text into tokens)
and `Gitsh::Parser` (which converts tokens into useful domain objects).

Why?
====

Distinguishing between _invalid input_ and _valid but incomplete input_ is
really hard with a PEG. There are various papers on improving PEG error
reporting, and some support in Parslet for various strategies, but I
couldn't find a satisfactory way to accurately work out why parsing failed
without making the grammar significantly more complex.

We want to add support for various multi-line constructs, which means we
need to know if a line is invalid or just waiting for more input. The
specific issues I have in mind are:

- Support multi-line strings
  (#31)

- Add a `:function` command for defining functions
  (#35)

We also want to improve tab-completion in various ways, which also involves
working with very similar types of incomplete input. Most of the
enhancements we have in mind will only be possible if we know more exactly
what we're completing, and re-using some of the parsing code to understand
the input seemed like the most logical approach. Specific issues are:

- Support the same tab completion options as zsh
  (#25)

- Add tab completion for options
  (#80)

- Auto complete stash commands
  (#220)

- Tab completion only works for the first command on the line
  (#261)

Note that this commit doesn't implement any of these enhancements, it just
makes them more likely to happen in the future.

Implementation details
======================

- Introduces equality methods on argument objects, used to testing parser
  output.

- git-prefix correction (i.e. interpreting `git foo` as `foo` when
  `help.autocorrect` is set) has moved from the Parser to the GitCommand
  class.

- The subshell implementation in this commit is not very good. It will be
  significantly improved in the next couple of commits, but it seemed too
  big of a change to roll into this one.
georgebrock added a commit that referenced this issue Apr 1, 2017
This is a really major change, and therefore a big diff.

Replaces the Parslet-based parsing expression grammar (PEG) with an
RLTK-based context-free grammar (CFG).

The `Gitsh::Parser` (which converted text into a AST) and
`Gitsh::Transformer` (which converted the AST into useful domain objects)
have been replaced with a `Gitsh::Lexer` (which converts text into tokens)
and `Gitsh::Parser` (which converts tokens into useful domain objects).

Why?
====

Distinguishing between _invalid input_ and _valid but incomplete input_ is
really hard with a PEG. There are various papers on improving PEG error
reporting, and some support in Parslet for various strategies, but I
couldn't find a satisfactory way to accurately work out why parsing failed
without making the grammar significantly more complex.

We want to add support for various multi-line constructs, which means we
need to know if a line is invalid or just waiting for more input. The
specific issues I have in mind are:

- Support multi-line strings
  (#31)

- Add a `:function` command for defining functions
  (#35)

We also want to improve tab-completion in various ways, which also involves
working with very similar types of incomplete input. Most of the
enhancements we have in mind will only be possible if we know more exactly
what we're completing, and re-using some of the parsing code to understand
the input seemed like the most logical approach. Specific issues are:

- Support the same tab completion options as zsh
  (#25)

- Add tab completion for options
  (#80)

- Auto complete stash commands
  (#220)

- Tab completion only works for the first command on the line
  (#261)

Note that this commit doesn't implement any of these enhancements, it just
makes them more likely to happen in the future.

Implementation details
======================

- Introduces equality methods on argument objects, used to testing parser
  output.

- git-prefix correction (i.e. interpreting `git foo` as `foo` when
  `help.autocorrect` is set) has moved from the Parser to the GitCommand
  class.

- The subshell implementation in this commit is not very good. It will be
  significantly improved in the next couple of commits, but it seemed too
  big of a change to roll into this one.
georgebrock added a commit that referenced this issue Apr 8, 2017
This is a really major change, and therefore a big diff.

Replaces the Parslet-based parsing expression grammar (PEG) with an
RLTK-based context-free grammar (CFG).

The `Gitsh::Parser` (which converted text into a AST) and
`Gitsh::Transformer` (which converted the AST into useful domain objects)
have been replaced with a `Gitsh::Lexer` (which converts text into tokens)
and `Gitsh::Parser` (which converts tokens into useful domain objects).

Why?
====

Distinguishing between _invalid input_ and _valid but incomplete input_ is
really hard with a PEG. There are various papers on improving PEG error
reporting, and some support in Parslet for various strategies, but I
couldn't find a satisfactory way to accurately work out why parsing failed
without making the grammar significantly more complex.

We want to add support for various multi-line constructs, which means we
need to know if a line is invalid or just waiting for more input. The
specific issues I have in mind are:

- Support multi-line strings
  (#31)

- Add a `:function` command for defining functions
  (#35)

We also want to improve tab-completion in various ways, which also involves
working with very similar types of incomplete input. Most of the
enhancements we have in mind will only be possible if we know more exactly
what we're completing, and re-using some of the parsing code to understand
the input seemed like the most logical approach. Specific issues are:

- Support the same tab completion options as zsh
  (#25)

- Add tab completion for options
  (#80)

- Auto complete stash commands
  (#220)

- Tab completion only works for the first command on the line
  (#261)

Note that this commit doesn't implement any of these enhancements, it just
makes them more likely to happen in the future.

Implementation details
======================

- Introduces equality methods on argument objects, used to testing parser
  output.

- git-prefix correction (i.e. interpreting `git foo` as `foo` when
  `help.autocorrect` is set) has moved from the Parser to the GitCommand
  class.

- The subshell implementation in this commit is not very good. It will be
  significantly improved in the next couple of commits, but it seemed too
  big of a change to roll into this one.
georgebrock added a commit that referenced this issue Apr 19, 2017
This is a really major change, and therefore a big diff.

Replaces the Parslet-based parsing expression grammar (PEG) with an
RLTK-based context-free grammar (CFG).

The `Gitsh::Parser` (which converted text into a AST) and
`Gitsh::Transformer` (which converted the AST into useful domain objects)
have been replaced with a `Gitsh::Lexer` (which converts text into tokens)
and `Gitsh::Parser` (which converts tokens into useful domain objects).

Why?
====

Distinguishing between _invalid input_ and _valid but incomplete input_ is
really hard with a PEG. There are various papers on improving PEG error
reporting, and some support in Parslet for various strategies, but I
couldn't find a satisfactory way to accurately work out why parsing failed
without making the grammar significantly more complex.

We want to add support for various multi-line constructs, which means we
need to know if a line is invalid or just waiting for more input. The
specific issues I have in mind are:

- Support multi-line strings
  (#31)

- Add a `:function` command for defining functions
  (#35)

We also want to improve tab-completion in various ways, which also involves
working with very similar types of incomplete input. Most of the
enhancements we have in mind will only be possible if we know more exactly
what we're completing, and re-using some of the parsing code to understand
the input seemed like the most logical approach. Specific issues are:

- Support the same tab completion options as zsh
  (#25)

- Add tab completion for options
  (#80)

- Auto complete stash commands
  (#220)

- Tab completion only works for the first command on the line
  (#261)

Note that this commit doesn't implement any of these enhancements, it just
makes them more likely to happen in the future.

Implementation details
======================

- Introduces equality methods on argument objects, used to testing parser
  output.

- git-prefix correction (i.e. interpreting `git foo` as `foo` when
  `help.autocorrect` is set) has moved from the Parser to the GitCommand
  class.

- The subshell implementation in this commit is not very good. It will be
  significantly improved in the next couple of commits, but it seemed too
  big of a change to roll into this one.
georgebrock added a commit that referenced this issue Apr 19, 2017
This is a really major change, and therefore a big diff.

Replaces the Parslet-based parsing expression grammar (PEG) with an
RLTK-based context-free grammar (CFG).

The `Gitsh::Parser` (which converted text into a AST) and
`Gitsh::Transformer` (which converted the AST into useful domain objects)
have been replaced with a `Gitsh::Lexer` (which converts text into tokens)
and `Gitsh::Parser` (which converts tokens into useful domain objects).

Why?
====

Distinguishing between _invalid input_ and _valid but incomplete input_ is
really hard with a PEG. There are various papers on improving PEG error
reporting, and some support in Parslet for various strategies, but I
couldn't find a satisfactory way to accurately work out why parsing failed
without making the grammar significantly more complex.

We want to add support for various multi-line constructs, which means we
need to know if a line is invalid or just waiting for more input. The
specific issues I have in mind are:

- Support multi-line strings
  (#31)

- Add a `:function` command for defining functions
  (#35)

We also want to improve tab-completion in various ways, which also involves
working with very similar types of incomplete input. Most of the
enhancements we have in mind will only be possible if we know more exactly
what we're completing, and re-using some of the parsing code to understand
the input seemed like the most logical approach. Specific issues are:

- Support the same tab completion options as zsh
  (#25)

- Add tab completion for options
  (#80)

- Auto complete stash commands
  (#220)

- Tab completion only works for the first command on the line
  (#261)

Note that this commit doesn't implement any of these enhancements, it just
makes them more likely to happen in the future.

Implementation details
======================

- Introduces equality methods on argument objects, used to testing parser
  output.

- git-prefix correction (i.e. interpreting `git foo` as `foo` when
  `help.autocorrect` is set) has moved from the Parser to the GitCommand
  class.

- The subshell implementation in this commit is not very good. It will be
  significantly improved in the next couple of commits, but it seemed too
  big of a change to roll into this one.
@georgebrock georgebrock self-assigned this Jul 3, 2017
@georgebrock
Copy link
Collaborator

After the tab completion improvements introduced in #296, #304, #310, #311, #312, #313, I think the tab completion is at least as good as the zsh completion that ships with Git, if not better. Thanks, @mike-burns, for the comment on this issue that inspired the DSL-based approach.

There are further specific improvements I'd like to make to tab completion, documented in #314, #315, #316, #317, #318, and #319.

Given the recent improvements, and all of those new more-specific issues, I'm going to close this.

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

5 participants