thoughtbot / gitsh

An interactive shell for git
https://thoughtbot.com
BSD 3-Clause "New" or "Revised" License
1.95k stars 105 forks source link

Brace expansions #366

Open georgebrock opened 5 years ago

georgebrock commented 5 years ago

e.g. :echo h{i,o}p produces hip hop.

The implementation differs from GNU Bash and other general purpose shells in a few ways. First, there are a few deliberate things that I think improve the consistency of the language:

There are also a couple of differences that we might want to consider changing:

To support this new behaviour this PR also updates all of the various Gitsh::Arguments::* classes' #value methods to produce Arrays instead of single values. The Gitsh::ArgumentList class takes on the responsibility of flattening the results.

Begins to address #145

georgebrock commented 5 years ago

I've been using this version for a few days, and I think I want to revisit some of the deliberate differences from how GNU Bash et al. handle things. Specifically these two:

  • Single-option expansions behave like strings, e.g. {x} is like 'x'.
  • Zero-option expansions behave like empty strings, e.g. {} is like ''.

I'll frequently diff my local branch against upstream, e.g. after a complex interactive rebase to make sure I didn't introduce accidental changes. The easiest way I know of doing that is diff @{u} @. After this change, that's pretty cumbersome (either diff '@{u}' @ or diff @\{u\}).

There are other similar shorthands, which I use less often but others might not, like @{-1}.

Three solutions I can think of:

  1. Do the Bash-like thing, and treat {} or {x} as literals, only doing expansion when there's at least one comma.
  2. Introduce a magic variable for upstream, e.g. $_u, and advise gitsh users to use that.
  3. Leave things as they are, alias diff @{u} @ to diffu for my own use case, and trust others will find similar work arounds.

Following the principal of least astonishment, I'm inclined to do the first one.

What do other gitsh users things? /cc @sharplet @mike-burns

mike-burns commented 5 years ago

Huh I had no idea:

~% echo a.{b,c}
a.b a.c
~% echo a.{b}
a.{b}
~% echo a.{} 
a.{}

(zsh)

I'm in favor of that, option (1).

sharplet commented 5 years ago

I’m also in favour of option 1. I regularly use this syntax to inspect my stash:

git show stash@{1} # show me the next stash below the top
georgebrock commented 5 years ago

Finally got back to this and (pairing with @seanpdoyle) figured out how to make this behave more like general-purpose shells. As of now:

We had to make some minor compromises to get there, specifically an unmatched brace is now a parse error, but it's possible to work around by using an escaped brace e.g.

gitsh@ :echo }
gitsh: parse error
gitsh@ :echo \}
}