wl-copy is a daemon process that serves its stdin to any wl-paste processes.
On Wayland, we launch it from fish_clipboard_copy. It then lives in the
same process group as fish (see `ps -o pid,pgid,comm`).
For some reason pressing ctrl-c inside the VSCode integrated terminal with
fish as the default shell kills the wl-copy process, thus clearing the
clipboard. On other terminals it works fine.
This is also reproducible by running "echo foo | wl-copy" ctrl-v ctrl-c ctrl-v
(the second ctrl-v does not paste because wl-copy was killed).
Work around this for now by running wl-copy asynchronously, and disowning it.
This seems to fix it though I really don't know why. Alternatively we could
"setsid" but that's technically not available on BSD.
For some reason this works in Bash. We should strace it to figure out why.
alt-d used to do that until evil merge[*] 213e90704 (Merge remote-tracking branch
'upstream/master' into bind_mode, 2014-01-15) which changed the order of
the \ed bindings such that the smart dirh version would be shadowed by the
simpler ones.
[*] git blame alone failed to find it because it skips merge commits.
This is another problem that has been bothering me for years: as mentioned
in 1dd901e52 (Maintain cursor in history prefix search, 2024-04-12), up-arrow
search highlights search matches but the contrast is really bad, especially in
command position, because the search matches --background=brblack is combined
with whatever foreground syntax highlighting the command has. The history
pager had a similar problem (for the selected history item) but circumented
it by disabling syntax highlighting altogether for the selected item.
fish_color_search_match's foreground component is ignored.
Let's use it instead of syntax highlighting.
This fixes the contrast on some default colorschemes but the bryellow
foreground looks weirdly like an error/warning on some terminals. Change it
to white. This needs a hack because we don't have a canonical way to tell
if a uvar has been set by the user. Fortunately the foreground component
hasn't been used at all so far, so we're not so much changing it as much as
initializing it.
Indented multiline commandlines look ugly in an external editor. Also,
fish doesn't properly handle the case when the editor runs fish_indent.
Fix is by indenting when exporting the commandline and un-indenting when
importing the commandline again.
Unindent only if the file is properly indented (meaning at least by the
amount fish would use). Another complication is that we need to offset
cursor positions by the indentation.
This approach exposes "fish_indent --only-indent" and "--only-unindent"
though I don't imagine they are useful for others so I'm not sure if this
is the right place and whether we should even document it.
One alternative is to add "commandline --indented" to handle indentation
transparently.
So "commandline --indented" would print a indented lines,
and "commandline --indented 'if true' ' echo'" would remove the unecessary
indentation before replacing the commandline.
That would probably simplify the logic for the cursor position offset.
On
a;
we don't expand the abbreviation because the cursor is right of semicolon,
not on the command token. Fix this by making sure that we call expand-abbr
with the cursor on the semicolon which is the end of the command token.
(Now that our bind command execution order is less surprising, this is doable.)
This means that we need to fix the cursor after successfully expanding
an abbreviation. Do this by setting the position explicitly even when no
--set-position is in effect.
An earlier version of this patch used
bind space self-insert backward-char expand-abbr or forward-char
The problem with that (as a failing test shows) was that given "abbr m
myabbr", after typing "m space ctrl-z", the cursor would be after the "m",
not after the space. The second space removes the space, not changing the
cursor position, which is weird. I initially tried to fix this by adding
a hack to the undo group logic, to always restore the cursor position from
when begin-undo-group was used.
bind space self-insert begin-undo-group backward-char expand-abbr end-undo-group or forward-char
However this made test_torn_escapes.py fail for mysterious reasons.
I believe this is because that test registers and triggers a SIGUSR1 handler;
since the signal handler will rearrange char events, that probably messes
with the undo group guards.
I resorted to adding a tailor-made readline cmd. We could probably remove
it and give the new behavior to expand-abbr, not sure.
Fixes#9730
Some of these handled multiline prompts but not multiline command lines. We
first need to move the cursor to the end of the commandline, then we can
print a message. Finally, we need to move the cursor back to where it was.
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
Similar to 20bbdb68f (Set terminal title unconditionally, 2024-03-30).
While at it, get rid of a few unnecessary guards (we are never called from
a command substitution, so the check only adds confusion).
I'm not sure if it's worth supporting a terminal that mishandles unknown OSC
and CSI sequences. Better to fix the terminal. Note that there are Emacs
terminals available that don't have this problems; for example "vterm".
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
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.
Unfortunately on Debian "open" is a symlink to "openvt", and there's
no way from outside to tell.
This prevents fish from failing because no browser could be found.
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#10286Closes#3299
We have
bind --preset -M $mode --sets-mode paste \e\[200~ __fish_start_bracketed_paste
Commit c3cd68dda (Process shell commands from bindings like regular char
events, 2024-03-02) made it so __fish_start_bracketed_paste is no longer
executed before the bind mode is updated.
This is a long-awaited fix but it broke __fish_start_bracketed_paste's
assumption that $fish_bind_mode is the mode before we entered paste mode.
This means we never exit paste mode.
Work around that. I forgot about this issue because I already replaced our
bracketed paste handling on my fork.
Today,
bind foo "commandline -f expand-abbr; commandline -i \n"
does not work because this
1. enqueues an expand-abbr readline event
2. "commandline -i" inserts \n
3. processes the expand-abbr readline event
Since there is no abbreviation on the new line, this doesn't do anything.
PR https://github.com/fish-shell/fish-shell/pull/9398 would fix this
particular instance however it does not fix the issue that "commandline -i"
is run before the expand-abbr is processed by the reader. This is harmless
here but there would be a problem if "commandline" tried to read commandline
state that was created by a preceding command.
It's not super clear to me whether the above binding should work as one
would naively expect. That would imply that "commandline" would need to
drain all input events (at least all synthetic ones) from the input queue,
to ensure it sees the current state.
Fortunately the parent commit makes it so if we separate them
bind foo "commandline -f expand-abbr" "commandline -i \n"
both will be separate events and the commandline state will be synced after
each of them. This fixes abbreviation expansion here.
Also, we can now mix readline cmds and shell commands, which makes it shorter.
Most chat programs I found use Shift+Return to insert a newline while plain
Return sends the message. One user reported having only tried Shift+Return
and not knowing about Alt+Return.
No release notes yet because this only works on a very small number of
terminals. Once we enable CSI u, this should work on most modern terminals.
Unless the editor changed to a different file for some reason.
Note that the Kakoune integration uses -always to export the cursor even if
the user temporarily suppressed hooks - possibly a "fish_indent" hook.
One of the things that keep me from using Vi mode is that it doesn't define an
insert-mode shortcut to accept autosuggestions. Let's use Control-N because
that Vim key is the closest equivalent.
Closes#10339
... even if the file hasn't changed. This addresses an oddity in the following
case:
* Shell is started,
* function `foo` is sourced from foo.fish
* foo.fish is *externally* edited and saved
* <Loaded definition of `foo` is now stale, but fish is unaware>
* `funced foo` loads `type -p foo` showing changed definition, user exits
$EDITOR saving no changes (or with $status 0, more generally).
* Stale definition of `foo` remains
If a hostname starts with a dash `-` character, the prompt_hostname function
fails because the `string` function interprets it as an option instead
of an argument.
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#6923Fixes#5274Closes#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.
Fish functions are great for configuring fish but they don't integrate
seamlessly with the rest of the system. For tasks that can run outside fish,
writing scripts is the natural approach.
To edit my scripts I frequently run
$EDITOR (which my-script)
Would be great to reduce the amount typing for this common case (the names
of editor and scripts are usually short, so that's a lot of typing spent on
the boring part).
Our Alt+o binding opens the file at the cursor in a pager. When the cursor
is in command position, it doesn't do anything (unless the command is actually
a valid file path). Let's make it open the resolved file path in an editor.
In future, we should teach this binding to delegate to "funced" upon seeing
a function instead of a script. I didn't do it yet because funced prints
messages, so it will mess with the commandline rendering if used from
a binding. (The fact that funced encourages overwriting functions that
ship with fish is worrysome. Also I'm not sure why funced doesn't open the
function's source file directly (if not sourced from stdin). Persisting the
function should probably be the default.)
Alternative approach: I think other shells expand "=my-script" to
"/path/to/my-script". That is certainly an option -- if we do that we'd want
to teach fish to complete command names after "=". Since I don't remember
scenarios where I care about the full path of a script beyond opening it in
my editor, I didn't look further into this.
Closes#10266
gpg's --use-embedded-filename is a dangerous option that can cause gpg
to write arbitrary content to arbitrary files.
According to the GnuPG maintainer, this is not an option recommended
for use (https://dev.gnupg.org/T4500). Fish shouldn't encourage users
to supply it.
I've offered https://dev.gnupg.org/T6972 to upstream to make it even
more clear that this option is a bad idea.
While removing it, we might as well also remove
--no-use-embedded-filename, since it is effectively a no-op.
Instead of skipping for non-interactive shells, skip when stdin is not a tty.
This allows the cursor to be set for scripts that use the `read` command.