Commit Graph

5240 Commits

Author SHA1 Message Date
Johannes Altmanninger
e8ebeedfca Don't assume libc::c_char is signed
Fixes #10214
2024-01-14 17:12:02 +01:00
Johannes Altmanninger
68d1207d53 Rename flag that fails expansions with command substitutions
SKIP_CMDSUBST does not pass through command substitutions, unlike
SKIP_VARIABLES and SKIP_WILDCARDS.
2024-01-14 13:19:38 +01:00
Johannes Altmanninger
126036c980 Silence a dead code warning
This is still used in commented-out code.
2024-01-14 13:17:59 +01:00
ridiculousfish
0f56db55a2 Correct "fire_exit" event back to "fish_exit"
This was causing fish_exit to not fire, which caused (among other things)
leaking tmux processes from the tests.

This was bisected to eacbd6156d
2024-01-13 15:20:59 -08:00
Mahmoud Al-Qudsi
33f33c5f41 Simplify (and fix?) build.rs HAVE_XXX detection
Since none of the compiles(xxx) calls are to particularly complex code, we can
just use `rsconf` directly to test for the presence of the symbols or headers as
needed.

Note that it seems at least some of the previous detection was not working
correctly; in particular HAVE_PIPE2 was evaluating to false on my WSL install
where pipe2(2) was available (caught because it revealed some compilation errors
in that conditional compilation path after porting).

I kept the cfg names and the tests themselves mostly as-is, though we might want
to change that to conform with the rust convention of lowercase cfg names and
decide whether we want to prefix all these with have_, fish_, or nothing at all.
Also the posix_spawn() test should probably check for the symbol `posix_spawn()`
rather than the header `spawn.h` since we don't use it via the header but rather
via the symbol (but in reality they're almost certainly going to give the same
result).
2024-01-13 15:45:42 -06:00
Mahmoud Al-Qudsi
e02c572738 Fix build error when HAVE_PIPE2 is true
NB: I only encountered this when rewriting the cfg detection, which means that
the previous detection wasn't correct since I have pipe2 on Linux but didn't run
into this build error before.
2024-01-13 15:44:03 -06:00
Mahmoud Al-Qudsi
6e002b6d80 Use cfg directly instead of going through features
Features should be for user-specifiable build configurations but our dynamic,
target-based conditional compilation is something else.
2024-01-13 15:16:47 -06:00
ridiculousfish
8554eb5f80 Further cleanup of FdMonitor 2024-01-13 12:51:36 -08:00
ridiculousfish
d8da79717e Remove some FFI bits from FdMonitor 2024-01-13 12:51:36 -08:00
Mahmoud Al-Qudsi
30f70f02de Feature-detect localeconv_l() presence 2024-01-13 14:21:14 -06:00
Mahmoud Al-Qudsi
195852b562 Use locale::LOCALE_LOCK for all setlocale() calls
I had originally created a safe `set_locale()` wrapper and clippy-disallowed
`libc::setlocale()` but almost all our uses of `libc::setlocale()` are in a loop
where it makes much more sense to just obtain the lock outright then call
`setlocale()` repeatedly rather than lock it in the wrapper function each time.
2024-01-13 13:50:31 -06:00
Mahmoud Al-Qudsi
a138d74688 Fix unused code warning on cannot-be-WSL platforms
No need to use cfg_attr and have to worry about syncing the preconditions for
the cfg_attr with the preconditions for where `slice_contains_slice()` is used
in the codebase, just mark it as `allow(unused)` with a comment.
2024-01-13 13:15:31 -06:00
Fabian Boehm
0a92d03498 Remove L! from sprintf calls
Remove unnecessary L!
2024-01-13 08:52:54 +01:00
Fabian Boehm
fae780d666 clippy
There are a bunch more now that widestrs is gone
2024-01-13 08:52:54 +01:00
Fabian Boehm
09cd7c7ad9 Remove widestring-suffix uses
This removes both the `#[widestrs]` annotation as well as all `"foo"L`
suffixes, and does a `cargo fmt` run on the result
2024-01-13 08:52:54 +01:00
David Adam
ca972f6e0f fix permissions on source file 2024-01-13 11:12:02 +08:00
David Adam
5e8a7fb862 Drop unused C++ fishlib 2024-01-13 11:12:02 +08:00
Johannes Altmanninger
3ae20bdba0 Move fish-rust to project root 2024-01-13 03:58:33 +01:00
David Adam
1683e720a8 Use Rust for executables
Use Rust for executables

Drops the C++ entry points and restructures the Rust package into a
library and three binary crates.

Renames the fish-rust package to fish.

At least on Ubuntu, "fish_indent" is built before "fish".
Make sure export CURSES_LIBRARY_LIST to all binaries to make sure
that "cached-curses-libnames" is populated.

Closes #10198
2024-01-13 03:07:29 +01:00
Johannes Altmanninger
29bd6eebd0 Remove cxx and autocxx
Notably this gets rid of the Cargo target directory inside build directories,
in favor of "target/" at workspace root.
2024-01-07 22:19:56 +01:00
Johannes Altmanninger
102ab2c90d Remove FFI code and C++ files
There's a lot more to remove, like
- cxx/autocxx
- now-unused CMake code
- C++ pcre
- C++ entry points
- remaining mentions of "ffi"
2024-01-07 12:12:09 +01:00
Johannes Altmanninger
ab98566c67 Remove fish_tests
The remaining tests are all obsolete or already ported.
2024-01-07 12:12:09 +01:00
Johannes Altmanninger
77550a2f0d Turn FFI tests into native Rust tests
Keep running tests serially to avoid breaking assumptions.

I think many of these tests can run in parallel and/or don't need test_init().
Use the safe variant everywhere, to get it done faster.
2024-01-07 12:12:09 +01:00
Johannes Altmanninger
c758765503 Port shell_modes
The C++ one is still there but it's only used in dead code.
2024-01-07 12:12:09 +01:00
Johannes Altmanninger
7f110ed4c0 Port fish_key_reader 2024-01-07 00:54:22 +01:00
Johannes Altmanninger
55fd43d86c Port reader 2024-01-07 00:54:22 +01:00
Fabian Boehm
5a77db8353 fish_key_reader: Only name keys if they match the entire sequence
This would misname `\e\x7F` as "backspace":

bind -k backspace 'do something'
bind \e\x7F 'do something'

because it would check if there was any key *in there*.

This was probably meant for continuous mode, but it simply doesn't
work right. It's preferable to not give a key when one would work over
giving one when it's not correct.
2024-01-02 17:27:20 +01:00
David Adam
365027d55d drop obsolete headers 2024-01-02 01:59:02 +08:00
David Adam
3cdca4738a drop unused wildcard module
Some of the definitions in wildcard.h are still used in C++.
2024-01-02 01:59:02 +08:00
David Adam
118dfe776a drop unused path functions 2024-01-02 01:59:02 +08:00
ridiculousfish
8190e3419d Add remaining input FFI bits and port builtin_bind
This implements input and input_common FFI pieces in input_ffi.rs, and
simultaneously ports bind.rs. This was done as a single commit because
builtin_bind would have required a substantial amount of work to use the input
ffi.
2023-12-31 17:17:43 -08:00
ridiculousfish
7ffb62d1d9 Port input.cpp to input.rs
This is not yet adopted.
2023-12-31 15:45:08 -08:00
David Adam
413ba192a0 drop unused code:
fish_tests.cpp:
* comma_join

env.cpp:
* env_get_inherited
* env_get_runtime_path
* check_runtime_path (from tmux)
2023-12-31 21:14:40 +08:00
Shou Ya
b44bdea230 Enable globbing in history-pager
The existing subsequence search commonly returns false positives.
Support globs, to allow searching for disconnected substrings in a better way.

Closes #10143
Closes #10131
2023-12-24 09:08:03 +01:00
Shou Ya
31d157f117 Disable redundant filtering in history pager
Part of #10143
2023-12-24 08:42:20 +01:00
Johannes Altmanninger
2358d4dec8 Fix MoveWordStyle naming convention 2023-12-24 08:42:20 +01:00
Johannes Altmanninger
e194f35a5e Port test_word_motion 2023-12-22 18:10:29 +01:00
Johannes Altmanninger
afe9013b4c Port test_pthread 2023-12-22 18:10:29 +01:00
Johannes Altmanninger
9b1acd5260 Fix regression not ignoring fish_trace when writing title 2023-12-17 17:12:13 +01:00
Johannes Altmanninger
38d52b7835 Port perf_convert_ascii
The "#[bench]" attribute is not allowed in stable Rust, so keep it behind
a new feature flag. Run on nightly Rust with

    $ cargo bench --features=bechmark
    test tests::encoding::bench::bench_convert_ascii ... bench:     125,988 ns/iter (+/- 1,128) = 1040 MB/s
2023-12-10 14:35:43 +01:00
Johannes Altmanninger
f3dd8d306f Port make_autoclose_pipes, fd_event_signaller_t
This allows to get rid of the C++ autoclose_fd_t.
2023-12-10 14:35:43 +01:00
Johannes Altmanninger
f2cd916f65 Remove unused io_data_t structs 2023-12-10 14:35:43 +01:00
Fabian Boehm
eb196c8330 Encode all ENCODE_DIRECT codepoints with encode_direct
forward-port of 09986f5563
2023-12-10 09:29:42 +01:00
Johannes Altmanninger
e380654fff Port test_convert_nulls 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
a31ef0aeaa Delete test_wcstod
This seems to be ported already.
2023-12-09 21:35:08 +01:00
Johannes Altmanninger
a55e95f5fb Port test_env_snapshot 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
fe19cbded0 Port test_wwrite_to_fd 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
d5ccbb6e9c Port test_error_messages 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
f3d1e0d63a Port test_new_parser_errors 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
a7791aab4d Port test_new_parser_ad_hoc 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
d5cfa0e346 Port test_new_parser_ll2 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
af4b8ccc91 Port test_new_parser_fuzzing 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
afddb5dd3e Port test_new_parser_correctness 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
3fab9adab6 Port test_illegal_command_exit_code 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
c74cc71e26 Port rest of test_parser
Most of this is already ported into the "test_parser" test.
2023-12-09 21:35:08 +01:00
Johannes Altmanninger
09b7f3892f Port test_pipes 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
9430d5c542 Port test_wgetopt 2023-12-09 21:35:08 +01:00
Johannes Altmanninger
44a9a873af lru tests don't need porting since we'll drop our implementation 2023-12-09 16:55:20 +01:00
Johannes Altmanninger
749e760cf5 Port debounce tests 2023-12-09 16:48:02 +01:00
Johannes Altmanninger
b28521c3d5 Port fish_indent 2023-12-06 09:59:16 +01:00
Thomas Queiroz
a64324421f Port builtin ulimit
Closes #10121
2023-12-03 11:39:15 +01:00
Johannes Altmanninger
43e2d7b48c Port pager.cpp 2023-12-03 11:02:04 +01:00
Johannes Altmanninger
fadf0f2e5b Port editable_line_t 2023-12-02 20:04:07 +01:00
Johannes Altmanninger
31ad182aa5 Port screen.cpp 2023-12-01 11:59:33 +01:00
ridiculousfish
9b54e243b1 Add FFI bindings to universal notifiers and adopt in input_common
This removes the C++ bits for universal notifiers.
2023-11-26 17:29:53 -08:00
ridiculousfish
0f29e0de2f Remove extract_most_significant_digit
This is now unused.
2023-11-26 17:23:37 -08:00
David Adam
f2f41c6eec drop unused functions and configure checks
Remove the following C++ functions/methods, which have no callers:

common.cpp:
- read_loop
- narrow_string_safe
- escape_string_for_double_quotes
- read_unquoted_escape
- format_size
- format_size_safe
- valid_func_name
- get_executable_path

env.cpp:
- env_stack_t::set_empty
- env_stack_t::set_argv

fallback.cpp:
- fish_mkstemp_cloexec
- flock

proc_util.cpp:
- parse_util_slice_length
- parse_util_argument_is_help

path.cpp:
- path_get_path
- path_as_implicit_cd
- path_apply_working_directory
- path_emit_config_directory_messages
- path_get_data_remoteness
- path_get_config_remoteness
- path_is_valid
- paths_are_same_file

wcstringutil.cpp:
- split_string_tok

wutil.cpp:
- wgetcwd
- wunlink
- wrealpath
- wrename
- file_id_for_path
- fish_wcstoull

Also drop unused configure checks/defines:
- HAVE_FLOCK
2023-11-26 22:35:51 +08:00
ridiculousfish
c1e4a447fd Remove C++ UTF-8 bits
These are no longer used.
2023-11-18 19:21:25 -08:00
ridiculousfish
377ef9786e Remove null_terminated_array C++ bits
These are now unused.
2023-11-18 10:28:52 -08:00
Johannes Altmanninger
7f67588e63 fish_tests: label tests to indicate if they need porting 2023-11-15 11:09:48 +01:00
Johannes Altmanninger
6569943cb8 Port builtin read 2023-11-15 11:09:48 +01:00
Johannes Altmanninger
77aeb6a2a8 Port execution
Drop support for history file version 1.

ParseExecutionContext no longer contains an OperationContext because in my
first implementation, ParseExecutionContext didn't have interior mutability.
We should probably try to add it back.

Add a few to-do style comments. Search for "todo!" and "PORTING".

Co-authored-by: Xiretza <xiretza@xiretza.xyz>
(complete, wildcard, expand, history, history/file)
Co-authored-by: Henrik Hørlück Berg <36937807+henrikhorluck@users.noreply.github.com>
(builtins/set)
2023-11-15 11:09:48 +01:00
Johannes Altmanninger
c4155db933 Rename Rust-side parser_t/io_streams_t to Parser/IoStreams
This reduces noise in the upcoming "Port execution" commit.

