Commit Graph

175 Commits

Author SHA1 Message Date
Aaron Gyes
99cfca8498 input.cpp: remove unused describe_char() 2022-04-08 17:59:09 -07:00
ridiculousfish
1bdd629326 Prevent signals from tearing multi-char bindings
Say the user has a multi-char binding (typically an escape sequence), and a
signal arrives partway through the binding. The signal has an event handler
which enques some readline event, for example, `repaint`. Prior to this
change, the readline event would cause the multi-char binding to fail. This
would cause bits of the escape sequence to be printed to the screen.

Fix this by noticing when a sequence was "interrupted" by a non-char event,
and then rotating a sequence of such interruptions to the front of the
queue.

Fixes #8628
2022-02-05 13:18:36 -08:00
ridiculousfish
8a4ed096ed Stop passing check_exit events to match key bindings
check_exit events are generated to give the reader a chance to respond to
commands, or otherwise to return control to the reader loop. Prior to this
change they were being passed to match key bindings. This is useless since
no key binding can match a check_exit event. FLOG noisily complains about
unmatched events. So just don't pass these to mapping_execute.
2022-02-05 13:17:45 -08:00
Andrey Mishchenko
fb73a4b2e2 Implement nextd-or-forward-word and prevd-or-backward-word in C++ 2021-12-11 10:19:18 +01:00
Fabian Homborg
aa470e12b2 Defer escape bindings as well
This allows rebinding escape in the user list without breaking e.g.
arrow keys (which send escape and then `[A` and similar, so escape is
a prefix of them).

Fixes #8428.
2021-11-10 20:40:21 +01:00
ridiculousfish
f577c221eb Introduce get_by_sorted_name
Given that we have several lists of things sorted by name, replace a
bunch of ad-hoc lower_bound calls with a single function.
2021-08-26 13:40:37 -07:00
Rosen Penev
ba91b39715 replace push_back with emplate_back
The latter forwards the arguments directly.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-17 18:56:19 -05:00
ridiculousfish
fdf8f17397 Stop using thread local vectors
These don't build on macOS 10.9, and are unnecessary anyways.
Thread local variables should only be simple primitives.
2021-08-10 13:07:13 -07:00
ridiculousfish
f345464879 Simplify ASSERT_SORT_ORDER
In practice this only looked at the name property, so we can simplify it
by using an ordinary template function instead of a macro.
2021-07-15 13:15:24 -07:00
ridiculousfish
8bed818039 Remove some main thread assertions that are not helping
This is to make experimenting with concurrent execution easier.
No functional change in this commit.
2021-07-15 10:49:27 -07:00
ridiculousfish
179073ce62 Clear the control-C cancel flag earlier, allowing event handlers to run
When the user presses control-C, fish marks a cancellation signal which
prevents fish script from running, allowing it to properly unwind.
Prior to this commit, the signal was cleared in the reader. However this
missed the case where a binding would set $fish_bind_mode which would
trigger event handlers: the event handlers would be skipped because of
the cancellation flag was still set. This is similar to #6937.

Let's clear the flag earlier, as soon as we it's set, in inputter_t.
Fixes #8125.
2021-07-11 18:04:44 -07:00
ridiculousfish
0a559ac457 Reformat source files with clang-format 2021-04-21 13:31:58 -07:00
ridiculousfish
7c153a8307 Introduce prepare_to_select, fixing job_summary.py
This concerns printing status messages for background jobs which have
stopped or finished. Previously fish would do this from two places:

1. Before running a command (including empty string)
2. If a signal is received during select()

So if the job finishes while fish is doing something else (like running an
event handler) then we would not print status messages until the user hit
return. This caused the job_summary.py test to be flaky.

