Commit Graph

96 Commits

Author SHA1 Message Date
Johannes Altmanninger
86f92cb1a2 Remove crate-wide suppression of non_camel_case_types lint 2026-06-09 22:24:07 +09:00
Johannes Altmanninger
a580d82407 Stop exposing internal module names when we can use re-exports
Types like Environment are sometimes imported using their FQN and
sometimes via their re-export in the parent module; it seems better
to have one canonical name. I think we usually use the re-exports
already, so use them always.

It't not as trivial to enforce this in child modules (such as "mod
tests" which) but that's not a big loss.

While at it, make some other consistency improvements to imports.
2026-06-09 22:24:07 +09:00
Peter Ammon
068fa42202 Reimplement test_only_suppress_stderr
This parameter is used to suppress certain verbose errors that are
expected during tests. It was awkwardly threaded through multiple call
sites. Just set it (test only) on Parser.
2026-05-23 18:13:16 -07:00
Johannes Altmanninger
8250507a0f Rename Signal to RawSignal to make way for nix Signal 2026-05-23 09:24:21 +08:00
Johannes Altmanninger
ef8e62727c Pass Parser by exclusive reference
As described in
https://github.com/fish-shell/fish-shell/pull/9990#discussion_r1382494440,
prior to 77aeb6a2a8 (Port execution, 2023-10-08), "Parser" was
passed by mutable reference ("parser_t&"), even though operation
context was passed as "const operation_context_t &".  This worked
because C++ doesn't propagate const to pointers by default (see
https://en.cppreference.com/cpp/experimental/propagate_const).

	class operation_context_t {
		std::shared_ptr<parser_t> parser;
		...
	};

So "*ctx->parser" was a "parser_t&", not "const parser_t&".

Rust has stricter const propagation rules which means that const
operation context can't simply hand out a non-const reference to parser.

