Commit Graph

2325 Commits

Author SHA1 Message Date
Johannes Altmanninger
e015956de7 Orphan background tasks to work around terminals being sensitive to unreaped processes
When a command like "long-running-command &" exits, the resulting SIGCHLD
is queued in the topic monitor. We do not process this signal immediately
but only after e.g. the next command has finished. Only then do we reap the
child process.

Some terminals, such as Terminal.app, refuse to close when there are unreaped
processes associated with the terminal -- as in, having the same session ID,
see setsid(3).

In future, we might want to reap proactively.

For now, apply an isolated workaround: instead of taking care of a child
process, double-fork to create an orphaned process. Since the orphan will
be reaped by PID 1, we can eventually close Terminal.app without it asking
for confirmation.

	/bin/sh -c '( "$@" ) >/dev/null 2>&1 &' -- cmd arg1 arg2

This fix confines the problem to the period during which a background process
is running. To complete the fix, we would need to call setsid to detach the
background process from a controlling terminal. That seems to be desirable
however macOS does provide a setsid utility.

	setsid cmd arg1 arg2 >/dev/null 2>&1

Fixes #11181
2025-03-04 09:16:40 +01:00
Johannes Altmanninger
44d5abdc05 Add back legacy bindings to address modifyOtherKeys regressions in iTerm2<3.5.12
As of 303af07, iTerm2 3.5.11 on two different machines has two different
behaviors. For unknown reasons, when pressing alt-right fish_key_reader
shows "\e\[1\;9C" on one machine and "\e\[1\;3C" on another.

Feels like iTerm2 interprets modifyOtherKeys differently, depending on
configuration.

We don't want to risk asking for the kitty
keyboard protocol until iTerm2 3.5.12 (see
https://github.com/fish-shell/fish-shell/issues/11004#issuecomment-2571494782).

So let's work around around this weirdness by adding back the legacy
bindings removed in c0bcd817ba (Remove obsolete bindings, 2024-04-28) and
plan to remove them in a few years.

Note that fish_key_reader still reports this as "left", which already has
a different binding, but it looks like literal matches of legacy sequences
have precedence.

Fixes the problem described in
https://github.com/fish-shell/fish-shell/issues/11192#issuecomment-2692247060

Closes #11192
2025-03-03 14:44:00 +01:00
Johannes Altmanninger
495083249b Fix regression causing cursor shape commands to leak into noninteractive shell
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$CLuoHTdvcRj_8-HBBq0p-lmGWeix5khEtKEDxN2Ulfo

Running

	fish -C '
		fzf_key_bindings
		echo fish_vi_key_bindings >>~/.config/fish/config.fish
		fzf-history-widget
	'

and pressing "enter" will add escape sequences like "[2 q" (cursor shape)
to fish's command line.

This is because fzf-history-widget binds "enter" to a filter
that happens to be a fish script:

	set -lx FZF_DEFAULT_OPTS \
		... \
		"--bind='enter:become:string replace -a -- \n\t \n {2..} | string collect'" \
		'--with-shell='(status fish-path)\\ -c)

The above ~/.config/fish/config.fish (redundantly) runs "fish_vi_key_bindings"
even in *noninteractive* shells, then "fish_vi_cursor" will print cursor
sequences in its "fish_exit" handler.  The sequence is not printed to the
terminal but to fzf which doesn't parse CSI commands.

This is a regression introduced by a5dfa84f73 (fish_vi_cursor: skip if stdin
is not a tty, 2023-11-14). That commit wanted "fish -c read" to be able to
use Vi cursor.  This is a noninteractive shell, but inside "read" we are
"effectively interactive".  However "status is-interactive" does not tell
us that.

Let's use a more contained fix to make sure that we print escape sequences only
if either fish is interactive, or if we are evaluating an interactive read.

In general, "fish -c read" is prone to configuration errors, since we
recommend gating configuration (for bind etc) on "status is-interactive"
which will not run here.
2025-03-02 09:34:06 +01:00
Peter Rice
d1bb4503d6 edit_command_buffer: pass cursor position to helix 2025-03-02 07:27:06 +01:00
Johannes Altmanninger
c926a87bdb Work around Konsole not recognizing file:://$hostname/path as local
Konsole has a bug: it does not recognize file:://$hostname/path as directory.
When we send that via OSC 7, that breaks Konsole's "Open Folder With"
context menu entry.

