Commit graph

5594 commits

Author SHA1 Message Date
Johannes Altmanninger
bc26481558 Retry writing some escape sequences on EINTR
Maybe we should be using SA_RESTART?
2024-12-30 10:50:01 +01:00
Johannes Altmanninger
41e82c8c9e Protect some cursor movements against untimely ctrl-c
Commit 01dbfb0a3f (replace writestr() with fwprintf() in reader.cpp,
2016-12-20) accidentally replaced a retry-on-EINTR write with a
non-retrying version. Commit 7f31acbf9b (Prevent fish_title output
from triggering a bel, 2022-02-02) fixed this for some cases but
not all, fix that.
2024-12-30 10:50:01 +01:00
Johannes Altmanninger
376bf3a982 Remove redundant return value from write_loop()
This function ought to match the standard write_all().
2024-12-30 10:50:01 +01:00
Johannes Altmanninger
1e384900fa kitty kbd: stop parsing CSI R as F3
This has been removed, see kitty commit cd92d50a0 (Keyboard protocol:
Remove CSI R from the allowed encodings of the F3 key as it conflicts
with the *Cursor Position Report* escape code, 2022-12-24).
2024-12-30 10:50:01 +01:00
Johannes Altmanninger
69f0d960cf Fix off-by-one error in Vi-style upcase-word at commandline end
cursor_selection_mode=inclusive means the commandline position is
bounded by the last character. Fix a loop that fails to account
for this.

Fixes d51f669647 (Vi mode: avoid placing cursor beyond last character,
2024-02-14).

This change looks very odd because if the commandline is like

	echo foo.

it makes us try to uppercase the trailing period even though that's
not part of word range.  Hopefully this is harmless.

Note that there seem to be more issues remaining, for example Vi-mode
paste leaves the cursor in an out-of-bounds odd position.

Fixes #10952
Closes #10953

Reported-by: Lzu Tao <taolzu@gmail.com>
2024-12-30 10:50:01 +01:00
Fabian Boehm
6f9ca42a30
Add status buildinfo (#10896)
This can be used to get some information on how fish was built - the
version, the build system, the operating system and architecture, the
features.
2024-12-29 13:37:28 +01:00
Joan Bruguera Micó
b8df9648f2 Create new base directories with mode 0700
If base directories (e.g. $HOME/.config/fish) need to be created,
create them with mode 0700 (i.e. restricted to the owner).
This both keeps the behavior of old fish versions (e.g. 3.7.1) and is
compliant with the XDG Base Directory Specification.

See: https://specifications.freedesktop.org/basedir-spec/0.8/#referencing
2024-12-28 12:13:48 -08:00
Peter Ammon
b97598fa6c
Clean up some logic around handling the parser blocks
Fix a todo. Enforce reverse iteration order.
2024-12-27 16:42:38 -08:00
Peter Ammon
64cb86ac26
Stop copying node sources so aggressively in parse_execution
Eliminates some allocations and fixes a TODO.
2024-12-27 15:47:34 -08:00
Peter Ammon
a14906f52f
Fix a todo!
Stop cloning the delimiter unnecessarily in builtin read.
2024-12-27 15:00:59 -08:00
Peter Ammon
36d7049749
Minor cleanup of other unsafe impl 2024-12-27 14:46:46 -08:00
Peter Ammon
4b9767ce83
Remove as_ptr from IoData
We don't need this. Also improve IoChain::remove().
2024-12-27 14:36:55 -08:00
Peter Ammon
f6d76d2057
Remove some unsafe impls of Send / Sync
We no longer have C++ so we don't need these; Rust does the right thing by
default.
2024-12-27 14:14:47 -08:00
Peter Ammon
659c926dbd
Additional cleanup of io buffering
Eliminate some ugly bits. No functional change expected.
2024-12-27 14:09:07 -08:00
Peter Ammon
56da15d11f Rework the file descriptor monitor
[Do NOT cherry-pick to 4.0 - this needs more time to be tested]

fish sometimes needs to capture the output of a command or block of
commands. Examples include fish_prompt or any command substitution
("cmdsubs"). It does this the obvious way: by creating a pipe, using dup2
to replace stdout of the command with the write end of the pipe, and then
reading from the read end into a buffer, until EOF or the command
substitution completes. Importantly, this task also overlaps with waiting
for the process to exit; that is when executing:

    set var (some_cmd)

fish needs to both wait on `some_cmd` and ALSO read its output into memory.
This is awkward to do in a portable way in a single thread (though maybe
doable on Linux with pidfd). So we wait and read on different threads.

To make things worse, command substitutions may themselves create
additional command substitutions (recursion, etc). Creating a read thread
for every command substitution would result in excessive threads. So rather
than a thread per cmdsub, we have a single dedicated thread that handles
ALL command substitutions, by multiplexing multiple file descriptors via
select/poll. This is the "fd monitor." You hand it a file descriptor and it
lets you know when it's readable, and then you can read from it (via a
callback). Also, it has a "wakeup" fd: if you write to that then the fd
monitor wakes up, figures out what it has to do, and resumes.

