`read` allows specifying the initial command line text. This was
text got accidentally ignored starting in a32248277f. Fix this
regression and add a test.
Fixes#8633
Cygwin tests are failing because cygwin has a low limit of only 64 fds in
select(). Extend select_wrapper_t to also support using poll(), according to
a FISH_USE_POLL new define. All systems now use poll() except for Mac.
Rename select_wrapper_t to fd_readable_set_t since now it may not wrap
select().
This allows the deep-cmdsub.fish test to pass on Cygwin.
Use the remaining_to_disclose count to determine if all completions
are shown (allows consistent behavior between short and long completion
lists).
Closes#8485
On a commandline like "ls arg" (cursor at end) we do not expand
abbrevations on enter. OTOH, on "ls " we do expand. This can be
frustrating because it means that the two obvious ways to suppress
abbrevation expansion (C-Space or post-expansion C-Z) cannot be used to
suppress expansion of a command without arguments. (One workaround is
"ls #".)
Only expand-on-execute if the cursor is at the command name (no space
in between).
This is a strict improvement for realistic scenarios, because if there
is a space, the user has already expressed the intent to not expand
the abbreviation. (I hope no one is using recursive abbreviations.)
Closes#8423
This allows to disable autosuggestions in config or with
fish -C 'set -g fish_autosuggestion_enabled 0'
instead of only in existing interactive sessions.
I'm not sure if passing the env var table is actually necessary here,
since we already have a reader.
This adds a variable, $fish_autosuggestion_enabled.
When set to 0, it will turn off autosuggestions/highlighting.
Setting it to anything else will enable it (which also
means this remains enabled by default).
Fixes#8232.
Note that this needed to have expect_prompt used in the pexpect test -
we might want to add a "catchup" there so you can just ignore the
prompt counter for a bit and pick it back up later.
Today the reader exposes its internals directly, e.g. to the commandline
builtin. This is of course not thread safe. For example in concurrent
execution, running `commandline` twice in separate threads would cause a
race and likely a crash.
Fix this by factoring all the commandline state into a new type
'commandline_state_t'. Make it a singleton (there is only one command
line
after all) and protect it with a lock.
No user visible change here.
No functional change here; this migrates the fix ensuring that history
items are available in the builtin interactive read command into the
reader itself, in preparation for removing reader_get_history().
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.
This crashed on Fedora with the rpm packages, but not when building
from source, so some compiler option triggers it.
But the root cause is us running `text.front()` on an empty string,
which isn't something you should do.
Fixes#8009.
This simply checks if the parser requested exit after running any
binding scripts (in read_normal_chars).
I think this means we no longer need the `exit` bind function.
Fixes#7967.
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.
select_wrapper_t wraps up the annoying bits of using select(): keeping
track of the max fd, passing null for boring parameters, and
constructing the timeout. Introduce a wrapper struct for this and
replace the existing uses of select() with the wrapper.
When a terminal in a tiling WM starts, it might start the shell before
it has reached its "final" size. So we get the terminal width,
then the terminal would be resized (to appease the tiling logic),
and then we would print the abandon line with the omitted newline
char, only if the size got smaller (likely!), we would overflow the
line and land on the next.
So what we do is a bit of a hack: We don't abandon the first line.
This means that `printf %s foo; fish` will overwrite the `foo`, but
that's a super small problem and I don't see another way around this.
Fixes#7893.
The bell is a mechanism for important notifications. Not having things
to do in response to a keypress isn't important enough, especially
because we're already flashing and the bell might actually be a bell.
Fixes#7875.
This fixes the following problem: if a command is entered while the
previous command is still executing, fish will see it all at once and
execute it before syntax highlighting as a chance to start. So the
command will appear wrong on the terminal. Fix this by detecting this
case and performing a fast no-io highlight.
An example of how to reproduce this:
run `sleep 3` and then type `echo foo` while the sleep is still running.
013a563ed0 made it so we only try to
adjust terminal modes if we are in the terminal pgroup, but that's not
enough.
Fish starts background jobs in events inside its own pgroup, so
function on-foo --on-event foo
fish -c 'sleep 3' &
end
would have the backgrounded fish try to fiddle with the terminal and
succeed.
Instead, only fiddle with the terminal if we're interactive (this
should probably be extended to other bits, but this is the particular
problematic part)
Fixes#7842.
Consider
$ complete -c foo -a 'aab aaB' -f
$ foo A<TAB>
since 28d67c8 we would insert the common prefix AND show the pager.
Due to case-insensitive comparison, "b/B" was considered to be part
of the prefix. Since the prefix is added to each pager item [1]
we get wrong results. Fix this by removing the insensitive comparison
between completions - I don't think it was of much use anyway.
Commandline tokens are still matched case-insensitively, this is
just about completions.
Test this by running interactive fish inside tmux (pexpect's terminal
emulation not have enough capabilities). Also add tests for recent
interactive regressions #7526 and #7738.
Closes#3978
[1]: b38a23a would solve this differently by giving every pager item
its own prefix, but was reverted since it needs more fixes.
This concerns the behavior when running an external command from a key
binding. The history is:
Prior to 5f16a299a7, fish would run these external commands in shell
modes. This meant that fish would pick up any tty changes from external
commands (see #2114).
After 5f16a299a7, fish would save and restore its shell modes around
these external commands. This introduced a regression where anything the
user typed while a bound external command was executing would be echoed,
because external command mode has ECHO set in c_lflag. (This can be
reproed easily with `bind -q 'sleep 1'` and then pressing q and typing).
So 5f16a299a7 was reverted in fd9355966.
This commit partially reverts fd9355966. It has it both ways: external
commands are launched with shell modes, but/and shell modes are restored
after the external command completes. This allows commands to muck with
the tty, as long as they can handle getting shell modes; but it does not
enable ECHO mode so it fixes the regression found in #7770.
Fixes#7770. Fixes#2114 (for the third time!)
This partially reverts commit fd9355966e.
Unfortunately this causes input coming in while bind functions are
running to show up on screen.
Since the cure is worse than the disease let's just stop doing it.
My guess is this needs to *only* be done while running an external
command.
Fixes#7770
Reintroduces #2114
Partially reverts 5f16a299a7
Before now, we would be getting the terminal modes before config.fish,
then running config.fish without any of the term "stealing" and modes
copying. This meant that changes made to the terminal modes in there
were simply lost.
So, what we do is simply set the modes before config and then copy
them after, once.
Note that this does *not* turn off flow control again - if you turn it
on in config.fish that should work.
Fixes#7783.
This half-reverts commit a3cb1e2dcd,
avoiding the bit that passed arguments differently.
Note that this means the initial bug is kept in the hardcoded fallback title.
Fixes#7749.
Since smartcase, we could land in a situation where we offer one
option in the pager, which is awkward.
So detect this and just insert the option directly, we can add any
more smartness later.
Fixes#7738.
fish maintains two tty modes: one for itself and one for external
commands. The external command mode is also used when executing
fish-script key bindings, which was added in 5f16a299a7 (note that
commit had the wrong issue, the correct issue is #2114).
Prior to this fix, when switching to external modes, we would also reset
the tty's foreground color. This bumped tty's timestamp, causing us to
believe that the tty had been modified, and then repainting the prompt. If
the prompt were multi-line, we would repaint the whole prompt starting
from its second line, leaving a trailing line above it.
It would be reasonable to save the tty timestamp after resetting the
color, but given that using external modes for keybindings is new, it's
better to instead not reset the color in this case. So migrate the color
resetting to only when we run external commands.
Fixes#7722
Since, unlike e.g. OPOST, this can sometimes be useful, just copy
whatever flow control settings the terminal ends up with.
We still *default* flow control to off (because it's an awful default
and allows us to bind ctrl-s), but if the user decides to enable it so
be it.
Note that it's _possible_ flow control ends up enabled accidentally, I
doubt this happens much and it won't render the shell unusable (and
good terminals might even tell you you've stopped the app).
Fixes#7704
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
Now that we have multiple clients of count_preceding_backslashes, factor
it out from fish_indent into wcstringutil.h, and then use the shared
implementation.
Just like OPOST this just breaks output for anything not prepared for
it. Fish itself might work with it (and #4505 recommends it), but external commands are broken.
You'll see output like
foo
⏎
from `echo foo`.
Fixes#4873.
Continuation of #7133.
Prior to this change, histories were immortal and allocated with either
unique_ptr or just leaked via new. But this can result in races in the
path detection test, as the destructor races with the pointer-captured
history. Switch to using shared_ptr.
When adding a command to history, we first expand its arguments to see
if any arguments are paths which refer to files. If so, we will only
autosuggest that command from history if the files are still valid. For
example, if the user runs `rm ./file.txt` then we will remember that
`./file.txt` referred to a file, and then only autosuggest that if the file
is present again.
Prior to this change we only performed simple expansion relative to the
working directory. This change extends it to variables and tilde
expansion. For example we will now apply the same hinting for
`rm ~/file.txt`
Fixes#7582
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...)
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.
Prior to this change, `fish_private_mode` worked by just suppressing
history outright. With this change, `fish_private_mode` can be toggled on
and off. Commands entered while `fish_private_mode` is set are stored but
in memory only; they are not written to disk.
Fixes#7590Fixes#7589
Commands that start with a space should not be written to the history
file. Prior to this change, that was implemented by simply not adding them
to history. Items with leading spaces were simply dropped.
With this change, we add a 'history_persistence_mode_t' to
history_item_t, which tracks how the item persists. Items with leading
spaces are now marked as "ephemeral": they can be recovered via up arrow,
until the user runs another command, or types a space and hits return.
This matches zsh's HIST_IGNORE_SPACE feature.
Fixes#1383
If the user types something like `/**`, prior to this change we would
attempt to expand it in the background for both highlighting and
autosuggestions. This could thrash your disk and also consume a lot of
memory.
Add a a field to operation_context_t to allow specifying a limit, and add
a "default background" limit of 512 items.
Prior to this change, if fish were launched connected to a tty but not as
pgroup leader, it would attempt to become pgroup leader only if
--interactive is explicitly passed. But bash will unconditionally attempt
to become pgroup leader if launched interactively. This can result in
scenarios where fish is running interactively but in another pgroup. The
most obvious impact is that control-C will result in the pgroup leader
(not fish) exiting and make fish orphaned.
Switch to matching the bash behavior here - we will always try to become
pgroup leader if interactive.
Fixes#7060.
And again clang-format does something I don't like:
- if (found != end && std::strncmp(found->name, name, len) == 0 && found->name[len] == 0) return found;
+ if (found != end && std::strncmp(found->name, name, len) == 0 && found->name[len] == 0)
+ return found;
I *know* this is a bit of a long line. I would still quite like having
no brace-less multi-line if *ever*. Either put the body on the same
line, or add braces.
Blergh
The pager cleanup missed that the existing token could already include active (as in unescaped) expansions, and just escaped them all.
This means things like `ls ~/<TAB>` would escape the `~`, which is obviously wrong and makes it awkward to use.
This reverts commit b38a23a46d.
I fully expect that we'll try again, but there's no use in keeping master broken while that happens.
Fixes#7526.
This is an attempt to simplfy some completion logic. It mainly refactors
reader_data_t::handle_completions such that all completions have the token
prepended; this attempts to simplify the logic since now all completions
replace the token. It also changes how the pager prefix works. Previously
the pager prefix was an extra string that was prepended to all
completions. In the new model the completions already have the prefix
prepended and the prefix is used only for certain width calculations.
This is a somewhat frightening change in an interactive component with
low test coverage. It tweaks things like how long completions are
ellipsized. Buckle in!
In preparation for introducing "smart case", refactor string fuzzy
matching. Specifically split out the case folding and match type into
separate fields, so that we can introduce more case folding types without
a combinatoric explosion.
When fish presents an autosuggestion, there is some logic around whether
to retain it or discard it as the user types "into" it. Prior to this
change, we would retain the autosuggestion if the user's input text is a
case-insensitive prefix of the autosuggestion. This is reasonable for
certain case-insensitive autosuggestions like files, but it is confusing
especially for history items, e.g. `git branch -d ...` and `git branch -D
...` should not be considered a match.
With this change, when we compute the autosuggestion we record whether it
is "icase", and that controls whether the autosuggestion permits a
case-insensitive extension.
This addresses part of #3978.
The code to override the `(status current-command) was present`, but not
handled in either the default `fish_title` function or the fallback.
Closes#7444.
Prior to this change, we would run fish_prompt and then afterwards set
the shell modes. For users with an initially slow prompt, this would
mean that characters would be echoed to the tty until after the prompt
completes.
Reorder these so that we set the tty mode first. This implies we will
run the prompt in shell mode, but this was already the case up until
2a3677b386.
Fixes#7489. Note that the prior commit e0cedd4ad2 is also necessary
here, as that fixed an extra prompt execution.
Prior to this fix, when key binding is a script command (i.e. not a
readline command), fish would run that key binding using fish's shell
tty modes. Switch to using the external tty modes. This re-fixes
issue #2214.
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.
It may happen that the user types an abbreviation and then hits return.
Prior to this commit, we would perform a form of syntax highlighting
that does not require I/O, so as to not block the user. However this
could cause invalid commands to be colored as valid.
More generally if the user has e.g a slow NFS mount, then syntax
highlighting may lag behind the user's typing, and be incorrect at the
time the user hits return. This is an unavoidable race, since proper
syntax highlighting may take arbitrarily long.
Introduce a new function `finish_highlighting_before_exec`, which waits
for any outstanding syntax highlighting to complete, BUT has a timeout
(250 milliseconds). After this, it falls back to the no-I/O variant, which
colors all commands as valid and nothing as paths.
Fixes#7418Fixes#5912
In some cases the completion we come up with may be unexpected, e.g.
if you have files like
/etc/realfile
and
/etc/wrongfile
and enter "/etc/gile", it will accept "wrongfile" because "g" and
"ile" are in there - it's a substring insertion match.
The underlying cause was a typo, so it should be easy to go back.
So we do a bit of magic and let "cancel" undo, but only right after a
completion was accepted via complete or complete-and-search.
That means that just reflexively pressing escape would, by default, get you back to
the old token and let you fix your mistake.
We don't do this when the completion was accepted via the pager,
because 1. there's more of a chance to see the problem there and 2.
it's harder to redo in that case.
Fixes#7433.
It is apparently possible to launch fish such that its pid owns the tty,
but its pid is in a different pgroup. In that case, do not attempt to stop
with SIGTTIN; instead simply attempt to place fish in its own pgroup.
Fixes#7388
This allows
bind -k backspace suppress-autosuggestion or backward-delete-char
To remove the suggestion on the first press and then delete
chars.
Note: This requires that we then don't reenable suggestions
immediately afterwards. Currently we don't after deletion.
Fixes#1419.
This makes history searches case-insensitive, unless the search string
contains an uppercase character.
This is what vim calls "smartcase".
Fixes#7273.
When pressing tab repeatedly, completions only computed on the first one. This
is because the old logic assumed that completions are present if the last
key was tab. Recompute them if there are no completions at all.
Fixes#6863
(regression from d415350aaf)
This is important especially in e.g. the new Windows Terminal, because
for some reason that lets the tab stick around if the process exited
with a non-zero status.
Will add tests as soon as I figure out how.
This can easily lead to an infinite loop, if a variable handler
triggers a repaint and the variable is set in the prompt, e.g. some of
the git variables.
A simple way to reproduce:
function fish_mode_prompt
commandline -f repaint
end
Repainting executes the mode prompt, which triggers a repaint, which
triggers the mode prompt, ....
So we just set a flag and check it.
Fixes#7324.
Found with gcc's -Wmissing-declarations which gives warnings like
../src/tinyexpr.cpp:61:5: warning: no previous declaration for ‘int get_arity(int)’ [-Wmissing-declarations]
61 | int get_arity(const int type) {
The same warnings show up for builtin functions like builtin_bg because they
currently don't include their own headers. I left that.
Also reformat the touched files.
So we can do something on every edit, for example repaint the pager (#7318).
This patch fixes pager refiltering and repainting when pressing Control+U
after typing something in the search field.
Implement this by moving the convenience functions from editable_line_t to
the reader, so we have fewer places where we need to refilter. Essentially we
only have two cases: insertions at the cursor are handled by insert_string(),
and all others go through push_edit(). This should also make it clearer
where we update undo_history.may_coalesce.
This commit was on the history-search-edit-needle branch, so it should
work fine. I hope it does play well with some recent changes.
In 6d339df61 (Factor repainting decions from readline commands better
in the reader), insert_string() was simplified a lot, mirror that.
The tests for editable_line_t are not that useful anymore since the caller has
to decide whether to coalesce insertions, but I guess they don't hurt either.
We should have more tests for some interactive scenarios like undo and the
pager filtering.
This was broken in 6d339df612, when we removed
the normal repainting logic.
The pager *search* however needs to trigger a refilter, and therefore
needs to trigger after every insert/removal.
Fixes#7318
This would only check for fish_right_prompt at startup, so if one
wasn't defined then it would never accept one.
The "config" here is just the *name* of the function (which we never
change, so it wouldn't really be necessary, but whatever).
The one exception is the breakpoint, in those we don't run the right
prompt.
Fixes#7302.
This adds a new type 'exit_state_t' which encapsulates where fish is in
the process of exiting. This makes it explicit when fish wants to cancel
"ordinary" fish script but still run exit handlers.
There should be no user-visible behavior change here; this is just
refactoring in preparation for the next commit.
The line offset of a trailing newline on the commandline was computed incorrectly.
As a result, up-arrow did not work for a commandline like the one inserted by:
commandline -i echo '' ''
Note this and the previous commit in the changelog.
Enter a multiline commandline, for example using
commandline -i echo echo
And press down-arrow. This will start a new history search which fails.
Then press up-arrow. I expect the cursor to move up, however, because we
are still in history search mode, up-or-search will search instead of moving
the cursor. Correct that by stopping history searches that don't have any results.
Prior to this change, if we saw more than one repaint readline command in
a row, we would try to ignore the second one. However this was never the
right thing to do since sometimes we really do need to repaint twice in a
row (e.g. the user hits Ctrl+L twice). Previously we were saved by the
buginess of this mechanism but with the repainting refactoring we see
missing redraws.
Remove the coalescing logic and add a test. Fixes#7280.
If you expand an abbreviation by executing the command, fish uses a
synchronous mode of syntax highlighting that performs no I/O, because we
want to highlight the abbreviation but don't know if it's valid or not
without doing I/O. However we were doing this too aggressively, after
every command regardless of whether it contained an abbreviation. Only
do this for commands with abbreviations.
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.
Prior to this fix, the `exit` command would set a global variable in the
reader, which parse_execution would check. However in concurrent mode you
may have multiple scripts being sourced at once, and 'exit' should only
apply to the current script.
Switch to using a variable in the parser's libdata instead.
This used to be used to determine which token contained the cursor, so
as to highlight potential paths. But now we highlight all potential paths,
so we can remove the field.
In practice we didn't use the cache for anything. Always compute it on
demand.
This eliminates the 'indents' variable which had to be manually kept in
sync with the command line.
This can be used to determine whether the previous command produced a real status, or just carried over the status from the command before it. Backgrounded commands and variable assignments will not increment status_generation, all other commands will.
Have the reader accept a constant configuration object, which controls
whether autosuggestions, etc. are enabled. These things don't change
dynamically.
Prior to this fix, if you invoked fish with --private and then used
`read --silent` to read something sensitive, the variable would be
stored in history, with the plain text available through up-arrow.
Fix it to not store items in silent mode.
Note the item was never written to disk; it was only stored in memory.
Fixes#7230
The prefix has already been case-corrected at this point and the remaining
completions are for the suffix only.
Fixes#7211
Introduced in
28d67c8f Show completion list on Tab also if a common prefix was inserted
When fish receives a "cancellation inducing" signal (SIGINT in particular)
it has to unwind execution - for example while loops or whatever else that
is executing. There are two ways this may come about:
1. The fish process received the signal
2. A child process received the signal
An example of the second case is:
some_command | some_function
Here `some_command` is the tty owner and so will receive control-C, but
then fish has to cancel function execution.
Prior to this change, these were handled uniformly: both would just set a
cancellation signal inside the parser. However in the future we will have
multiple parsers and it may not be obvious which one to set the flag in.
So instead distinguish these cases: if a process receives SIGINT we mark
the signal in its job group, and if fish receives it we set a global
variable.
We were previously aborting the main event loop before calling fish_exit
in the event of a SIGHUP. This patch causes the SIGHUP to be stored in a
separate state variable from a regular "must exit" condition so the
associated event can be fired before we terminate the loop.
All streams are redirected before the event is called to prevent a
SIGTTIN/SIGTTOU due to the user script reading/writing from a disposed
tty.
Closes#7014
When selectiong a large completion entry in the pager, it would clobber the
prompt. To reproduce, first run this command
complete -c : -xa '(
# completion entries that, when applied to the commandline
# need one, two, or three lines respectively
echo 1
echo 2(string repeat -n (math $COLUMNS - 5) x)
echo 3(string repeat -n $COLUMNS x)
printf %s\n n(seq $LINES)
)'
then type ": " and hit Tab repeatedly. When cycling through completion
entries, observe that fish always tries to render the pager with the same
size, even though the number of lines occupied by the command line buffer
changes due to soft wrapping.
Fix this by rendering the pager after the command line has been rendered, so
we know how many lines we have left.