Fix this by splitting the interrupt handler into two parts: a part that
handles signals (e.g. triggering exit from the reader), and a part that
always runs just before blocking in select(). This second part always
reaps jobs and prints their status messages. This narrows the window for a
job exit to be "missed" before fish blocks in select, and should make the
job_summary.py test more reliable.
2021-04-17 16:43:28 -07:00
ridiculousfish
3684c91ad2 Make input_event_queue_t a base class
This concerns the problem of "injecting" fancy fish bits like job reaping
into the "common" input stuff which is also used by fish_key_reader.
Instead of providing a callback, make the input event queue a base class
with virtual functions. This allows for a richer interface and simplifies
some memory management issues.
2021-04-17 16:43:28 -07:00
ridiculousfish
939aba02de Refactor input_common.cpp:readb
readb is used to read a single byte from stdin, or maybe update universal
variables, or maybe invoke completion handlers, etc. Previously it
returned char_event_t but this is more complex than necessary; instead we
can just have it return a single byte, or one of a few special error
codes. This makes the readb's role more clear.
2021-04-17 16:43:28 -07:00
ridiculousfish
78147abe8a Switch the interrupt handler from a global to an instance variable
"The" interrupt handler is used when we get a signal while waiting at the
prompt. Switch it from a global function pointer to an std::function. This
is a mild refactoring which itself will be replaced soon.
2021-04-17 16:43:28 -07:00
ridiculousfish
060ce4f7da Remove timeout input events
Now that timeouts are stored in the event queue peeker, we can remove the
notion of timeout events altogether. Instead you may ask for an event with
a timeout, and get back none on timeout. This simplifies how input events
work.
2021-04-17 16:43:28 -07:00
ridiculousfish
bd72791340 Use event_queue_peeker_t when matching key bindings
Previously, when attempting to match a key binding, we would dequeue
events from the queue and put them back on if the binding fails. The
tricky part is timeouts: distinguishing between an escaped character and
the escape key itself. This was handled with "timeout events" and we had
to be careful to know when to discard them.

Switch to a new model: use event_queue_peeker more pervasively.
Temporarily dequeued events are stored in the peeker, and the peeker
itself remembers when it has seen a timeout. This is in preparation for
removing the idea of "timeout events" altogether.
2021-04-17 16:43:27 -07:00
ridiculousfish
c570a14c04 Simplify event_queue_peeker_t
Make it an ordinary struct wrapping a vector, instead of a template.
This is in preparation for using it more widely, for matching bindings
as well as mouse CSI sequences.
Also add some mouse-disabling tests.
2021-04-17 16:43:27 -07:00
Mahmoud Al-Qudsi
774488686c Correct handling of SGR mouse tracking events
They are of variable length, taking semicolon-separated ASCII characters
and not single chars/bytes as the parameters. Additionally, the global
maximum size for a CSI is 16 characters (NPAR), even though I believe
the maximum possible mouse-tracking CSI is 12 characters.
2021-02-17 15:45:35 -06:00
Fabian Homborg
00fabb4fe1 Enhance fallback keybindings a bit
Bind \cc like normal, since we now no longer use a function, and bind
some important control bindings like \cs and the ever-important emacs \cb/f/p/n.

What really kills the usability here is the up-line vs up-or-search.
2021-02-15 20:54:35 +01:00
Mahmoud Al-Qudsi
5fda1e05dc Statically assert the sort order of input_function_metadata_t 2021-02-08 15:16:20 -06:00
Mahmoud Al-Qudsi
2df16b53ff Use thread-local vectors for caching peeked events
These functions are called in the event queue hot path every time an
input event takes place. If we could guarantee a maximum length of
non-char (i.e. readline) events in the queue, we could use
`event_queue_peeker_t` with a fixed storage size of, e.g., 32 events,
but I'm not sure what a reasonable number would in fact be, so I'm just
changing these to use a thread-local vector that will re-use its
previous heap allocation in subsequent invocations rather than thrashing
the heap.
2021-02-08 15:16:20 -06:00
Mahmoud Al-Qudsi
2c1764fd45 Convert more event queue push_front loops to insert_front 2021-02-08 15:16:20 -06:00
Mahmoud Al-Qudsi
5c014e129a Reduce input latency searching for readline function mappings
The lookups are executed on all input events, so they are worth
optimizing.

