Commit Graph

21689 Commits

Author SHA1 Message Date
Johannes Altmanninger
708703b9ec Reimplement should_suppress_stderr_for_tests() for some tests
"cargo test" captures stdout by default but not stderr.

So it's probably still useful to suppress test output like

	in function 'recursive1'
	in function 'recursive2'
	[repeats many times]

This was done by should_suppress_stderr_for_tests() which has been
broken. Fix that, but only for the relevant cases instead of setting
a global.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
def9230ad6 fish-path: remove needless UTF-8 requirement and code clone
At least on our MSRV, strip_suffix() also exists for byte slices,
not just str.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
4ef0e37011 status fish-path: remove dead code
This value is either "fish" or an absolute path (as promised by the
docs of std::env::current_exe()); it can't be empty.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
ce82577d2f Actually fix stripping of " (deleted)" suffix
Commit 7b59ae0d82 (Unbreak hack to strip " (deleted)" suffix from
executable path, 2025-10-02) accidentally droped the "!".
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
f6584225c2 Pin down "status fish-path" at startup
On some platforms, Rust's std::env::current_exe() may use relative
paths from at least argv[0].  That function also canonicalizes the
path, so we could only detect this case by duplicating logic from
std::env::current_exe() (not sure if that's worth it).

Relative path canonicalization seems potentially surprising, especially
after fish has used "cd". Let's try to reduce surprise by saving the
value we compute at startup (before any "cd"), and use only that.

The remaining problem is that

	creat("/some/directory/with/FISH");
	chdir("/some/directory/with/");
	execve("/bin/fish", "FISH", "-c", "status fish-path")

surprisingly prints "/some/directory/with/FISH" on some platforms.

But that requires the user actively trying to break things (passing
a relative argv[0] that doesn't match the cwd).
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
a0a8a0b817 Move get_fish_path to a meaningful module 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
f88b1fd393 Don't use argv[0] directly when computing executable path
When "status fish-path" fails, we fall back to argv[0],
hoping that it contains an absolute path to fish, or at
least is equal to "fish" (which can happen on OpenBSD, see
https://github.com/rust-lang/rust/issues/60560#issuecomment-489425888).

I don't think it makes sense to duplicate logic that's probably
already in std::env::current_exe().
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
bd720ec9f6 Use early return in get_executable_path 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
56555f6319 Remove obsolete Unicode char reinitialization code path
Since c8001b5023 (encoding: use UTF-8 everywhere, 2025-10-18), a
change in locale variables can no longer cause us to toggle between
"…" or "...".  Have the control flow reflect this.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
71a962653d Be explicit about setlocale() scope
We use the following locale-variables via locale-aware C functions
(to look them up, grep for "libc::$function_name"):

- LC_CTYPE:    wcwidth
- LC_MESSAGES: strerror, strerror 
- LC_NUMERIC:  localeconv/localeconv_l, snprintf (only in tests)
- LC_TIME:     strftime

Additionally, we interpret LC_MESSAGES in our own code.

As of today, the PCRE2 library does not seem to use LC_MESSAGES
(their error messages are English-only); and I don't think it uses
LC_CTYPE unless we use "pcre2_maketables()".

Let's make it more obvious which locale categories are actually used
by setting those instead of LC_ALL.

This means that instead of logging the return value of «
setlocale(LC_ALL, "") » (which is an opaque binary string on Linux),
we can log the actual per-category locales that are in effect.
This means that there's no longer really a reason to hardcode a log
for the LC_MESSAGES locale. We're not logging at early startup but
we will log if any locale var had been set at startup.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
732942ec62 Force libc wcwidth to use UTF-8 locale again
Commit 046db09f90 (Try to set LC_CTYPE to something UTF-8 capable
(#8031), 2021-06-06) forced UTF-8 encoding if available.

Since c8001b5023 (encoding: use UTF-8 everywhere, 2025-10-18) we no
longer override LC_CTYPE, since we no longer use it for anything like
mbrtowc or iswalpha.

However there is one remaining use: our fallbacks to system wcwidth().
If we are started as

	LC_ALL=C fish

then wcwidth('😃') will fail to return the correct value, even if
the UTF-8 locale would have been available.

Restore the previous behavior, so locale variables don't affect
emoji width.

This is consistent with the direction in c8001b5023 which stops us
from falling back to ASCII characters if our desired multibyte locale
is missing (that was not the ideal criteria).

In future we should maybe stop using wcwidth().
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
5eebeff5a9 Retire our "use-LC_NUMERIC-internally" workaround
Commit 8dc3982408 (Always use LC_NUMERIC=C internally (#8204),
2021-10-13) made us use LC_NUMERIC=C internally, to make C library
functions behave in a predictable way.

We no longer use library functions affected by LC_NUMERIC[*]..

Since the effective value of LC_NUMERIC no longer matters, let's
simplify things by using the user locale again, like we do for the
other locale variables.

The printf crate still uses libc::snprintf() which respects LC_NUMERIC,
but it looks like "cargo test" creates a separate process per crate,
and the printf crate does not call setlocale().
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
f6d7198317 printf tests: extract function for calling libc::sprintf 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
dc553ac628 Minor style change in read_locale() 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
6643b8c3e1 Document LANGUAGE as :envvar: too 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
2954ff3991 Update docs on locale variables
* since c8001b5023 (encoding: use UTF-8 everywhere, 2025-10-18)
  we always use UTF-8, which simplifies docs.
* emphasize that we (as of an earlier commit) document only the locale
  variables actually used by fish. We could change this in future,
  as long as the docs make it obvious whether it's about fish or
  external programs.
* make things a bit more concise
* delete a stale comment - missing encoding support is no longer a problem
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
ab69ef4b83 Remove unused LC_COLLATE and LC_MONETARY
We may have used LC_COLLATE in the past via libc functions but I
don't think we do today.  In future, we could document the variables
not used by fish, but we should make it obvious what we're documenting.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
e8c0b3df24 Extract some setlocale() calls; use C-string literals 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
5a12247572 Extract function for listing all locale variables
These include variables that are ignored by fish, which seems
questionable for __fish_set_locale?  The the effect seems benign
because __fish_set_locale will do nothing if any of those variables
is defined.  Maybe we can get rid of this function eventually.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
58eec96a5b Document fish-specific bits about locale vars
Link to history, printf and "builtin _" which are the only(?) users
of LC_TIME, LC_NUMERIC and LC_MESSAGES respectively (besides the core
equivalent of "builtin _").
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
2be3f34f2c Remove more obsolete uses of LC_CTYPE
Our test driver unsets all LC_* variables as well as LANGUAGE, and
it sets LANG=C, to make errors show up as

	set_color: Unknown color 'reset'

rather than

	set_color: Unknown color “reset”

It also sets LC_CTYPE which is hardly necessary since c8001b5023
(encoding: use UTF-8 everywhere, 2025-10-18).

The only place where we need it seems to be the use of GNU sed as
called in tests/checks/sphinx-markdown-changelog.fish.

In future we might want to avoid these issues by setting LANG=C.UTF-8
in the test_driver again.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
7bd6e577d9 Remove obsolete uses of LC_CTYPE
These are obsolete as of c8001b5023 (encoding: use UTF-8 everywhere,
2025-10-18). The only place where we still read the user's LC_CTYPE
is in libc::wcwidth(), but that's kind of a regression -- we should
always be using a UTF-8 LC_CTYPE if possible -- which will be fixed
by a following commit.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
e09583e99e Double-down on using non-ASCII characters even if MB_CUR_MAX==1
Commit c8001b5023 (encoding: use UTF-8 everywhere, 2025-10-18)
removed some places where we fallback to ASCII if no UTF-8 encoding
is available.  That fallback may have been a reasonable approximator
for glyph availability in some cases but it's probably also wrong in
many cases (SSH, containers..).

There are some cases where we still have this sort of fallback.
Remove them for consistency.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
d1983b29c1 Reword warnings about missing sphinx-build/msgfmt
Also merge them into one warning because some of these lines wrap
on a small (80 column) terminal, which looks weird.  The reason they
wrap might be the long prefix ("warning: fish-build-man-pages@0.0.0:").
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
c0a988da21 Re-enable tests/checks/locale in CI
We don't currently run tsan tests anywhere.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
f5544fe2ae Fix libc import convention
Functions are always qualified with "libc::".  This is important for
finding who still uses "setlocale()".
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
75be4e3f6a tests/config-paths-standalone: skip on installed builds
This fails:

	tests/test_driver.py ~/.local/opt/fish/bin tests/checks/config-paths-standalone.fish

because  we don't expect to run from a relocatable tree.
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
6c267e88a1 __fish_macos_set_env: match macOS "path_helper" if MANPATH is overridden
Try to match
b33f386ac4/path_helper/path_helper.c
1. don't add empty segments
2. For MANPATH specifically, always add an empty segment at the end

See #10684
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
27f49b9523 __fish_macos_set_env: extract function to make it testable 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
b8f12ed857 More build fixes for Illumos' msgfmt
Their msgfmt doesn't support --output-file=- yet, so use a temporary
file if "msgfmt" doesn't support "--check-format".  Else we should
have GNU gettext which supports both.

See #11982
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
5cad71c081 Fix weird indentation in macro_rules 2025-11-01 12:45:17 +01:00
Johannes Altmanninger
f331f6a8a9 Relax test_close_during_select_ebadf
It failed for me on Linux.  Same as abf3f50bb9 (Relax test
`test_dup2_during_select_ebadf` (#11976), 2025-10-19).
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
461670c36a alt-p binding: don't add extra space character before pipe 2025-11-01 12:45:17 +01:00
Kaya Arro
0f32866980 docs: corrected some section title conflicts
Part of #11796
2025-11-01 12:45:17 +01:00
Kaya Arro
c123126991 help: fix anchor link to intropages
Part of #11796
2025-11-01 12:45:17 +01:00
Johannes Altmanninger
1302ac16f0 printf: remove unused re-export of en_US locale
As suggested in
https://github.com/fish-shell/fish-shell/pull/11992#discussion_r2464108030,
I don't know if anyone wants to use the re-exports rather than using
the `locale` crate.
2025-11-01 12:45:17 +01:00
Daniel Rainer
cc51d91e77 cleanup: avoid allocation in autoloader
There is no need to allocate a new box in these cases.
Flagged by nightly clippy.

There's also no need for the box at all; the comment is no longer
valid, especially because Rust const-propagates by default.

Closes #12014
2025-11-01 12:45:17 +01:00
Daniel Rainer
2d1c34c36a ci: update stable Rust version to 1.91
Closes #12013
2025-11-01 12:44:48 +01:00
Daniel Rainer
6422139fe0 cleanup: derive Default where possible
Not doing so triggers a clippy lint on Rust >= 1.91.

Part of #12013
2025-11-01 12:44:48 +01:00
Daniel Rainer
f511ef69c3 gettext: don't cache messages outside of gettext
Using gettext by calling it once on initialization and then reusing the
result prevents changes to the messages as when locale variables change.
A call to the gettext implementation should be made every time the
message is used to handle language changes.

Closes #12012
2025-11-01 12:42:55 +01:00
Johannes Altmanninger
525c9bbdcb Move Rust tests to implementation files
For historical reasons[^1], most of our Rust tests are in src/tests,
which
1. is unconventional (Rust unit tests are supposed to be either in the
   same module as the implementation, or in a child module).
   This makes them slightly harder to discover, navigate etc.
2. can't test private APIs (motivating some of the "exposed for
   testing" comments).

Fix this by moving tests to the corresponding implementation file.
Reviewed with

        git show $commit \
            --color-moved=dimmed-zebra \
            --color-moved-ws=allow-indentation-change

- Shared test-only code lives in
  src/tests/prelude.rs,
  src/builtins/string/test_helpers.rs
  src/universal_notifier/test_helpers.rs
  We might want to slim down the prelude in future.
- I put our two benchmarks below tests ("mod tests" followed by "mod bench").

Verified that "cargo +nightly bench --features=benchmark" still
compiles and runs.

[^1]: Separate files are idiomatic in most other languages; also
separate files makes it easy to ignore when navigating the call graph.
("rg --vimgrep | rg -v tests/").  Fortunately, rust-analyzer provides
a setting called references.excludeTests for textDocument/references,
the textDocument/prepareCallHierarchy family, and potentially
textDocument/documentHighlight (which can be used to find all
references in the current file).

Closes #11992
2025-11-01 12:42:55 +01:00
Johannes Altmanninger
7bc560190f Fix warning about unused test_notifiers on windows 2025-11-01 12:42:55 +01:00
Johannes Altmanninger
54b39be7e7 build_tools/style.fish: check that {rustfmt,Cargo}.toml edition specs are in sync
Commit 1fe6b28877 (rustfmt.toml: specify edition to allow 2024 syntax,
2025-10-19) mentions that "cargo fmt" has different behavior than
"rustfmt" before that commit.  Probably because when .rustfmt.toml
exists, rustfmt implicitly uses a different edition (2018?)  that
doesn't support c"" yet.  That commit bumped the edition to 2024,
which caused yet another deviation from "cargo fmt":

    Error writing files: failed to resolve mod `tests`: cannot parse /home/johannes/git/fish-shell/src/wutil/tests.rs
    error: expected identifier, found reserved keyword `gen`
      --> /home/johannes/git/fish-shell/src/tests/topic_monitor.rs:48:9
       |
    48 |     for gen in &mut gens_list {
       |         ^^^ expected identifier, found reserved keyword

This has since been fixed by
00784248db (Update to rust 2024 edition, 2025-10-22).

Let's add a test so that such changes won't randomly break "rustfmt"
again.

Fix that by using 2021 edition, like we do in Cargo.toml.

In future, rustfmt should probably default to a current edition (or
maybe read the edition from Cargo.toml?)  Not yet sure which one is the
upstream issue, maybe https://github.com/rust-lang/rustfmt/issues/5650
2025-11-01 12:42:55 +01:00
kerty
578f46c008 build_tools/style.fish: improve style and consistency 2025-11-01 12:42:55 +01:00
Johannes Altmanninger
b1cbbf7ce5 build_tools/style.fish: extract function 2025-11-01 12:42:55 +01:00
Johannes Altmanninger
af9b03625b build_tools/style.fish: reuse variable 2025-11-01 12:42:55 +01:00
Johannes Altmanninger
71f0e75651 Remove dead misc_init() 2025-11-01 12:42:55 +01:00
Johannes Altmanninger
3c4243fdd2 clang-format fish_test_helper 2025-11-01 12:42:55 +01:00
Peter Ammon
c66fa682e9 Fix some clipplies 2025-10-31 17:38:37 -07:00
David Adam
819759840e Debian packaging: use MSRV compiler if available
Allows the Ubuntu builds to work when using the cargo-VERSION packages.
2025-10-28 05:55:10 +08:00