OSC 7 producers are strongly encouraged to set a non-empty hostname, but
it's not clear if consumers are supposed to accept an empty hostname (see
https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/20).
I think it should be fine; implementations should treat it as local path.

Let's work around the Konsole bug by omitting the hostname for now. This
may not be fully correct when using a remote desktop tool to access a
system running Konsole but I guess that's unlikely and understandable.
We're using KONSOLE_VERSION, so it the workaround should not leak into SSH
sessions where a hostname component is important.

Closes #11198

Proposed upstream fix https://invent.kde.org/frameworks/kio/-/merge_requests/1820
2025-03-02 05:44:36 +01:00
Johannes Altmanninger
f415413bfb Strip "$ " prefixes on paste
Code blocks are often written like

	$ echo hello world
	hello world

The "$ " is widely understood to introduce a shell command.  It's often
easier to copy the whole line than copying everything after "$ ".

This gets more pronounced when there are multiple commands without interleaved
output (either due to omission or the rule of silence). Copying the whole
code block is the most natural first step.

You could argue that this is a presentation issue - the dollar prefix
should be rendered but not copied to clipboard. But in my experience there
are many cases where there is no HTML or Javascript that would allow the
copy-to-clipboard functionality to strip the prefixes.

The "$ " prefix is almost never useful when pasting; strip it automatically.

