Fish-shell: Let's create fish 3.0 (our second major release)

Created on 21 Jun 2017  Â·  67Comments  Â·  Source: fish-shell/fish-shell

In the past 1.7 years (the time frame I've been contributing changes to the project) there have been a couple of controversial, non backward compatible, changes made in minor releases. In each case the core devs felt the risks were worth the benefits. We're now poised to make a couple more changes that are not strictly backward compatible. One is how set -lx works (see #1091 and #4149). The other is implementing "tied" variables (see #436 and #4082). I also have a proof of concept implementation for making abbreviations more efficient (see #4048). That one would be simpler and even more efficient if we didn't have to also maintain backward compatibility. You can find a list of issues tagged for the next major release here. There are probably quite a few more with a "fish-future" (meaning next minor) milestone that really should only be done in a major release.

So the question is whether we should bite the bullet and focus on a few of the changes that are risky to do in a minor release and focus on completing them for a fish 3.0 release sometime in the next six months (give or take).

If we did this it would mean fish 2.x would be put in bug fix only status. With the exception of continuing to add new completions that people submit. The fish project simply does not have enough regular contributors to actively enhance two major versions in parallel.

enhancement packaging

Most helpful comment

Okay, after I have just punted a few unimportant things from the checklist (if anybody implements them, we'll still take them, of course! There's just no need to have them block 3.0), the state is:

  • [x] #5210 and #3805 would be fixed by merging #5219
  • [x] #5251 is easy enough, I'd just like to know if the special case is really the smart decision
  • [x] #5229 is in the grand scheme of things not _too_ important
  • [x] #5267
  • [x] #4154 is this one, and would be solved by releasing

I've reset the due date to 11.11.

All 67 comments

In general, I would be okay with doing a major release, with breaking changes and such.

However, the major question is "How much do we break?". Do we go all-in and change e.g. the command substitution syntax to $() (something I'd actually like!) or do we still try to keep breakage to a minimum (e.g. #4149 is unlikely to actually affect any code negatively)?

Then there's another question: How much are we capable of implementing in a timely manner (nobody would be served by us taking two years to release anything)? A tiny major release might be a bad idea.

Then there's the issue of getting enough carrot of cool stuff to go along with the stick of breakage - if the changes don't appear worth it, people won't want to switch.

These last two points are maybe a bit too doom'n'gloom, I just don't want another programming-thing-with-an-animals-name-jumping-from-version-2.6-to-3.


Okay, so let's say we do it. How do we go about it? For how long will fish 2.x be supported? Do we delay the planned release date for now-3.0? Will poor @zanchey suffer a meltdown and become a wombat-farmer? Do we provide any facility for versioning (e.g. fish 3.0 installs as "fish3", or we rename the entire project to "Great Original SHell")?


So that's a "yes, if we can pull it off". I'd propose that we try to get 4 cool compat-breaking changes in PRs. I.e. we don't merge #4149 and #4082 until we have two more. Then we branch off a 2.7.0 branch as a backup and merge all of them to master. Then we just try to stuff 3.0 full with cool features so that it eclipses 2.6.0 completely.

Also, I'd like to have greater buy-in from and communication with the community. I'm kinda annoyed that #4103 only reached us after release, even though it was discovered earlier.

We should go as big as we can and still commit to a major release no more than six to 12 months in the future. Because once we start working on it we'll have very few resources for fixing issues with the 2.x branch. We should definitely change () to $() for example. Although we'll almost certainly need to still recognize () outside of quoted strings. We should also take the opportunity to no longer automatically turn PATH, MANPATH and CDPATH into arrays by leveraging the tied variable change I have in progress. Finding similar items that can be implemented in the near future shouldn't be hard.

My thinking is fish 2.x would continue to be supported for two or three years. But critical bug fixes only and possibly new completion scripts people submit. We would branch master to a Integration_2.7 branch and that would be our last 2.x minor release. After that it would be 2.7.1, 2.7.2, etc. as necessary to address critical bugs.

Whether we should rebrand as "fish3" is a tough question. When iTerm 2.0 came out it became known as iTerm2 and it lives in /Applications/iTerm2.app/. But iTerm 3.0 is still referred to as iTerm2 and lives in the same directory. I've seen that happen with other projects too. And calling it "fish3" only superficially makes it easier for people to have both versions installed. Look at the situation with python for example.

Another change we should make: math should be a builtin rather than a wrapper around bc. This needs to be done in a major release because we can't simply embed bc in our project due to licensing issues. So we'll need to pick another implementation whose license is compatible with this project.

Okay, so I've started tagging issues/PRs with a new "fish-3.0" milestone (and I pulled a random due date from hammerspace). See https://github.com/fish-shell/fish-shell/milestone/18 for the full list.

The idea is that that milestone would contain things that we are reasonably certain we want to actually do for 3.0, while "next-major" would be for proposed breaking changes.

math should be a builtin rather than a wrapper around bc. This needs to be done in a major release because we can't simply embed bc in our project due to licensing issues.

Yes, #3157, included in the list.

From a Distro packager / maintainer point of view it makes my life much easier if breaking changes only ever occur in major versions and if that means releasing major versions more frequently then In my opinion its not a bad thing.

If you consider we have the following Major.Minor.Point I strongly think the following should apply

Point: Bugfixes only
Minor: Anything in point + New features that don't affect compatibility
Major: Any change including breaking ones.

That sends a clear signal to those of us putting fish into distro's about when and what updates we can push. For example in the openSUSE world we have Tumbleweed which is for users who want the latest and greatest, at an extreme case you could do a new major version every couple of months there and knowone would complain (I'm not suggesting you would). Then we have Leap which is designed to be more conservative. And while we would always take a new fish major version for a new Leap version and a Minor version (no breaks) for a new Leap Service Pack/Minor version, depending on the changes and the time in the release cycle I might not take a new Major version for a new Leap SP depending on the breakages, ie I might not take a new major version between Leap SP3-SP4 if it has a number of breaks, but I'd be more likely to take it between SP1 and SP2. Similar for our packaging system for SUSE Linux Enterprise although through OBS people can always choose the latest version if they want it.

And then for a version of Leap thats already released I'd only ever update to a new point version of fish and if a minor version came out with bugfixes that users care about i'd probably manually backport them into our packages.

I guess in summary I would have preferred if you did 3.0 instead of 2.5 with the breaking changes (especially the change in behavior for running applications when fish exited) instead of releasing. If your going to make breaking changes and not bump the major version the major / minor version numbers don't really mean anything.

We should definitely change () to $() for example. Although we'll almost certainly need to still recognize () outside of quoted strings.

I agree here, if your making a change like this compatibility needs to stay around for a while, maybe in fish 4.0 you can move to printing something to std:err when its detected and remove the old syntax in fish 5.0 (Just as an example it of course depends on actual release timelines). It would also be nice if you could enable a environment variable in fish 3.0 to also print to std:err to make it easy for people trying to port to catch everything.

My thinking is fish 2.x would continue to be supported for two or three years. But critical bug fixes only and new completion scripts people submit. We would branch master to a Integration_2.7 branch and that would be our last 2.x minor release. After that it would be 2.7.1, 2.7.2, etc. as necessary to address critical bugs.

Speaking with a Distro maintainer hat on I do like this idea, but how many critical fixes do you think we will find? To me fish 2.X seems really stable so i'd consider a halfway approach, create the branch but don't plan any releases then if any critical issues or security issues do appear you can spin a release but know one is expecting one otherwise.

I also suspect most people outside those who are just using whichever version of fish there distro provides will migrate to 3.0 pretty quickly the only exception will be the few who use fish as there main scripting language as opposed to there main interactive shell and I don't see this group being as concerned about getting new completions etc. From all the people I talk to there is not many of these people, most I speak to use fish as an interactive shell and still use bash or python for scripting.

Whether we should rebrand as "fish3" is a tough question. When iTerm 2.0 came out it became known as iTerm2 and it lives in /Applications/iTerm2.app/. But iTerm 3.0 is still referred to as iTerm2 and lives in the same directory. I've seen that happen with other projects too. And calling it "fish3" only superficially makes it easier for people to have both versions installed. Look at the situation with python for example.

I don't think we should, in the Linux world atleast most applications don't do this and the ones that do cause us a bunch of headaches. Python is a different example, the changes between 2 and 3 were massive and many people had massive python code bases and 10 years on there are still some of these that knowone has finished porting to python3 yet. Distro's also have all handled this slightly differently arch for example has had /usr/bin/python as python3 for a long time and /usr/bin/python2 as python 2. Python 2 -> Python 3 had atleast 10 to 20 as big breaking changes as going from () to $() without being backwards compatible. (They have since realised that was too much and won't go that far with python 4)

On Linux atleast its easy to co install multiple fish versions you can install one to /usr/local. or install them to /opt/fish2 /opt/fish3 then symlink or use update alternatives to choose the one thats actually used. This still leaves you with both versions using the same config files and presumably the reason you would want to have multiple versions installed is because you haven't migrated all your config / scripts yet. So to install multiple versions you'd also want to create new fish3 config files, which for most people is going to be more effort then its worth, given most people will probably be able to get the new version fix any issues in there config and then be happy on fish version 3. There will be some people with a larger number of fish scripts that they need to port and I'd expect these people would be able to co install both versions until they had ported.

It will be a more interesting problem if fish 3 breaks the plugin managers such as fisherman oh-my-fish etc, but there developers really should be trying the beta's so they are ready in time but if there not there users will just wait and migrate when its ready.

I also forgot to mention in my last message another reason for not creating a /usr/bin/fish3 etc is if come 2-3 years time if someone can see valid reasons for breaking changes even if there small breaks i'd much rather a fish 4.0 gets released rather then trying to squeeze them into a fish 3.X release, and having to change biniaries and config files again would make that process much harder.

@simotek: Many thanks for the feedback.

how many critical fixes do you think we will find?

Very few. Probably no more than five over the two to three years we would expect to support it. Because even though we'll continue to see people reporting bugs against 2.x few of them will impact enough people, or represent a security issue, to warrant a point release.

Your thoughts on "fish3" mirror mine. I have fish23, fish24, and fish25 installed with different root directories. This allows me to easily test the behavior of older versions. But because I've updated my fish config to rely on recent changes I almost always have to use the env HOME=xxx fish23 trick when using those old versions. Not something a typical user is going to want to deal with. Which argues pretty strongly for us not changing the binary name. Anyone who needs multiple versions will be prepared to deal with it via symlinks and such. Those who don't will just be annoyed that it's now "fish3" rather than "fish".

Why change command substitution syntax to $()? Is this discussed in another issue? I tried to search for it with no success.

Also, I feel pretty strongly that we should be aiming for a fish 3.0 release closer to six months from now than 12 months. If that means not doing a fish 2.7 release I think that's a reasonable tradeoff.

Why change command substitution syntax to $()?

For a variety of reasons but the primary one is to allow command substitutions inside double quoted strings. Also for consistency with ksh/zsh/bash. There is no good reason for fish to be different in this regard. There may be others but the primary issue where this is discussed is #159.

My 2 cents are simple:
If Python can do it, Fish can do it too. It happens time to time that ideas that seemed good at their time are deemed obsolete or even wrong, so changing is not only desirable but actually necessary to improve the quality of the product. So, please go for the changes if most of us agree they're good changes.

Another +1 to fish 3.0, FWIW. I'm certainly biased by being quite new to fish, but it's perhaps significant that I've already ran into #159 twice, and -- as noted by at least one additional user in that issue -- I'd completely forgotten about the issue and its workarounds the second time I ran into it.

Additionally:

And calling it "fish3" only superficially makes it easier for people to have both versions installed. Look at the situation with python for example.

Not only that, but naming it fish3 might (unfairly, in my humble opinion) bias users against moving on from fish 2.

My 1/2 cent: I agree with Braham-Snyder. Do not isolate users by changing the name. For the rest, it has already been said above.

Long time fish user, first time poster. Freaking love this shell!

Don't have anything against forward progress and breaking / non-compatible changes.

Fish 3.0 sounds good to me, but I'd strongly encourage the binary name to stay the same. The full path to a binary of a shell has it's way of showing up in lots of places you might not expect (chsh, /etc/passwd, user scripts, crontab, etc.). For a shell, even if the changes are breaking, I'd prefer to maintain the binary name. The other things that people mention about the future (fish4?) also place doubt in my mind.

I personally think Python caused themselves a lot of trouble when they decided to continue with two binaries (e.g. python3), and that's probably a lot of what is preventing the general public from moving on (as well as creating strain for the python programmers, as they now have to continue to support and develop two completely separate code trains). Just my 2 cents.

What I would like to see in a major release is more safety (ref #805). That's the reason I use bash for scripting.

Of the low hanging fruit, I don't see why we don't have the equivalent of bash's set -u by default:

> set hippopotamus
> ls $typopotamus
fish: $typopotamus is not defined.
ls $typopotamus
   ^

Compare that to failglob, which we already have:

> ls *nonexist
fish: No matches for wildcard '*nonexist'. See `help expand`.
ls *nonexist
   ^

I don't know if I'm the only fish user who don't use fish for scripting, but we may be overestimating the importance of backward compatibility: Unlike most programming languages, fish is a user interface that happens to be a programming language. Compare that to python: Python is a programming language that happens to have a REPL interface. So it was more important for python.

Python3 was a failure in that some people still cling to python2. I think the lesson from that must be that even a major release must not be too backward incompatible.

I agree with @anordal that fish 3.0 should make dereferencing an unset variable an error. It will be interesting to see how many bugs that turns up in our scripts; let alone those contributed to Fisherman and OMF. I'll open an issue.

It's pretty clear there is strong support for a fish 3.0 release. And we have a solid list of items we know we want to do and several more we could include time permitting. What are the next steps?

Do we want to make a 2.7 release in two months? I think the answer is yes as it gives us one more published milestone for fixing bugs in the 2.x series before we stop making 2.x releases other than for a critical/security bug. On the other hand I know @zanchey wants to stop being responsible for release management. It might be better to let him focus on automating more of the process and better documenting the manual steps so that someone else can assume responsibility for publishing a release. In which case 2.6 becomes our last minor release in the 2.x series.

What do we want to do with the nightly builds? The simplest for us is to create a Integration_2.7.0 branch that we add to explicitly prior to making that release (or a Integration_2.6.1 branch). The master branch is then free for us to make non-backward compatible changes. The problem with this is that it means anyone updating from the nightly Ubuntu PPA, for example, could be quite surprised. It might be better if we switched the nightly build to the Integration_2.7.0 branch. At least until we're within a month of a fish 3.0 release date at which time we formally enter beta testing of 3.0 and switch the nightly build to the master branch so our non-backward compatible changes start seeing more exposure. Alternatively we create a Integration_3.0.0 branch that the core devs work from and master remains 2.x until 3.0 is released. The risk here is that doing git checkout master then merging other branches is pretty much a reflex action (at least for me). Which means we're likely to see changes merged into the defacto 2.x branch that we don't want included.

Regardless of the answer to the above questions, and others I haven't thought of, we should probably put a stake in the ground and declare that as of today only bugs and new completion scripts will be included in the 2.7 branch (however we manage it). This will allow us to start focusing our efforts on the "big" changes we want for the 3.0 release.

If $() is to be supported, could the same be done for && and ||?

If $() is to be supported, could the same be done for && and ||?

Probably not. In no small part because the latter has been extensively debated and the core devs remain unconvinced that syntax is needed in fish. Fish already has an equivalent mechanism. Please do not turn this issue into a discussion about && and ||. Read issue #150. And if you still feel you can make a convincing argument for adding it to fish 3.0 open a new issue with your argument.

(This was written last week but not posted; I'll try address some of the follow ups since I wrote in in due course.)

In October 2013, the fish committers had a thread looking at how we will manage versioning, which is unfortunately not public, but where we agreed:

(@zanchey)
I had made the assumption that we were going to do versioning along the
lines of Python and the Semantic Versioning spec; i.e. that scripts
targeting fish 2.N will always work in fish 2.N+x, and that fish 3.0
breaks that backward compatibility guarantee.

Any direct negatives to that idea? One problem we may run into is having
fish 2.10, and wanting to bump the major revision just to simplify things.
There's no real reason to do so, but we haven't written down anywhere that
that is the intention.

(@ridiculousfish)
Yes, that is the versioning style I had in mind, with the caveat that minor revisions may
contain breaking changes if we are confident that most scripts will be unaffected. An example is
the change to file redirections in fish 2.1 - that may break someone, but probably will not.

Certainly fish 3.0 will be the appropriate version for backwards-incompatible changes.

It's notable that this will be the first major deliberate backwards-compatibility break in my five years with fish - fish 2.0 kept all scripts running largely unchanged. There's an argument that in the 12 years since fish was released, the language really should have stabilised; certainly backwards-incompatible syntax is unusual for shells, and is something of a user-hostile change. In making a deliberate decision we need to acknowledge the failure of foresight (in the past) and imagination (at present).

If we go ahead, I wonder if there's something we can do to ease the pain.

Some options:

  • provide separate binaries (ie fish2, fish3), or at least work on the infrastructure to allow co-installation of multiple versions, presumably by adding a flag to the configure script. Thanks for the considered opinions above - I agree this is not something we want to do by default.
  • compatibility levels, ala bash: potentially enormous amounts of work in keeping multiple parsing implementations working, and how we describe the effective compatibility level of scripts is hard to get right. Interactive mode presumably starts in the newest compatibility level - do scripts run in the oldest or newest until declared otherwise? Is there a pragma or a status compatibility-level subcommand to change the active level?

I don't particularly like either of these, but I can't think of anything better.

I'm happy to keep maintaining release branches for 2.x and 3.x - in fact the way the distribution repositories are set up was explicitly designed to allow this, and the new release infrastructure that is slowly getting there will be easy to extend to the same.

@zanchey, As far as I can tell only one of the proposals changes syntax: adding $( ). And that will be backwards compatible as long as we continue to support ( ) outside of double quotes. We may want to mark it deprecated syntax targeted for removal in fish 4.0 but it should definitely still be valid in fish 3.0

There is one proposed change that is a significant backward incompatible change in behavior: making dereferencing an undefined variable an error. All the other changes (e.g., tied vars) pose some risks but are unlikely to cause problems for 99% of users. As for the undef var behavior change that is still very much up for debate. It is definitely going to be painful and noticed by a significant percentage of users. We may have to do something we've so far shied away from: making the behavior configurable. With the default being to only warn and only if interactive. But that should be discussed in #4163.

@zanchey and others: Should we use the master branch for 3.0 work and create a Integration_2.7.0 branch that we add to selectively until we're ready to publish the 2.7.0 release? Or should we create a Integration_3.0.0 branch (or equivalent) that we merge 3.0 only changes into? The latter means the current setup for "nightly" builds continues to create 2.x packages without change. The former means we need to change the nightly build config so that users using the nightly build packages aren't unexpectedly getting a fish 3.0 work in progress. I prefer the former (3.0 work merged to the master branch) because it's less likely to result in major release changes leaking into the 2.x series.

There is one proposed change that is a significant backward incompatible change in behavior: making dereferencing an undefined variable an error.

That change has now been rejected, so we now have a bunch of "somewhat incompatible" changes. Which is okay, to be honest.

Note that I haven't heard of a single example of breakage resulting from #4149, which I specifically asked for. So I'd be okay with adding that in 2.7.0 - if it breaks nothing in practice, it is practically backwards-compatible.

@faho, I'd prefer we be conservative with respect to the 2.7.0 release since it is intended to be our last release in the 2.x series. So even changes that might, but are unlikely, to cause problems should be deferred to the 3.0.0 release. We should be cautious and only merge changes we are close to 100% confident won't break any existing 2.x users. I don't think #4149 is in that category.

Since no one else has voiced an opinion let's create a major branch and keep master targeted for 2.7.0. That's the safest approach for anyone building from source and means we don't have to do anything to keep our "nightly" build packages that lots of users install still based on the 2.x tree.

I want strict mode by default - fail immediately if any command returns non-zero status that is not handled.

@techtonik, Your request to implement behavior similar to bash/zsh set -e is already being tracked in issue #510. If you want it included in fish 3.0 you should comment on that issue. But, FWIW, given all the other changes we have already tentatively committed to doing for fish 3.0 it is highly unlikely that will be implemented.

Not necessarily for the first 3.0 release, but speaking of awesome breaking changes, has there been a discussion about replacing the abomination that is test with native (basic) evaluation in the builtins?

Is it out of the question to natively support if $status == 2 or while (echo foo) != (echo bar)

(I guess that latter should now be $(echo ...)..)

@mqudsi, That's something we could only do in a major release (so fish 4.0) since it would require extensive changes to the parser. But more important is that it violates the fish manifesto to minimize magic syntax and implement as much as possible in terms of commands. What would be more palatable is a command that is an alternative to test but without its weird quirks. For example, test versus test '' versus test 'x'.

Meh. IMO operators like == are hardly inscrutable bits of magic syntax that violate a core fish belief. Fish 3.0 is a while off still; if you wanted to try to implement it @mqudsi I think people would be happy to review it.

I am very perplexed by all the thumbs-up to @floam's previous comment. There is absolutely nothing magic about == as an equality operator. What is magic, and problematical, are constructs like this:

if abc == $var
   # do something
end

How would fish determine that it should treat that as if test "abc" == "$var" rather than running a command named abc with arguments == and whatever $var expands to? The way Korn shell (ksh), bash, et. al. handle this is via the double-bracket syntax:

if [[ abc == $var ]]; then

Note, not single brackets which are just an alias for test. We could certainly introduce support for the double-bracket syntax. What we cannot do, even in a major release, is introduce support for bare expressions following if and while keywords as doing so fundamentally changes the nature of the language. Or are you proposing that we require

if some-command + x
    # do something
end

rewritten as

some-command + x
if $status == 0
    # do something
end

The suggestion is actually dead in the water because you can't feasibly change the behavior of > to become the greater than comparison operator instead of the redirection operator.

... because you can't feasibly change the behavior of > ...

You could, sort of, by requiring that it be escaped by a backslash. But that is worse than the current situation. Again, the only way to do this is implement something like the double-bracket syntax pioneered by Korn shell (ksh).

My bias towards C would have me prefer ( condition ) over [[ condition ]], but fish' history with ( .. ) for subshell execution makes that a no-go.

The suggestion is actually dead in the water because you can't feasibly change the behavior of > to become the greater than comparison operator instead of the redirection operator.

The ksh double-bracket syntax does:

[[ 2 < 5 ]] && echo smaller

@faho right, I was referring to "bare" expressions (which was actually not the point of my initial suggestion. I'm not against decorators, just against test's needlessly arcane syntax). I'd be fine with ksh' syntax, tbh.

Since it seems that making fish's syntax more compatible with other shells is the name of the game for fish 3, I would like to suggest that we finally allow FOO=bar cmd to set an environment variable for cmd.

We already support export FOO=bar as a compatibility shim for set -x foo bar, allowing FOO=bar cmd isn't much of a reach and it would address a constant question newcomers to fish have from pretty much any other shell.

I would like to suggest that we finally allow FOO=bar cmd...

The reason we haven't supported that is it is superfluous as it only avoids prefixing env to the job. And it will greatly complicate the parser. Having said that I'm not philosophically opposed but someone else will have to do the work as I don't see the point. Go ahead and open an issue with the "RFC" tag.

Also, "making fish's syntax more compatible with other shells is the name of the game for fish 3," isn't an explicit goal. And other than supporting $(...) I can't think of a change targeted for inclusion that does so.

Also, "making fish's syntax more compatible with other shells is the name of the game for fish 3," isn't an explicit goal. And other than supporting $(...) I can't think of a change targeted for inclusion that does so.

Yes, I may be overstating things. I guess () vs $() is just such a big one that it felt that way to me.

The problem isn't with simply using env per se, it's when you have multiple variables to set and you end up with nested env commands half a dozen or so deep.

(Additionally, I _still_ forget thanks to muscle memory when to use foo bar or foo=bar, but that's neither here nor there.)

The problem isn't with simply using env per se, it's when you have multiple variables to set and you end up with nested env commands half a dozen or so deep.

Huh? Every env implementation I've ever used supports setting multiple env vars. This is perfectly legal:env FOO=bar BAZ=frob my_command.

We already support export FOO=bar as a compatibility shim for set -x foo bar, allowing FOO=bar cmd isn't much of a reach and it would address a constant question newcomers to fish have from pretty much any other shell.

Shouldn't it be set -gx foo bar ? if atleast being compatible with bash. In bash you need to use the local keyword if you want to set the variable with local scope ie local FOO=bar instead of export FOO=bar

allow FOO=bar cmd to set an environment variable for cmd.

Previous discussions: #587, #438 and https://github.com/fish-shell/fish-shell/issues/564#issuecomment-13261782

Wild idea: Make echo print its arguments linewise (or add an option or another builtin for that) because:

  • command substitutions split by newline → this is how you return a vector
  • it is trivial to inhibit by concatenating the arguments (and quoting any variable expansions)
  • less mindblowing than printf '%s\n' with multiple args

We can't change the default behavior of echo. Not even in a major release. Way too much code would be broken if we did that, @anordal. And we can't add a flag to get the alternative behavior precisely because the set of flags it allows is not extensible. The echo command should be marked deprecated due to its historical quirks.

A quick suggestion: if any valid breaking changes don't make it into fish 3.0 but could be included in a future release, please document them in some findable way. For example, a post-3.0-roadmap wiki page, a "breaking changes" milestone, "breaking change" issue tag...

a "breaking changes" milestone

That's basically what the "fish-major" milestone is.


Okay, so here's what I consider the final blockers to 3.0 releasing:

  • [x] #4394 (Removal of ^) needs to be decided

  • [x] #4230 (Removal of %, renaming of var) needs to have backwards compatibility sorted out

  • [x] #4896 needs to be fixed (trivial) - or some form of compatibility for ? in case statements needs to be reinstated

  • [x] #4897 needs to be fixed - and I'm not quite sure how

  • [x] #4893 needs to be figured out and possibly fixed - and I need to find the root cause

  • [ ] #4778, maybe?

Also, I _think_ we've solved the $_ kerfuffle? Did we rename any other variables that we might to add back?

And I think @ridiculousfish wanted to add . (as another name for source) back.

The best we've come up with for #4897 is still not something I'm completely sure about, so I'd rather not add it to 3.0 now.

4394 and #4230 have now been addressed, so as far as I'm concerned we could release now.

We still have some issues in the milestone, we need to decide whether to fix or punt each.

We still have some issues in the milestone, we need to decide whether to fix or punt each.

Going through the list:

  • 4965 is a bit of a moonshot - I'd love to not ship that bug again, but I'd also like for the solution to work well, and I'm not 100% sold.

  • 4230 has effectively been fixed by adding "%self" to everything that takes it

  • 4794 and #4825 are both about cmake, while we still ship autotools. Also, both are about non-critical parts of the cmake build.

  • 4478 needs more work

  • 4627 is entirely non-critical

  • 4540 is a shame, but also nothing new

  • 4255 has two parts, and the part that should be in 3.0 is.

  • 4191 is non-critical and also something that needs a bunch of work.

  • 154 needs more work.

  • 436 needs more work.

  • 4154 is this issue, and automatically solved by releasing :smile_cat:

So the one remaining issue is #4778.

Also the ./source thing. Which I'm gonna take care of now.

Is it possible to merge #4849? Personally, I want this feature in 3.0.

It's still not clear to me what we gain by dropping (rather than adding lowercase versions of) CMD_DURATION, FISH_VERSION etc (#4414).

@faho I'll work on #4778 later today, DV.

@faho not exactly the same day, but I've updated the code for #4778 to reflect the situation as best as I've been able to figure it out.

Given that the one remaining issue in https://github.com/fish-shell/fish-shell/issues/4154#issuecomment-387762493 is fixed, how’re we doing with this? :)

I'm working through the huge number of commits as I prepare the release notes, but I'd also like to restore the variables I mentioned above and possibly a better story for the removal of process expansion.

I'd also like to restore the variables I mentioned above

When it comes to $FISH_VERSION, that's something we should either commit to (and deprecate $version finally), or we should keep $version. The advantage that $version has is that it was in all fishes ever released.

$FISH_VERSION is the nicer name, but it only goes back to 2.0.0. On the other hand... do we really expect people to use fish < 2? It's effectively an entirely different application.

So... I slightly prefer $FISH_VERSION (because the name is nicer), but I don't care too much either way. I just want us to commit to one, finally.


When it comes to $CMD_DURATION, I don't think the rename was worth it. I don't like the hassle of switching, and I hate to impose more hassle on early adopters by switching back (though they probably did the $CMD_DURATION $cmd_duration trick I explained in a few places).

However, keeping both and deprecating the old one here is the worst solution - that means you have to try the new one and fall back, instead of just doing above trick, and some will just stick to the old one until it's too late.

a better story for the removal of process expansion.

Agreed! I'd argue we should keep %self as a special case, and enhance the jobs builtin so you can use that to get the necessary PIDs and whatnot. I don't really like the %something DSL.

Keeping both, in both cases, is low-friction - it doesn't appreciably impact the performance of the shell or (I think) make the shell any more difficult to learn.

Hi there. I'm just curious--do we have a new timeline or estimate on when 3.0 will be released? I've been excitedly monitoring the tickets tagged with the 3.0 milestone getting closed but new tickets also keep getting added to the milestone.

No estimate; I consider all issues remaining in the 3.0 milestone to be blockers and these are trending down slowly. Things that get added at this point are newly discovered blockers (e.g. zanchey's observation that out-of-tree tarballs don't work).

Okay, after I have just punted a few unimportant things from the checklist (if anybody implements them, we'll still take them, of course! There's just no need to have them block 3.0), the state is:

  • [x] #5210 and #3805 would be fixed by merging #5219
  • [x] #5251 is easy enough, I'd just like to know if the special case is really the smart decision
  • [x] #5229 is in the grand scheme of things not _too_ important
  • [x] #5267
  • [x] #4154 is this one, and would be solved by releasing

I've reset the due date to 11.11.

I've fixed #5267, #5251 and #5229.

In addition @ridiculousfish has opened #5271, which is a bit of a follow-up to #5245. Not having that in 3.0 would be a bit awkward.

The release notes need a bit of work, which I'll hopefully get to this week.

Are you about to release 3.0? I don't think I need to switch from bash, but I was looking for better alternatives just for a change.

I found zsh and fish. Zsh releases more often and is more stable. Fish is still in the beta-testing phase, but it works well out of the box.

Fish is still in the beta-testing phase,

It's not? Fish has been released software for twelve years.

We're preparing the next release, is all.

I've set the deadline for 3.0 to 11.11, so a little over a week from now. We probably want to have a beta before that.

Also you might find that there are large differences between fish and zsh, so this categorization doesn't really fit. Fish isn't posix-compatible on purpose, and tries to be nicer to use without having to configure everything. Zsh on the other hand tries to be everything to everyone, so you can configure everything. It has a daunting number of knobs and options to fiddle with, and a number of extensions to posix-style shellscripting, like extended globs (print *.c(#q:s/#%(#b)s(*).c/'S${match[1]}.C'/) is legal zsh code, taken from the zshexpn manpage).

Lack of POSIX compatiblity can be a problem with terminal programs.

I use vim, nvim, htop, ranger, and so on.

@crocket: Not really. vim needs "set shell=/bin/bash" if you're using plugins that use $shell (and using $shell in this manner isn't a practice I can recommend). Other things should just work, as they run in the shell they were written for. They just specify it in the shebang line (for example).

I know that htop works as I use it myself, and I've not heard of problems with ranger.

The only significant problem is if you're using things that require you to source them like nvm or direnv.

Anyway, fish 2.7.1 is out so you could just try it out.

I use (n)vim and htop all day long both in my day job and to develop fish itself. I can promise you they work fine without bash (yes even with anything other than the shoddiest of plug-ins).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Ambrevar picture Ambrevar  Â·  82Comments

joshuaconner picture joshuaconner  Â·  98Comments

dag picture dag  Â·  92Comments

ghost picture ghost  Â·  106Comments

dag picture dag  Â·  58Comments