I accidentally made IoStreams a "class" instead of a "struct".  Would be
easy to correct that but this will be deleted soon, so I don't think we care.
2023-11-15 11:09:48 +01:00
Fabian Boehm
67faa107b0 expand_cmdsubst: Make more errors known
These printed "Unknown error while evaluating command substitution".

Now they print something like

```
fish: for: status: cannot overwrite read-only variable
for status in foo; end
    ^~~~~^
in command substitution
fish: Invalid arguments
echo (for status in foo; end)
     ^~~~~~~~~~~~~~~~~~~~~~~^
```

for `echo (for status in foo; end)`

This is, of course, still not *great*. Mostly the `fish: Invalid
arguments` is basically entirely redundant.

An alternative is to simply skip the error message, but that requires some
more scaffolding (describe_with_prefix adds some error messages on its
own, so we can't simply say "don't add the prefix if we don't have a
message")

(cherry picked from commit 1b5eec2af6)
2023-11-09 17:51:15 +01:00
Fabian Boehm
0f8bcb0414
wildcard: Rationalize file/command completions (#10052)
* wildcard: Remove file size from the description

We no longer add descriptions for normal file completions, so this was
only ever reached if this was a command completion, and then it was
only added if the file wasn't a regular file... in which case it can't
be an executable.

So this was dead.

* Make possible_link() a maybe

This gives us the full information, not just "no" or "maybe"

* wildcard: Rationalize file/command completions

This keeps the entry_t as long as possible, and asks it, so especially
on systems with working d_type we can get by without a single stat in
most cases.

Then it guts file_get_desc, because that is only used for command
completions - we have been disabling file descriptions for *years*,
and so this is never called there.

That means we have no need to print descriptions about e.g. broken symlinks, because those are not executable.

Put together, what this means is that we, in most cases, only do
an *access(2)* call instead of a stat, because that might be checking
more permissions.

So we have the following constellations:

- If we have d_type:
  - We need a stat() for every _symlink_ to get the type (e.g. dir or regular)
    (this is for most symlinks, if we want to know if it's a dir or executable)
  - We need an access() for every file for executables
- If we do not have d_type:
  - We need a stat() for every file
  - We need an lstat() for every file if we do descriptions
    (i.e. just for command completion)
  - We need an access() for every file for executables

As opposed to the current way, where every file gets one lstat whether
with d_type or not, and an additional stat() for links, *and* an
access.

So we go from two syscalls to one for executables.

* Some more comments

* rust link option

* rust remove size

* rust accessovaganza

* Check for .dll first for WSL

This saves quite a few checks if e.g. System32 is in $PATH (which it
is if you inherit windows paths, IIRC).

Note: Our WSL check currently fails for WSL2, where this would
be *more* important because of how abysmal the filesystem performance
on that is.
2023-10-14 08:45:15 +02:00
Johannes Altmanninger
6ef5ae0935 env: skip env lines without equal sign
Given an env like

    foo
    bar=baz

we would set "foo" to empty due to a typo.
The typo is pointed out by a PORTING comment.

Luckily I don't think we ever hit this case because that would mean our
parent process has a serious bug.  Rust's std::env::vars_os() skips env
lines that don't contain a "=" char.  This seems like a reasonable behavior
for us too. Do that.
2023-10-08 20:46:53 +02:00
Fabian Boehm
86803e4442
Reduce stat calls for wildcards ending in "/" (#10032)
This makes it so expand_intermediate_segment knows about the case
where it's last, only followed by a "/".

When it is, it can do without the file_id for finding links (we don't
resolve the files we get here), which allows us to remove a stat()
call.

This speeds up the case of `...*/` by quite a bit.

If that last component was a directory with 1000 subdirectories we
could skip 1000 stat calls!

One slight weirdness: We refuse to add links to directories that we already visited, even if they are the last component and we don't actually follow them. That means we can't do the fast path here either, but we do know if something is a link (if we get d_type), so it still works in common cases.
2023-10-08 16:46:59 +02:00
Fabian Boehm
c4ca1a68d3
Add a clear-screen bind function to clear the screen (#10044)
This can be bound like `bind \cl clear-screen`, and is, by default

In contrast to the current way it doesn't need the external `clear`
command that was always awkward.

Also it will clear the screen and first draw the old prompt to remove
flicker.
Then it will immediately trigger a repaint, so the prompt will be overwritten.
2023-10-08 11:41:30 +02:00
ridiculousfish
f7e7396c69 Fix a deadlock affecting fish_config
This fixes the following deadlock. The C++ functions path_get_config and
path_get_data lazily determine paths and then cache those in a C++ static
variable. The path determination requires inspecting the environment stack.
If these functions are first called while the environment stack is locked
(in this case, when fetching the $history variable) we can get a deadlock.

The fix is to call them eagerly during env_init. This can be removed once
the corresponding C++ functions are removed.

This issue caused fish_config to fail to report colors and themes.

Add a test.
2023-10-07 15:20:14 -07:00
Johannes Altmanninger
48ce8f8721 Remove test_history_speed benchmark
Doesn't seem terribly important? We can add it back easily.
2023-10-07 19:30:46 +02:00
Johannes Altmanninger
ffbb56c4a9 common: port test_format 2023-10-07 19:30:46 +02:00
Johannes Altmanninger
408161f4d6 Port test_tokenizer 2023-10-07 19:30:46 +02:00
Fabian Boehm
496d65fb5d Apply variable overrides for exec
Fixes #9995
2023-10-06 18:15:25 +02:00
Fabian Boehm
ff433b0cb2 reader: Only move cursor if needed for repaint-mode
This uses "screen.reset_line" to move the cursor without informing the
reader's machinery (because that deals with positions *in the
commandline*), but then only repainted "if needed" - meaning if the
reader thought anything changed.

That could lead to a situation where the cursor stays at column 0
until you do something, e.g. in

```fish
bind -m insert u undo
```

when you press alt+u - because the *escape* calls repaint-mode, which
puts the cursor in column 0, and then the undo doesn't, which keeps it
there.

Of course this binding should also `repaint-mode`, because it changes
the mode.

Some changes might be ergonomic:

1. Make repaint-mode the default if the mode changed (we would need to
skip it for bracketed-paste)
2. Make triggering the repaint easier - do we need to set
force_exec_prompt_and_repaint to false here as well?

Anyway, this

Fixes #7910
2023-10-06 16:38:26 +02:00
Fabian Boehm
10d91b0249 screen: Unset color at the end of a line even without clr_eol
This is a sensible thing to do, and fixes some cases where we're
state-dependent.

E.g. this fixes the case in the pager where some things are bold and
some aren't, because that bolding is (rather awkwardly) implicitly
triggered when we have a background, and so we don't notice we need to
re-do that bolding after we moved to the next line because we think we
still have the same color.

Fixes #9617
2023-09-30 15:32:54 +02:00
David Adam
4fab9e525a drop now-unused postfork C++ module 2023-09-25 21:47:19 +08:00
ridiculousfish
555171cb55 Adopt Rust postfork code
This adopts the Rust postfork code, bridging it from C++ exec module.

We use direct function calls for the bridge, rather than cxx/autocxx, so that we
can be sure that no memory allocations or other shenanigans are happening.
2023-09-24 13:04:00 -07:00
ridiculousfish
c862a06874 Implement postfork code in Rust
This implements the "postfork" code in Rust, including calling fork(),
exec(), and all the bits that have to happen in between. postfork lives
in the fork_exec module.

It is not yet adopted.
2023-09-24 13:04:00 -07:00
Henrik Hørlück Berg
80d92dcc6d
Port the easy part of wildcard.{h,cpp}
- wildcard_match is now closer to the original that is linked in a comment, as
  pointer-arithmetic translates very poorly. The act of calling wildcard
  patterns wc or wildcard is kinda confusing when wc elsewhere is widechar.
2023-09-15 14:38:30 +02:00
Fabian Boehm
5b44c26a19 reader: Use existing search string when opening the history pager
I sometimes find myself doing something like this:

- Look for a commandline that includes "echo" (as an example)
- Type echo, press up a few times
- I can't immediately find what I'm looking for
- Press ctrl-r to open up the history pager
- It uses the current commandline as the search string,
  so now I'm looking for "echo foobar"

This makes it so if the search string already is in use, that's what
the history-pager picks as the initial search string.
2023-09-09 08:29:24 +02:00
Henrik Hørlück Berg
6283274c24 Remove C++ version of start_private_mode 2023-09-05 11:38:59 +02:00
Henrik Hørlück Berg
fca41c0459 Fully migrate to Rust env_init 2023-09-05 11:38:59 +02:00
Henrik Hørlück Berg
ea704179c1 Remove now unused in C++ hacks 2023-09-05 11:38:59 +02:00
Henrik Hørlück Berg
eacbd6156d Port and adopt main written in Rust
We don't change anything about compilation-setup, we just immediately jump to
Rust, making the eventual final swap to a Rust entrypoint very easy.

There are some string-usage and format-string differences that are generally
quite messy.
2023-09-05 11:38:59 +02:00
Henrik Hørlück Berg
96e58dac21 Port env_init to Rust
- This does not adopt it.
2023-09-05 11:38:59 +02:00
Henrik Hørlück Berg
55302629cd Add various FFI-interop-functions
- `libc::setlinebuf` is not available through Rust's libc it appears.
- autocxx fails to generate bindings using `*mut FILE`, instead go through
  `void*`
- rust_main needs `parse_util_detect_errors_in_ast`, which is _partially_
  ported, instead add FFI interop for C++.
- We need to set the filename if we are sourcing a file
2023-09-05 11:38:59 +02:00
yanshay
01db48a712
Added fish_sequence_key_delay_ms to set time to wait between sequence key presses (#7401) (#9926)
* added support for fish_sequence_key_delay_ms to set how long to wait between sequence key presses

* fixed cargo fmt
2023-08-30 23:12:22 +02:00
Fabian Boehm
7b5667b11f parse_execution: Remove dead tcgetattr code
This used to be assigned to the job, but that was removed in
f30ce21aaa.

Since then this was vestigial. It could have technically errored out,
but we should be catching that where we use the actual modes, not here.
2023-08-26 14:58:14 +02:00
Fabian Boehm
b454b3bc40 Also allow command and in a pipeline
Similar to `time`, except that one is more common as a command.

Note that this will also allow `builtin and`, which is somewhat
useless, but then it is also useless outside of a pipeline.

Addition to #9985
2023-08-26 13:45:54 +02:00
Fabian Boehm
55c425a0dd fish_key_reader: Humanize key descriptions
This used to print all codepoints outside of the ASCII range (i.e.
above 0x80) in \uXXXX or \UYYYYYYYY notation.

That's quite awkward, considering that this is about keys that are
being pressed, and many keyboards have actual symbols for these on
them - I have an "ö" key, so I would like to use `bind ö` and not
`bind \u00F6`. So we go by iswgraph.

On a slightly different note, `\e` was written as `\c[ (or \e)`. I do
not believe anyone really uses `\c[` (the `[` would need to
be escaped!), and it's confusing and unnecessary to even mention that.
2023-08-26 10:43:42 +02:00
Fabian Boehm
482616f101 parse_util: Only reject time in a pipeline without decorator
This allows e.g. `foo | command time`, while still rejecting `foo | time`.

(this should really be done in the ast itself, but tbh most of
parse_util kinda should)

Fixes #9985
2023-08-25 19:45:15 +02:00
ridiculousfish
04299cb4c9 Remove RgbColor::description
This was unused; deriving Debug is sufficient.
2023-08-19 20:04:23 -07:00
Fabian Boehm
566123edc6
Port builtin count to rust (#9963)
* Port builtin count to rust

* Explicitly use wstring
2023-08-18 23:18:52 +02:00
ridiculousfish
2b25cd1654 Complete the transition of the kill ring and remove kill.cpp
This finishes off the transition of the kill ring from C++ to Rust, and removes
the C++ bits.
2023-08-13 13:06:06 -07:00
Fabian Boehm
5f0df359b8 Remove C++ version of builtin functions
And the C++ reformat_for_screen and event_filter_names as there are no more users.
2023-08-13 14:17:44 +02:00
Fabian Boehm
6489ef5ac0 Rewrite builtin functions in rust 2023-08-13 14:17:44 +02:00
99jte
5b136d450f
Include the target of bad redirects in the error (#9947)
Fixes #8877
2023-08-13 14:01:32 +02:00
ridiculousfish
b2ff4d6bc0 Adopt Rust PosixSpawner
This removes the C++ posix_spawner_t, adopting the Rust implementation.
2023-08-12 17:15:21 -07:00
ridiculousfish
245f7db5b3 Port PosixSpawner to Rust
PosixSpawner is our wrapper around posix_spawn.
2023-08-12 16:59:38 -07:00
Johannes Altmanninger
b7f7dcf788 Copy history pager search field to command line on Enter if no match
Closes #9934
2023-08-08 21:53:42 +02:00
Henrik Hørlück Berg
f4a5de1fbf Port builtins/path to Rust 2023-08-07 21:01:11 -07:00
Fabian Boehm
73d30ac4f8 parse_execution: Remove some useless no_exec checks
These are both clearly behind early returns, there is no need to check it again.

This isn't a case where we're doing logic gymnastics to see that it
can't be run without no_exec() being handled, this is

```c++
if (no_exec()) return;
// ..
// ..
// ..

if (no_exec()) foo;
```
2023-08-07 17:42:47 +02:00
Fabian Boehm
ee75b45687 Remove a waccess call when completing executables
We have already run waccess with X_OK. We already *know* the file is
executable.

There is no reason to check again.

Restores some of the speedup from the fast_waccess hack that was
removed to fix #9699.
2023-08-03 19:53:07 +02:00
Henrik Hørlück Berg
20be990fd9 Port builtins/string to Rust
- Add test to verify piped string replace exit code

Ensure fields parsing error messages are the same.

Note: C++ relied upon the value of the parsed value even when `errno` was set,
that is defined behaviour we should not rely on, and cannot easilt be replicated from Rust.
Therefore the Rust version will change the following error behaviour from:

```shell
> string split --fields=a "" abc
string split: Invalid fields value 'a'
> string split --fields=1a "" abc
string split: 1a: invalid integer
```

To:

```shell
> string split --fields=a "" abc
string split: a: invalid integer
> string split --fields=1a "" abc
string split: 1a: invalid integer
```
2023-07-27 22:00:03 -07:00
ridiculousfish
a672edc0d5 Adopt the new function store and rewrite builtin_function
This adopts the new function store, replacing the C++ version.

It also reimplements builtin_function in Rust, as these was too coupled to
the function store to handle in a separate commit.
2023-07-23 17:18:36 -07:00
ridiculousfish
076f317c31 Implement (but do not yet adopt) fish function store in Rust
This reimplements the function module in Rust. The function module stores the
global set of fish functions, and provides information about them.
2023-07-23 17:18:36 -07:00
Henrik Hørlück Berg
6325b3662d Fix #9899 integer overflow in string repeat
We could end up overflowing if we print out something that's a multiple of the
chunk size, which would then finish printing in the chunk-printing, but not
break out early.
2023-07-17 15:41:08 +02:00
Fabian Boehm
6823f5e337 wildcard: Remove useless access() call for trailing slash
This confirmed that a file existed via access(file, F_OK).

But we already *know* that it does because this is the expansion for
the "trailing slash" - by definition all wildcard components up to
here have already been checked.

And it's not checking for directoryness either because it does F_OK.

This will remove one `access()` per result, which will cut the number
of syscalls needed for a glob that ends in a "/" in half.

This brings us on-par with e.g. `ls` (which uses statx while we use
newfstatat, but that should have about the same results)

Fixes #9891.
2023-07-14 20:20:34 +02:00
David Adam
861da91bf1 drop unused functions and configure checks
Remove the following C++ functions/methods, which have no callers:

fallback.cpp:
- wcstod_l

proc.cpp:
- job_t::get_processes

wutil.cpp:
- fish_wcstoll
- fish_wcstoull

Also drop unused configure checks/defines:
- HAVE_WCSTOD_L
- HAVE_USELOCALE
2023-07-14 20:48:56 +08:00
David Adam
44cf0e5043 add comment regarding importance of unused describe_char function 2023-07-14 20:48:56 +08:00
David Adam
0037e6e98d drop ported C++ functions
Remove the following C++ functions/methods, which have all been ported to Rust and no longer have any callers in C++:
common.cpp:
- assert_is_locked/ASSERT_IS_LOCKED

path.cpp:
- path_make_canonical

wutil.cpp:
- wreadlink
- fish_iswgraph
- file_id_t::older_than
2023-07-14 20:48:56 +08:00
Fabian Boehm
a6c36a014c Return a falsey status if the last -c command has a parse error
This makes `fish -c begin` fail with a status of 127 - it already
printed a syntax error so that was weird. (127 was the status for
syntax errors when piping to fish, so we stay consistent with that)

We allow multiple `-c` commands, and this will return the regular
status if the last `-c` succeeded.

This is fundamentally an extremely weird situation but this is the
simple targeted fix - we did nothing, unsuccessfully, so we should
fail.

Things to consider in future:

1. Return something better than 127 - that's the status for "unknown
command"!
2. Fail after a `-c` failed, potentially even checking all of them
before executing the first?

Fixes #9888
2023-07-12 18:06:34 +02:00
Henrik Hørlück Berg
726819e8ee Clean up feature flags API
This also cleans up and removes unnecessary usage of FFI-oriented `feature_metadata_t`,
which is only used from Rust code after `builtins/status` was ported.
2023-07-11 12:05:38 -07:00
elyashiv
4a2c7e38d0 [jobs.cpp] added const to escaped cmd string 2023-07-10 18:38:26 +02:00
elyashiv
4ea867bc55 [jobs.cpp] add escaping for job comamnd 2023-07-10 18:38:26 +02:00
ridiculousfish
57afaf7fb2 Restore the behavior of remembering the CWD fd in the parser
This will be important for concurrent execution, because different parsers will
have different working directories.
2023-07-10 21:30:37 +08:00
David Adam
289fbecaa9 Rewrite cd builtin in Rust
Note this is slightly incomplete - the FD is not moved into the parser, and so
will be freed at the end of each directory change. The FD saved in the parser is
never actually used in existing code, so this doesn't break anything, but will
need to be corrected once the parser is ported.
2023-07-10 21:30:37 +08:00
Henrik Hørlück Berg
595d593732 Fully migrate to Rust escape string tests and code
Co-Authored-By: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
2023-07-04 13:27:53 -07:00
ridiculousfish
37fed01642 FLOG to stop depending on the ffi
Prior to this commit, FLOG used the ffi bridge to get the output fd. Invert
this: have fish set the output fd within main. This allows FLOG to be used in
pure Rust tests.
2023-07-04 13:26:19 -07:00
Johannes Altmanninger
052823c120 history pager: delete selected history entry with Shift-Delete
After accidentally running a command that includes a pasted password, I want
to delete command from history. Today we need to recall or type (part of)
that command and type "history delete".  Let's maybe add a shortcut to do
this from the history pager.

The current shortcut is Shift+Delete. I don't think that's very discoverable,
maybe we should use Delete instead (but only if the cursor is at the end of
the commandline, otherwise delete a char).

Closes #9454
2023-07-04 18:42:11 +02:00
Johannes Altmanninger
857612d243 Simplify logic for special input functions "and" & "or"
No functional change.
2023-07-04 18:42:11 +02:00
Johannes Altmanninger
5678602af4 Stop special input functions "and" & "or" from tearing up multi-char binding
The tentative binding for the upcoming "history-pager-delete" is

    bind -k sdc history-pager-delete or backward-delete-char

When Shift+Delete is pressed while the history pager is active,
"history-pager-delete" succeeds. In this case, the "or" needs to kick the
"backward-delete-char" out of the input queue.
After doing so, it continues reading, but interprets the input as
single-char binding. This breaks when the next key emits a multi-char sequence,
like the arrow keys.

Fix this by reading a full sequence, which means we need to run "read_char()"
instead of "read_ch()" (confusing, right?).

I'm still working on writing a test. Somehow this only reproduces in the
history pager where Shift+Delete followed by down arrow emits "[B" (since
we swallowed the leading escape char).  Confusingly, it doesn't do that in
the commandline or the completion search field.
2023-07-04 18:42:11 +02:00
Henrik Hørlück Berg
cee2b7c4a2 Remove C++ code 2023-07-01 15:33:01 -07:00
Henrik Hørlück Berg
7b3637cd1f Port builtins/status to fish
- Also port tests of wdirname and wbasename, as they were bugged
2023-07-01 15:33:01 -07:00
David Adam
14cfd268d8 path: drop path_get_paths_ffi
f77dc24 provides the pieces to call path_get_paths directly from Rust
code. Drop the C++ implementation and its FFI.
2023-06-30 10:05:01 +08:00
ridiculousfish
f77dc2451e Expose Rust EnvStack from parser_t
Prior to this change, parser_t exposed an environment_t, and Rust had to go
through that. But because we have implemented Environment in Rust, it is
better to just expose the native Environment from parser_t. Make that
change and update call sites.
2023-06-19 13:45:54 -07:00
Henrik Hørlück Berg
292f7b2be1 Port builtins/argparse to Rust 2023-06-19 13:45:54 -07:00
ridiculousfish
a09947cd99 Implement builtin set_color in Rust
This rewrites the set_color builtin in Rust, restoring italics support in
iTerm2.
2023-06-17 12:14:42 -07:00
ridiculousfish
84b24d5615 Adopt the new output.rs
This switches output.cpp from C++ to Rust.
2023-06-17 12:14:42 -07:00
ridiculousfish
76205e5b55 Port debug_thread_error() to Rust 2023-06-17 12:14:42 -07:00
Simon Börjesson
71c320ca32 Redraw pager on new selection when nothing was selected previously 2023-06-04 13:40:30 -07:00
Clemens Wasser
c2f58cd312 Port killring 2023-06-04 12:18:19 -07:00
David Adam
688a28c1d2 Rewrite and adopt print_help in Rust 2023-06-01 23:17:13 +08:00
David Adam
3b55563769 print_help: simplify function to always use stdout
It's only called in two places and always uses stdout.
2023-05-28 12:55:40 +08:00
David Adam
30d9d48bc1 env_dispatch: drop C++ implementation 2023-05-27 11:32:14 +08:00
Mahmoud Al-Qudsi
6638c78b30 Port env_dispatch to Rust and integrate with C++ code 2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
32912b6525 Expose env_dyn_t in env.h
So that we may use it from files other than `src/env.cpp` to accept a
`&dyn Environment` out of rust.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
6bb2725f67 Make sure rust's fish_setlocale() inits global C++ variables
We can't just call the Rust version of `fish_setlocale()` without also either
calling the C++ version of `fish_setlocale()` or removing all `src/complete.cpp`
variables that are initialized and aliasing them to their new rust counterparts.

Since we're not interested in keeping the C++ code around, just call the C++
version of the function via ffi until we don't have *any* C++ code referencing
`src/common.h` at all.

Note that *not* doing this and then calling the rust version of
`fish_setlocale()` instead of the C++ version will cause errant behavior and
random segfaults as the C++ code will try to read and use uninitialized values
(including uninitialized pointers) that have only had their rust counterparts
init.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
c409b1a89c Port env_dispatch dependencies to rust
Either add rust wrappers for C++ functions called via ffi or port some pure code
from C++ to rust to provide support for the upcoming `env_dispatch` rewrite.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
8a549cbb15 Port/move some code from src/environment.cpp to src/env/mod.rs
The global variables are moved (not copied) from C++ to rust and exported as
extern C integers. On the rust side they are accessed only with atomic semantics
but regular int access is preserved from the C++ side (until that code is also
ported).
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
3ab8b34b1e Use Rust version of global fallback variables 2023-05-25 16:54:07 -05:00
ridiculousfish
21e31c9b59 Remove C++ builtin test implementation
Now that builtin test is in Rust, remove the C++ bits.
2023-05-21 11:50:24 -07:00
ridiculousfish
d0aba9d42c Port builtin_test tests to Rust
fish_tests has a bunch of tests for the 'test' builtin. Port these to Rust.
2023-05-21 11:50:24 -07:00
ridiculousfish
cdb77a6176 Adopt the Rust test builtin
This switches the builtin test implementation from C++ to Rust
2023-05-21 11:50:24 -07:00
ridiculousfish
10a7de03e2 Implement builtin test in Rust
This implements (but does not yet adopt) builtin test in Rust.
2023-05-21 11:50:24 -07:00
ridiculousfish
60d439ab22 Rationalize fish_wcstoi/d and friends
Historically fish has used the functions `fish_wcstol`, `fish_wcstoi`, and
`fish_wcstoul` (and some long long variants) for most integer conversions.
These have semantics that are deliberately different from the libc
functions, such as consuming trailing whitespace, and disallowing `-` in
unsigned versions.

fish has started to drift away from these semantics; some divergence from
C++ has crept in.

Rename the existing `fish_wcs*` functions in Rust to remove the fish
prefix, to express that they attempt to mirror libc semantics; then
introduce `fish_` wrappers which are ported from C++. Also fix some
miscellaneous bugs which have crept in, such as missing range checks.
2023-05-14 18:03:52 -07:00
ridiculousfish
e71b75e0e4 Reimplement environment and the environment stack in Rust
This reimplements the environment stack in Rust.
2023-05-07 15:15:56 -07:00
ridiculousfish
8ec1467dda Implement (but do not yet adopt) Environment in Rust
This implements the primary environment stack, and other environments such
as the null and snapshot environments, in Rust. These are used to implement
the push and pop from block scoped commands such as `for` and `begin`, and
also function calls.
2023-05-07 15:15:56 -07:00
ridiculousfish
0681b6b53a Make C++ env_var_t wrap Rust EnvVar
This reimplements C++'s env_var_t to reference a Rust EnvVar.
The C++ env_var_t is now just a thin wrapper.
2023-05-07 15:15:56 -07:00
ridiculousfish
10ee87eb28 Reimplement owning_null_terminated_array in Rust
owning_null_terminated_array is used for environment variables, where we need to
provide envp for child processes. This switches the implementation from C++ to
Rust.

We retain the C++ owning_null_terminated_array_t; it simply wraps the Rust
version now.
2023-05-07 15:15:56 -07:00
Mahmoud Al-Qudsi
73983bada5 Fix ncurses memory leak in init_curses()
init_curses() is/can be called more than once, in which case the previous
ncurses terminal state is leaked and a new one is allocated.

`del_curterm(cur_term)` is supposed to be called prior to calling `setupterm()`
if `setupterm()` is being used to reinit the default `TERMINAL *cur_term`.
2023-05-02 11:52:42 -05:00
Mahmoud Al-Qudsi
3651e0e9d8 Actually report ASAN memory leaks
The new asan exit handlers are called to get proper ASAN leak reports (as
calling _exit(0) skips the LSAN reporting stage and exits with success every
time).

They are no-ops when not compiled for ASAN.
2023-05-02 11:52:41 -05:00
ridiculousfish
4771f25102 Adopt the new Rust signal implementation
This switches the signals implementation from C++ to Rust.
2023-04-30 16:22:57 -07:00
ridiculousfish
1ecf9d013d Port (but do not adopt) signal handling bits in Rust
This ports some signal setup and handling bits to Rust.

The signal handling machinery requires walking over the list of known signals;
that's not supported by the Signal type. Rather than duplicate the list of
signals yet again, switch back to a table, as we had in C++.

This also adds two further pieces which were neglected by the Signal struct:

1. Localize signal descriptions
2. Support for integers as the signal name
2023-04-30 16:22:55 -07:00
Mahmoud Al-Qudsi
ecf1676601 Add and use type-erased RAII callback wrapper for ffi
This allows the rust code to free up C++ resources allocated for a callback even
when the callback isn't executed (as opposed to requiring the callback to run
and at the end of the callback cleaning up all allocated resources).

Also add type-erased destructor registration to callback_t. This allows for
freeing variables allocated by the callback for debounce_t's
perform_with_callback() that don't end up having their completion called due to
a timeout.
2023-04-29 11:02:59 -05:00
Mahmoud Al-Qudsi
6cd2d0ffed Integrate threads.rs w/ legacy C++ code
Largely routine but for the trampolines in iothread.h and iothread.cpp which
were a real PITA to get correct w/ all their variants.

Integration is complete with all old code ripped out and the tests using the
rust version of the code.
2023-04-29 11:02:59 -05:00
Xiretza
b76e6c5637 complete: fix condition to suppress variable autocompletion 2023-04-25 21:47:11 -07:00
Johannes Altmanninger
1df64a4891 Replace maybe_t::missing_or_empty with a more Rust-friendly helper
There are many places where we want to treat a missing variable the same as
a variable with an empty value.

In C++ we handle this by branching on maybe_t<env_var_t>::missing_or_empty().
If it returns false, we go on to access maybe_t<env_var_t>::value() aka
operator*.

In Rust, Environment::get() will return an Option<EnvVar>.
We could define a MissingOrEmpty trait and implement it for Option<EnvVar>.

However that will still leave us with ugly calls to Option::unwrap()
(by convention Rust does use shorthands like *).

Let's add a variable getter that returns none for empty variables.
2023-04-21 13:57:29 +02:00
Johannes Altmanninger
82a797db9c clang-format C++ builtins 2023-04-21 13:57:29 +02:00
Johannes Altmanninger
33f51b45e4 Tease apart parser.eval() overloads
The most common overload takes a string and an io chain so let that one keep
its name.
2023-04-21 13:57:29 +02:00
Johannes Altmanninger
12ce42a2f9 Rename kw() to keyword() also in C++ 2023-04-19 22:43:36 +02:00
Johannes Altmanninger
e4f6169a01 clang-format C++ files
Forgot to run this after the wcstring_list_t -> std::vector<wcstring> rename.
2023-04-19 22:43:36 +02:00
Johannes Altmanninger
09ffac5a0a Port parse_util_compute_indents 2023-04-19 10:35:22 +02:00
Johannes Altmanninger
12afb320a3 Port parse_util
Except for the indent visitor bits.

Tests for parse_util_detect_errors* are not ported yet because they depend
on expand.h (and operation_context.h which depends on env.h).
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
22c8e9f60d Don't leak ParseErrorList FFI crutch type into Rust
Just like 16ea4380c (redirection.rs: don't leak FFI type into Rust code,
2023-04-09).
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
6ede7f8009 Delete wcstring_list_t
We don't want it in Rust. Remove it to smoothen the transition.
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
fdeb0d9f06 Port the rest of wcstringutil 2023-04-18 12:54:19 +02:00
ridiculousfish
1bf29a5e13 Support constructing a wcstring_list_ffi_t from Rust
This allows passing a vector of strings from Rust to C++
2023-04-16 13:36:13 -07:00
Xiretza
aab2f660a7 Port math builtin, tinyexpr and wcstod_underscores to Rust 2023-04-16 22:26:46 +02:00
Xiretza
cc744d30c0 io: add FFI wrappers for io_streams_t fields 2023-04-16 22:26:46 +02:00
Johannes Altmanninger
971d257e67 Port AST to Rust
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.

Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.

Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now.  In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t".  This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.

Alternatively, we could define FFI wrappers for recursive AST traversal.

Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:

The only client that requires mutable access is the populator.  To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.

The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).

Like in the C++ implementation, the AST nodes themselves are largely defined
via macros.  Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.

This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList".  To make this work
we need to manually define "ExternType".

There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.

One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.

Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.

The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:

    $ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
    Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
      Time (mean ± σ):     195.5 ms ±   2.9 ms    [User: 190.1 ms, System: 4.4 ms]
      Range (min … max):   193.2 ms … 205.1 ms    15 runs

    Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
      Time (mean ± σ):     677.5 ms ±  62.0 ms    [User: 665.4 ms, System: 10.0 ms]
      Range (min … max):   611.7 ms … 805.5 ms    10 runs

    Summary
      './fish.old -c 'source ../share/completions/git.fish'' ran
        3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''

Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
  changed since  it's not user visible.
2023-04-16 17:46:56 +02:00
Johannes Altmanninger
8ae1ba3432 wutil: remove unused locale handling code that has been ported already 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
77ae80f842 wutil.cpp: remove unused function 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
d47590b864 proc.h: remove unused declaration 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
16ea4380c5 redirection.rs: don't leak FFI type into Rust code 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
a848877e65 Remove an overload in io, to prepare for Rust 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
df6525e770 Make RustBuiltin a scoped enum
This prevents name clashes. It already is used as scoped enum.
2023-04-16 17:21:54 +02:00
Fabian Boehm
72a32f1a12 Rewrite "builtin" builtin in Rust
This is very simple and basically a subset of type.
2023-04-16 11:30:31 +02:00
Fabian Boehm
b65a53a2a6 Rewrite "command" builtin in Rust
This is basically a subset of type, so we might as well.

To be clear this is `command -s` and friends, if you do `command grep` that's
handled as a keyword.

One issue here is that we can't get "one path or not" because I don't
know how to translate a maybe_t? Do we need to make it a shared_ptr instead?
2023-04-16 11:27:08 +02:00
Fabian Boehm
662a4740e2 Rewrite the type builtin in rust 2023-04-16 11:27:08 +02:00
Fabian Boehm
7c37b681b2 Expose out_is_redirected to rust 2023-04-16 11:27:08 +02:00
Fabian Boehm
d02d0f3309 highlight: Add colorize_shell wrapper
Since we don't reuse the vector anyway, this allows us to keep the
highlighting on the C++-side.
2023-04-16 11:27:08 +02:00
Fabian Boehm
31d65de26c function: Add a bunch of awkward helper functions
This makes function_properties_ref_t not const, in order to work
around cxx
2023-04-16 11:27:08 +02:00
Fabian Boehm
d0c2d0c9cf path: Add method to return wcstring_list_ffi_t
This is palatable to Cxx
2023-04-16 11:27:08 +02:00
ridiculousfish
15c8f08458 Eliminate to_rust_string_vec
This can just use wcstring_list_ffi_t now.
2023-04-15 18:15:37 -07:00
ridiculousfish
dee969bf3a Introduce wcstring_list_ffi_t
wcstring_list_ffi_t is an autocxx-friendly type for passing lists of
strings from C++ to Rust.
2023-04-15 17:53:52 -07:00
Eric N. Vander Weele
4ed53d4e3f reader: Apply fish_color_selection fg color and options in vi visual mode
Vi visual mode selection highlighting behaves unexpectedly when the selection
foreground and background in the highlight spec don't match. The following
unexpected behaviors are:

*  The foreground color is not being applied when defined by the
   `fish_color_selection` variable.
* `set_color` options (e.g., `--bold`) would not be applied under the cursor
  when selection begins in the middle of the command line or when the cursor
  moves forward after visually selecting text backward.

With this change, visual selection respects the foreground color and any
`set_color` options are applied consistently regardless of where visual
selection begins and the position of the cursor during selection.
2023-04-08 20:20:58 -07:00
ridiculousfish
a487b1ecf2 Revert "Revert "Implement builtin_printf in Rust""
This reverts commit 9f7e6a6cd1.

Add additional fixes from code review.
2023-04-06 15:54:09 -07:00
Johannes Altmanninger
05bad5eda1 Port common.{h,cpp} to Rust
Most of it is duplicated, hence untested.

Functions like mbrtowc are not exposed by the libc crate, so declare them
ourselves.
Since we don't know the definition of C macros, add two big hacks to make
this work:
1. Replace MB_LEN_MAX and mbstate_t with values (resp types) that should
   be large enough for any implementation.
2. Detect the definition of MB_CUR_MAX in the build script. This requires
   more changes for each new libc. We could also use this approach for 1.

Additionally, this commit brings a small behavior change to
read_unquoted_escape(): we cannot decode surrogate code points like \UDE01
into a Rust char, so use � (\UFFFD, replacement character) instead.
Previously, we added such code points to a wcstring; looks like they were
ignored when printed.
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
998cb7f1cd New wcs2zstring to explicitly convert to zero-terminated strings
wcs2string converts a wide string to a narrow one.  The result is
null-terminated and may also contain interior null-characters.
std::string allows this.

Rust's null-terminated string, CString, does not like interior null-characters.
This means we will need to use Vec<u8> or OsString for the places where we
use interior null-characters.
On the other hand, we want to use CString for places that require a
null-terminator, because other Rust types don't guarantee the null-terminator.

Turns out there is basically no overlap between the two use cases, so make
it two functions. Their equivalents in Rust will have the same name, so
we'll only need to adjust the type when porting.
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
3b15e995e7 str2wcs: encode invalid Unicode characters in the private use area
Rust does not like invalid code points, so let's ease the transition by
treating them like byte sequences that do not map to any code point.
See https://github.com/fish-shell/fish-shell/pull/9688#discussion_r1155089596
2023-04-02 15:17:06 +02:00
ridiculousfish
c67d77fc18 Revert "Speed up executable command completions"
This reverts commit 0b55f08de2.

This was found to have caused regressions in completions in #9699
2023-03-31 20:21:52 -07:00
Clemens Wasser
3ae16a5b95 trace: Port trace to Rust 2023-03-28 20:11:42 -07:00
ridiculousfish
9f7e6a6cd1 Revert "Implement builtin_printf in Rust"
This reverts PR #9666. This had outstanding review comments and should
not have been committed.
2023-03-27 22:03:30 -07:00
ridiculousfish
f096841e4d Remove C++ printf bits
This removes the builtin printf C++ implementation, as it is now in
Rust.
2023-03-26 17:40:24 -07:00
ridiculousfish
3eb6f2ac74 Implement builtin_printf in Rust
This implements builtin_printf in Rust.
2023-03-26 17:40:24 -07:00
ridiculousfish
558baf4957 Implement some locale pieces
This adds locale.rs, which maintains a locale struct sufficient to
support printf.
2023-03-26 17:40:24 -07:00
Johannes Altmanninger
312ae36a34 common.h: remove unused declaration 2023-03-26 17:17:37 +02:00
Fabian Boehm
aa268696bf reader: Skip FreeBSD directory hack for stdin
This can be triggered on linux with:

```js
import { spawn } from 'child_process';
const shell = spawn('/home/alfa/dev/fish-shell/build-c++/fish', []);
```

Under node 19.8.1.

*No clue* how that happens, but since this is a workaround we shall
skip it.
2023-03-25 20:47:38 +01:00
Fabian Boehm
cd7e8c00e1 Silence fstatat errors
These just keep happening, people run haunted computers.

Fixes #9674.
2023-03-21 17:10:23 +01:00
ridiculousfish
732f7284d4 Adopt the new termsize
This eliminates the C++ version.
2023-03-19 16:13:41 -07:00
ridiculousfish
6ec35ce182 Reimplement termsize in Rust
This is not yet adopted by fish.
2023-03-19 16:13:41 -07:00
ridiculousfish
30feef6a72 Migrate env_stack_t::get_or_null to environment_t
Allows it to be used when we only have an environment_t.
2023-03-19 16:13:41 -07:00
ridiculousfish
57f4571a01 Rewrite wait handles and wait handle store in Rust 2023-03-18 18:53:04 -07:00
Fabian Boehm
a16abf22d9 builtins: Don't crash for negative return values
Another from the "why are we asserting instead of doing something
sensible" department.

The alternative is to make exit() and return() compute their own exit
code, but tbh I don't want any *other* builtin to hit this either?

Fixes #9659
2023-03-14 10:53:35 +01:00
Victor Song
ca494778e4 builtins: Port realpath to Rust 2023-03-12 19:50:35 -07:00
Victor Song
77fe9933e2 builtins: Rewrite pwd in Rust
Closes #9625.
2023-03-12 15:18:15 -05:00
Xiretza
9ac6cbefb1 Port event.cpp to rust
Port src/event.cpp to fish-rust/event.rs and some needed functions.

Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
2023-03-12 14:55:50 -05:00
Xiretza
dd7b177d72 builtins: set_color: remove unhandled -v/--version flag
Invoking `set_color -v` crashes fish.
2023-03-05 16:09:36 +01:00
Mahmoud Al-Qudsi
455b744bca Port fd_monitor tests to rust
This shows some of the ugliness of the rust borrow checker when it comes to
safely implementing any sort of recursive access and the need to be overly
explicit about which types are actually used across threads and which aren't.

We're forced to use an `Arc` for `ItemMaker` (née `item_maker_t`) because
there's no other way to make it clear that its lifetime will last longer than
the FdMonitor's. But once we've created an `Arc<T>` we can't call
`Arc::get_mut()` to get an `&mut T` once we've created even a single weak
reference to the Arc (because that weak ref could be upgraded to a strong ref at
any time). This means we need to finish configuring any non-atomic properties
(such as `ItemMaker::always_exit`) before we initialize the callback (which
needs an `Arc<ItemMaker>` to do its thing).

Because rust doesn't like self-referential types and because of the fact that we
now need to create both the `ItemMaker` and the `FdMonitorItem` separately
before we set the callback (at which point it becomes impossible to get a
mutable reference to the `ItemMaker`), `ItemMaker::item` is dropped from the
struct and we instead have the "constructor" for `ItemMaker` take a reference to
an `FdMonitor` instance and directly add itself to the monitor's set, meaning we
don't need to move the item out of the `ItemMaker` in order to add it to the
`FdMonitor` set later.
2023-03-05 00:33:53 -06:00
Johannes Altmanninger
5dbffa8b6d Add a maybe_t constructor taking std::unique_ptr
CXX does not allow generic types like maybe_t.  When porting a C++ function
that returns maybe_t to Rust, we return std::unique_ptr instead. Let's make
the transition more seamless by allowing to convert back to maybe_t implicitly.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
494f10a5a8 Use the correct type names for forward-declared parser types
This allows using the types in cxx bridges other than the ones that define
them.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
0410bacdf6 clang-format C++ files 2023-03-04 22:24:22 +01:00
ridiculousfish
497073f74e Add an assert in wcharz_t's constructor that it is not null
These strings should never be null.
2023-03-04 13:13:24 -08:00
Xiretza
8427e05bf7 Move escape_string tests to Rust
This way, both the Rust FFI wrapper and the actual C++ implementation are
tested.
2023-03-04 12:42:06 -08:00
Fabian Boehm
1aa3393f05 Test ifind bug with non-ascii codepoints 2023-03-02 16:33:20 +01:00
Fabian Boehm
7c91d009c1 reader: Remove assert in history search
This isn't a great use of `assert` because it turns a benign "oh I
need to search again" bug into a crash.

Fixes #9628
2023-03-02 16:29:49 +01:00
Johannes Altmanninger
14f3a5f79a Re-add highlighter tests
These were removed by accident.
2023-03-02 08:54:58 +01:00
Clemens Wasser
17c1fa9d64
Port bg builtin to Rust (#9621)
* bg: Port bg builtin to Rust
2023-02-28 16:42:12 -06:00
Victor Song
c7ea768a74
Rewrite wrealpath from wutil in Rust (#9613)
* wutil: Rewrite `wrealpath` in Rust

* Reduce use of FFI types in `wrealpath`

* Addressed PR comments regarding allocation

* Replace let binding assignment with regular comparison
2023-02-26 20:13:40 -07:00
Clemens Wasser
6f5be9bae4 block: Port block builtin to Rust
Closes #9612.
2023-02-26 14:16:55 -06:00
Clemens Wasser
330e8a86c7 block: Use an integer to count blocks 2023-02-26 14:12:57 -06:00
Mahmoud Al-Qudsi
562eeac43e
Port job_group to rust (#9608)
More ugliness with types that cxx bridge can't recognize as being POD. Using
pointers to get/set `termios` values with an assert to make sure we're using
identical definitions on both sides (in cpp from the system headers and in rust
from the libc crate as exported).

I don't know why cxx bridge doesn't allow `SharedPtr<OpaqueRustType>` but we can
work around it in C++ by converting a `Box<T>` to a `shared_ptr<T>` then convert
it back when it needs to be destructed. I can't find a clean way of doing it
from the cxx bridge wrapper so for now it needs to be done manually in the C++
code.

Types/values that are drop-in ready over ffi are renamed to match the old cpp
names but for types that now differ due to ffi difficulties I've left the `_ffi`
in the function names to indicate that this isn't the "correct" way of using the
types/methods.
2023-02-25 16:42:45 -06:00
Neeraj Jaiswal
f52569a800 abbr: port abbreviation and abbr builtin to rust 2023-02-25 12:24:58 +01:00
Neeraj Jaiswal
e384e63b24 re: port regex make anchored to rust and helper ffi funtions for regex 2023-02-25 12:24:57 +01:00
Johannes Altmanninger
b7041ad89b clang-format C++ files 2023-02-25 12:24:25 +01:00
Johannes Altmanninger
b6ede1c2a3 complete.cpp: re-use constant in try_complete_variable 2023-02-25 11:53:43 +01:00
Neeraj Jaiswal
3b60bc1de0 contains: port contains builtin to rust 2023-02-22 18:32:27 +01:00
Xiretza
77a474ee37 Move POD components of library_data_t to separate struct
This allows them to be accessed as regular fields from Rust, rather than having
to create setter/getter methods for each of them.
2023-02-20 11:32:12 +01:00
Mahmoud Al-Qudsi
aaf2d1c19d Use * const u8 instead of * const c_void
The way cxx bridge works, it doesn't recognize any types from another module as
being shared cxx bridge types with generations native to both C++ and Rust,
meaning every module that was going to use function pointers would have to
define its own `c_void` type (because cxx bridge doesn't recognize any of
libc::c_void, std::ffi::c_void, or autocxx::c_void).

FFI on other platforms has long used the equivalent of `uint8_t *` as an
alternative to `void *` for code where `void` was not available or was
undesirable for some reason. We can join the club - this way we can always use
`* {const|mut} u8` in our rust code and `uint8_t *` in our C++ code to pass
around parameters or values over the C abi.
2023-02-19 15:42:07 -06:00
Mahmoud Al-Qudsi
ce559bc20e Port fd_monitor (and its needed components)
I needed to rename some types already ported to rust so they don't clash with
their still-extant cpp counterparts. Helper ffi functions added to avoid needing
to dynamically allocate an FdMonitorItem for every fd (we use dozens per basic
prompt).

I ported some functions from cpp to rust that are used only in the backend but
without removing their existing cpp counterparts so cpp code can continue to use
their version of them (`wperror` and `make_detached_pthread`).

I ran into issues porting line-by-line logic because rust inverts the behavior
of `std::remove_if(..)` by making it (basically) `Vec::retain_if(..)` so I
replaced bools with an explict enum to make everything clearer.

I'll port the cpp tests for this separately, for now they're using ffi.

Porting closures was ugly. It's nothing hard, but it's very ugly as now each
capturing lambda has been changed into an explicit struct that contains its
parameters (that needs to be dynamically allocated), a standalone callback
(member) function to replace the lambda contents, and a separate trampoline
function to call it from rust over the shared C abi (not really relevant to
x86_64 w/ its single calling convention but probably needed on other platforms).

I don't like that `fd_monitor.rs` has its own `c_void`. I couldn't find a way to
move that to `ffi.rs` but still get cxx bridge to consider it a shared POD.
Every time I moved it to a different module, it would consider it to be an
opaque rust type instead. I worry this means we're going to have multiple
`c_void1`, `c_void2`, etc. types as we continue to port code to use function
pointers.

Also, rust treats raw pointers as foreign so you can't do `impl Send for * const
Foo` even if `Foo` is from the same module. That necessitated a wrapper type
(`void_ptr`) that implements `Send` and `Sync` so we can move stuff between
threads.

The code in fd_monitor_t has been split into two objects, one that is used by
the caller and a separate one associated with the background thread (this is
made nice and clean by rust's ownership model). Objects not needed under the
lock (i.e. accessed by the background thread exclusively) were moved to the
separate `BackgroundFdMonitor` type.
2023-02-19 15:42:03 -06:00
Fabian Boehm
4fd1458d85 Port random to rust 2023-02-19 21:01:46 +01:00
ridiculousfish
27f5490a55 Merge branch 'riir'
This merges the Rust bits.
2023-02-19 08:57:47 -08:00
Neeraj Jaiswal
1adfce18ee builtins: port return/exit to rust 2023-02-18 18:53:40 +01:00
Xiretza
ba0bfb9df7 functions: list caller-exit handlers correctly
`functions --handlers-type caller-exit` did not list any functions, while
`functions --handlers-type process-exit` listed both process-exit and
caller-exit handlers:

$ echo (function foo --on-job-exit caller; end; functions --handlers-type caller-exit | grep foo)

$ echo (function foo --on-job-exit caller; end; functions --handlers-type process-exit | grep foo)
caller-exit foo
2023-02-18 18:35:40 +01:00
Mahmoud Al-Qudsi
a1a8bc3d8d Port timer.cpp to rust 2023-02-14 15:54:18 -06:00
esdmr
a607421912
functions --copy: store file and lineno (#9542)
Keeps the location of original function definition, and also stores
where it was copied. `functions` and `type` show both locations,
instead of none. It also retains the line numbers in the stack trace.
2023-02-13 09:59:28 -06:00
ridiculousfish
15c3698258 Mark Dup2List as a struct, not a class
Fixes clang warnings "class 'Dup2List' was previously declared as a
struct."
2023-02-11 12:13:51 -08:00
ridiculousfish
b7de768c73 Allow custom completions to have leading dots
By default, fish does not complete files that have leading dots, unless the
wildcard itself has a leading dot. However this also affected completions;
for example `git add` would not offer `.gitlab-ci.yml` because it has a
leading dot.

Relax this for custom completions. Default file expansion still
suppresses leading dots, but now custom completions can create
leading-dot completions and they will be offered.

Fixes #3707.
2023-02-11 11:27:14 -08:00
Xiretza
5a76c7d3b1 Port emit builtin to rust 2023-02-11 15:04:57 +01:00
Fabian Boehm
b1b2294390 Add workaround for Midnight Commander's issue with prompt extraction
When we draw the prompt, we move the cursor to the actual
position *we* think it is by issuing a carriage return (via
`move(0,0)`), and then going forward until we hit the spot.

This helps when the terminal and fish disagree on the width of the
prompt, because we are now definitely in the correct place, so we can
only overwrite a bit of the prompt (if it renders longer than we
expected) or leave space after the prompt. Both of these are benign in
comparison to staircase effects we would otherwise get.

Unfortunately, midnight commander ("mc") tries to extract the last
line of the prompt, and does so in a way that is overly naive - it
resets everything to 0 when it sees a `\r`, and doesn't account for
cursor movement. In effect it's playing a terminal, but not committing
to the bit.

Since this has been an open request in mc for quite a while, we hack
around it, by checking the $MC_SID environment variable.

If we see it, we skip the clearing. We end up most likely doing
relative movement from where we think we are, and in most cases it
should be *fine*.
2023-02-11 14:18:10 +01:00
Johannes Altmanninger
39f3c894d7 Port tokenizer.cpp to Rust
In hindsight, I should probably have split this into three different commits.
2023-02-09 00:37:22 +01:00
Johannes Altmanninger
7f8d247211 Port parse_constants.h to Rust 2023-02-09 00:37:22 +01:00
Johannes Altmanninger
25816627de Port redirection.cpp to Rust 2023-02-09 00:37:22 +01:00
Johannes Altmanninger
9ca160eac2 Convert parse_error_code_t to a scoped enum
This will make the Rust port's diff smaller.
2023-02-08 21:49:54 +01:00
Johannes Altmanninger
8fd1db06ed Remove unused parse error code 2023-02-08 21:49:54 +01:00
Johannes Altmanninger
4639f7ec40 Follow Rust naming convention for some types
But don't do it for enum variants just yet.
2023-02-08 21:49:54 +01:00
Johannes Altmanninger
47cc98fd57 wutil.h: enable implicit conversion from wcharz_t to wcstring
This allows to write

    wcstring result = some_rust_function_that_returns_wcharz_t();
2023-02-08 21:49:41 +01:00
Xiretza
a16e2ecb1b Port echo builtin to Rust 2023-02-07 22:25:47 +01:00
Xiretza
4b85c2f6db builtin: propagate status from Rust builtins
The return type of `builtin_run_rust()` reflects that of C++ builtins.
2023-02-07 22:25:47 +01:00
Xiretza
cfb5bb2505 builtin: correctly flush streams after running Rust builtin 2023-02-07 22:25:47 +01:00
Fabian Boehm
e90f003d2d Silence ENODEV errors for fstatat
Some broken gdrive filesystem can return these.

Fixes #9550
2023-02-06 21:49:07 +01:00
ridiculousfish
c2df63f586 Remove an errant printf from fish_tests 2023-02-04 11:24:54 -07:00
Johannes Altmanninger
83fd7ea7c4 Port future_feature_flags.cpp to Rust
This is early work but I guess there's no harm in pushing it?
Some thoughts on the conventions:

Types that live only inside Rust follow Rust naming convention
("FeatureMetadata").

Types that live on both sides of the language boundary follow the existing
naming ("feature_flag_t").
The alternative is to define a type alias ("using feature_flag_t =
rust::FeatureFlag") but that doesn't seem to be supported in "[cxx::bridge]"
blocks. We could put it in a header ("future_feature_flags.h").

"feature_metadata_t" is a variant of "FeatureMetadata" that can cross
the language boundary. This has the advantage that we can avoid tainting
"FeatureMetadata" with "CxxString" and such. This is an experimental approach,
probably not what we should do in general.
2023-02-03 18:55:06 +01:00
Johannes Altmanninger
132d99a27b Call rust_init() in fish_indent too
The initial port of feature flags requires a global initialization. Since
fish_indent accesses feature flags, let's make sure to initialize them here.
In future, we can stop initializing things fish_indent doesn't need (like
the topic monitor) but that's no big deal. Global initialization should
always be a benign addition.
2023-02-03 18:55:06 +01:00
Johannes Altmanninger
517d53dc46 Port util.cpp to Rust
The original implementation without the test took me 3 hours (first time
seriously looking into this)

The functions take "wcharz_t" for smooth integration with existing C++ callers.
This is at the expense of Rust callers, which would prefer "&wstr".  Would be
nice to declare a function parameter that accepts both but I don't think
that really works since "wcharz_t" drops the lifetime annotation.
2023-02-03 18:55:06 +01:00
ridiculousfish
76adfed0e7 Implement builtin_wait in Rust
This implements builtin_wait in Rust.
2023-02-02 19:34:48 -07:00
ridiculousfish
f38543ccb7 Rename ast::job_t to ast::job_pipeline_t
This works around an autocxx limitations where different types cannot
have the same name even if they live in different namespace.

ast::job_t conflicts with job_t.
2023-02-02 19:34:48 -07:00
ridiculousfish
55f655f003 Add a gettext wrapper in Rust
This allows the wgettext! macro, which calls into C++.
2023-02-02 19:34:48 -07:00
ridiculousfish
681a165721 Add an FFI test facility
This allow testing Rust functions (from fish_tests.cpp) which need to
cross the FFI. See the example in smoke.rs.
2023-02-02 19:34:48 -07:00
ridiculousfish
d843b67d2d Initial Rust commit 2023-02-02 19:34:47 -07:00
Fabian Boehm
7f2cb47437 fish_key_reader: Don't translate things to "\v" and friends
This translated ctrl-k to "\v", which is a "vertical tab", and ctrl-l
to "\f" and ctrl-g to "\a".

There is no "vertical tab" or "alarm" or "\f" *key*, so these
shouldn't be translated. Just drop these and call them `\ck` and such.

(vertical tab specifically is utterly useless and I would be okay with
dropping it entirely, I have never seen it used anywhere)
2023-01-27 17:07:18 +01:00
Fabian Boehm
bd871c5372 Fix last PCRE2_UCHAR32
See #9502
2023-01-23 20:03:29 +01:00
Eddie Lebow
00692bcdfe Include subsequence matches in history-pager
If a `contains` search yields no results, try again with `contains_subsequence`.
2023-01-22 16:11:46 +01:00
Fabian Boehm
9043008933 abbr: Clarify universal variable message
And give explicit upgrade instructions.
2023-01-21 16:53:59 +01:00
Fabian Boehm
52d2087dd3 re: Use the variable-width pcre2 type
This was what we always did in string. It makes it match the
annoyingly variable width of wchar_t.

Fixes #9502
2023-01-21 10:49:44 +01:00
Johannes Altmanninger
e84f588d11 reader: make Escape during history search restore commandline again
Commit 3b30d92b6 (Commit transient edit when closing pager, 2022-08-31)
inadvertently introduced two regressions to history search:

1. It made Escape keeps the selected history entry,
   instead of restoring the commandline before history search.
2. It made history search commands add undo entries.

Fix both of this issues.
2023-01-17 09:31:04 +01:00
Fabian Boehm
6df09b3753
completions: Offer ../ and ./ again (#9477)
Inadvertently broken in a2d816710f,
this made `cd .` no longer offer `cd ../` (same for general file completions
like `ls .`, which only offers dotfiles)
2023-01-16 10:05:01 +01:00
Fabian Boehm
077118d983 abbr: Fix crash when no name has been given
This crashed for

```fish
abbr --add --regex '{\d+..\d+}' --function foo
```

i.e. a regex and a function but no name - that's 0 additional
arguments.
2023-01-15 10:50:09 +01:00
Fabian Boehm
da0c640750 abbr: Warn when -U is given
This prints a warning to stderr and then still does the thing.

Because of the error trailer, it points to the abbr help page.
2023-01-14 22:27:28 +01:00
Fabian Boehm
5c56fa0e6f Remove str2wcs special case for MB_CUR_MAX
This meant we didn't actually do our weird en/decoding scheme for e.g.
a C locale, which meant that, when you then switch to a proper locale
the previous variables were broken.

I don't know how to test this automatically - none of my attempts seem
to ever *fail* with the old code, here's what you'd do manually:

- Run fish with an actual C locale (LC_ALL=C
fish_allow_singlebyte_locale=1 fish)
- `set -gx foo 💩`
- `set -e LC_ALL`
- `echo $foo` outputs "💩" if it works and "ð⏎" if it's broken.

Fixes #2613
2023-01-14 22:27:16 +01:00
ridiculousfish
7fa13e4451 Remove enum_iter_t
This was unused.
2023-01-14 12:58:20 -08:00
Fabian Boehm
9ef7fe1a15 Make one error translatable
This is now the same as in `read`
2023-01-13 17:57:04 +01:00
Fabian Boehm
dad8c527e0 read: Error on read-only variables
Fixes #9346
2023-01-13 17:56:28 +01:00
Fabian Boehm
1b1cf73b60 abbr: Stop escaping the name for abbr --list
This is so we can pass it to `abbr --erase`.

Fixes #9470
2023-01-13 16:38:34 +01:00
Fabian Boehm
572a568268 abbr: Erase the old universal variable with abbr --erase
This means cleaning out old universal variables is now just:

```fish
abbr --erase (abbr --list)
```

which makes upgrading much easier.

Note that this erases the currently defined variable and/or any
universal. It doesn't stop at the former because that makes it *easy*
to remove the universals (no running `abbr --erase` twice), and it
doesn't care about globals because, well, they would be gone on
restart anyway.

Fixes #9468.
2023-01-13 16:09:53 +01:00
Fabian Boehm
1d455be9fa Cleanup 2023-01-09 22:53:34 +01:00
Fabian Boehm
5792e4a12b
Make history pager use more entries (#9458)
Like I mentioned in #9089, 12 entries is a bit few.

So, instead, we do like we do for completions before disclosing and
pick half the screen (but at least X, in this case 12).

This avoids filling the entire screen, and will avoid an unsightly "X
more entries" (which requires scrolling down to fully disclose)
because it matches what the pager does.

Note: For multiline commands we can be pushed further upwards, and in
case of a multi-column layout we could fit more lines. That would
require asking the pager to fit as many as possible and give us back
the index of the last matching entry and rewinding the history search.

That's gonna be left as an exercise for later if it turns out to be necessary.
2023-01-09 21:39:55 +01:00
Fabian Boehm
f1a150ed43 postfork: Also check if interpreter is a directory
"#!/bin/"
2023-01-08 12:44:02 +01:00
Fabian Boehm
ead0b03108 postfork: Also check shebang/interpreter for EACCESS
This happens e.g. with a shebang of "#!/bin/" - we would complain
about EACCESS, even tho accessing *the file to run* worked.
2023-01-08 12:44:02 +01:00
Aaron Gyes
6ce0b93851 tinyexpr.h: rename __TINYEXPR_H__ include guard
Identifiers that start with _ or include two consecutive underscores
are reserved for the implementation
2023-01-01 03:20:01 -08:00
ridiculousfish
30c708e8a5 builtin_print_help to take its error argument by reference
This fixes a confusing use of pointers.
2022-12-31 10:13:03 -08:00
ridiculousfish
5c216e3d8c Remove unused 'end' variable from SHLVL calculation 2022-12-30 13:38:47 -08:00
ridiculousfish
7ff0e7d0f7 Remove bogus job_chain_is_fully_constructed declaration
This member function no longer exists.
2022-12-30 13:35:33 -08:00
Aaron Gyes
7340761b21 subsequence_in_string: fix broken optimization
haystack.size() > haystack.size() is always false

change it to needle.size() > haystack.size() as seems intended
2022-12-29 01:02:44 -08:00
Fabian Boehm
4c39aeed87 abbr: Let --function use a mandatory argument
This now means `abbr --add` has two modes:

```fish
abbr --add name --function foo --regex regex
```

```fish
abbr --add name --regex regex replacement
```

This is because `--function` was seen to be confusing as a boolean flag.
2022-12-24 10:29:26 +01:00
Fabian Boehm
3005adebd5 Revert "Remove print_hints from builtin_missing_argument and builtin_unknown_option"
Unfortunately print_hints was true *by default* - so for all builtins
that didn't pass it it would now be false instead.

This resulted in the trailer missing, which includes the line number
and context. So if you ran a script that includes `bind -M` the error
message would now just be "bind: -M: option requires an argument",
with no indication as to where.

This reverts commit 8a50d47a46.
2022-12-22 17:24:47 +01:00
ridiculousfish
5f23da9939 Add a TSAN workaround and re-enable the test
This reverts commit 865602e8d1.
2022-12-19 15:54:23 -08:00
ridiculousfish
8a50d47a46 Remove print_hints from builtin_missing_argument and builtin_unknown_option
The print_hints variable was always false, so just remove it.

This caused a cascade of other changes where the parser_t variable
becomes unused, so remove it from the call sites.

No functional change expected here.
2022-12-19 15:05:51 -08:00
Johannes Altmanninger
224f81e250 fish_tests: use default argument for abbreviation tests
Some tests place the cursor at the end of the command line.  This is the
obvious default, so let's make it a default argument.
2022-12-17 18:09:54 +01:00
Johannes Altmanninger
2df8bde5eb fish_tests: test that make_anchored regex helper actually anchors 2022-12-17 18:09:54 +01:00
Johannes Altmanninger
b225ab42aa builtin: fix typo in builtin description 2022-12-17 18:09:54 +01:00
Johannes Altmanninger
f6db6c41e6 reader: clarify bounds check when probing for cached highlighting
When we insert characters that don't yet have highlighting, we use the
highlighting to the left, unless there is nothing to our left.  The logic to
check if we are the leftmost character uses an overly loose comparison. Let's
make it more specific.
No functional change.
2022-12-17 18:09:54 +01:00
Johannes Altmanninger
0b6eab4ec3 event: include handler name in event log output
When there are multiple event handlers for a single event, we would print
the same log statement twice. Let's add the function name to make this
less confusing.
2022-12-17 18:09:54 +01:00
Fabian Boehm
bb98cb01c7 abbr: Also show --position
(if not the default)
2022-12-14 18:06:24 +01:00
Fabian Boehm
30a37d9433 abbr: Make show output actually work
This would print

```
abbr -a -- dotdot --regex ^\\.\\.+\$ --function multicd
```

which expands "dotdot" to "--regex ^\\.\\.+\$...".

Instead, we move the name to right before the replacement, and move
the `--` before that:

```
abbr -a --regex ^\\.\\.+\$ --function -- dotdot multicd
```

It might be possible to improve that, but this at least round-trips.
2022-12-13 19:38:58 +01:00
Johannes Altmanninger
9790907ca8 abbr: stop parsing option after first expansion token
Historical behavior is to stop option parsing at the first non-option argument.
Since we have added more options, it seemed impractical to keep that behavior.

However people are using options in their abbr expansions ("abbr e emacs
-nw").  To support this, we ignore options. However, we only ignore them
if they are not valid "abbr" options.  Let's ignore all options in the
expansion definition, which is a small price to pay to keep most existing
configurations working.

Fixes #9410

This does not fix other cases which used to work, like

    abbr x -unknown

Those are hopefully not used by anyone, so I don't think we need to maintain
support for that.
2022-12-13 01:39:31 +01:00
Johannes Altmanninger
c120305b8d
Merge pull request #9313 from ridiculousfish/mega-abbr
Enhances abbreviations with extra features
- global abbreviations
- trigger on regex match as alternative to literal match
- the ability to expand abbreviations with a user-defined function  
- the ability to set cursor position after expansion
2022-12-12 23:56:11 +01:00
ridiculousfish
6bc545d503 Use actual enum names in wgetopt
No functional change here.
2022-12-11 10:26:39 -08:00
ridiculousfish
d8dbb9b259 Switch abbreviation '-r' flag from --rename to --regex
This will be the more common option and provides consistency with
`string`.
2022-12-10 16:21:39 -08:00
ridiculousfish
e08f4db1f9 Rename abbreviation cursor "sentinel" to "marker"
Also default the marker to '%'. So you may write:

    abbr -a L --position anywhere --set-cursor "% | less"

or set an explicit marker:

   abbr -a L --position anywhere --set-cursor=! "! | less"
2022-12-10 16:15:03 -08:00
ridiculousfish
01039537b0 Remove abbreviation triggers
Per code review, this does not add enough value to introduce now.
Leaving the feature in history should want want to revisit this
in the future.
2022-12-10 16:15:00 -08:00
ridiculousfish
35a4688650 Rename abbreviation triggers
This renames abbreviation triggers from `--trigger-on entry` and
`--trigger-on exec` to `--on-space` and `--on-enter`. These names are less
precise, as abbreviations trigger on any character that terminates a word
or any key binding that triggers exec, but they're also more human friendly
and that's a better tradeoff.
2022-12-10 15:38:50 -08:00
ridiculousfish
5841e9f712 Remove '--quiet' feature of abbreviations
Per code review, this is too risky to introduce now. Leaving the feature
in history should want want to revisit this in the future.
2022-12-10 15:38:50 -08:00
ridiculousfish
c51a1f1f60 Implement trigger-on for abbreviations
trigger-on enables abbreviations to trigger only on "entry" (anything
which closes a token, like space) or only on "exec" (typically enter key).
2022-12-10 15:38:50 -08:00
ridiculousfish
7118cb1ae1 Implement set-cursor for abbreviations
set-cursor enables abbreviations to specify the cursor location after
expansion, by passing in a string which is expected to be found in the
expansion. For example you may create an abbreviation like `L!`:

    abbr L! --position anywhere --set-cursor ! "! | less"

and the cursor will be positioned where the "!" is after expansion, with
the "| less" appearing to its right.
2022-12-10 15:38:50 -08:00
ridiculousfish
1d205d0bbd Reimplement abbreviation expansion to support quiet abbreviations
This reimplements abbreviation to support quiet abbreviations. Quiet
abbreviations expand "in secret" before execution.
2022-12-10 15:38:46 -08:00
ridiculousfish
8135c52c13 Abbreviations to support functions
This adds support for the `--function` option of abbreviations, so that the
expansion of an abbreviation may be generated dynamically via a fish
function.
2022-12-10 15:29:04 -08:00
ridiculousfish
d15855d3e3 Abbreviations to support matching via regex
This adds the --regex option to abbreviations, allowing them to match a
pattern of tokens.
2022-12-10 15:29:04 -08:00
ridiculousfish
470153c0df Refactor abbreviation set into its own type
Previously the abbreviation map was just an unordered map; switch it to a
real class so we can hang methods off of it.
2022-12-10 15:29:04 -08:00
ridiculousfish
1402bae7f4 Re-implement abbreviations as a built-in
Prior to this change, abbreviations were stored as fish variables, often
universal. However we intend to add additional features to abbreviations
which would be very awkward to shoe-horn into variables.

Re-implement abbreviations using a builtin, managing them internally.

Existing abbreviations stored in universal variables are still imported,
for compatibility. However new abbreviations will need to be added to a
function. A follow-up commit will add it.

Now that abbr is a built-in, remove the abbr function; but leave the
abbr.fish file so that stale files from past installs do not override
the abbr builtin.
2022-12-10 15:29:03 -08:00
ridiculousfish
d2daa921e9 Introduce re::make_anchored
This allows adjusting a pattern string so that it matches an entire
string, by wrapping the regex in a group like ^(?:...)$

This is a workaround for the fact that PCRE2_ENDANCHORED is unavailable
on PCRE2 prior to 2017, so we have to adjust the pattern instead.

Also introduce an overload of match() which creates its own
match_data_t.
2022-12-10 12:24:43 -08:00
ridiculousfish
fe7d095647 Add maybe_t::value_or
This enables getting the value or returning the passed-in value.
This is helpful for "default if none."
2022-12-10 12:24:43 -08:00
Johannes Altmanninger
892a820672 Make sure that cd to a relative CDPATH results in absolute $PWD
We have had multiple crashes for relative CDPATH entries.  Commit 5e274066e
(Always return absolute path in path_get_cdpath, 2019-10-17) tried to fix
all of them but it failed to do justice to its title.  Let's fix this to
actually return absolute paths, always.  Take care to to normalize the path
because it is used for autosuggestions. The normalization is mostly relevant
for CDPATH=. (the default) but it doesn't hurt others.

Closes #9407
2022-12-10 11:06:54 +01:00
ridiculousfish
b0ec7e07b8 Fix a wgetopt crash and add a test
This has apparently been a problem since forever.
2022-12-09 13:54:00 -08:00
ridiculousfish
35bad1f94c Untangle some pointers in wgetopt
wgetopt had a "nameend" parameter which was a confusing pointer. Make it
into a slightly less confusing size_t.
2022-12-04 14:48:20 -08:00
ridiculousfish
962d1083d3 Remove wgeopter_t::wopterr
wopterr was a feature to allow wgetopt to emit error messages; but we do
not use this and never will. Remove its support. No functional change
expected here.
2022-12-04 12:03:13 -08:00
Johannes Altmanninger
6072ea1900 Fix false positive cd higlighting when token ends in slash
We wrongly highlight this as prefix when actually the trailing slash should
invalidate it. Turns out path normalization drops the slash, so let's
sidestep that.

Fixes #9394
2022-12-03 22:36:56 +01:00
ridiculousfish
39b7f112c7 Remove the "flag" field from woption
The "flag" field enables an option to discover which flag it was invoked
with. However in practice none of our options use multiple flags so this
parameter was always nullptr. Remove it and fix up all the builtins to
stop passing this.

No functional change here.
2022-11-29 16:08:37 -08:00
Mahmoud Al-Qudsi
063450b8f4 Update likely/unlikely macros to avoid double negation
I believe this should be identical to the previous code and handle the same
cases (I'm guessing going by the comment that this came from a C codebase
without `bool` types).

The problem with the previous code is that it tripped up the `clangd` analyzer
into thinking `assert()` expressions can/should be simplified via DeMorgan's to
improve readability (because it was seeing the fully expanded macro).
2022-11-29 13:26:32 -06:00
ridiculousfish
7ee161af8d Fix the flaky tty_ownership test on Mac
The tty_ownership test was sometimes failing. In this test,
`fish_test_helper` creates a child and transfers the tty to it,
"abandoning" the tty. In some cases, the child was running before the
parent; the child claims the tty. When the parent tries to transfer it to
the child, it get SIGTTIN and stops. Fix this by ignoring SIGTTIN and
SIGTTOU.

This only affects macOS and BSDs.
2022-11-28 15:01:12 -08:00
Mahmoud Al-Qudsi
0c111b1c6b Add comments to brace expansion 2022-11-16 14:10:30 -06:00
Fabian Boehm
0f8b9699a1 Fix error for {$}
Fixes #9337
2022-11-15 19:02:30 +01:00
ridiculousfish
f1e73a1839 Increase debounce timeout in debounce test
On slow machines this was spuriously failing.
2022-11-12 14:08:22 -08:00
ridiculousfish
4ab728b3a2 Reduce FISH_MAX_EVAL_DEPTH under tsan
The stack overflow tests are too slow without this.
This is because the tests are essentially quadratic: with 500 jobs, and
each job attempts to reap all jobs.
2022-11-12 14:08:22 -08:00
Johannes Altmanninger
c4a60feff1 Stop attempting to complete inside comments
Inside a comment we offer plain file completions (or command completions if
the comment is in command position). However these completions are broken
because they don't consider any of the surrounding characters. For example
with a command line

    echo # comment
              ^ cursor

we suggest file completions and insert them as

    echo # comsomefile ment

Providing completions inside comments does not seem useful and it can be
misleading. Let's remove the completions; this should communicate better that
we are in a free-form comment that's not subject to fish syntax.

Closes #9320
2022-11-12 22:37:27 +01:00
Aaron Gyes
e38c9bb062 builtin set --show: put read-only part on same line. 2022-11-12 06:21:36 -08:00
Mahmoud Al-Qudsi
093ee6def5 Drop global variable shadowing warning on universal var unset
When unsetting, the scope indicates the scope that was *removed* not
set, so the warning is incorrectly triggered. If anything, the confusion
is now removed or we emit a warning that the variable is still present
in another scope (but don't do that!).

Closes #9338.
2022-11-10 21:25:01 -06:00
Fabian Boehm
311e1aa968 Revert "builtin string: push_back \n chars rather than append strings"
This reverts commit 3739c53bcf.

It misses the point of e69be38235 and reintroduces a lot of write calls.

See #9229
2022-11-07 22:37:53 +01:00
Aaron Gyes
3739c53bcf builtin string: push_back \n chars rather than append strings
prefer
    streams.out.append(foo)
    streams.out.push_back(L'\n')

vs e.g.
    foo.append(L"\n");
    streams.out.append(foo)
2022-11-07 13:34:52 -08:00
Fabian Boehm
33edac2c0c path: Show main path docs for path subcommand --help
Fixes #9334
2022-11-07 20:47:07 +01:00
Aaron Gyes
1a0d6ebe59 builtins/printf: use wcsto[i,u]max, check EINVAL, add test
This fixes #9321

IEEE Std 1003.1-2017 Issue 6 added optional error condition
[EINVAL] for if no conversion could be performed.

Switch back to wcstoimax/wcstoumax: do not work around the old FreeBSD
8 issue.

Add a test for printf '%d %d' 1 2 3
2022-10-31 19:58:18 -07:00
Mahmoud Al-Qudsi
4cb19e244b Sort and deduplicate output of complete -C
This addresses a long-standing TODO where `complete -C` output isn't
deduplicated.

With this patch, the same deduplication and sort procedure that is run on actual
pager completions is also executed for `complete -C` completions (with a `-C`
payload specified).

This makes it possible to use `complete -C` to test what completions will
actually be generated by the completions pager instead of it displaying
something completely divorced from reality, improving the productivity of fish
completions developers.

Note that completions that wouldn't be shown in the pager are also omitted from
the results, e.g. `test/buildroot/` and `test/fish_expand_test/` are omitted
from the check matches in `checks/complete_directories.fish` because even if
they were generated, the pager wouldn't have shown them. This again makes
reasoning about and debugging completions much easier and more sane.
2022-10-31 16:52:36 -05:00
Mahmoud Al-Qudsi
8750f9ccb7 fixup! Reintroduce trivially copyable maybe_t impl
`git revert --no-commit` leaving the repo in a "middle of revert" state
tripped me up and my changes weren't included in the commit. Mea culpa.
2022-10-29 11:39:33 -05:00
Mahmoud Al-Qudsi
4f46abec9d Reintroduce trivially copyable maybe_t impl
This reverts commit 1c92d4c5db and
reintroduces support for trivially copyable `maybe_t` impls but with a
GCC version check to disable the optimization for GNU GCC compiler
versions 9 and below.

GCC 8.3.0 armhf builds seem to have a problem with the trivially
copyable `maybe_t` impl that introduces odd heisenbugs that cause the
tests to fail. GDB reveals that `maybe_t` function parameters received
in the callee differ from what was passed-in by the caller.

This behavior appears to be (but has not been confirmed as) a
platform-specific compiler bug. Under the same system (32-bit Debian 10
armhf), compiling with clang 7.0.1 does not result in any bugs and
causes all the tests to pass while compiling with GCC 10.2 under 32-bit
Debian 11 armhf also doesn't run into any problems, so just expand the
existing GCC version check that gates support for trivially copyable
`maybe_t` impls to encompass both the troublesome GCC 8 version and the
untested GCC 9 version.
2022-10-29 11:26:34 -05:00
Mahmoud Al-Qudsi
1c92d4c5db Revert "maybe_t: make maybe_t<T> trivially copyable if T is"
This reverts commit 9d303a74e3.
This reverts commit 0305c842e6.

9d303a7 broke 32-bit armhf builds for unknown reasons, specifically in
settings where a trivial copy of `maybe_t<int>` was performed. A caller
would pass a literal int in the place of a `maybe_t<int>` parameter and
the callee would see a populated `maybe_t` but with a value of `0`
rather than the actual value that was passed in. It was too painful to
debug to a resolution under qemu.
2022-10-29 10:12:41 -05:00
Fabian Boehm
8d7662335e function: Don't list empty function names and directories 2022-10-29 10:24:42 +02:00
Aaron Gyes
daf5e11179 Spelling fixes
Found with scspell
2022-10-28 20:10:09 -07:00
Aaron Gyes
b7593a377a fish_key_reader: stop looping on SIGHUP
Using the machinery in reader.cpp rather than going back to
intalling our own handlerss

(see 89644911a1)

Fixes #9309
2022-10-27 17:17:05 -07:00
Johannes Altmanninger
0305c842e6 Fix build on CentOS 7
This fixes a regression in 9d303a74e (maybe_t: make maybe_t<T> trivially
copyable if T is, 2022-10-26). I subscribed to the launchpad repo now -.-
2022-10-27 09:28:52 +02:00
Aaron Gyes
efa2cf0cb6 Replace fallthrough comments with __fallthrough__
Defined in config.h
2022-10-26 21:02:48 -07:00
Aaron Gyes
df546e01f6 IWYU fixup 2022-10-26 20:04:04 -07:00
Aaron Gyes
92698dff48 Unallowed command subst error: add missing newline and simplify
Fixes ommitted newline char shown after complete -n'(foo)'
Also axes the 'contains syntax errors' line before the error.
Update tests

before
> complete -n'(foo)'
complete: Condition '(foo)' contained a syntax error
complete: Command substitutions not allowed⏎

after
> complete -n'(foo)'
complete: -n '(foo)': command substitutions not allowed here
2022-10-26 19:58:40 -07:00
Aaron Gyes
b2a4a50daf Run include-what-you-use 2022-10-26 19:58:40 -07:00
ridiculousfish
a4aaa4f59b Fix the Xenial build
The Xenial build was failing due to a missing default constructor
in maybe_t. Add it.
2022-10-26 14:19:01 -07:00
Mahmoud Al-Qudsi
f7da014602 Optimize storage of completion entries
This is a salvage of the "no functional changes" part of #9221, and cherry-picks
storing completion entries in a vector instead of a linked list. The legacy
"reverse intuitive" group ordering is kept by iterating in reverse order.

Tests pass but don't actually cover group order, which needs another test.
2022-10-26 12:48:31 -05:00
Mahmoud Al-Qudsi
7133285c88 Move parser status vars to their own struct
Instead of using an enum + array, just use a struct and drop the getter and
setter methods from `parser_t`.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
6ac18defd2 Add status current-commandline
Makes it possible to retrieve the currently executing command line as
opposed to the currently executing command (`status current-command`).

Closes #8905.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
e01eb2e615 Add proper way of storing value for status current-command
There should be no functional changes in this commit.

The global variable `$_` set in the parser variables by `reader.cpp` and
read by the `status` builtin was deprecated in fish 2.0 but kept around
internally because there's no good way to store/share/forward parser
variables.

A new enum is added that identifies the status variable and they are
stored in a private array in the parser. There is no need for
synchronization because they are only set during job init and never
thereafter. This is currently asserted via ASSERT_IS_MAIN_THREAD() but
that assert can be dropped in the interest of making the parser possible
to clone and use from worker threads.

The old `$_` global variable is still kept for backwards compatibility,
though it will be dropped in a future release.
2022-10-26 12:15:02 -05:00
Johannes Altmanninger
f637fb31b5 highlight: underline prefixes of valid paths only if at cursor
As the user is typing an argument, fish continually checks if the input is
the prefix of a valid file path. If yes, the input is underlined.

The same prefix-logic is used for all tokens on the command line, even for
"finished" tokens. This means we highlight any token that happens to be
a prefix of a valid file path. We actually want this to only apply to the
token that the user is currently typing.

Let's use the prefix-logic only for tokens adjacent to the cursor.  This should
better match user expectations (and reduce IO traffic). I don't think this is
the perfect criteria but I don't know how else we can determine if a token is
"unfinished".
2022-10-26 16:12:43 +02:00
Johannes Altmanninger
6667c9f50c highlighter: pass the cursor position to the highlighter
This allows the next commit to correct highlighting based on the cursor
position.
2022-10-26 16:11:00 +02:00
Johannes Altmanninger
861ac00a61 highlighter: underline valid "cd" arguments also if they come from CDPATH
When visiting the "cd" node, we mark invalid paths as error, but don't
underline valid paths.  This works fine most of the time because we later
underline paths (for any command, not just "cd").
However the latter check fails to honor CDPATH.  Let's correct that, which
also allows to simplify the logic.
2022-10-26 16:11:00 +02:00
Johannes Altmanninger
dfb0c00d72 highlighter: stop performing IO if canceled
The next commit wants to move the "Underline every valid path" logic into the
visit() methods. The logic currently polls the cancel checker before checking
each path. If that's valid, it should probably have the same behavior inside
visit(). Since we currently can't cancel an AST-visitation, the next best
thing seems to suspend all IO operations, the rest should be very fast anyway.

I'm not sure if the motivation is strong enough; a conceivable alternative
would be to stop using the cancel checker altogether for highlighting.
2022-10-26 16:11:00 +02:00
Johannes Altmanninger
9c6f46a808 highlighter: remove redundant check if we can do io
It's done a few lines above.
2022-10-26 16:09:02 +02:00
Johannes Altmanninger
acb47f70d2 history_file.cpp: remove an unused variable
Now that maybe_t<size_t> no longer has a user-defined destructor, the compiler
can better detect an unused variable of this type.
2022-10-26 16:09:02 +02:00
Johannes Altmanninger
9d303a74e3 maybe_t: make maybe_t<T> trivially copyable if T is
When passing a value of type maybe_t<size_t>, clangd complains:

    Parameter 'cursor' is passed by value and only copied once; consider
    moving it to avoid unnecessary copies (fix available)

We get this warning because maybe_t<size_t> is not trivially copyable
because it has a user-defined destructor and copy-constructor.  Let's remove
them if the contained type is trivially copyable, to avoid such warnings.
No functional change.
2022-10-26 16:09:02 +02:00
Johannes Altmanninger
1ce2961561 maybe_t: remove user-defined destructor
The destructor is equivalent to the compiler-generated one.  The user-defined
destructor prevents maybe_t<size_t> from bearing the predicate "trivially
copyable". Let's remove it. No functional change.
2022-10-26 14:54:33 +02:00
Johannes Altmanninger
45da77c5c5 Format some C++ files with clang-format 2022-10-26 14:53:06 +02:00
Mahmoud Al-Qudsi
21599a49ea Make CALL_STACK_LIMIT_EXCEEDED_ERR_MSG more generic
We're now using this when a stack overflow is detected during eval/substitution
loops, too.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
175caab583 Prevent stack overflow from eval/substitution recursion
It seems to have originally been thought that the only possible way a stack
overflow could happen is via function calls, but there are other possibilities.

Issue #9302 reports how `eval` can be abused to recursively execute a string
substitution ad infinitum, triggering a stack overflow in fish.

This patch extends the stack overflow check to also check the current
`eval_level` against a new constant `FISH_MAX_EVAL_DEPTH`, currently set to a
conservative but hopefully still fair limit of 500. For future reference, with
the default stack size for the main/foreground thread of 8 MiB, we actually have
room for a stack depth around 2800, but that's only with extremely minimal state
stored in each stack frame.

I'm not entirely sure why we don't check `eval_depth` regardless of block type;
it can't be for performance reasons since it's just a simple integer comparison
- and a ridiculously easily one for the branch predictor handle, at that - but
maybe it's to try and support non-recursive nested execution blocks of greater
than `FISH_MAX_STACK_DEPTH`? But even without recursion, the stack can still
overflow so may be we should just bump the limit up some (to 500 like the new
`FISH_MAX_EVAL_DEPTH`?) and check it all the time?

Closes #9302.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
e7bf98adc1 Make block_t moveable
The presence of the explicit constructor (even though it did nothing) prevented
the compiler from generating a move constructor for `block_t`.
2022-10-24 22:06:30 -05:00
Mahmoud Al-Qudsi
84b53b4cae Significantly reduce size of block_t
A `block_t` instance is allocated for each live block type in memory when
executing a script or snippet of fish code. While many of the items in a
`block_t` class are specific to a particular type of block, the overhead of
`maybe_t<event_t>` that's unused except in the relatively extremely rare case of
an event block is more significant than the rest, given that 88 out of the 216
bytes of a `block_t` are set aside for this field that is rarely used.

This patch reorders the `block_t` members by order of decreasing alignment,
bringing down the size to 208 bytes, then changes `maybe_t<event_t>` to
`shared_ptr<event_t>` instead of allocating room for the event on the stack.
This brings down the runtime memory size of a `block_t` to 136 bytes for a 37%
reduction in size.

I would like to investigate using inheritance and virtual methods to have a
`block_t` only include the values that actually make sense for the block rather
than always allocating some sort of storage for them and then only sometimes
using it. In addition to further reducing the memory, I think this could also be
a safer and saner approach overall, as it would make it very clear when and
where we can expect each block_type_type_t-dependent member to be present and
hold a value.
2022-10-24 21:04:17 -05:00
Mahmoud Al-Qudsi
44c9c51841 Disable leak detection in test_autosuggest_suggest_special() under CI
This is a false positive as a result of disabling TLS support in LSAN due to an
incompatibility with newer versions of glibc.

Also remove the older workaround (because it didn't work).
2022-10-24 19:02:49 -05:00
Mahmoud Al-Qudsi
fed64999bc Allow erasing in multiple scopes in one go 2022-10-20 11:21:05 -05:00
Mahmoud Al-Qudsi
99bc112de0 Fix unqualified calls to std::move
`using` is for types, not functions :(
2022-10-19 12:31:55 -05:00
Mahmoud Al-Qudsi
920ded26b9 history: Handle Ctrl-C/SIGINT or other errors on output append
When there are multiple screens worth of output and `history` is writing to the
pager, pressing Ctrl-C at the end of a screen doesn't exit the pager (`q` is
needed for that) but previously caused fish to emit an error ("write:
Interrupted system call) until we starting silently handling SIGINT in
`fd_output_stream_t::append()`.

This patch makes `history` detect when the `append()` call returns with an error
and causes it to end early rather than repeatedly trying (and failing) to write
to the output stream.
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
83636fa599 Silently handle fd_output_stream_t append errors in case of SIGINT
If EINTR caused by SIGINT is encountered while writing to the
`fd_output_stream_t` output fd, mark the output stream as errored and return
false to the caller but do not visibly complain.

Addressing the outstanding TODO notwithstanding, this is needed to avoid
littering the tty with spurious errors when the user hits Ctrl-C to abort a
long-running builtin's output (w/ the primary example being `history`).
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
8e97fcb22c Make output_stream_t::append() fallible
Allow errors encountered by certain implementations of `output_stream_t` when
writing to the output sink to be bubbled back to the caller.
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
b94b896503 Shrink size of env_mode_flags_t 2022-10-15 15:15:04 -05:00
Fabian Boehm
52dcfe11af Make \x the same as \X
Up to now, in normal locales \x was essentially the same as \X, except
that it errored if given a value > 0x7f.

That's kind of annoying and useless.

A subtle change is that `\xHH` now represents the character (if any)
encoded by the byte value "HH", so even for values <= 0x7f if that's
not the same as the ASCII value we would diverge.

I do not believe anyone has ever run fish on a system where that
distinction matters. It isn't a thing for UTF-8, it isn't a thing for
ASCII, it isn't a thing for UTF-16, it isn't a thing for any extended
ASCII scheme - ISO8859-X, it isn't a thing for SHIFT-JIS.

I am reasonably certain we are making that same assumption in other
places.

Fixes #1352
2022-10-09 15:24:01 +02:00
Mahmoud Al-Qudsi
85d4834b35 Make maybe_t safer against accidental misuse
Closes #9240.

Squash of the following commits (in reverse-chronological order):

commit 03b5cab3dc40eca9d50a9df07a8a32524338a807
Author: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Date:   Sun Sep 25 15:09:04 2022 -0500

    Handle differently declared posix_spawnxxx_t on macOS

    On macOS, posix_spawnattr_t and posix_spawn_file_actions_t are declared as void
    pointers, so we can't use maybe_t's bool operator to test if it has a value.

commit aed83b8bb308120c0f287814d108b5914593630a
Author: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Date:   Sun Sep 25 14:48:46 2022 -0500

    Update maybe_t tests to reflect dynamic bool conversion

    maybe_t<T> is now bool-convertible only if T _isn't_ already bool-convertible.

commit 2b5a12ca97b46f96b1c6b56a41aafcbdb0dfddd6
Author: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Date:   Sun Sep 25 14:34:03 2022 -0500

    Make maybe_t a little harder to misuse

    We've had a few bugs over the years stemming from accidental misuse of maybe_t
    with bool-convertible types. This patch disables maybe_t's bool operator if the
    type T is already bool convertible, forcing the (barely worth mentioning) need
    to use maybe_t::has_value() instead.

    This patch both removes maybe_t's bool conversion for bool-convertible types and
    updates the existing codebase to use the explicit `has_value()` method in place
    of existing implicit bool conversions.
2022-10-08 11:56:38 -05:00
Johannes Altmanninger
485873b19b Share logic between move constructor/assignment of dir_iter_t
The parent commit made the destructor of the DIR* member close it if necessary
(i.e. only if it's not null).  This means that we can use the same logic in
the move constructor (where the source DIR* is null) and for move assignment
(where it might not be).

No functional change.
2022-10-08 17:32:12 +02:00
Johannes Altmanninger
da5d93b4de dir_iter_t to use unique_ptr for closing directory
dir_iter_t closes its DIR* member in two places: the move assignment and
the destructor. Simplify this by closing it in the destructor of the DIR*
member which is called in both places. Use std::unique_ptr, which is shorter
than a dedicated wrapper class. Conveniently, it calls the deleter only if
the pointer is not-null.  Unfortunately, std::unique_ptr requires explicit
conversion to DIR* when interacting with C APIs but it's probably still
better than a wrapper class.

This means that the noncopyable_t annotation is now implied due to the
unique_ptr member.
Additionally, we could probably remove the user-declared move constructor
and move assignment (the compiler-generated ones should be good enough). To
be safe, keep them around since they also erase the fd (though I hope we
don't rely on that behavior anywhere).

We should perhaps remove the user-declared destructor entirely but
dir_iter_t::entry_t also has one, I'm not sure why. Maybe there's a good
reason, like code size.

No functional change.
2022-10-08 17:31:47 +02:00
Johannes Altmanninger
f82537bcdc color_string_internal to use a sentinel value that's definitely invalid
I think -1 is slightly more elegant than 0 because 0 could be a valid offset.

No functional change.
2022-10-05 22:27:00 -05:00
Johannes Altmanninger
5868b3c380 read_unquoted_escape: remove dead loop condition
This was recently converted to a while-loop. However, we only
loop in a specific case when (by hitting "continue") so a
loop condition is not necessary.

No functional change.
2022-10-05 22:27:00 -05:00
Fabian Boehm
e7a7a58030 Remove use of maybe_t that makes gcc grumpy
We have a state machine here already, we can just use the state where
the variable is valid.
2022-10-05 22:34:19 +02:00
Fabian Boehm
460f56f95a Revert "Silence gcc warning"
This reverts commit 8ab437a989.

It introduced a warning for clang - because that read the GCC pragma and didn't understand it.
2022-10-05 22:29:04 +02:00
Fabian Boehm
8ab437a989 Silence gcc warning
This complained that the variable might be uninitialized *right* after
the check that it wasn't, because it doesn't understand maybe_t.
2022-10-05 19:07:41 +02:00
Fabian Boehm
396e276286 Decode multibyte escapes immediately
We forgot to decode (i.e. turn into nice wchar_t codepoints)
"byte_literal" escape sequences. This meant that e.g.

```fish
string match ö \Xc3\Xb6

math 5 \X2b 5
```

didn't work, but `math 5 \x2b 5` did, and would print the wonderful
error:

```
math: Error: Missing operator
'5 + 5'
   ^
```

So, instead, we decode eagerly.
2022-10-05 18:55:01 +02:00
Sergei Shilovsky
e274ef6c0d
commandline --selection-start and --selection-end implementation
Fixes #9197
2022-10-05 18:51:00 +02:00
Fabian Boehm
dcf52dbba5 fix path --null-out
Regression from 7bc4c9674b.

Appending `"\0"` to an std::string does nothing.

I blame C++.
2022-10-05 17:25:00 +02:00
Fabian Boehm
cb28b39b24 string shorten: Make max of 0 mean no shortening
This makes it easier to just slot in `string shorten` wherever,
without having to do a weird "if test $max -gt 0" check.
2022-10-04 18:44:21 +02:00
Fabian Boehm
cdf1a94e29 ifdef DT_WHT 2022-10-04 17:00:04 +02:00
ridiculousfish
757c117591 Handle symlink loops in descend_unique_hierarchy
descend_unique_hierarchy is used for the cd autosuggestion: if a directory
contains exactly one subdirectory and no other entries, then propose that
as part of the cd autosuggestion.

This had a bug: if the subdirectory is a symlink to the parent, we would
chase that, going around the loop suggesting a longer path until we hit
PATH_MAX.

Fix this by using the new API which provides the inode "for free," and
track whether we've seen this inode before. This is technically too
conservative since the inode may be for a directory on a different device,
but devices are not available for free so this would incur a cost. In
practice encountering the same inode twice with different devices in a
unique hierarchy is unlikely, and should it happen the consequences are
merely cosmetic: we fail to suggest a longer path.
2022-10-02 18:56:46 -07:00
ridiculousfish
0b47ba0642 Remove wreaddir and wreaddir_resolving
dir_iter_t has replaced these functions; we can remove them.
2022-10-02 18:48:16 -07:00
ridiculousfish
a2d816710f Adopt dir_iter_t in wildcard.cpp
Migrate wildcard's directory iteration to the new dir_iter_t.
Remove a now-unused function.
2022-10-02 18:48:16 -07:00
ridiculousfish
749d71288d Adopt dir_iter_t in descend_unique_hierarchy
Migrate this function from wreaddir_resolving to dir_iter_t
2022-10-02 18:48:16 -07:00
ridiculousfish
2a9366f938 Migrate highlight.cpp usage of wreaddir to dir_iter_t
Switch to the new API instead of using opendir directly.
2022-10-02 18:48:16 -07:00
ridiculousfish
36fbfef74c Switch uses of dir_t to dir_iter_t
dir_t was a thin wrapper around readdir; switch to the new dir_iter_t API
and remove dir_t.
2022-10-02 18:48:16 -07:00
ridiculousfish
b684f7b076 Introduce dir_iter_t
This introduces dir_iter_t, a new class for iterating the contents of a
directory. dir_iter_t encapsulates the logic that tries to avoid using
stat() to determine the type of a file, when possible.
2022-10-02 18:48:16 -07:00