Commit Graph

5212 Commits

Author SHA1 Message Date
Johannes Altmanninger
15cd74a3bb Fix fish_escape_delay_ms for terminals that send CSI 27 u
See the parent commit for some context.  Turns out that 8bf8b10f6 (Extended &
human-friendly keys, 2024-03-30) broke this for terminals that speak CSI u.
This is pretty complex, probably not worth it.
2024-04-10 22:39:33 +02:00
Johannes Altmanninger
b815319607 Remove redundant default escape delay
When a terminal sends \x1ba, that could be either escape,a or alt-a.
Historically we've handled this with an escape delay that defaults to 30
milliseconds.  If we read nothing for that time, it's escape. Otherwise it's
an alt modifier (or an escape sequence).

As a side effect of 8bf8b10f6 (Extended & human-friendly keys, 2024-03-30) we
added a new way of disambiguating escape: whenever we read the escape byte,
we immediately try another (nonblocking) read.  If it succeeds, we treat it
as modifier, else it's escape. Before that commit, we didn't have a concept
of modifiers.

The new way works fine for disambiguating escape,a from alt-a (as pressed
by the user) because only for alt-a the data is sent in the same packet.

So we no longer need the escape delay to disambiguate the alt from the
escape key.  Let's simplify things by not using it by default.

The escape delay as set by fish_escape_delay_ms also serves another purpose;
it allows to disambiguate "escape,a" from "escape (pause) a". For that use
case we want to keep it.
2024-04-10 22:39:33 +02:00
Johannes Altmanninger
1da2087038 Also refresh TTY timestamps before "commandline -f repaint"
As mentioned in 8a7c3ceec (Don't abandon line after writing control sequences,
2024-04-06) we need to freshed stdout timestamps after writing to stdout
but before we might redraw, in particular when writing control sequences.

Commit a583fe723 ("commandline -f foo" to skip queue and execute immediately,
2024-04-08) made "commandline -f repaint" redraw immediately, while still
executing the bound shell command; at that time we have written "disabling"
sequences but not refreshed timestamps yet, so do that.

This is probably not needed for commands outside the repaint family.
Needless to say that this is messy, maybe we can simplify things in future.