When the command substitution ends, we need to remove the fd from the fd
monitor, because we intend to close it. You might object "the commands in
the cmdsub have all completed so the write end of the pipe has been closed
so the fd monitor can just notice that the pipe is closed" but it's not so:
consider the horrible case of `set var (yes &)` and abandon all hope.

The current mechanism for removing the fd from the monitor is called a
"poke." We tell the fd monitor (through a "control" self-pipe) to
explicitly wake up the item. It then invokes the callback ("pokes") the
item on the dedicated fd monitor thread. The item notices that the command
substitution is complete, and it returns a value meaning "remove me" and
the fd monitor does so. The client thread is stuck waiting for this process
to complete.

So basically removing a fd from the monitor requires a round trip to its
dedicated thread. This is slow and also complicated (Rust doesn't have
futures)!

So let's not do that.

The big idea is to remove this round-trip synchronization. That is, when we
intend to remove the fd from the fd monitor, we _just do it_ and then close
the fd. Use a lock rather than a round-trip to the thread. Crucially that
lock is unlocked while the monitor thread waits in select/poll.

This invites all sorts of races:

1. fish might remove and close the fd right before the monitor polls it. It
   will thus attempt to poll a closed fd.
2. fish might remove and close the fd, and then something else opens a file
   and receives the same fd. Now the fd monitor will poll an fd that was
   never added.
3. fish might remove and close the fd _while the fd monitor is polling it_.
   What happens then? (Turns out on macOS we get EBADF, and on Linux the fd is
   marked readable).

The Big Idea is that *all of these races are benign*. As long as
poll/select doesn't crash or hang, we don't care *what* it returns, because
the source of truth are the set of items stored in the fd monitor and these
item IDs are never recycled. (This also assumes that it's OK to select/poll
on random file descriptors; there ought to be no side effects).

Not only is this a large simplification since we no longer need that round
trip, it's a substantial performance improvement as well. The
"aliases.fish" benchmark goes from 164 to 154 msec on my Mac, and from 124
to 112 msec on my Linux machine - nearly 10%.

Add some tests to verify our assumptions about the behavior of closing or
replacing a file descriptor during poll. But even if these fail, all we
care about is that poll/select doesn't crash or hang.
2024-12-27 13:23:11 -08:00
Peter Ammon
5e59762117 FdMonitor: Use a HashMap instead of Vec of items
Preparing for a substantial optimization.
2024-12-27 13:23:11 -08:00
Peter Ammon
69fdbc89d6 Refactor FdMonitorItem readability checks
No functional change. Preparing for an optimization.
2024-12-27 13:21:44 -08:00
Peter Ammon
244c55f9ce FdMonitor: change_signaller to be held strongly not weakly
There's no reason to use Weak here, especially since we just unwrap it. There's
no reference cycles, so just share the data via Arc.
2024-12-27 13:21:44 -08:00
Peter Ammon
b7ae159824
Remove the ability for FdMonitorItems to have timeouts
FdMonitor is used to monitor a set of file descriptors and invoke a callback
when one becomes readable. Prior to this commit, they coudl also have the
callback invoked on timeout. fish used to use this feature but no longer does;
remove it.
2024-12-27 13:03:49 -08:00
Peter Ammon
6dad396498
Clean up some stale comments 2024-12-27 13:03:49 -08:00
Blair Noctis
6c63139d23 refactor: macroize SIGNAL_TABLE entries
reducing boilerplate and chance of typo
2024-12-24 15:25:10 +01:00
Mahmoud Al-Qudsi
f3dd4ee022 Fix typo in hard-coded name of SIGSTKFLT 2024-12-23 14:29:00 -06:00
Fabian Boehm
e2596d13cd Remove SIGUNUSED
It is, as the name implies, unused - it became SIGSYS, which we
already check.