To be able to port code without changing its structure,
77aeb6a2a8 passed "Parser" by shared reference, using interior
mutability (RefCell) to modify parser fields. This is a bit ugly
(c.f. https://doc.rust-lang.org/std/cell/index.html "interior mutability
is something of a last resort") and means that some borrowing conflicts
are not found at compile time but runtime.

Pass both parser and operation context by exclusive reference, and
remove the interior mutability wrappers from parser's fields.
Since "libdata" is no longer inside a "RefCell", add a "ScopedRefCell"
around "transient_commandline".

The downside is that "ScopeGuard" use can become more intrusive
when we pass "Parser" or "OperationContext" as context (especially
when we use "zelf" since we can't shadow "self"), see
* 2930466d53 (Introduce ScopedCell and ScopedRefCell, 2025-03-15)
* 29ae571afa (Make scoped_push nicer, 2024-12-28)
Avoid this in some cases, specifically when using "ScopedCell" or
"ScopedRefCell". Since "&mut Parser" prevents the "ScopeCell"'s
"ScopeGuard" from holding a shared reference, use an "Rc" to capture
a dynamically-checked reference to the Cell. We could also use raw
pointers instead.

Change "Completer::apply_var_assignments" to return  a block ID, to
avoid the need to return a "zelf" "ScopeGuard".  In future, we could
probably untangle completer and get away with returning a "ScopeGuard"
called "ctx".

Closes #12694
2026-05-11 10:41:14 +08:00
Johannes Altmanninger
e25ebf1067 handle_command_not_found: extract constant 2026-05-11 10:24:12 +08:00
Johannes Altmanninger
161f31f42b run_1_job: remove code clone for profiling 2026-05-03 20:03:46 +08:00
Johannes Altmanninger
4b069b51e7 Remove "get_" prefix from some getters
In C++ we can't have a field and method sharing a name,
but in Rust we can.

For some structs, most getters don't have a "get_", so it's weird
that some do.  Remove the "get_" prefix where it's obvious enough.

While at it, give some related getters better names.
2026-05-01 18:35:41 +08:00
Johannes Altmanninger
0441bdc634 Remove ScopeGuard::commit in favor of drop
As of commit a296ee085c (Stop returning a value from ScopeGuarding::commit,
2025-03-15) "ScopeGuard::commit()" is equivalent to "drop()".
Let's use that instead.
2026-05-01 18:03:13 +08:00
Johannes Altmanninger
df5067cc1c parse_execution: remove pipeline node reference from ExecutionContext
Upcoming changes will pass Parser by exclusive reference ("&mut") which
prevents aliasing; let's remove an alias which seems simpler anyway.
2026-05-01 18:03:13 +08:00
Johannes Altmanninger
1034945690 Fix regression causing "nosuchcommand || hello" to short-circuit
Commit 3534c07584 (Adopt the new AST in parse_execution, 2020-07-03)
added to parse_execution_context_t::run_job_conjunction an early
return when any job in a job conjunction fails to launch.  This causes
"nosuchcommand || echo hello" to not execute the continuation.

Fix this by restoring the previous behavior.

Fixes #12654
2026-04-29 01:55:32 +08:00
Johannes Altmanninger
81e8eebd8d Use UpperCamelCase for enum variants
Missed in 17ba602acf (Use PascalCase for Enums, 2025-12-14).

Fixes #12647
2026-04-28 23:11:33 +08:00
Daniel Rainer
8ae71c80f4 refactor: extract string escape and unescape funcs
Move the functions for escaping and unescaping strings from
`src/common.rs` into `fish_common`. It might make sense to move them
into a dedicated crate at some point, but for now just move them to the
preexisting crate to unblock other extraction.

Closes #12625
2026-04-11 17:49:50 +08:00
Daniel Rainer
9c819c020e refactor: don't reexport fish_common in common
Not reexporting means that imports have to change to directly import
from `fish_common`. This makes it easier to see which dependencies on
`src/common.rs` actually remain, which helps with identifying candidates
for extraction.

While at it, group some imports.

Part of #12625
2026-04-11 17:49:41 +08:00
Nahor
30e6aa85e2 error rewrite: use new Error to report errors
To homogenize error reporting format, use a new Error struct. Currently this
is used for builtins and ensuring a common cmd/subcmd prefix.

Part of #12556
2026-04-08 14:11:31 +08:00
xtqqczze
4eac5f4d9d clippy: fix unused_trait_names lint
https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names

Closes #12450
2026-02-17 11:28:58 +11:00
Daniel Rainer
0d79681070 gettext: remove remaining trailing newlines
Complete the work started in
e78e3f16e (gettext: remove trailing newlines, 2026-01-30)

Now, there are no remaining trailing newlines in the localizable strings
in our Rust sources. A bit more work is still needed to get rid of a few
leading and trailing spaces, the goal being that for all localizable
strings `s` in our Rust sources, `s == s.trim()`.

Includes a bit of drive-by refactoring.

Part of #12405
2026-02-03 11:58:52 +11:00
Daniel Rainer
e78e3f16e1 gettext: remove trailing newlines
Remove trailing newlines from msgids. Newlines do not need to be
localized, so translators should not have to care about them.

In addition to simplifying the jobs of translators using gettext, not
having trailing newlines also makes it easier to port localizations to
Fluent.

Closes #12399
2026-01-31 14:12:50 +11:00
Peter Ammon
08a9f5e683 Remove LineCounter
LineCounter was a funny type which aided in eagerly computing line
numbers. It's no longer needed as we lazily compute lines, so remove it.
2026-01-30 09:30:57 -08:00
Peter Ammon
1ab12dadac Remove "parse_util" prefix from functions in that module
This was a naming holdover from C++
2026-01-24 14:35:46 -08:00
Daniel Rainer
8718d62b11 assertions: use assert_eq! where possible
Using `assert_eq!` instead of `assert!` has the advantage that when the
assertion fails, the debug representation of both sides will be shown,
which can provide more information about the failure than only seeing
that the assertion failed.

Part of #12336
2026-01-18 13:25:00 +01:00
xtqqczze
49b3721b75 clippy: fix unnecessary_semicolon lint
https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_semicolon

Closes #12328
2026-01-16 11:40:47 +01:00
Daniel Rainer
253f6726c0 widestring: rename wchar -> widestring
This is a more descriptive name for the crate.

https://github.com/fish-shell/fish-shell/pull/12311#discussion_r2681191208

Closes #12313
2026-01-15 17:17:40 +01:00
Daniel Rainer
116bcdac28 common: extract more code into separate crate
This extracts the remaining code from `src/common.rs` which does not
depend on other parts of the main library crate. No functional changes.

Closes #12310
2026-01-12 09:44:42 +01:00
xtqqczze
06a14c4a76 clippy: fix assigning_clones lint
https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones

Closes #12267
2026-01-04 13:08:26 +01:00
Johannes Altmanninger
2b3bd29588 Fix infinite repaint when setting magic variables in prompt
Commit 7996637db5 (Make fish immediately show color changes again,
2025-12-01) repaints unnecessarily when a local unexported color
variable changes.  Also, it repaints when the change comes from
fish_prompt, causing an easy infinite loop.  Same when changing TERM,
COLORTERM and others.

This feature is relevant when using a color-theme aware theme, so
try to keep it. Repaint only on global/universal changes.
Also ignore changes if already repainting fish prompt.

This change may be at odds with concurrent execution (parser should
not care about whether we are repainting) but that's intentional
because of 1. time constraints and 2. I'm not sure what the solution
will look like; we could use the event infrastructure.  But a lot of
existing variable listeners don't use that.

Extract a context object we pass whenever we mutate the environment; While
at it, use it to pass EnvMode::USER, to reduce EnvMode responsibilities.

Fixes #12233
2025-12-30 17:20:42 +01:00
Johannes Altmanninger
6c34bcf8f6 parser: reuse set_var() 2025-12-30 17:20:42 +01:00
Johannes Altmanninger
f1c8e6995d On process exit, read output into buffer to fix ordering
This command

	echo $(/bin/echo -n 1; echo -n 2)

sometimes outputs "21" because we implement this as

	let bufferfill = IoBufferfill::create_opts(...);
	...
	let eval_res = parser.eval_with(...);
	let buffer = IoBufferfill::finish(bufferfill);

i.e. /bin/echo and builtin echo both output to the same buffer; the
builtin does inside parser.eval_with(), and the external process may
or may not output before that, depending on when the FD monitor thread
gets scheduled (to run item_callback).

(Unrelated to that we make sure to consume all available input in
"IoBufferfill::finish(bufferfill)" but that doesn't help with
ordering.)

Fix this by reading all available data from stdout after the child
process has exited.

This means we need to pass the BufferFill down to
process_mark_finished_children().

We don't need to do this for builtins like "fg" or "wait",
because commands that buffer output do not get job control, see
2ca66cff53 (Disable job control inside command substitutions,
2021-07-26).
We also don't need to do it when reaping from reader because there
should be no buffering(?).

fish still deviates from other shells in that it doesn't wait for
it's child's stdout to be closed, meaning that this will behave
non-deterministically.

	fish -c '
	    echo -n $(
	        sh -c " ( for i in \$(seq 10000); do printf .; done ) & "
	    )
	' | wc -c

We should fix that later.

Closes #12018
2025-12-25 14:35:54 +01:00
Daniel Rainer
b62a312cba rename: crate::wchar::prelude -> crate::prelude
Having the prelude in wchar is not great. The wchar module was empty
except for the prelude, and its prelude included things from wutil.

Having a top-level prelude module in the main crate resolves this. It
allows us to completely remove the wchar module, and a top-level prelude
module makes more sense conceptually. Putting non-wchar things into the
prelude also becomes more sensible, if we ever want to do that.

Closes #12182
2025-12-19 19:37:11 +01:00
Daniel Rainer
2f37eda9d9 wchar: extract logic into separate crate
Another reduction in size of the main crate. Also allows other crates to
depend on the new wchar crate.

The original `src/wchar.rs` file is kept around for now to keep the
prelude imports working.

Part of #12182
2025-12-18 15:13:50 +01:00
Toyosatomimi no Miko
bf38e1beca Rename FLOG, FLOGF, to lowercase flog, flogf
Closes #12156
2025-12-16 13:04:43 +01:00
Toyosatomimi no Miko
17ba602acf Use PascalCase for Enums
Part of #12156
2025-12-16 13:04:43 +01:00
xtqqczze
831411ddd5 fix: clippy::ref_as_ptr
https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr

Part of #12136
2025-12-11 17:46:58 +01:00
Johannes Altmanninger
4ffa06fb7e Fix section names in suggested "help" commands
Fixes 2cd60077e6 (help: get section titles from Sphinx, 2025-11-05)
Fixes #12082
2025-11-23 12:30:22 +01:00
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
787c6a443d Remove redundant per-module lints; fix some
As mentioned in 6896898769 (Add [lints] table to suppress lints
across all our crates, 2024-01-12), we can use workspace lints in
Cargo.toml now that we have MSRV >=1.74 and since we probably don't
support building without cargo.

This implies moving some lints from src/lib.rs to "workspace.lints".
While at it, address some of them insrtead.
2025-10-24 13:48:19 +02:00
Daniel Rainer
43f8d7478e style: change rustfmt edition to 2024
This commit adds `style_edition = "2024"` as a rustfmt config setting.
All other changes are automatically generated by `cargo fmt`.

The 2024 style edition fixes several bugs and changes some defaults.
https://doc.rust-lang.org/edition-guide/rust-2024/rustfmt-style-edition.html

Most of the changes made to our code result from a different sorting
method for `use` statements, improved ability to split long lines, and
contraction of short trailing expressions into single-line expressions.

While our MSRV is still 1.70, we use more recent toolchains for
development, so we can already benefit from the improvements of the new
style edition. Formatting is not require for building fish, so builds
with Rust 1.70 are not affected by this change.

More context can be found at
https://github.com/fish-shell/fish-shell/issues/11630#issuecomment-3406937077

Closes #11959
2025-10-18 09:29:50 +02:00
Isaac Oscar Gariano
1cf110d083 Use idiomatic Rust error handling for function builtin.
This simply does the same thing as #10948, but for the function builtin.

Part of #11780
2025-10-11 10:46:21 +02:00
Daniel Rainer
83af5c91bd printf: remove all uses of length modifiers
Length modifiers are useless. This simplifies the code a bit, results in
more consistency, and allows removing a few PO messages which only
differed in the use of length modifiers.

Closes #11878
2025-10-05 15:16:41 +02:00
Johannes Altmanninger
1d893b77d3 Also flag MSRV rustc/clippy warnings in CI 2025-06-28 11:04:29 +02:00
Peter Ammon
d67fdd1f02 Make Job store boxed process list instead of Vec 2025-06-14 12:04:52 -07:00
Peter Ammon
6fffb76937 Move Process's block node into its Type
Previously, for Processes which were BlockNodes, we stored the node separately
in the Process via an Option; just promote this to a real field of the
ProcessType::BlockNode.

No user visible changes expected.
2025-06-14 10:34:05 -07:00
Peter Ammon
36e385e1fb Make ProcessType not Eq or PartialEq
We are going to give it fields shortly.
2025-06-14 10:33:58 -07:00
Peter Ammon
e598010020 Clean up some Node representations
Use NodeRef more pervasively, leading to simplifications.
2025-06-14 10:33:53 -07:00
Peter Ammon
eba4c906ae Minor cleanup of process creation
Remove some useless types and unnecessary boxing.
2025-06-14 10:33:48 -07:00
Peter Ammon
fbb4a8d853 Adopt Rust naming conventions in JobControl and ProcessType 2025-06-14 10:33:46 -07:00
Daniel Rainer
80033adcf5 Use LocalizableString for gettext
This new wrapper type can be constructed via macros which invoke the
`gettext_extract` proc macro to extract the string literals for PO file
generation.

The type checking enabled by this wrapper should prevent trying to obtain
translations for a string for which none exist.

Because some strings (e.g. for completions) are not defined in Rust, but rather
in fish scripts, the `LocalizableString` type can also be constructed from
non-literals, in which case no extraction happens.
In such cases, it is the programmer's responsibility to only construct the type
for strings which are available for localization.

This approach is a replacement for the `cargo-expand`-based extraction.

When building with the `FISH_GETTEXT_EXTRACTION_FILE` environment variable set,
the `gettext_extract` proc macro will write the messages marked for extraction
to a file in the directory specified by the variable.

Updates to the po files:
- This is the result of running the `update_translations.fish` script using the
  new proc_macro extraction. It finds additional messages compared to the
  `cargo-expand` based approach.
- Messages IDs corresponding to paths are removed. The do not have localizations
  in any language and localizing paths would not make sense. I have not
  investigated how they made it into the po files in the first place.
- Some messages are reordered due to `msguniq` sorting differing from `sort`.

Remove docs about installing `cargo-expand`
These are no longer needed due to the switch to our extraction macro.
2025-06-07 00:10:05 +02:00
Daniel Rainer
98b3ba5e8e Remove concat! macro from localized strings
This is done in preparation for a proc macro which extracts strings which are
passed to `gettext`. Because the `concat!` macro would get expanded after the
proc macro, the proc macro would still see the `concat!`, which it cannot
handle.
2025-06-07 00:02:14 +02:00
Peter Ammon
d88a656e9e ast: further adoption of Kind 2025-05-04 18:59:05 -07:00
Peter Ammon
d6ee4ec698 ast: Clean up BlockStatementHeader
Make this a real Node.
2025-05-04 18:59:05 -07:00