Ref https://github.com/fish-shell/fish-shell/issues/10409#issuecomment-2044863817
2024-04-09 21:53:48 +02:00
Johannes Altmanninger
adb40149a3 Do not insert key's PUA encoding into the command line
If a key's codepoint is in the PUA1 range, it could
be either from our own named keys (like key::Space)
or from a CSI u key that we haven't assigned a name yet
https://sw.kovidgoyal.net/kitty/keyboard-protocol/#functional-key-definitions
(The latter can still be bound using the \u1234 or the equivalent \e[4660u
raw CSI u sequence.)

It doesn't make sense to insert a PUA character into the commandline when
the user presses PrintScreen; ignore them silently.

This partially reverts b77d1d0e2 (Stop crashing on invalid Unicode input,
2024-02-27). That commit did:
1. convert input byte sequences that map to a PUA codepoint into several
   characters, using our on-char-per-byte PUA encoding.
2. do the same for inputs that are codepoints outside the valid Unicode range.
3. render them as replacement character (one per input byte)

In future, we should probably remove these features altogether, and simply
ignore invalid Unicode code points.
2024-04-09 00:46:16 +02:00
Johannes Altmanninger
a583fe7230 "commandline -f foo" to skip queue and execute immediately
Commit c3cd68dda (Process shell commands from bindings like regular char
events, 2024-03-02) mentions a "weird ordering difference".
The issue is that "commandline -f foo" goes through the input
queue while other commands are executed directly.
For example

    bind ctrl-g "commandline -f end-of-line; commandline -i x"

is executed in the wrong order. Fix that.

This doesn't yet work for "commandline -f exit" but that can be fixed easily.

It's hard to imagine anyone would rely on the existing behavior.  "commandline
-f" in bindings is mostly used for repainting the commandline.
2024-04-09 00:22:41 +02:00
Johannes Altmanninger
9d7116c12d Move readline loop state into reader state
To be used by the next commit.
2024-04-09 00:22:41 +02:00
Johannes Altmanninger
f9bdad3f77 Remove unused function 2024-04-09 00:22:41 +02:00
Johannes Altmanninger
11bd5d7f0c Extract function for handling input event
Will use in a following commit.
2024-04-09 00:22:41 +02:00
Johannes Altmanninger
e934e1b009 Test that bind output can recreate the same bindings 2024-04-09 00:22:41 +02:00
Johannes Altmanninger
f61ef2c63d Display raw escape sequences the old way again
If a binding was input starting with "\e", it's usually a raw control sequence.
Today we display the canonical version like:

    bind --preset alt-\[,1,\;,5,C foo

even if the input is

    bind --preset \e\[1\;5C foo

Make it look like the input again.  This looks more familiar and less
surprising (especially since we canonicalize CSI to "alt-[").

Except that we use the \x01 representation instead of \ca because the
"control" part can be confusing. We're inside an escape sequence so it seems
highly unlikely that an ASCII control character actually comes from the user
holding the control key.

The downside is that this hides the canonical version; it might be surprising
that a raw-escape-sequence binding can be erased using the new syntax and
vice versa.
2024-04-09 00:07:27 +02:00
Johannes Altmanninger
d025b245f6 Fix parsing of single-digit function keys 2024-04-09 00:07:27 +02:00
Johannes Altmanninger
ece4ebaf72 fish_key_reader: show unmapped function key as hex code
We don't yet support all keys from
https://sw.kovidgoyal.net/kitty/keyboard-protocol/#functional-key-definitions
Instead of displaying a private-use character, show the character code;
this can be used to map the key even if we don't know a name for it.

    bind \uE011 'echo print screen'
    bind ctrl-\uE011 'echo do control + print screen'

Note that it's also possible to mape the raw CSI u sequence, like

    bind \e\[57361u 'echo print screen'

but we should not encourage that syntax because it does not allow adding
the modifiers like ctrl.

Of course leaking the PUA character code is not ideal.
2024-04-08 09:16:55 +02:00
Johannes Altmanninger
1c41bcd1a4 fish_key_reader: minimize logic following recent changes 2024-04-08 09:16:22 +02:00
Johannes Altmanninger
405c9c6aaf Remove unused import 2024-04-08 09:16:22 +02:00
Johannes Altmanninger
d30fab372f Pop CSI u mode on SIGTERM
As implied by the changelog.

Unfortunately it's not obvious how to access the RefCell value in spite
of a potential (albeit unlikely) present mutable borrow. We need to use a
different type to make it work in such cases, hopefully doing that in future.

In future we could even use panic=abort and use this style of cleanup for
panics (instead of RAII).
2024-04-07 13:32:48 +02:00
Johannes Altmanninger
1696b1527a builtin commandline: remove redundant function calls 2024-04-07 13:32:48 +02:00
Johannes Altmanninger
e0bbeb647b Remove unused function 2024-04-07 12:59:16 +02:00
Johannes Altmanninger
866585c6ce Fix accidental truncation of raw sequences
For numpad 1 with nulock, Alacritty sends

    escape,[,5,7,4,0,0,u

which is codepoint \x31, key "1".  We have a terminfo mapping for "sright"
which translates to

    escape,[,1,;,2,C

The first two characters, escape and [ match. Then we accidentally match the
"1" from the mapping against the entire sequence, because that sequence is
canonicalized to codepoint "1" . The most blatant problem is that we discard
the rest of the sequence. Fix that.

This allows us to re-enable raw CSI u mappings like "bind \e[1u ..."
which is what kitty uses for shell integration.
2024-04-07 09:59:28 +02:00
Johannes Altmanninger
b97187c90b Fix crash displaying CSI u codepoints in ASCII control range 2024-04-07 09:59:09 +02:00
Johannes Altmanninger
c8f3659737 Add special_key=1 to prompt marking
Kitty uses this for more graceful mouse handling
when the completion pager is active, see
https://github.com/kovidgoyal/kitty/pull/7316#issuecomment-2041279797
2024-04-07 09:59:09 +02:00
Johannes Altmanninger
3b9e3e251b Emit OSC 133 sequences to mark prompt/command output regions
This allows terminals like foot and kitty to
* scroll to the previous/next prompt with ctrl-shift-{z,x}
* pipe the last command's output to a pager with ctrl-shift-g

Kitty has existing fish shell integration
shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish which we
can simplify now. They keep a state variable to decide which of prompt start,
command start or command end to output.  I think with our implementation
this is no longer necessary, at least I couldn't reproduce any difference.
We also don't need to hook into fish_cancel or fish_posterror like they do;
only in the one place where we actually draw the prompt.

As mentioned in the above shell integration script, kitty disables reflow
when it sees an OSC 133 marker, so we need to do it ourselves,
otherwise the prompt will go blank after a terminal resize.

Closes #10352
2024-04-06 22:22:56 +02:00
Johannes Altmanninger
8a7c3ceec3 Don't abandon line after writing control sequences
Commit 8164855b7 (Disable terminal protocols throughout evaluation, 2024-04-02)
changed where we output control sequences (to enable bracketed paste and CSI).
Likewise, f285e85b0 (Enable focus reporting only just before reading from
stdin, 2024-04-06) added control sequence output just before we read().

This output causes problems because it invalidates our stdout/stderr
timestamps, which causes us to think that a rogue background process wrote
to the terminal; we react by abandoning the current line and redrawing the
prompt below. Our fix was to refresh the TTY timestamps after we run a bind
command that might add stdout (#3481).

Since commit c3cd68dda (Process shell commands from bindings like regular
char events, 2024-03-02), this timestamp refresh logic is in the wrong place;
shell commands are run later now; we could move it but wait -

... we also need to make sure to refresh timestamps after outputting control
sequences.  Since bracketed paste is enabled after CSI u, we can skip the
latter.  Additionally, since we currently output control sequences before
every single top-level interactive command, we no longer need to separately
refresh timestamps in between commands.

Fixes #10409
2024-04-06 17:45:55 +02:00
Johannes Altmanninger
de730b7885 Extract function for running commands from bindings 2024-04-06 17:45:55 +02:00
Johannes Altmanninger
f285e85b0c Enable focus reporting only just before reading from stdin
Some terminals send the focus-in sequences ("^[I") whenever focus reporting is
enabled.  We enable focus reporting whenever we are finished running a command.
If we run two commands without reading in between, the focus sequences
will show up on the terminal.

Fix this by enabling focus-reporting as late as possible.

This fixes the problem with `^[I` showing up when running "cat" in
gnome-terminal https://github.com/fish-shell/fish-shell/issues/10411.

This begs the question if we should do the same for CSI u and bracketed paste.
It's difficult to answer that; let's hope we find motivating test cases.
If we enable CSI u too late, we might misinterpret key presses, so for now
we still enable those as early as possible.

Also, since we now read immediately after enabling focus events, we can get
rid of the hack where we defer enabling them until after the first prompt.
When I start a fresh terminal, the ^[I no longer shows up.
2024-04-06 11:22:19 +02:00
Johannes Altmanninger
7ffe023735 builtin read: enable terminal protocols again
It's not clear whether builtin read should be able to do everything
that the normal prompt does but I guess we haven't found a problem yet.
Given that read could be used to read a single character at a type,
it's a bit odd to toggle terminal protocols all the time.
But that's not the typical case (at least not for when stdin is a TTY),
and it seems fine.

Teste with

    bind ctrl-4 'echo yay'

Regressed in 8164855b7 (Disable terminal protocols throughout evaluation,
2024-04-02).
2024-04-06 11:22:19 +02:00
Johannes Altmanninger
629cad66a3 Clean up log statement 2024-04-06 11:22:19 +02:00
Fabian Boehm
ce92472af1 input: Comment out flogs
These are *extremely* chatty.

If they are needed we should add them to a subcategory like `input` or
`reader-input` so you can easily disable them.
2024-04-03 20:15:17 +02:00
Fabian Boehm
1f2e0617d1 tests: Pass correct length for buffer
This allocated 64 bytes and then told snprinf it was 128. That's a
no-no even if we never need that much.
2024-04-03 20:15:17 +02:00
Johannes Altmanninger
66c6e89f98 Don't add collateral sentinel key to input queue
This is for bracketed paste and focus reporting where we already add a proper
event to the queue.
2024-04-03 20:02:08 +02:00
Johannes Altmanninger
1baa893e60 Don't end history search on focus in/out events
Apparently VTE terminals send the "focus in" event whenever we re-enable
focus reporting. That's probably a sensible thing to do.

Anyway, our problem is simply that we accidentally end history search on these
focus events which are implemented as anonymous (unmappable) readline cmds.
Perhaps there should be a separate cmd category.

Focus events show up as key::Invalid which is a weird private use code point;
probably we can get rid of this key..

Fixes #10411
2024-04-03 20:02:08 +02:00
Johannes Altmanninger
350598cb99 Decode arrow keys as sent by urxvt
Not sure if we want to support this indefinitely but appears to be free as
of today.
2024-04-03 19:37:03 +02:00
Fabian Boehm
e8eb4822ce input: Fix crash for weird bracketed paste
I can reproduce by pasting after

```fish
echo \cc foo | fish_clipboard_copy
```

in Wezterm
2024-04-03 16:30:38 +02:00
Johannes Altmanninger
af1b599818 On redo, restore pre-undo cursor position 2024-04-03 13:09:27 +02:00
Fabian Boehm
fe95e4f4cd curses: Remove f13-f20
No longer supported by keys, and these are not a thing in the real world
2024-04-02 21:33:54 +02:00
Johannes Altmanninger
8164855b70 Disable terminal protocols throughout evaluation
Test changes are very hacky, will cleanup later.

Closes #10408
2024-04-02 21:25:47 +02:00
Johannes Altmanninger
695b408396 kitty keyboard protocol: decode numlock keys
Also disable the legacy matching hack for CSI u sequences, to prevent bindings
from treating this as prefix.
2024-04-02 18:20:35 +02:00
Johannes Altmanninger
b04dee358e Don't translate \n to enter
Apparently it's never entere because we turn off ICRNL.

I'm not sure why it says "no binding found".
2024-04-02 17:59:40 +02:00
Johannes Altmanninger
e8e91c97a6 fish_key_reader: ignore sentinel key
Also, move the undo grouping for paste to the right place.
2024-04-02 16:48:25 +02:00
Johannes Altmanninger
8bf8b10f68 Extended & human-friendly keys
See the changelog additions for user-visible changes.

Since we enable/disable terminal protocols whenever we pass terminal ownership,
tests can no longer run in parallel on the same terminal.

For the same reason, readline shortcuts in the gdb REPL will not work anymore.
As a remedy, use gdbserver, or lobby for CSI u support in libreadline.

Add sleep to some tests, otherwise they fall (both in CI and locally).

There are two weird failures on FreeBSD remaining, disable them for now
https://github.com/fish-shell/fish-shell/pull/10359/checks?check_run_id=23330096362

Design and implementation borrows heavily from Kakoune.

In future, we should try to implement more of the kitty progressive
enhancements.

Closes #10359
2024-04-02 14:35:16 +02:00
Johannes Altmanninger
22717339b4 fish_clipboard_paste: don't bypass pager search field.
To do so add an ad-hoc "commandline --search-field" to operate on pager
search field.

This is primarily motivated because a following commit reuses the
fish_clipboard_paste logic for bracketed paste. This avoids a regression.
2024-04-02 14:35:16 +02:00
Johannes Altmanninger
d0cdb142de Make CharEvent a native enum 2024-04-02 14:35:16 +02:00
Johannes Altmanninger
aa40c3fb7e Remove set-mode char event
Use generic shell commands instead.  This keeps us honest.

No functional change expected.
2024-04-02 14:35:16 +02:00
Johannes Altmanninger
20bbdb68fa Set terminal title unconditionally
Terminal titles are set with an OSC 0 sequence.  I don't think we want to
support terminals that react badly to unknown OSC (or CSI) sequences.

So let's remove our feature detection.

This will fix future false negatives along the lines of
https://github.com/fish-shell/fish-shell/pull/10037
2024-04-02 14:35:16 +02:00
Johannes Altmanninger
a216b3cf6a Print panic message to stderr, like the stack trace 2024-04-02 07:34:19 +02:00
Johannes Altmanninger
1232cfd3bb Fix typo 2024-04-02 07:33:07 +02:00
Johannes Altmanninger
af6dc9221f Use panic::set_hook instead of catch_unwind to help debug panics 2024-04-02 07:27:22 +02:00
Mahmoud Al-Qudsi
41eaf2f8dc
Merge pull request #10398 from mqudsi/forward-char-passive
Add `forward-char-passive` and `backward-char-passive`
2024-03-30 22:29:46 -05:00
Johannes Altmanninger
a29cc8f169 Fix regression when selection start is deleted
Ranges with start > end are invalid; we crash with "slice index starts at
10 but ends at 0".
2024-03-30 09:56:48 +01:00
Mahmoud Al-Qudsi
1adbec2d37 Add backward-char-passive 2024-03-29 14:23:51 -05:00
Mahmoud Al-Qudsi
df09ab598f Add forward-char-passive binding
This binding is akin to ForwardSingleChar but it is "passive" in that is not
intended to affect the meta state of the shell: autocompletions are not accepted
if the cursor is at the end of input and it does not have any effect in the
completions pager.
2024-03-28 00:13:34 -05:00
Fabian Boehm
217b009e18
abbr: expand command abbrs after decorators (#10396)
Currently, we expand command-abbrs (those with `--position command`) after `if`, but not after `command` or `builtin` or `time`:

```fish
abbr --add gc "git checkout"
```

will expand as `if gc` but not as `command gc`.

This was explicitly tested, but I have no idea why it shouldn't be?
2024-03-27 17:17:55 +01:00
Mahmoud Al-Qudsi
326d986186 Fix broken read_ni() not making fd non-blocking on Linux
The incorrect order of operations was being used since && binds tighter than ||
in rust (as with most sane languages).

Under Linux, EAGAIN == EWOULDBLOCK so this would always succeed in the case of a
non-blocking fd without making the call to make_fd_nonblocking().

Comparing to the 3.7.0 C++ code, it looks like this was an oversight introduced
in the migration to rust.
2024-03-26 01:06:42 -05:00
Johannes Altmanninger
6efe0907e9 Fix --debug-output regression
We accidentally close FLOG output file.  Let's leak it for now; in future
we should close it.
2024-03-25 20:56:08 +01:00
Johannes Altmanninger
5b324f8ecb Fix regression in parse_util_process_extent
Found on a two-line commandline

    for file in (path base<TAB>
    echo
2024-03-24 16:34:36 +01:00
Johannes Altmanninger
1216801474 Use RAII for restoring term modes
In particular, this allows restoring the terminal on crashes, which is
feasible now that we have the panic handler.  Since std::process::exit() skips
destructors, we need to reshuffle some code.  The "exit_without_destructors"
semantics (which std::process::exit() als has) was mostly necessary for C++
since Rust leaks global variables by default.
2024-03-24 16:34:36 +01:00
Johannes Altmanninger
3cfa09d1bd Make test_init() return a scope guard
To be used in the next commit.
2024-03-24 16:33:35 +01:00
Johannes Altmanninger
ecdc9ce1dd Install a panic handler to avoid dropping crash stacktraces
When fish crashes due to a panic, the terminal window is closed.  Some
terminals keep the window around when the crash is due to a fatal signal,
but today we don't exit via fatal signal on panic.

There is the option to set «panic = "abort"» in Cargo.toml, which
would give us coredumps but also worse stacktraces on stderr.
More importantly it means that we don't unwind, so destructors are skipped
I don't think we want that because we should use destructors to
restore the terminal state.

On crash in interactive fish, read one more line before exiting, so the
stack trace is always visible.

In future, we should move this "read one line before exiting" logic to where
we call "panic!", so I can attach a debugger and see the stacktrace.
2024-03-24 13:36:59 +01:00
Johannes Altmanninger
5c5ab4f179 Move termsize test into separate file 2024-03-24 12:18:20 +01:00
Johannes Altmanninger
99ffa4567a Remove unused import 2024-03-24 12:18:20 +01:00
Johannes Altmanninger
c209e6b5fb Fix clippy lint 2024-03-23 14:26:08 +01:00
Johannes Altmanninger
d51f669647 Vi mode: avoid placing cursor beyond last character
Today fish_cursor_selection_mode controls whether selection mode includes
the cursor. Since it's by default only used for Vi mode, perhaps use it to
also decide whether it should be allowed to select one-past the last character.

Not allowing to select to select one-past the last character is much nicer
in Vi mode.  Unfortunately Vi mode sometimes needs to temporarily select
past end (using forward-single-char and such), so reset fish_cursor_selection_mode
for the duration of the binding.

Also fix other things like cursor placement after yank/yank-pop.

Closes #10286
Closes #3299
2024-03-23 14:12:21 +01:00
Johannes Altmanninger
0f758f12b7 environment.rs: minor cleanup 2024-03-23 10:38:28 +01:00
Johannes Altmanninger
c3cd68dda5 Process shell commands from bindings like regular char events
A long standing issue is that bindings cannot mix special input functions
and shell commands. For example,

    bind x end-of-line "commandline -i x"

silently does nothing. Instead we have to do lift everything to shell commands

    bind x "commandline -f end-of-line; commandline -i x"

for no good reason.

Additionally, there is a weird ordering difference between special input
functions and shell commands. Special input functions are pushed into the
the queue whereas shell commands are executed immediately.

This weird ordering means that the above "bind x" still doesn't work as
expected, because "commandline -i" is processed before "end-of-line".

Finally, this is all implemented via weird hack to allow recursive use of
a mutable reference to the reader state.

Fix all of this by processing shell commands the same as both special input
functions and regular chars. Hopefully this doesn't break anything.

Fixes #8186
Fixes #10360
Closes #9398
2024-03-23 10:06:11 +01:00
Johannes Altmanninger
232483d89a History pager to only operate on the line at cursor
Multiline search strings are weirdly broken (inserting control characters
in the command line) and probably not very useful anyway.
On the other hand I often want to compose a multi-line command
from single-line commands I ran previously.

Let's support this case by limiting the initial search string to the current
line; and replace only that line.

Alternatively this could operate on jobs (that is, replace a surrounding
"foo | bar") instead of using line boundaries.
2024-03-23 09:54:18 +01:00
Mahmoud Al-Qudsi
0ca199ef98 Change wopen_cloexec() to return File 2024-03-23 01:34:23 -05:00
Mahmoud Al-Qudsi
8d9d4ce1f9 Add and use separate open_dir() method
This is resistant to misuse by including O_DIRECTORY in the open flags and it is
a separate function from {w,}open_cloexec() in preparation for making that one
return a `File` instead of an `OwnedFd`.
2024-03-23 01:15:43 -05:00
Mahmoud Al-Qudsi
99c9d6eef6 IoFile: Wrap File instead of OwnedFd 2024-03-23 00:44:27 -05:00
Mahmoud Al-Qudsi
6f9f9ee400 Use bitflags contains() instead of intersects()
`intersects()` is "any of" while `contains()` is "all of" and while it makes no
difference when testing a single bit, I believe `contains()` is less brittle
for future maintenance and updates as its meaning is clearer.

</pedantic>
2024-03-23 00:24:31 -05:00
Mahmoud Al-Qudsi
6ed4d09c93 Switch more to File/BorrowedFd from OwnedFd/RawFd
More work in prep for having wopen_cloexec() return `File` directly.

This eliminates checking for an invalid fd and makes both ownership and
mutability clear (some more operations that involve changes to the underlying
state of the fd now require `&mut File` instead of just a `RawFd`).

Code that clearly does not use non-blocking IO is ported to use
`Write::write_all()` directly instead of our rusty port of the `write_loop()`
function (which handles EAGAIN/EWOULDBLOCK in addition to EINTR, while
`write_all()` only handles the latter).
2024-03-23 00:01:57 -05:00
Mahmoud Al-Qudsi
c0d68084f7 Add AsFd impl for AutoCloseFd
Will be used to remove RawFd usages.
2024-03-22 23:58:12 -05:00
Mahmoud Al-Qudsi
4e50ae34da Add native read_retry() and write_retry() methods
These are equivalent to read_loop() and write_loop() but operate on native Rust
types without libc ffi.
2024-03-22 23:05:56 -05:00
Fabian Boehm
ce62b284b1 test_helper: Give self-signalling a chance to trigger
This abort()ed right after the signal, so it's possible to crash
before the signal is delivered. This could trigger under ASAN on
Github Actions.
2024-03-19 16:41:25 +01:00
Mahmoud Al-Qudsi
decf99f71b
Use File instead of OwnedFd in a few places (#10355)
This is a step towards converting `wopen_cloexec()` to return `File` instead of
`OwnedFd`/`AutocloseFd`.¹

In addition to letting us use native standard library functions instead of
unsafe libc calls, we gain additional semantic safety because `File` operations
that manipulate the state of the fd (e.g. `File::seek()`) require a `&mut`
reference to the `File`, whereas using `RawFd` or `OwnedFd` everywhere leaves us
in a position where it's not clear whether or not other references to the same
fd will manipulate its underlying state.

¹ We actually wouldn't even need `wopen_cloexec()` at all (just a widechar
wrapper) as Rust's native `File::open()`/`File::create()` functionality uses
`FD_CLOEXEC` internally.
2024-03-17 11:20:44 -05:00
Johannes Altmanninger
2972407b9e builtin read: minor code cleanup 2024-03-16 10:31:01 +01:00
The0x539
b8d1dc93d6 ast: Replace can_parse with static dispatch 2024-03-16 08:39:27 +01:00
Andrew Neth
08220c2189
builtin/test: refactor the Token enum to be more granular (#10357)
* builtin/test: Split Token enum into 2-level hierarchy

* builtin/test: Rearrange the Token enum hierarchy

* builtin/test: Separate Token into Unary and Binary

* builtin/test: import IsOkAnd polyfill

* builtin/test: Rename enum variants one more time
2024-03-15 23:24:44 -05:00
Fabian Boehm
a64a50db47 reader: Use our isatty overload
Removes an annoying use of unsafe
2024-03-10 20:47:26 +01:00
Fabian Boehm
ffc4372cad History: Change an assert into return None
I was able to trigger this by flipping around the history pager.

Since the only applicable caller here already stops if it gets None,
just don't assert.
2024-03-10 16:55:43 +01:00
Fabian Boehm
074b96640d pager: Make search text translatable 2024-03-10 16:38:05 +01:00
Fabian Boehm
00c68145b8 fmt
I still hate this
2024-03-10 16:17:40 +01:00
Fabian Boehm
25e170141c Fix some translated strings 2024-03-10 16:15:15 +01:00
Mahmoud Al-Qudsi
3f6b009870 Only update env_universal self.last_read_file on success
I don't think the existing logic is correct, as the comment says, our internal
state is only matched if we *actually* wrote out the file. But if we ran into an
error, it doesn't match, does it?
2024-03-10 09:49:54 +01:00
Johannes Altmanninger
94477f3029 Fix commandline -C regression handling negative offsets 2024-03-10 09:46:16 +01:00
Fabian Boehm
947883c842 commandline: Fix setting cursor
Fixes #10358
2024-03-10 09:27:56 +01:00
Mahmoud Al-Qudsi
7c173c4b45 Fix formatting of new test 2024-03-09 22:06:33 -06:00
Mahmoud Al-Qudsi
4e95a3713e Add test asserting stdlib uses O_CLOEXEC 2024-03-09 22:05:23 -06:00
Bartłomiej Maryńczak
d5cde80447
Use Result for write_to_fd return value (#10308) 2024-03-09 21:29:50 -06:00
Mahmoud Al-Qudsi
e6687dc61f Make open_temporary_file() fallible again
I was under the apparently mistaken impression that `FLOG!(error, ...)`
triggered an abort when I committed 58a6eb6e45.
2024-03-09 21:21:29 -06:00
Mahmoud Al-Qudsi
6d30363090 Simplify control flow in env_universal_common::save() 2024-03-09 15:21:47 -06:00
Mahmoud Al-Qudsi
58a6eb6e45 Convert fish_mkstemp_cloexec() to return an OwnedFd 2024-03-09 15:21:47 -06:00
The0x539
cfe9881eaa Suppress unknown_lints lint
This is to prevent stable from complaining about nightly-only lints.

Closes #10354
2024-03-09 13:49:25 +01:00
The0x539
6c0381c335 Suppress assigning_clones and incompatible_msrv
The incompatible_msrv one is a false positive because we have polyfills for
is_some_and() and is_ok_or() which are Rust 1.74. I'm not yet sure how to
communicate that to Clippy.
2024-03-09 13:49:25 +01:00
The0x539
4296c49a06 Remove unnecessary scoped #[allow] attributes 2024-03-09 13:49:25 +01:00
The0x539
4c3e814a50 Address clippy lints 2024-03-09 13:49:25 +01:00
Fabian Boehm
b03e727531 Remove unnecessary formatting 2024-03-09 12:06:24 +01:00
Fabian Boehm
f7cc1743c6
Allow deciding if a command should be saved to history (#10302)
Call fish_should_add_to_history to see if a command should be saved

If it returns 0, it will be saved, if it returns anything else, it
will be ephemeral.

It gets the right-trimmed text as the argument.

If it doesn't exist, we do the historical behavior of checking for a
leading space.

That means you can now turn that off by defining a
`fish_should_add_to_history` that just doesn't check it.

documentation based on #9298
2024-03-09 12:04:16 +01:00
Fabian Boehm
97e7e730e1 Clean up two awkward wgettext_fmt invocations 2024-03-09 11:48:29 +01:00
The0x539
1de7ebcf68 Simplify shared-from-this pattern 2024-03-09 10:09:03 +01:00
Peter Collingbourne
e5f83cd9a7 Fix logic for relocatable directory trees
The existing logic did not work because:

- Path::new("/foo/bar").ends_with("/bar") does not return true.
- PathBuf::shrink_to() only (potentially) reallocates the backing
  storage, and won't have an effect on the stored value.
2024-03-09 09:38:48 +01:00
John
b75e5ee823
remove repetitive words (#10348)
Signed-off-by: hishope <csqiye@126.com>
2024-03-07 18:35:41 -06:00
Mahmoud Al-Qudsi
80133c4bc6
Fix safety issues with some static variables (#10329)
Add safe Send/Sync wrapper for main thread data
2024-03-05 12:33:13 -06:00
Fabian Boehm
031dbb33b1 commandline: Borrow libdata later
builtin_print_help will end up borrowing it as mutable.

Fixes #10342
2024-03-04 16:53:51 +01:00
ridiculousfish
ff6fd699fe Fix a warning about an unused import on macOS 2024-03-03 14:12:59 -08:00
Johannes Altmanninger
33a7172ee8 Revert to not inserting control characters from keyboard input
As mentioned in the comment the historical behavior is because pressing unknown
control characters like Ctrl+4 inserts confusing characters, so let's back
out that part of b77d1d0e2 (Stop crashing on invalid Unicode input, 2024-02-27).

We still have the code for rendering control characters, for pasted text,
or text recalled from history. It is unclear whether we should strip those.
Some terminals already strip control characters from pasted text -- but not
all of them: see https://codeberg.org/dnkl/foot/pulls/312 for example which
has a follow up called "Don't strip HT when pasting in non-bracketed mode".
2024-03-02 23:31:08 +01:00
Fabian Boehm
2a4e776d92 Reimplement git version generation ourselves
This allows us to remove two dependency crates
2024-03-02 10:05:37 +01:00
Mahmoud Al-Qudsi
1ac17756c2 Also address safety issues with principal_parser() 2024-03-01 19:54:28 -06:00
Mahmoud Al-Qudsi
2ecbc56de9 Change MainThread<T> abstraction
Don't force the internal use of `RefCell<T>`, let the caller place that into
`MainThread<>` manually. This lets us remove the reference to `MainThread<>`
from the definition of `Screen` again and reduces the number of
`assert_is_main_thread()` calls.
2024-03-01 19:42:43 -06:00
Mahmoud Al-Qudsi
5c94ebd095 Fix output::stdoutput() safety issues
Fairly straightforward, with the only unfortunate part of this being that
`Screen` isn't as pure and now encodes the facte that we use it with
main-thread-only stdout `Outputter`.
2024-02-29 11:29:37 -06:00
Mahmoud Al-Qudsi
f67ce2ac4b Add Sync/Send wrapper for main-thread-only data 2024-02-28 13:06:04 -06:00
Fabian Boehm
29af775390 abbr: Box the regex
The regex struct is pretty large at 560 bytes, with the entire
Abbreviation being 664 bytes.

If it's an "Option<Regex>", any abbr gets to pay the price. Boxing it
means abbrs without a regex are over 500 bytes smaller.
2024-02-28 18:48:24 +01:00
Fabian Boehm
3d1e8a6106 pager: Simplify some code 2024-02-28 18:34:57 +01:00
Fabian Boehm
31c2eb3f3c pager: Use selected color for parentheses if applicable
This always used pager_completion even for the selected one, now it
uses pager_selected_completion for that.

Fixes #10328
2024-02-28 18:14:05 +01:00
Fabian Boehm
5641ae71b8 ast: Box a large enum variant
IfStatement is 680 bytes, much larger than the other
variants (SwitchStatement is next at 232). An enum is as large as its
largest variant, so this saves a bunch, especially since
DecoratedStatement is much more likely than IfStatement.

This will speed up the no-execute benchmark by 1.07x.
2024-02-28 18:14:05 +01:00
Mahmoud Al-Qudsi
e7b94454df Add unsafety warnings
See https://github.com/rust-lang/rust/issues/114447
2024-02-28 10:09:53 -06:00
Mahmoud Al-Qudsi
5eb6b22fa4 Allow unused fns in ConcreteNodeMut 2024-02-28 09:44:11 -06:00
Mahmoud Al-Qudsi
50ff6b8a34 Remove using statements already imported by preludes 2024-02-28 09:41:51 -06:00
Johannes Altmanninger
b77d1d0e2b Stop crashing on invalid Unicode input
Unlike C++, Rust requires "char" to be a valid Unicode code point.  As a
workaround, we take the raw (probably UTF-8-encoded) input and convert each
input byte to a char representation from the private use area (see commit
3b15e995e (str2wcs: encode invalid Unicode characters in the private use
area, 2023-04-01)).  We convert back whenever we output the string, which
is correct as long as the encoding didn't change since the data was input.

We also need to convert keyboard input; do that.

Quick testing shows that our reader drops PUA characters.  Since this patch
converts both invalid Unicode input as well as PUA input into a safe PUA
representation, there's no longer a reason to not add PUA characters to
the commandline, so let's do that to restore traditional behavior.

Render them as � (REPLACEMENT CHARACTER); unfortunately we show one per
input byte instead of one per code point. To fix this we probably need our
own char type.

While at it, remove some special cases that try to prevent insertion of
control characters. I don't think they are necessary. Could be wrong..
2024-02-27 22:59:49 +01:00
Fabian Boehm
f93a3e9e9b fish_indent: Collapse successive newlines
This makes it so code like

```fish
echo foo

echo bar
```

is collapsed into

```fish
echo foo

echo bar
```

One empty line is allowed, more is overkill.

We could also allow more than one for e.g. function endings.
2024-02-27 16:25:01 +01:00
Fabian Boehm
da6a9bad5f Add additional paths for NetBSD and Nix
These seems weird to add upstream, and we might want to read
more here.
2024-02-22 20:10:16 +01:00
Fabian Boehm
785d784482 Make term warning less shouty
We don't need to know that it tried these five before finally getting
one, the list is *right there*.

It is also very unlikely that someone has "xterm" or "ansi" but not "xterm-256color"

For xterm-256color, we don't warn *at all* because we have that one hardcoded.
2024-02-22 20:10:16 +01:00
Fabian Boehm
75f7cda6ab Add xterm-256color fallback
And use it if $TERM is xterm-256color and could not be found, *without* warning.

These barely change, especially in the parts we use.
2024-02-22 20:10:16 +01:00
Fabian Boehm
8c86336109 Remove useless use of cstring 2024-02-22 20:10:16 +01:00
Fabian Boehm
57317fdaf2 Remove now unused assert helpers 2024-02-22 20:10:16 +01:00
Fabian Boehm
fc794bab4c Switch to the terminfo crate
This allows us to get the terminfo information without linking against curses.

That means we can get by without a bunch of awkward C-API trickery.

There is no global "cur_term" kept by a library for us that we need to invalidate.

Note that it still requires a "unhashed terminfo database", and I don't know how well it handles termcap.

I am not actually sure if there are systems that *can't* have terminfo, everything I looked at
has the ncurses terminfo available to install at least.
2024-02-22 20:10:16 +01:00
Fabian Boehm
b7cc7db93c fish_key_reader: Remove unnecessary parser
I have no idea what this would be used for, it's instantiated, we set
is_interactive, and then we never use it.
2024-02-20 16:55:32 +01:00
Fabian Boehm
9a2729d298 Fix builtin read crash with negative nchars
Also make it simpler by just passing it along as a usize
2024-02-19 18:48:21 +01:00
Johannes Altmanninger
b687ef036b Fix regression of C-e always accepting autosuggestion 2024-02-17 01:34:32 +01:00
Fabian Boehm
0d9c737a47 builtins/history: Remove unnecessary unwrap 2024-02-16 19:40:42 +01:00
Fabian Boehm
46afbea72b exec: Pass some cstrs as cstr instead of converting to ptr and back 2024-02-16 19:40:41 +01:00
Fabian Boehm
7e8a4dbe5c highlight: Stop copying pending variables 2024-02-16 19:40:41 +01:00
Fabian Boehm
1160bf84ed input: Resolve a TODO 2024-02-16 19:40:39 +01:00
Fabian Boehm
035948eb2f Correct and shorten a comment
There is no more "input.cpp"
2024-02-16 19:11:45 +01:00
Fabian Boehm
9ff02d6a7f Fix crash in the history pager
Delete the last shown entry and it'll subtract with overflow
2024-02-16 18:22:37 +01:00
Johannes Altmanninger
2915c525fa Revert "history: Skip lines with tabs when importing from bash"
We still don't support tabs but as of the parent commit, there are no more
weird glitches, so it should be fine to recall those lines?

This reverts commit cc0e366037.
2024-02-15 01:39:45 +01:00
Johannes Altmanninger
0627c9d9af Render control characters as Unicode Control Pictures
Inserting Tab or Backspace characters causes weird glitches. Sometimes it's
useful to paste tabs as part of a code block.

Render tabs as "␉" and so on for other ASCII control characters, see
https://unicode-table.com/en/blocks/control-pictures/. This fixes the
width-related glitches.

You can see it in action by inserting some control characters into the
command line:

	set chars
	for x in (seq 1 0x1F)
		set -a chars (printf "%02x\\\\x%02x" $x $x)
	end
	eval set chars $chars
	commandline -i "echo '" $chars

Fixes #6923
Fixes #5274
Closes #7295

We could extend this approach to display a fallback symbol for every unknown
nonprintable character, not just ASCII control characters.

In future we might want to support tab properly.
2024-02-15 01:39:45 +01:00
Johannes Altmanninger
d3b700f98c Promote debug-only assertion 2024-02-15 01:27:23 +01:00
Johannes Altmanninger
a1ed63fd83 Make wcwidth an isize
Seems more consistent with the rest of our code.
2024-02-15 01:27:23 +01:00
Johannes Altmanninger
8545b5debe Remove obsolete no_mangle directives 2024-02-15 01:22:37 +01:00
Johannes Altmanninger
4cb766324b Fix regression in forward-single-char
This crashes if the autosuggesion is exhausted.  C++ used

    autosuggestion.text.substr(pos, 1)

which throws if pos is OOB but not if pos + 1 is.
2024-02-14 10:52:38 +01:00
ridiculousfish
e1d539c7b6 Stop using errno for input_terminfo_get_sequence errors
Use a real error type. Fixes a TODO and cleans up the code.
2024-02-11 15:03:27 -08:00
ridiculousfish
5021639db1 Correct some comments and duplicative error messages
If we fail to create a pipe, we will report that fact in multiple places; remove
some redundant error reporting.
2024-02-11 12:16:58 -08:00
PolyMeilex
b9ba9e57e8 Use nix & Results 2024-02-11 11:40:27 -08:00
PolyMeilex
971d774e67 Use OwnedFd in AutoClosePipes 2024-02-11 11:40:27 -08:00
David Adam
7dfe6f2c07 common.rs: drop unused PACKAGE_BUGREPORT constant 2024-02-11 21:06:37 +08:00
Himadri Bhattacharjee
4e6e897781
string repeat: allow omission of -n (#10282) 2024-02-11 12:19:02 +01:00
Fabian Boehm
662fde7b71 Error out when share/config.fish can't be read
This file contains important configuration, so if we can't get it
something is broken.

We don't *exit*, but we will stop reading configuration.
2024-02-10 20:54:22 +01:00
Fabian Boehm
ed59cbe536 ast: Only reserve 16 nodes for each list
This reserved 64, which is *gigantic*.

Over all of share/**.fish, 75% of lists are empty, 99.97% are 16
elements or fewer.

Reducing this to 16 reduces memory usage for a gigantic example
script (git.fish pasted a bunch of times for a total of almost 100k
lines) by ~10% and speeds up "--no-execute" time by the same amount.

For smaller scripts it's less noticeable simply because parse time
matters less.

There are other options, like creating the vec ::with_capacity, or
using 8 instead of 16, or even letting the vec just grow
naturally (rust's vec currently grows from 0 to 4 and then doubles,
which isn't terrible for this use), but the point is that 64 is
wasteful and never comes out on top, always in the last two places
comparing a bunch of choices.
2024-02-10 11:33:32 +01:00
Simon Börjesson
7768952749 Reset scroll position when clearing pager
Closes #10288
2024-02-07 02:57:34 +01:00
Simon Börjesson
d51ecb7fb3 Scroll down to reveal the selected item after expanding pager 2024-02-07 02:57:19 +01:00
Johannes Altmanninger
0c5a616113 Show autosuggestion again after undoing deletion
Commit e5b34d5cd (Suppress autosuggesting during backspacing like browsers do,
2012-02-06) disabled autosuggestion when backspacing.  Autosuggestions are
re-enabled whenever we insert anything in the command line.  Undo uses a
different code path to insert into the command line, which does not re-enable
autosuggestion.

Fix that.

Also re-enable autosuggestion when undo erases from the command line.
This seems like the simplest approach. It's not clear if there's a better
behavior; browsers don't agree on one in any case.
2024-02-07 00:07:47 +01:00