Privileged commands use "# " as prefix which overlaps with comments, so do
not strip that until we can disambiguate (another potential reason not to
do that would be safety but it's unclear if that really matters).

Add the new logic to the commandline builtin, because we don't know about the
AST in fish script. (Technically, the tokenizer already knows whether a "$
" is in command position and at the beginning of a line, but we don't
have that either (yet).)

Maybe we should move the rest of __fish_paste over as well. I'm not sure what
difference that would make; for one, pasting could no longer be cancelled
by ctrl-c (in theory), which seems like a good direction?
2025-03-01 07:55:53 +01:00
Fabian Boehm
20e9fe9c95 Revert token movement bindings
Comments by macOS users have shown that, apparently, on that platform
this isn't wanted.

The functions are there for people to use,
but we need more time to figure out if and how we're going to bind
these by default.
For example, we could change these bindings depending on the OS in future.

This reverts most of commit 6af96a81a8.

Fixes #10926
See #11107

(cherry picked from commit 378f452eaa)
2025-02-27 21:10:07 +01:00
Fabian Boehm
6c9e6b3baf functions/help: Fix version number for betas 2025-02-19 21:47:00 +01:00
Johannes Altmanninger
f4503af037 Make alt-{b,f} move in directory history if commandline is empty
alt-{left,right} move in the directory history (like in browsers).
Arrow keys can be inconvenient to reach on some keyboards, so
let's alias this to alt-{b,f}, which already have similar behavior.
(historically the behavior was the same; we're considering changing
that back on some platforms).

This happens to fix alt-{left,right} in Terminal.app (where we had
a workaround for some cases), Ghostty, though that alone should not
be the reason for this change.

Closes #11105
2025-02-06 19:12:00 +01:00
phanium
1d827d1d2d Fix twice tokenize editor_cmd
```fish
export VISUAL='nvim --cmd let\ g:flatten_wait=1'
funced -s fish_prompt
```

`editor_cmd[3]` would be `let` rather than `let g:flatten_wait=1`
2025-02-02 16:20:12 -08:00
Fabian Boehm
4e13ce33c5 functions/__fish_cancel_commandline: Follow rename of bind function
See #10935
2025-01-22 17:43:59 +01:00
David Adam
945a535570 fish_default_key_bindings: remove duplicate ctrl-k binding
It's in the shared bindings since f9b7992.
2025-01-20 19:48:57 +08:00
Johannes Altmanninger
8208a12a76 Back out "Support help argument in "{ -h""
This backs out commit efce176ceb.
2025-01-19 18:57:21 +01:00
Fabian Boehm
98a96f5b58 Revert "Swap alt-{left,right,backspace,delete} with ctrl-* on macOS"
This reverts commit ebdc3a0393.

Not discussed, includes a new thing that queries the terminal for the client OS
when what is really needed is just a `uname` - which would also work on Terminal.app.
2025-01-19 18:52:10 +01:00
Fabian Boehm
494bdfa013 Revert accidentally pushed fork
Revert "README for this fork"

This reverts commit 97db461e7f.

Revert "Allow foo=bar global variable assignments"

This reverts commit 45a2017580.

Revert "Interpret () in command position as subshell"

This reverts commit 0199583435.

Revert "Allow special variables $?,$$,$@,$#"

This reverts commit 4a71ee1288.

Revert "Allow $() in command position"

This reverts commit 4b99fe2288.

Revert "Turn off full LTO"

This reverts commit b1213f1385.

Revert "Back out "bind: Remove "c-" and "a-" shortcut notation""

This reverts commit f43abc42f9.

Revert "Un-hide documentation of non-fish shell builtins"

This reverts commit 485201ba2e.
2025-01-19 18:34:59 +01:00
Johannes Altmanninger
485201ba2e Un-hide documentation of non-fish shell builtins
This makes "man exec" show the documentation from Linux man-pages.
2025-01-19 18:29:07 +01:00
Johannes Altmanninger
ebdc3a0393 Swap alt-{left,right,backspace,delete} with ctrl-* on macOS
See https://github.com/fish-shell/fish-shell/issues/ 10926
2025-01-19 18:29:07 +01:00
Johannes Altmanninger
efce176ceb Support help argument in "{ -h"
Unlike other builtins, "{" is a separate token, not a keyword-string
token.

Allow the left brace token as command string; produce it when parsing
"{ -h"/"{ --help" (and nowhere else).  By using a decorated statement,
we reuse logic for redirections etc.

Other syntax elements like "and" are in the builtin list, which
- adds highlighting logic
- adds it to "builtin --names"
- makes it runnable as builtin
  (e.g. "builtin '{'" would hypothetically print the man page)

These don't seem very important (highlighting for '{' needs to match
'}' anyway).

Additionally, making it a real builtin would mean that we'd need to
deactivate a few places that unescape "{" to BRACE_BEGIN.

Let's not add it to the built in list. Instead, simply synthesize
builtin_generic in the right spot.

I'm assuming we want "{ -h" to print help, but '"{" -h' to run an
external command, since the latter is historical behavior.  This works
naturally with the above fake builtin approach which never tries to
unescape the left brace.
2025-01-19 18:29:07 +01:00
Johannes Altmanninger
7ad47c34e8 Fix regression causing scrollback-push to not clear text below cursor
If a child program crashes with some text rendered below the cursor,
we fail to clear that text. For example run vim, "pkill -9 vim" and
observe that scrollback-push fails to clean up the leftover text.
Fix that.
2025-01-19 18:29:07 +01:00
Ilya Grigoriev
a328fd995b Clarify __fish_complete_subcommand comment 2025-01-19 10:49:07 +01:00
Johannes Altmanninger
6d18f57e96 Make ! a builtin too, fixing "! -h"
UnLike other aliases (":.["), ! is special in the grammar but in the
few cases like "! -h" where we parse it as decorated statement they
are equals. Add it to the built in list, so the help argument works.

It can still be overridden, so this should not break anything.
2025-01-15 10:54:18 +01:00
Johannes Altmanninger
c4b4e90031 Fix file completions for builtin fish_indent 2025-01-15 10:52:43 +01:00
Fabian Boehm
28233b0711 Make new ctrl-c behavior "clear-commandline"
And leave the old behavior under the name "cancel-commandline".

This renames "cancel-commandline-traditional" back to
"cancel-commandline", so the old name triggers the old behavior.

Fixes #10935
2025-01-14 20:01:56 +01:00
Fabian Boehm
723943fd1f fish_jj_prompt: Return false if nothing was generated
That means we go on to try git etc
2025-01-13 14:54:00 +01:00
Johannes Altmanninger
b46417c77b Fix broken completions for "mount -ouid="
Regressed in 2e55e34544 (Reformat, 2020-11-22).
2025-01-13 09:47:34 +01:00
Johannes Altmanninger
0f4e195819 fish_jj_prompt: remove change ID
This is not really helpful because it's somewhat transient; also we
can usually use the @ alias.
2025-01-13 09:47:34 +01:00
Johannes Altmanninger
7c539b9539 Rename the readline function for deleting active history item
history-pager-delete now also works for regular history search,
so rename it.
2025-01-11 18:58:49 +01:00
Mahmoud Al-Qudsi
f8b245eb31 completions/zfs: Add encryption-related completions 2025-01-11 10:44:40 -06:00
Johannes Altmanninger
4a6d8d0b3a Allow alt-enter and friends to insert into search field
Since this is user-visible, copy the logic rather than extracting
a function.
2025-01-11 13:50:08 +01:00
phanium
ef7aa793c6 Fix missing of builtin token description 2025-01-09 16:49:41 +01:00
Johannes Altmanninger
704b911168 Back out "Bind ctrl-l to clear-screen again for now"
As of the parent commits this should no longer cause breakage.

This backs out commit 07dd088d76.
2025-01-06 06:24:13 +01:00
Lzu Tao
f9b79926f1 Add more convenient key bindings for VI mode
To make it more familiar to vi/vim users.

In all mode, ctrl-k is bind to kill-line.

In Vi visual mode:
* press v or i turn into normal or insert mode respectively.
* press I turn to insert mode and move the cursor to beginning of line.
* because fish doesn't have upcase/locase-selection, and most people reach for
  g-U rather than g-u, g-U binds to togglecase-selection temporarily.
2025-01-05 23:00:21 +08:00
Johannes Altmanninger
07dd088d76 Bind ctrl-l to clear-screen again for now
Testing has revealed some problems on BSD and Windows terminals and
the Linux Console, let's revert to the old implementation until these
are fixed.  Leaving the changelog entry for now since it shouldn't
take long.

See #11003
2025-01-05 08:20:53 +01:00
David Adam
670541eec8 fish_jj_prompt: don't error if jj not installed 2025-01-03 12:38:14 +08:00
Johannes Altmanninger
0debddc9e5 Add a simple fish_jj_prompt
jj is often colocated with Git so the Git prompt also works, but
jj is always in a detached HEAD state, which is atypical for Git.
The jj prompt improves things by showing the revision ID which is
usually more useful than the commit ID.

This prompt is mostly adapted from the defaults for "jj log -r @".

Showing conflicting/empty commits seems useful.
Also perhaps bookmarks and tags, not sure.

The main problem with this prompt is that due to --ignore-working-copy,
the information may be stale.  That will be rectified after every jj
command, so hopefully this doesn't cause issues.
2025-01-03 00:03:58 +01:00
Fabian Boehm
d5efef1cc5 __fish_complete_subcommand: Just complete -C for a given commandline
Fixes #10980.

This would, if a commandline was given, still revert to checking
the *real* commandline if it was empty.

Unfortunately, in those cases, it could have found a command and tried
to complete it.

If a commandline is given, that is what needs to be completed.

(note this means this is basically useless in completions that use it
like `sudo` and could just be replaced with `complete -C"$commandline"`)
2024-12-30 21:01:21 +01:00
Fabian Boehm
e715c3e3ff help: Add special error for $BROWSER/$fish_help_browser being wrong 2024-12-30 21:01:21 +01:00
Johannes Altmanninger
83b0294fc9 ctrl-l to scroll content instead of erasing screen
On ctrl-l we send `\e[2J` (Erase in Display).  Some terminals interpret
this to scroll the screen content instead of clearing it. This happens
on VTE-based terminals like gnome-terminal for example.

The traditional behavior of ctrl-l erasing the screen (but not the
rest of the scrollback) is weird because:

1. `ctrl-l` is the easiest and most portable way to push the prompt
   to the top (and repaint after glitches I guess). But it's also a
   destructive action, truncating scrollback. I use it for scrolling
   and am frequently surprised when my scroll back is missing
   information.
2. the amount of lines erased depends on the window size.
   It would be more intuitive to erase by prompts, or erase the text
   in the terminal selection.

Let's use scrolling behavior on all terminals.

The new command could also be named "push-to-scrollback", for
consistency with others. But if we anticipate a want to add other
scrollback-related commands, "scrollback-push" is better.

This causes tests/checks/tmux-history-search.fish to fail; that test
seems pretty broken; M-d (alt-d) is supposed to delete the current
search match but there is a rogue "echo" that is supposed to invalidate
the search match.  I'm not sure how that ever worked.

Also, pexepect doesn't seem to support cursor position reporting,
so work around that.

Ref: https://codeberg.org/dnkl/foot/wiki#how-do-i-make-ctrl-l-scroll-the-content-instead-of-erasing-it
as of wiki commit b57489e298f95d037fdf34da00ea60a5e8eafd6d

Closes #10934
2024-12-30 10:50:38 +01:00
phanium
94dfe1b053 Fix alt-e cursor position restore on Vim <= 8 (#10946) 2024-12-26 06:35:37 +01:00
Johannes Altmanninger
5de6f4bb3d Provide old implementation of cancel-commandline as fallback
__fish_cancel_commandline was unused (even before) and has some issues
on multiline commandlines. Make it use the previously active logic.

Closes #10935
2024-12-23 14:34:59 +01:00
Johannes Altmanninger
7e5af914be Remove interactive-only completion hacks
I don't think these characters cause problems in filenames?
2024-12-23 08:40:02 +01:00
Johannes Altmanninger
ac951427af Fix alt-l on multiline tokens
This would invoke test with extra arguments.
2024-12-16 06:33:47 +01:00
Fabian Boehm
7c73c5fec0 Make fish installable
When built with the default "installable" feature, the data files (share/) are
included in the fish binary itself.

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

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

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

We set $__fish_help_dir to empty for installable builds, because we do not have
a way to generate html docs (because we need fish_indent for highlighting).
The man pages are found via $__fish_data_dir/man
2024-12-06 22:12:26 +01:00
Fabian Boehm
8dcde27e0b functions/history: Put back some checks for clear{,-session}
Mostly we pass on the options - otherwise they would be ignored.

For `clear`, we do need the full checks, because that will
prompt *before* running the builtin.

But this makes it easier to eventually move that logic into the builtin
2024-11-21 18:55:03 +01:00
Fabian Boehm
6fe192606a functions/history: Set variables in function-scope explicitly
```fish
set -g LESS foo

history search bar
```

changes the global $LESS and exports it.
2024-11-21 18:27:10 +01:00
Fabian Boehm
11f11e27a1 functions/history: Remove unnecessary code
These things are all handled in the builtin
2024-11-21 18:26:47 +01:00
Unbelievable Mystery
262e2d5fe6 Update completions for: wine (#10789)
* feat(function): move cmd completion function to a separate file

* feat(completion): support wine cmd subcommand

* feat(completion): support wine control subcommand

* feat(completion): support wine eject subcommand

* feat(completion): support wine explorer subcommand

* feat(completion): support wine explorer subcommand for desktops

* feat(completion): support wine start subcommand

* feat(completion): support wine winemenubuilder subcommand

* feat(completion): support wine winepath subcommand

* fix(function): rename function for cmd argument completion

* feat(function): implement function to complete registry keys

* feat(completion): support wine regedit subcommand

* feat(function): add top-level key descriptions

* fix(completion): remove redundant comment

* feat(completion): support wine msiexec subcommand

* refactor(completion): group code into functions

* feat(completion): enhance subcommand descriptions
2024-11-17 14:58:21 -08:00
Peter Ammon
dff454b1c7 Rework git detection for macOS
fish by default shows a git-aware prompt. Recall that on macOS, there are
two hazards we must avoid:

1. The command `/usr/bin/git` is installed by default. This command is not
actually git; instead it's a stub which pops open a dialog proposing to
install Xcode command line tools. Not a good experience.
2. Even after installing these tools, the first run of any `git` or other
command may be quite slow, because it's now a stub which invokes `xcrun`
which needs to populate a cache on a fresh boot. Another bad experience.

We previously attempted to fix this by having `xcrun` print out its cache
path and check if there's a file there. This worked because `xcrun` only
lazily created that file. However, this no longer works: `xcrun` now
eagerly creates the file, and only lazily populates it. Thus we think git
is ready, when it is not.

(This can be reproduced by running `xcrun --kill-cache` and then running
the default fish shell prompt - it will be slow).

Change the fix in the following way: using sh, run `/usr/bin/git --version;
touch /tmp/__fish_git_ready` in the background. Then detect the presence of
/tmp/__fish_git_ready as a mark that git is ready.

Fixes #10535
2024-11-09 12:46:06 -08:00
Fabian Boehm
0979b9a98b help: Print external URL if no browser was found
This is nicer when you use fish over ssh, and that system does not
have a browser. But the system where your terminal is has one, and so
now you can just click the link.
2024-11-06 18:48:57 +01:00
Johannes Altmanninger
7debdb75af Fix regression causing fish_cursor_external to be ignored
Regressed in 0e97b876e (Simplify fish_vi_cursor, 2024-10-25).
2024-11-06 07:24:00 +01:00