Commit Graph

5076 Commits

Author SHA1 Message Date
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