Skip to content

Conversation

@mqudsi
Copy link
Contributor

@mqudsi mqudsi commented Nov 10, 2024

This has been officially deprecated for a long, long time.

Additionally, pretty much all aspects of fish itself (aside from the core language) break when the user messes with $IFS (it was intentionally not a read-only variable) as all fish functions that rely on interpreting output of commands have their behavior changed in a way they can't handle. We've already decided to remove $IFS a long time ago, but if we wanted to keep it we would have to make it a special variable that only applies to the user script being executed but somehow doesn't apply to fish completions, default functions, runtime helpers, etc.

As an example, executing

> set IFS
> help

no longer works, because fish now thinks all of these potential paths are one long path:

> help
help: Help is being displayed in /mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
/mnt/c/WINDOWS/system32/cmd.exe
/mnt/c/Windows/System32/cmd.exe.
/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
/mnt/c/WINDOWS/system32/cmd.exe
/mnt/c/Windows/System32/cmd.exe: command not found

@mqudsi mqudsi added this to the fish 4.0 milestone Nov 10, 2024
@faho
Copy link
Member

faho commented Nov 10, 2024

This will break oh-my-fish.

They still claim compatibility with fish 2.2.0 (which in practice is broken - oh-my-fish/oh-my-fish#934).

Of course oh-my-fish is unmaintained at this point - oh-my-fish/oh-my-fish#947.


Setting $IFS globally was never a good idea, and isn't a good idea in posixy shells either.

What you do is set it locally like

set -l IFS '-'
echo $FISH_VERSION | read -la version_parts

That particular usage has been replaced with read --delimiter=-, introduced in fish 3.0 (from the very end of 2018).

Other uses would best be replaced with either string collect or "$()", which were introduced at other points.


I'm not saying we shouldn't remove it, but I would not want to introduce it at this point in the cycle.

I'd add it right after 4.0 and then give people some time, or back it out if it's too much of a problem.

@mqudsi mqudsi modified the milestones: fish 4.0, fish-future Nov 11, 2024
@mqudsi
Copy link
Contributor Author

mqudsi commented Nov 11, 2024

Ok, I changed the milestone.

I do think fish 4.0 would have been a good opportunity to finally break away from oh-my-fish issues, but it is true that we never emitted a "deprecated feature" message when IFS was set.

In the meantime I might add a hack to disable globally setting IFS?

@ridiculousfish
Copy link
Member

ridiculousfish commented Nov 19, 2024

I don't think we should do anything about IFS as part of the 4.0 release. We can add a feature flag in the next minor release; but I think oh-my-fish is a bigger concern and figuring out what to do about that would pay off even more.

@faho faho marked this pull request as draft November 19, 2024 19:37
@faho
Copy link
Member

faho commented Nov 19, 2024

(converted this to a draft so the "merge" button is unavailable to click by accident)

@krobelus
Copy link
Contributor

Not knowing much about this, I'd like to keep it for read.
This use might feel dated but it's not broken, not enough reason to outlaw it IMO.

For command substitutions, it might be broken and a good idea to remove, I'm not sure.

@mqudsi
Copy link
Contributor Author

mqudsi commented Nov 20, 2024

I like @krobelus's suggestion; that's a good compromise we could keep long-term and definitely beats making it a special local-only variable.

This has been officially deprecated for a long, long time.
This removes $IFS globally (which prevents fish internals from breaking when IFS
is manipulated) but keeps it as a legacy/deprecated mode of specifying `read`'s
`--delimiter` value for compatibility with (ba)sh and legacy fish scripts.
@mqudsi
Copy link
Contributor Author

mqudsi commented Dec 16, 2024

I've reworked the commit to keep $IFS as a (still to be someday removed) means of setting read --delimiter but removed it from everywhere else in the shell. This makes our own /usr/share/fish/ code much more resistant to $IFS manipulations (though we might have issues in the few places we use read in completions, etc if we aren't explicitly setting --delimiter ourselves), removing much of the need to remove $IFS altogether and making it easier to stomach keeping it around for legacy read compatibility purposes.

I think with this approach this should be included in 4.0 as the only thing it does is make fish itself more resilient to breakage (since globally setting $IFS basically broke everything, I believe it's safe to assume that removing that option does not hurt anyone) while preserving the local-only $IFS to dictate read behavior we intend to officially deprecate and hopefully remove at some point in the future.

@faho
Copy link
Member

faho commented Dec 16, 2024

I've reworked the commit to keep $IFS as a (still to be someday removed) means of setting read --delimiter but removed it from everywhere else in the shell.

That will still break setting IFS to empty to avoid splitting command substitutions. The replacements for that were added in 3.1 (string collect) and 3.4 ("$()").

I think with this approach this should be included in 4.0 as the only thing it does is make fish itself more resilient to breakage

I would not want to add it to 4.0 at this point. We could merge it first thing after, to possibly gain some information on what breaks, and back it out before 4.1 if it's too much.

@mqudsi
Copy link
Contributor Author

mqudsi commented Dec 17, 2024

That's a good point and sounds reasonable to me.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants