Commit graph

5648 commits

Author SHA1 Message Date
Johannes Altmanninger
e1e963ae66 Move cursor on mouse click via kitty's OSC 133 click_events=1
When the user clicks somewhere in the prompt, kitty asks the shell
to move the cursor there (since there is not much else to do).

This is currently implemented by sending an array of
forward-char-passive commands.  This has problems, for example it
is really slow on large command lines (probably because we repaint
everytime).

Implement kitty's `click_events=1` flag to set the
position directly.  To convert from terminal-coordinates
to fish-coordinates, query [CSI 6 n Report Cursor
Position](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)
and use it to compute the left prompt's terminal-coordinates (which
are (0, 0) in fish-coordinates).

Unfortunately this doesn't yet work correctly while the terminal
is scrolled.  This is probably because the cursor position is wrong
if off-screen.  To fix that we could probably record the cursor
position while not scrolled, but it doesn't seem terribly important
(the existing implementation also doesn't get it right).

We still turn off mouse reporting.  If we turned it on, it
would be harder to select text in the terminal itself (not fish).
This would typically mean that mouse-drag will alter fish's
selection and shift+mouse-drag or alt+mouse-drag can be used.

To improve this, we could try to synchronize the selection: if parts
of the fish commandline are selected in the terminal's selection,
copy that to fish's selection and vice versa.

Or maybe there is an intuitive criteria, like: whenever we receive a
mouse event outside fish, turn off mouse reporting, and turn it back on
whenver we receive new keyboard input.  One problem is that we lose
one event (though we could send it back to the terminal). Another
problem is we would turn it back on too late in some scenarios.

Closes #10932
2024-12-30 10:50:01 +01:00
Johannes Altmanninger
ca9c5f4cec Move some fake readline commands to a separate type 2024-12-30 10:50:01 +01:00
Johannes Altmanninger
48ae19b4b1 Update some stale doc comments 2024-12-30 10:50:01 +01:00
Johannes Altmanninger
7ec1487016 Deduplicate call to select() 2024-12-30 10:50:01 +01:00
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
Peter Ammon
0b68fbfd85
Clean up some stale comments 2024-12-07 10:37:53 -08:00
Fabian Boehm
1599293796 Build man pages into installable fish
This calls sphinx-build from build.rs to include the man pages in the binary.

We don't abort if sphinx doesn't exist, but we do if it failed.
2024-12-06 22:12:26 +01:00
Fabian Boehm
7c73c5fec0 Make fish installable
When built with the default "installable" feature, the data files (share/) are
included in the fish binary itself.

Run `fish --install` or `fish --install=noconfirm` (for
non-interactive use) to install fish's data files into ~/.local/share/fish/install

To figure out if the data files are out of date, we write the current version
to a file on install, and read it on start.

CMake disables the default features so nothing changes for that, but this allows installing via `cargo install`,
and even making a static binary that you can then just upload and have extract itself.

We set $__fish_help_dir to empty for installable builds, because we do not have
a way to generate html docs (because we need fish_indent for highlighting).
The man pages are found via $__fish_data_dir/man
2024-12-06 22:12:26 +01:00
Fabian Boehm
7827a8e533 Make bin path an Option
It is possible we cannot acquire this
2024-12-06 22:12:26 +01:00
Fabian Boehm
e24823dd6c Signals: Compute signal set once on startup
Really the only thing we're looking for here is if we're started with
HUP ignored or not.

Saves a syscall per external process.

Continuation of #10869
2024-12-04 20:18:16 +01:00
Himadri Bhattacharjee
d124c31958 refactor: remove unnecessary copied() for Utf32Str reference 2024-12-02 19:12:39 +01:00
Fabian Boehm
b2e6609367 builtin random: Be less strict about arguments
This now allows:

- Same argument (`random 5 5`)
- Swapped ends (`random 10 2`)
- One possibility (`random 0 5 4`)

This makes it easier to use with numbers generated elsewhere instead
of hard-coded, so you don't need to check as much before running it.

Fixes #10879
2024-12-02 19:06:14 +01:00
Fabian Boehm
1cad9898d6 Refactor some more .unwrap/asserts
No use in asserting and then unwrapping, just .expect()
2024-11-30 23:11:04 +01:00
Fabian Boehm
4859606e0c posix_spawn: Unconditionally default all signals (except HUP)
We don't really care if the process has a custom handler installed, we
can just set it to default.

The one we check is SIGHUP, which may be given to us via `nohup`.

This saves ~30 syscalls *per process* we spawn, so:

```fish
for f in (seq 1000)
    command true
end
```

has ~30000 fewer rt_sigaction calls. These take up about ~30% of the
total time spent in syscalls according to strace.

We could also compute this set once at startup and then reuse it.
2024-11-30 23:00:44 +01:00
Peter Ammon
5d10bc6a02
Fix/suppress some clippies
needless_lifetimes is annoying; supress that. Fix some spacing that clippy was
complaining about.
2024-11-30 12:21:30 -08:00
Fabian Boehm
eee44b7469 ulimit: Fix multiplication overflow 2024-11-30 15:40:48 +01:00
Fabian Boehm
8b464d96af Remove reference to static mut
This is what UnsafeCell is for: Providing interior mutability.

The docs at https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html
give an example just like this - `&mut *ptr.get()`

Without, rustc may complain - https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html
2024-11-28 19:36:50 +01:00
Johannes Altmanninger
644171fac6 fix: check whether a function is tombstoned during highlight
exists_no_autoload() wrongly thinks that tombstoned functions can be
autoloaded; fix that.

While at-it replace the use of get_props() with something simpler.

Co-authored-by: Himadri Bhattacharjee

Closes #10873
2024-11-27 08:44:36 +01:00
Fabian Boehm
4101bb30bf Remove unused variables
Never set since the introduction in 61686aff34
2024-11-25 16:29:00 +01:00
Johannes Altmanninger
b89619330b Disable terminal protocols before cancellable operations
The [disambiguate flag](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate) means that:

> In particular, ctrl+c will no longer generate the SIGINT signal,
> but instead be delivered as a CSI u escape code.

so cancellation only works while we turn off disambiguation.

Today we turn it off while running external commands that want to
claim the TTY.  Also we do it (only as a workaround for this issue)
while expanding wildcards or while running builtin wait.

However there are other cases where we don't have a workaround,
like in trivial infinite loops or when opening a fifo.

Before we run "while true; end", we put the terminal back in ICANON
mode. This means it's line-buffered, so we won't be able to detect
if the user pressed ctrl-c.

Commit 8164855b7 (Disable terminal protocols throughout evaluation,
2024-04-02) had the right solution: simply disable terminal protocols
whenever we do computations that might take a long time.
eval_node() covers most of that; there are a few others.

As pointed out in #10494, the logic was fairly unsophisticated then:
it toggled terminal protocols many times.  The fix in 29f2da8d1
(Toggle terminal protocols lazily, 2024-05-16) went to the extreme
other end of only toggling protocols when absolutely necessary.

Back out part of that commit by toggling in eval_node() again,
fixing cancellation.  Fortunately, we can keep most of the benefits
of the lazy approach from 29f2da8d1: we toggle only 2 times instead
of 8 times for an empty prompt.

There are only two places left where we call signal_check_cancel()
without necessarily disabling the disambiguate flag
1. open_cloexec() we assume that the files we open outside eval_node()
   are never blocking fifos.
2. fire_delayed(). Judging by commit history, this check is not
   relevant for interactive sessions; we'll soon end up calling
   eval_node() anyway.

In future, we can leave bracketed paste, modifyOtherKeys and
application keypad mode turned on again, until we actually run an
external command.  We really only want to turn off the disambiguate
flag.

Since this is approach is overly complex, I plan to go with either
of these two alternatives in future:
- extend the kitty keyboard protocol to optionally support VINTR,
  VSTOP and friends.  Then we can drop most of these changes.
- poll stdin for ctrl-c. This promises a great simplification,
  because it implies that terminal ownership (term_steal/term_donate)
  will be perfectly synced with us enabling kitty keyboard protocol.
  This is because polling requires us to turn off ICANON.
  I started working on this change; I'm convinced it must work,
  but it's not finished yet. Note that this will also want to
  add stdin polling to builtin wait.

Closes #10864
2024-11-24 16:11:57 +01:00
Fabian Boehm
f0a5f8738b Silence clippy lints 2024-11-24 11:17:34 +01:00
Mahmoud Al-Qudsi
1347df898e Add ascii fast path for fish_wcswidth(&wstrw)
chars.all(|c| c.is_ascii()) is autovectorizable but this outperforms even when
it's not vectorized.
2024-11-22 21:35:39 -06:00
Mahmoud Al-Qudsi
2fd51355c3 Speed up wcscasecmp by approximately 30-40%
Moving the "make empty ToLowercase iterator" logic to within the
`unwrap_or_else()` instead of always generating it brings most of the speedup;
unrolling the recursive call brings in the rest.
2024-11-22 21:34:25 -06:00
Mahmoud Al-Qudsi
8c8da78cf8 Speed up get_case_fold() 5x
Using `c.is_uppercase()` instead of getting the iterator and checking if the
first (and only) lowercase letter of the sequence is the same as the original
input is 5-8x faster (measured via criterion against `/usr/share/dict/words`).

(Additional benefit of forcibly inlining the now iterator-based comparison not
taken into account; this necessitated changing from a closure to a local
function as the inline attribute on closures is not yet supported with the
stable compiler toolchain.)
2024-11-22 16:30:10 -06:00
Mahmoud Al-Qudsi
b949497bc1 Use idiomatic names for CaseSensitivity and ContainType 2024-11-22 16:28:33 -06:00
Mahmoud Al-Qudsi
b570c7f6a6 Reduce allocations when deduping completions in place
This is still suboptimal because we are allocating a vector of indices to be
removed (but allocation-free in the normal case of no duplicates) but
significantly better than the previous version of the code that duplicated the
strings (which are larger and spread out all over the heap).

The ideal code (similar to what we had in the C++ version, iirc) would look like
this, but it's not allowed because the borrow checker hates you:

```
fn unique_in_place_illegal(comps: &mut Vec<Completion>) {
    let mut seen = HashSet::with_capacity(comps.len());
    let mut idx = 0;
    while idx < comps.len() {
        if !seen.insert(&comps[idx].completion) {
            comps.remove(idx);
            continue;
        }
        idx += 1;
    }
}
```
2024-11-22 14:11:01 -06:00
Fabian Boehm
212dd6ec37 builtins/history: Use the enum nicer
Name it so it's not SHOUTY CASE, make a `panic!` unrepresentable

No functional change
2024-11-21 18:33:32 +01:00
Mahmoud Al-Qudsi
edd82be58d Fix crash on invalid CSI parameters
If a semicolon-delimited list of CSI parameters contained an (invalid) long
sequence of ascii numeric characters, the original code would keep multiplying
by ten and adding the most recent ones field until the `params[count][subcount]`
u32 value overflowed.

This was found via automated fuzz testing of the `try_readch()` routine against
a corpus of some proper/valid CSI escapes.
2024-11-20 15:01:34 -06:00
Mahmoud Al-Qudsi
b92830cb17 Change readch() into try_readch()
This lets us call into the entirety of the prior `readch()` with an exhaustible
input stream without panicking on the `unreachable!()` call. The previous
functionality is kept under the old name by calling `try_readch()` with the
`blocking` parameter set to `true` (100% same behavior as before).

While the `try_readch(false)` entrypoint isn't used directly by the current fish
codebase, it is required in order to automate input reader tests without the
overhead and complexity of running the test harness in a tty emulator emulator
like pexpect or tmux, which moreover necessitates out-of-process testing – which
is incompatible with most perf-guided testing harnesses.

I hope to be able to upstream harness integrations using this entry point in the
near future.
2024-11-20 14:53:07 -06:00
Peter Ammon
c4bc6b6f09
Clean up print_help
`print_help` is a hacky-wacky function used to support the `--help` command
of `fish_key_reader` and others. The Rust version panics on an error; fix
that and make it print more useful help messages.
2024-11-17 17:03:34 -08:00
Peter Ammon
642eff9e1f
Fix some clippies and remove some dead code 2024-11-17 12:37:45 -08:00
Johannes Altmanninger
2d8fcbcdcd Fix regression causing mbrtowc(argv) to be called before setlocale()
Fixes #10847
2024-11-16 20:46:06 +01:00
Johannes Altmanninger
913860bd1c Fix regression causing alt-right to stop at autosuggestion
Fixes #10839
2024-11-16 13:05:44 +01:00
Johannes Altmanninger
ca21872d14 Clean up the accept-autosuggestion code path a little bit
It's still a bit too complex unfortunately.
2024-11-16 13:05:44 +01:00
Mahmoud Al-Qudsi
fea1e3aee5 Use iterators to clean up disown logic 2024-11-14 13:25:25 -06:00
Mahmoud Al-Qudsi
c1acbf2845 Deduplicate jobs passed to disown builtin
I'm guessing this was missed in the port because there were comments referencing
using a hash set to perform the deduplication but there was no hashset. (The
TODO was added later.)
2024-11-14 13:24:55 -06:00
Fabian Boehm
366c1b7210 Refuse to search history pager if no new results exist
This prevents searching further and collapsing results into one.

Now I need to figure out how to get it to flash.
2024-11-14 20:02:49 +01:00
Mahmoud Al-Qudsi
4061ef7137 Remove unnecessary Pid::get() calls 2024-11-14 13:02:03 -06:00
Mahmoud Al-Qudsi
fc47d9fa1d Use strongly typed Pid for job control 2024-11-14 13:02:03 -06:00
Mahmoud Al-Qudsi
2cf4b12d41 Use strongly typed Option<Pid> for event handler
This caught an incorrect description for process/job exit handlers for ANY_PID
(now removed) which has been replaced with a message stating the handler is for
any process exit event.
2024-11-14 13:02:03 -06:00
Mahmoud Al-Qudsi
95ac51101e Use Option<Pid> instead of Option<pid_t>
Statically assert that the interior value is both positive and non-zero.
2024-11-14 13:02:03 -06:00
Mahmoud Al-Qudsi
3307672998 Use type safety for pid values
The previous approach of "treat this field as an `Option<NonZeroU32>` and
remember to check `p.has_pid()` before accessing it" was a mix of C++ and rust
conventions and led to some bugs or incorrect behaviors.

* `jobs -p` would previously print both the (correct) external pid and the
  (incorrect) internal value of `0` if a backgrounded command contained a
  fish function (e.g. `function foo; end; cat | foo &; jobs`)
* Updating/calculating job cpu time and usage was incorrectly including all of
  fish's cpu usage/time for each function/builtin member of the job pipeline.

Closes #10832
2024-11-14 13:02:03 -06:00
Fabian Boehm
080e40aac0 Fix crash in history pager
ctrl-r ctrl-s ctrl-s

Attemps to go before the beginning and asserts out. Instead refuse to
do that.

(there's some weirdness where it can reduce the pager to the first
entry if you keep pressing, which I haven't found yet, but that's better than *crashing*)
2024-11-14 16:36:40 +01:00
Fabian Boehm
6d76b938c7 bind: Remove "c-" and "a-" shortcut notation
These are another way to spell the same thing that doesn't match what
`bind` would print.

They're also not documented and tested thoroughly.

Since they are just small shortcuts and unreleased we can just remove
them.

Fixes #10845
2024-11-13 17:48:15 +01:00
Mahmoud Al-Qudsi
4e3dc51bc4 Prevent test suite from hanging on panic 2024-11-11 16:45:13 -06:00
Fabian Boehm
960415db3f function: Error out for read-only variables
This will refuse to define the function instead of defining it with an
unusable argument.

Fixes #10842
2024-11-11 17:56:57 +01:00
Fabian Boehm
0ef811c86e dir_iter: Remove duplicate NUL-removal
This goes over the d_name twice.

Filenames already cannot contain NUL (the C-api cannot express it!), so we don't need to scan them.
2024-11-11 17:56:57 +01:00
Johannes Altmanninger
2543b8198d Fix crash when sprintf width argument overflows u64
Given "printf %18446744073709551616s", we parse the number only in
the printf crate, which tells us that we overflowed somwhere (but
not where exactly).
2024-11-09 08:16:08 +01:00
Mahmoud Al-Qudsi
9fddc3e887
Emit only sane pgid value for jobs output (#10833)
We were previously printing the internal `INVALID_PID` value (since removed),
which was a meaningless `-2` constant, when there was no pgid associated with a
job.

This PR changes that to `-` to indicate no pgid available, which I prefer over
something like `0` or `-1`, but will cause problems for code that is hardcoded
to convert this field to an integral value.
2024-11-08 10:33:30 -06:00
Johannes Altmanninger
5e3fdf3320 Fix regression causing crash when we should clamp negative wcwidth
Fixes c41dbe455 (Also use control pictures for pager prefix,
2024-10-19).

Fixes #10836
2024-11-07 07:36:36 +01:00
Fabian Boehm
373c5b1e14 fixup! Cursor visible sequence
Whoops, picked the wrong part of cnorm
2024-11-06 19:03:50 +01:00