Since it is entirely undefined on some architectures it causes a build
failure there, see discussion in #10633
2024-12-23 17:06:22 +01:00
Johannes Altmanninger
c1b460525c Temporary workaround for BSD WEXITSTATUS libc bug
The libc crate has a bug on BSD where WEXITSTATUS is not an 8-bit
value, causing assertion failures.

Any libc higher than our 0.2.155 would increase our MSRV, see libc
commit 5ddbdc29f (Bump MSRV to 1.71, 2024-01-07), so we want to
woraround this anyway.  It's probably not worth using a patched
version of libc since it's just one line.

While at it, tighten some types I guess.

Upstream fix: https://github.com/rust-lang/libc/pull/4213

Closes #10919
2024-12-23 14:34:59 +01:00
Johannes Altmanninger
5de6f4bb3d Provide old implementation of cancel-commandline as fallback
__fish_cancel_commandline was unused (even before) and has some issues
on multiline commandlines. Make it use the previously active logic.

Closes #10935
2024-12-23 14:34:59 +01:00
Johannes Altmanninger
54cc932215 Attempt to fix clippy lints 2024-12-23 14:34:59 +01:00
Johannes Altmanninger
ab4606430e Sort parser keywords 2024-12-23 08:40:02 +01:00
Fabian Boehm
3dc49d9d93 Allow installable builds to be installed into a specific path (#10923)
* Pass path to install()

It was dirty that it would re-get $HOME there anyway.

* Import wcs2osstring

* Allow installable builds to use a relocatable tree

If you give a path to `--install`, it will install fish into a
relocatable tree there, so

PATH/share/fish contains the datafiles
PATH/bin/fish contains the fish executable
PATH/etc/fish is sysconf

I am absolutely not sold on that last one - the way I always used
sysconfdir is that it is always /etc. This would be easy to fix but
should probably also be fixed for "regular" relocatable builds (no
idea who uses them).

An attempt at #10916

* Move install path into "install/" subdir

* Disable --install harder if not installable
2024-12-22 18:16:07 +01:00
Integral
b19a467ea6
Replace some PathBuf with Path avoid unnecessary heap allocation (#10929) 2024-12-21 12:34:27 -06:00
Johannes Altmanninger
610338cc70 On undo after execute, restore the cursor position
Ever since 149594f974 (Initial revision, 2005-09-20), we move the
cursor to the end of the commandline just before executing it.

This is so we can move the cursor to the line below the command line,
so moving the cursor is relevant if one presses enter on say, the
first line of a multi-line commandline.

As mentioned in #10838 and others, it can be useful to restore the
cursor position when recalling commandline from history. Make undo
restore the position where enter was pressed, instead of implicitly
moving the cursor to the end. This allows to quickly correct small
mistakes in large commandlines that failed recently.

This requires a new way of moving the cursor below the command line.
Test changes include unrelated cleanup of history.py.
2024-12-21 13:10:34 +01:00
Johannes Altmanninger
1e7de063bd Fix regression of builtin read not exiting on ctrl-c
Commit 8bf8b10f68 (Extended & human-friendly keys, 2024-03-30) stopped
ctrl-c from exiting without a motivation. Unfortunately this was
only noticeable on terminals that speak the kitty keyboard protocol,
which is probably no one had noticed so far.

Closes #10928
2024-12-21 05:54:52 +01:00
Johannes Altmanninger
039011bc81 Make full autosuggestions case-correcting again
Fixes ca21872d14 (Clean up the accept-autosuggestion code path a
little bit, 2024-11-14).
Fixes #10915
2024-12-18 19:02:27 +01:00
Fabian Boehm
f89e26b06e installable: Reword $HOME error 2024-12-18 17:26:25 +01:00
Johannes Altmanninger
0275c5e803 Swap variable overrides and time in not statement
This is allowed

	time a=b echo 123

but -- due to an oversight in 3de95038b0 (Make "time" a job prefix,
2019-12-21) -- this is not allowed:

	not time a=b echo 123

Instead, this one one works:

	not a=b time echo 123

which is weird because without the "not" this would run "/bin/time".

It seems wrong that "not" is not like the others. Swap the order
for consistency.

Note that unlike "not", "time" currently needs to come before variable
assignments, so "a=b time true" is disallowed. This matches zsh. POSIX
shells call "/bin/time" here. Since it's ambiguous, erroring out seems
fine. It's weird that we're inconsistent with not here but I guess
"command not" is not expected to have subtly different behavior.

Closes #10890
2024-12-16 06:33:47 +01:00
Johannes Altmanninger
8fd0399ed3 Remove runaway kw_builtin in not statement definition
This was added accidentally in 971d257e67 (Port AST to Rust,
2023-04-02).  It does not seem to be causing an observable effect
(although I didn't try hard).
2024-12-16 06:33:47 +01:00
Fabian Boehm
a98997fab0 curses: Just use our hardcoded xterm-256color entry as the fallback
The values we would try are:

xterm-256color, xterm, ansi, dumb

This is a pretty useless list, because systems without
"xterm-256color" but with "ansi" basically don't exist,
and it is very likely that the actual terminal is more
xterm-compatible than it is ansi.

So instead we just use our xterm-256color definition, which has a high
likelihood of being basically correct.
2024-12-14 12:10:34 +01:00
Fabian Boehm
378e9b236a Silence time_t deprecation
This is not something that affects us or we can do anything about.
2024-12-14 09:34:52 +01:00
Johannes Altmanninger
f9febba2b0 Fix replacing completions with a -foo prefix
Fixes #10904
2024-12-14 09:31:20 +01:00
Fabian Boehm
84d8655677 fmt! 2024-12-13 21:57:07 +01:00
Fabian Boehm
abc1a45ea1 Shorten error for broken $TERM 2024-12-13 21:46:17 +01:00
Fabian Boehm
be16eeef69 Make --install install without confirmation, and not exit 2024-12-13 19:19:26 +01:00
Fabian Boehm
6d28845c2b Automatically attempt to install
This is fairly subtle.

When installable, and we either can't find the version file or it is
outdated, we ask the user to confirm installation (just like `--install`).

We do that only if we are really truly interactive (with a tty!) to
avoid `fish -c` running into problems.
This check could be tightened even more, because currently:

```fish
fish -ic 'echo foo'
```

asks, while

```fish
fish -ic 'echo foo' < /dev/null
```

does not.

`fish -c` will still error out if it can't find the config, but it
will just run if it is out of date.
2024-12-13 19:19:26 +01:00
Fabian Boehm
99fa8aaaa7 Really hide install() from clippy 2024-12-11 17:21:34 +01:00
Fabian Boehm
fa298c41e0 Hide install() from clippy
Not checkable because it would require sphinx
2024-12-11 17:18:34 +01:00
Peter Ammon
5c8b6adc2c Fix infinite prompt loop if status message is printed in prompt
fish will print messages for some jobs when they exit abnormally, such as
with SIGABRT. If a job exits abnormally inside the prompt, then (prior to
this commit) fish would print the message and re-trigger the prompt, which
could result in an infinite loop. This has existed for a very long time.

Fix it by reaping jobs after running the prompt, and NOT triggering a
redraw based on that reaping. We still print the message but the prompt is
not executed.

Add a test.

Fixes #9796
2024-12-08 18:12:59 -08:00
Fabian Boehm
56a1403350 Revert "Enable gettext without the _nl_msg_cat_cntr gnuism"
This built on my test system, might be version differences.

(it's also not enough to make it *work*, but a necessary step)

This reverts commit 6fded249cd.
2024-12-08 22:04:59 +01:00
Fabian Boehm
6fded249cd Enable gettext without the _nl_msg_cat_cntr gnuism
This should allow e.g. musl to be translated.
2024-12-08 21:53:20 +01:00
Johannes Altmanninger
421ce13be6 Fix replacing completions spuriously quoting ~
Commit 29dc30711 (Insert some completions with quotes instead of
backslashes, 2024-04-13) wrongly copmletes

	$ cat ~/space

to

	$ cat '~/path with spaces'

Today completions can be either replacing or appending.  We never quote
(but backslash-escape) appending completions (unless they "append"
to an empty token).  We always quote replacing completions. The
assumption in this part of the code is that replacing completions
can be quoted without changing meaning.

This assumption is wrong for tildes.  For the backslash-escaping code
path, we take care of this edge case via a special DONT_ESCAPE_TILDES
flag. However that flag does not take effect when using quotes for
escaping. Fix that.

Unfortunately, e97a4fab7 (Escape : and = in file completions,
2024-04-19) introduced a (hopefully temporary) code clone in
escape_separators, which made added an extra step to debugging here.
2024-12-08 15:27:08 +01:00
Fabian Boehm
004953a3b2 Revert "BuiltinData to use const constructor function"
Unfortunately, this does not work with rust 1.70.

This reverts commit 7e516925e9.
2024-12-08 07:52:57 +01:00
Peter Ammon
7e516925e9
BuiltinData to use const constructor function
This makes the list of builtins one line per builtin. No functional change.
2024-12-07 10:37:53 -08:00