Cache the list of names, use binary search to get a function code from a
name, and stop enumerating mappings after `has_function` and `has_command`
have been determined.
2021-02-08 15:16:20 -06:00
Fabian Homborg
78358ab351 Make disable_mouse_tracking inaccessible
This isn't something you want to bind, it's only a readline symbol as
a hack, so we shouldn't expose it to the user.
2021-02-07 19:50:56 +01:00
Mahmoud Al-Qudsi
eecc223c51 Recognize and disable mouse-tracking CSI events
Fish was previously oblivious to the existence of mouse-tracking ANSI
escapes; this was mostly OK because they're disabled by default and we
don't enable them, but if a TUI application that turned on mouse
reporting crashed or exited without turning mouse reporting off, fish
would be left in an unusable state as all mouse reporting CSI sequences
would be posted to the prompt.

This can be tested by executing `printf '\x1b[?1003h'` at the prompt,
then clicking with any mouse button anywhere within the terminal window.
Previously, this would have resulted in seeming garbage being spewed to
the prompt; now, fish detects the mouse tracking CSIs posted to stdin by
the terminal emulator and a) ignores them to prevent invalid input, as
well as b) posts the CSI needed to disable future mouse tracking events
from being emitted on subsequent mouse interactions (until re-enabled).

Note that since we respond to a mouse tracking CSI rather than
pre-emptively disable mouse reporting, we do not need to do any sort of
feature detection to determine whether or not the terminal supports
mouse reporting (otherwise, if it didn't support it and we posted the
CSI anyway, we'd end up with exactly the kind of cruft posted to the
prompt that we're trying to avoid).

Fixes #4873
2021-02-06 17:22:59 -06:00
Mahmoud Al-Qudsi
cc392b3774 Add RAII-based event_queue_peeker_t helper
This is a stack-allocating utility class to peek up to N
characters/events out of an `event_queue_t` object. The need for a
hard-coded maximum peek length N at each call site is to avoid any heap
allocation, as this would be called in a hot path on every input event.
2021-02-06 17:18:53 -06:00
Mahmoud Al-Qudsi
c203c88c66 Add and use event_queue_t::insert_front()
This allows directly inserting multiple characters/events in one go at
the front of the input queue, instead of needing to add them one-by-one
in reverse order.

In addition to improving performance in case of fragmented dequeue
allocation, this also is less error prone since a dev need not remember
to use reverse iterators when looping over a vector of peeked events.
2021-02-06 17:18:53 -06:00
Mahmoud Al-Qudsi
7669e8e497 Add concept of edit groups
This allows for multiple edits to be undone/redone in one go, as if they
were one edit.

Useful when a function is editing the commandline buffer via scripted
changes or via a keybinding so the internal changes to the buffer can be
abstracted away.

(Having extreme difficulty getting pexpect to play nice with the concept
of undo/redo...)
2021-01-05 15:43:34 -06:00
Fabian Homborg
6eeb8861e7 Add exit bind function
Currently binding `exit` to a key checks too late that it's exitted,
so it leaves the shell hanging around until the user does an execute
or similar.

As I understand it, the `exit` builtin is supposed to only exit the
current "thread" (once that actually becomes a thing), and the
bindings would probably run in a dedicated one, so the simplest
solution here is to just add an `exit` bind function.

Fixes #7604.
2021-01-04 09:45:34 +01:00
ridiculousfish
90f4c458e5 Rename insert_line_above to insert_line_over
This is for symmetry with insert_line_under. See #7442.
2020-12-19 14:31:33 -08:00
ridiculousfish
2d2efc8b2e Implement o and O bindings for vi mode
Credit to @joallard for the patch. Fixes #7442
2020-12-19 14:28:00 -08:00
ridiculousfish
e9b683dee1 Refactor how inputter handles script commands
Prior to this change, for bindings which have script commands, the
inputter would execute them directly. However an upcoming fix for #7483
will require more integration with the reader. Switch to a new model where
the reader passes in a function to use for executing script commands.
2020-11-23 19:36:39 -08:00
Fabian Homborg
2a07673561 Don't call a variable "stdin"
Musl has a macro that interferes.
2020-10-31 18:15:19 +01:00
Fabian Homborg
0951a706cf Let read read from fds other than 0
This allows

read </dev/tty

to work.

Fixes #7358
2020-10-31 13:39:20 +01:00
ridiculousfish
6d339df612 Revert "Revert "Factor repainting decions from readline commands better in the reader""
This reverts commit eb86bf23e8.

This reintroduces the refactoring; the next two commits fix the
regressions identified in it.
2020-08-23 15:31:57 -07:00
ridiculousfish
eb86bf23e8 Revert "Factor repainting decions from readline commands better in the reader"
This reverts commit 7e7599b22a.

Identified a regression in highlighting
2020-08-23 04:08:03 -07:00
ridiculousfish
7e7599b22a Factor repainting decions from readline commands better in the reader
When typing into the command line, some actions should trigger repainting,
others should kick off syntax highlighting or autosuggestions, etc. Prior
to this change, these were all triggered in an ad-hoc manner. Each
possible

This change centralizes the logic around repainting. After each readline
command or text change, we compute the difference between what we would
draw and what was last drawn, and use that to decide whether to repaint
the screen.

This is a fairly involved change. Bugs here would show up as failing to
redraw, not reacting to a keypress, etc. However it better factors the
readline command handling from the drawing.
2020-08-23 03:41:17 -07:00
ridiculousfish
aaa59d377e Remove a bunch of #ifdef'd out code 2020-08-09 15:06:50 -07:00
Johannes Altmanninger
64601fd4d3 Reformat CPP files 2020-08-04 21:44:59 +02:00
Olivier FAURE
e7f0b5801d Add forward-single-char input command
This allows users to add custom keybindings to autocomplete only one
character at a time.

Resolves https://github.com/fish-shell/fish-shell/issues/4984
2020-08-01 12:09:31 +02:00
Olivier FAURE
6778d04aa5 Add or keybind input function 2020-08-01 12:09:31 +02:00
Fabian Homborg
eb35975c0f Make cancel-commandline actual bind function
This was always awkward as fish script, and had problems with
interrupting the autoloading.

Note that we still leave the old function intact to facilitate easier
upgrading for now.

Fixes #7145.
2020-07-01 20:56:56 +02:00
Joel Kuhn
6853705b0b Fix underflow in commandline jump functions
This patch fixes an underflow in the jump family of readline commands
when called via `commandline -f` outside of a bind context such as
`commandline -f backward-jump`. To reproduce, run that command at a
prompt and the shell will crash with a buffer underlow.

This happens because the jump commands have non-zero arity, requiring a
character event to be pushed on the function args stack. Pushing the
character event is handled in `function_push_args`, called by
`inputter_t::mapping_execute`, which checks the arity of the function
and enqueues the required number of charcter events. However,
`builtin_commandline` calls `reader_queue_ch`, which in turn calls
`inputter_t::queue_ch`, which immediately enqueues the readline event
without calling `function_push_args`, so the character event is never
pushed on the arg stack.

This patch adds a check in inputter_t::queue_ch which checks if the
character event is a readline event, and if so, calls
`function_push_args`.
2020-05-26 19:53:09 -07:00
Joel Kuhn
a3dfa21737 Change vi-mode tilde to toggle character case
This updates the behavior of tilde to match the behavior found in vim.
In vim, tilde toggles the case of the character under the cursor and
advances one character. In visual mode, the case of each selected
character is toggled, the cursor position moves to the beginning of
the selection, and the mode is changed to normal. In fish, tilde
capitalizes the current letter and advances one word. There is no
current tilde command for visual mode in fish.

This patch adds the readline commands `togglecase-letter` and
`togglecase-selection` to match the behavior of vim more closely. The
only difference is that in visual mode, the cursor is not modified.
Modifying the cursor in visual mode would require either moving it in
`togglecase-selection`, which seems outside its scope or adding
something like a `move-to-selection-start` readline command.
2020-04-18 14:59:37 +02:00
Rosen Penev
194fa4a548 [clang-tidy] performance
Found with performance*

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-05 10:13:13 +02:00
Rosen Penev
fee08a87e9 [cppcheck] add const in several places
Found with constParameter, functionConst, constVariable, constArgument

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-14 15:07:54 -07:00
ridiculousfish
5886b961d8 Send events more often for variable sets outside of builtin_set
When changing certain variables programmatically, ensure that events
are sent. Fixes #6653
2020-03-08 23:28:37 -07:00
ridiculousfish
77ad459aae Pull char_input_style_t into a top-level enum
Review feedback from
https://github.com/fish-shell/fish-shell/pull/6713#pullrequestreview-369853776
2020-03-07 13:55:19 -08:00