Commit graph

4651 commits

Author SHA1 Message Date
Fabian Boehm
2fe8b5d313 Don't replace tilde for error messages if we have no $HOME
This was an issue with "--no-execute", which has no variables and
therefore no $HOME:

```fish
fish --no-execute /path/to/file
```

would say the error is in `~/path/to/file`.

Instead, since this is just for a message, we simply return the
filename without doing the replacement.

Fixes #10171

Port of e318585021
2023-12-28 10:20:28 +01:00
elyashiv
51d5764fb2 [jobs.cpp] added const to escaped cmd string
(cherry picked from commit 4a2c7e38d0)
2023-12-25 19:51:33 +08:00
elyashiv
1ab24e4048 [jobs.cpp] add escaping for job comamnd
(cherry picked from commit 4ea867bc55)
2023-12-25 19:51:33 +08:00
David Adam
313b2993f5 Merge branch 'Integration_3.6.4' into Integration_3.7.0 2023-12-08 11:49:02 +08:00
Fabian Boehm
09986f5563 Encode all ENCODE_DIRECT codepoints with encode_direct 2023-12-04 23:00:01 +08:00
Fabian Boehm
8d5d0c24aa expand_cmdsubst: Make more errors known
These printed "Unknown error while evaluating command substitution".

Now they print something like

```
fish: for: status: cannot overwrite read-only variable
for status in foo; end
    ^~~~~^
in command substitution
fish: Invalid arguments
echo (for status in foo; end)
     ^~~~~~~~~~~~~~~~~~~~~~~^
```

for `echo (for status in foo; end)`

This is, of course, still not *great*. Mostly the `fish: Invalid
arguments` is basically entirely redundant.

An alternative is to simply skip the error message, but that requires some
more scaffolding (describe_with_prefix adds some error messages on its
own, so we can't simply say "don't add the prefix if we don't have a
message")

(cherry picked from commit 1b5eec2af6)
(cherry picked from commit 67faa107b0)
2023-11-09 17:53:32 +01:00
Johannes Altmanninger
211a3ceee1 Copy history pager search field to command line on Enter if no match
Closes #9934

(cherry picked from commit b7f7dcf788)
2023-10-17 17:34:40 +02:00
Johannes Altmanninger
64bff1a51c history pager: delete selected history entry with Shift-Delete
After accidentally running a command that includes a pasted password, I want
to delete command from history. Today we need to recall or type (part of)
that command and type "history delete".  Let's maybe add a shortcut to do
this from the history pager.

The current shortcut is Shift+Delete. I don't think that's very discoverable,
maybe we should use Delete instead (but only if the cursor is at the end of
the commandline, otherwise delete a char).

Closes #9454

(cherry picked from commit 052823c120)
2023-10-17 17:25:11 +02:00
Eddie Lebow
e1c2a4e50c Include subsequence matches in history-pager
If a `contains` search yields no results, try again with `contains_subsequence`.

(cherry picked from commit 00692bcdfe)
2023-10-17 17:04:25 +02:00
Fabian Boehm
85c03e4b67 wildcard: Rationalize file/command completions (#10052)
* wildcard: Remove file size from the description

We no longer add descriptions for normal file completions, so this was
only ever reached if this was a command completion, and then it was
only added if the file wasn't a regular file... in which case it can't
be an executable.

So this was dead.

* Make possible_link() a maybe

This gives us the full information, not just "no" or "maybe"

* wildcard: Rationalize file/command completions

This keeps the entry_t as long as possible, and asks it, so especially
on systems with working d_type we can get by without a single stat in
most cases.

Then it guts file_get_desc, because that is only used for command
completions - we have been disabling file descriptions for *years*,
and so this is never called there.

That means we have no need to print descriptions about e.g. broken symlinks, because those are not executable.

Put together, what this means is that we, in most cases, only do
an *access(2)* call instead of a stat, because that might be checking
more permissions.

So we have the following constellations:

- If we have d_type:
  - We need a stat() for every _symlink_ to get the type (e.g. dir or regular)
    (this is for most symlinks, if we want to know if it's a dir or executable)
  - We need an access() for every file for executables
- If we do not have d_type:
  - We need a stat() for every file
  - We need an lstat() for every file if we do descriptions
    (i.e. just for command completion)
  - We need an access() for every file for executables

As opposed to the current way, where every file gets one lstat whether
with d_type or not, and an additional stat() for links, *and* an
access.

So we go from two syscalls to one for executables.

* Some more comments

* rust link option

* rust remove size

* rust accessovaganza

* Check for .dll first for WSL

This saves quite a few checks if e.g. System32 is in $PATH (which it
is if you inherit windows paths, IIRC).

Note: Our WSL check currently fails for WSL2, where this would
be *more* important because of how abysmal the filesystem performance
on that is.
2023-10-14 08:46:14 +02:00
yanshay
8a8c7abb0f added support for fish_sequence_key_delay_ms to set how long to wait between sequence key presses 2023-10-08 21:56:06 +02:00
Fabian Boehm
724b44907e Reduce stat calls for wildcards ending in "/" (#10032)
This makes it so expand_intermediate_segment knows about the case
where it's last, only followed by a "/".

When it is, it can do without the file_id for finding links (we don't
resolve the files we get here), which allows us to remove a stat()
call.

This speeds up the case of `...*/` by quite a bit.

If that last component was a directory with 1000 subdirectories we
could skip 1000 stat calls!

One slight weirdness: We refuse to add links to directories that we already visited, even if they are the last component and we don't actually follow them. That means we can't do the fast path here either, but we do know if something is a link (if we get d_type), so it still works in common cases.

(cherry picked from commit 86803e4442)
2023-10-08 17:15:20 +02:00
Fabian Boehm
18c65df3c7 Add a clear-screen bind function to clear the screen (#10044)
This can be bound like `bind \cl clear-screen`, and is, by default

In contrast to the current way it doesn't need the external `clear`
command that was always awkward.

Also it will clear the screen and first draw the old prompt to remove
flicker.
Then it will immediately trigger a repaint, so the prompt will be overwritten.

(cherry picked from commit c4ca1a68d3)
2023-10-08 17:15:20 +02:00
Fabian Boehm
11304f00cf Apply variable overrides for exec
Fixes #9995

(cherry picked from commit 496d65fb5d)
2023-10-08 17:15:20 +02:00
Fabian Boehm
ac64331217 reader: Only move cursor if needed for repaint-mode
This uses "screen.reset_line" to move the cursor without informing the
reader's machinery (because that deals with positions *in the
commandline*), but then only repainted "if needed" - meaning if the
reader thought anything changed.

That could lead to a situation where the cursor stays at column 0
until you do something, e.g. in

```fish
bind -m insert u undo
```

when you press alt+u - because the *escape* calls repaint-mode, which
puts the cursor in column 0, and then the undo doesn't, which keeps it
there.

Of course this binding should also `repaint-mode`, because it changes
the mode.

Some changes might be ergonomic:

1. Make repaint-mode the default if the mode changed (we would need to
skip it for bracketed-paste)
2. Make triggering the repaint easier - do we need to set
force_exec_prompt_and_repaint to false here as well?

Anyway, this

Fixes #7910

(cherry picked from commit ff433b0cb2)
2023-10-08 17:15:20 +02:00
Fabian Boehm
577dc2be94 screen: Unset color at the end of a line even without clr_eol
This is a sensible thing to do, and fixes some cases where we're
state-dependent.

E.g. this fixes the case in the pager where some things are bold and
some aren't, because that bolding is (rather awkwardly) implicitly
triggered when we have a background, and so we don't notice we need to
re-do that bolding after we moved to the next line because we think we
still have the same color.

Fixes #9617

(cherry picked from commit 10d91b0249)
2023-10-08 17:15:20 +02:00
Fabian Boehm
67a0c04605 reader: Use existing search string when opening the history pager
I sometimes find myself doing something like this:

- Look for a commandline that includes "echo" (as an example)
- Type echo, press up a few times
- I can't immediately find what I'm looking for
- Press ctrl-r to open up the history pager
- It uses the current commandline as the search string,
  so now I'm looking for "echo foobar"

This makes it so if the search string already is in use, that's what
the history-pager picks as the initial search string.

(cherry picked from commit 5b44c26a19)
2023-10-08 17:15:20 +02:00
Fabian Boehm
65db0b2ec8 fish_key_reader: Humanize key descriptions
This used to print all codepoints outside of the ASCII range (i.e.
above 0x80) in \uXXXX or \UYYYYYYYY notation.

That's quite awkward, considering that this is about keys that are
being pressed, and many keyboards have actual symbols for these on
them - I have an "ö" key, so I would like to use `bind ö` and not
`bind \u00F6`. So we go by iswgraph.

On a slightly different note, `\e` was written as `\c[ (or \e)`. I do
not believe anyone really uses `\c[` (the `[` would need to
be escaped!), and it's confusing and unnecessary to even mention that.

(cherry picked from commit 55c425a0dd)
2023-10-08 17:15:17 +02:00
Fabian Boehm
4d59d9cfb5 Also allow command and in a pipeline
Similar to `time`, except that one is more common as a command.

Note that this will also allow `builtin and`, which is somewhat
useless, but then it is also useless outside of a pipeline.

Addition to #9985

(cherry picked from commit b454b3bc40)
2023-10-06 18:54:25 +02:00
Fabian Boehm
7815cb363c parse_util: Only reject time in a pipeline without decorator
This allows e.g. `foo | command time`, while still rejecting `foo | time`.

(this should really be done in the ast itself, but tbh most of
parse_util kinda should)

Fixes #9985

(cherry picked from commit 482616f101)
2023-10-06 18:50:02 +02:00
Fabian Boehm
d1f3058c6d Remove a waccess call when completing executables
We have already run waccess with X_OK. We already *know* the file is
executable.

There is no reason to check again.

Restores some of the speedup from the fast_waccess hack that was
removed to fix #9699.

(cherry picked from commit ee75b45687)
2023-10-06 18:35:26 +02:00
Henrik Hørlück Berg
a7c8e0cdfb Fix #9899 integer overflow in string repeat
We could end up overflowing if we print out something that's a multiple of the
chunk size, which would then finish printing in the chunk-printing, but not
break out early.

(cherry picked from commit 6325b3662d)
2023-10-06 18:35:06 +02:00
Fabian Boehm
9892ce3a5a wildcard: Remove useless access() call for trailing slash
This confirmed that a file existed via access(file, F_OK).

But we already *know* that it does because this is the expansion for
the "trailing slash" - by definition all wildcard components up to
here have already been checked.

And it's not checking for directoryness either because it does F_OK.

This will remove one `access()` per result, which will cut the number
of syscalls needed for a glob that ends in a "/" in half.

This brings us on-par with e.g. `ls` (which uses statx while we use
newfstatat, but that should have about the same results)

Fixes #9891.

(cherry picked from commit 6823f5e337)
2023-10-01 10:37:29 +02:00
Fabian Boehm
72edd888f1 Return a falsey status if the last -c command has a parse error
This makes `fish -c begin` fail with a status of 127 - it already
printed a syntax error so that was weird. (127 was the status for
syntax errors when piping to fish, so we stay consistent with that)

We allow multiple `-c` commands, and this will return the regular
status if the last `-c` succeeded.

This is fundamentally an extremely weird situation but this is the
simple targeted fix - we did nothing, unsuccessfully, so we should
fail.

Things to consider in future:

1. Return something better than 127 - that's the status for "unknown
command"!
2. Fail after a `-c` failed, potentially even checking all of them
before executing the first?

Fixes #9888

(cherry picked from commit a6c36a014c)
2023-10-01 10:37:29 +02:00
Simon Börjesson
0d65d5a422 Redraw pager on new selection when nothing was selected previously
(cherry picked from commit 71c320ca32)
2023-10-01 10:37:28 +02:00
Xiretza
fc0e033b82 complete: fix condition to suppress variable autocompletion
(cherry picked from commit b76e6c5637)
2023-10-01 09:44:33 +02:00
Eric N. Vander Weele
5df36130b7 reader: Apply fish_color_selection fg color and options in vi visual mode
Vi visual mode selection highlighting behaves unexpectedly when the selection
foreground and background in the highlight spec don't match. The following
unexpected behaviors are:

*  The foreground color is not being applied when defined by the
   `fish_color_selection` variable.
* `set_color` options (e.g., `--bold`) would not be applied under the cursor
  when selection begins in the middle of the command line or when the cursor
  moves forward after visually selecting text backward.

With this change, visual selection respects the foreground color and any
`set_color` options are applied consistently regardless of where visual
selection begins and the position of the cursor during selection.

(cherry picked from commit 4ed53d4e3f)
2023-09-08 19:57:56 +02:00
ridiculousfish
47587ee05a Revert "Speed up executable command completions"
This reverts commit 0b55f08de2.

This was found to have caused regressions in completions in #9699

(cherry picked from commit c67d77fc18)
2023-09-08 19:57:56 +02:00
Fabian Boehm
3bef75fb79 builtins: Don't crash for negative return values
Another from the "why are we asserting instead of doing something
sensible" department.

The alternative is to make exit() and return() compute their own exit
code, but tbh I don't want any *other* builtin to hit this either?

Fixes #9659

(cherry picked from commit a16abf22d9)
2023-09-08 19:57:41 +02:00
Fabian Boehm
693595a6c0 Silence fstatat errors
These just keep happening, people run haunted computers.

Fixes #9674.

(cherry picked from commit cd7e8c00e1)
2023-03-21 17:17:55 +01:00
Xiretza
b1dc7e8697 builtins: set_color: remove unhandled -v/--version flag
Invoking `set_color -v` crashes fish.

(cherry picked from commit dd7b177d72)
2023-03-05 16:09:47 +01:00
Fabian Boehm
37575c5f79 reader: Remove assert in history search
This isn't a great use of `assert` because it turns a benign "oh I
need to search again" bug into a crash.

Fixes #9628

(cherry picked from commit 7c91d009c1)
2023-03-02 16:34:19 +01:00
Fabian Boehm
1a20184ba4 Silence ENODEV errors for fstatat
Some broken gdrive filesystem can return these.

Fixes #9550

(cherry picked from commit e90f003d2d)
2023-02-27 22:40:59 +08:00
Fabian Boehm
a48c787439 Add workaround for Midnight Commander's issue with prompt extraction
When we draw the prompt, we move the cursor to the actual
position *we* think it is by issuing a carriage return (via
`move(0,0)`), and then going forward until we hit the spot.

This helps when the terminal and fish disagree on the width of the
prompt, because we are now definitely in the correct place, so we can
only overwrite a bit of the prompt (if it renders longer than we
expected) or leave space after the prompt. Both of these are benign in
comparison to staircase effects we would otherwise get.

Unfortunately, midnight commander ("mc") tries to extract the last
line of the prompt, and does so in a way that is overly naive - it
resets everything to 0 when it sees a `\r`, and doesn't account for
cursor movement. In effect it's playing a terminal, but not committing
to the bit.

Since this has been an open request in mc for quite a while, we hack
around it, by checking the $MC_SID environment variable.

If we see it, we skip the clearing. We end up most likely doing
relative movement from where we think we are, and in most cases it
should be *fine*.

(cherry picked from commit b1b2294390)
2023-02-27 22:24:13 +08:00
Fabian Boehm
ef5b29652f Fix last PCRE2_UCHAR32
See #9502

(cherry picked from commit bd871c5372)
2023-01-23 20:04:43 +01:00
Fabian Boehm
9043008933 abbr: Clarify universal variable message
And give explicit upgrade instructions.
2023-01-21 16:53:59 +01:00
Fabian Boehm
52d2087dd3 re: Use the variable-width pcre2 type
This was what we always did in string. It makes it match the
annoyingly variable width of wchar_t.

Fixes #9502
2023-01-21 10:49:44 +01:00
Johannes Altmanninger
e84f588d11 reader: make Escape during history search restore commandline again
Commit 3b30d92b6 (Commit transient edit when closing pager, 2022-08-31)
inadvertently introduced two regressions to history search:

1. It made Escape keeps the selected history entry,
   instead of restoring the commandline before history search.
2. It made history search commands add undo entries.

Fix both of this issues.
2023-01-17 09:31:04 +01:00
Fabian Boehm
6df09b3753
completions: Offer ../ and ./ again (#9477)
Inadvertently broken in a2d816710f,
this made `cd .` no longer offer `cd ../` (same for general file completions
like `ls .`, which only offers dotfiles)
2023-01-16 10:05:01 +01:00
Fabian Boehm
077118d983 abbr: Fix crash when no name has been given
This crashed for

```fish
abbr --add --regex '{\d+..\d+}' --function foo
```

i.e. a regex and a function but no name - that's 0 additional
arguments.
2023-01-15 10:50:09 +01:00
Fabian Boehm
da0c640750 abbr: Warn when -U is given
This prints a warning to stderr and then still does the thing.

Because of the error trailer, it points to the abbr help page.
2023-01-14 22:27:28 +01:00
Fabian Boehm
5c56fa0e6f Remove str2wcs special case for MB_CUR_MAX
This meant we didn't actually do our weird en/decoding scheme for e.g.
a C locale, which meant that, when you then switch to a proper locale
the previous variables were broken.

I don't know how to test this automatically - none of my attempts seem
to ever *fail* with the old code, here's what you'd do manually:

- Run fish with an actual C locale (LC_ALL=C
fish_allow_singlebyte_locale=1 fish)
- `set -gx foo 💩`
- `set -e LC_ALL`
- `echo $foo` outputs "💩" if it works and "ð⏎" if it's broken.

Fixes #2613
2023-01-14 22:27:16 +01:00
ridiculousfish
7fa13e4451 Remove enum_iter_t
This was unused.
2023-01-14 12:58:20 -08:00
Fabian Boehm
9ef7fe1a15 Make one error translatable
This is now the same as in `read`
2023-01-13 17:57:04 +01:00
Fabian Boehm
dad8c527e0 read: Error on read-only variables
Fixes #9346
2023-01-13 17:56:28 +01:00
Fabian Boehm
1b1cf73b60 abbr: Stop escaping the name for abbr --list
This is so we can pass it to `abbr --erase`.

Fixes #9470
2023-01-13 16:38:34 +01:00
Fabian Boehm
572a568268 abbr: Erase the old universal variable with abbr --erase
This means cleaning out old universal variables is now just:

```fish
abbr --erase (abbr --list)
```

which makes upgrading much easier.

Note that this erases the currently defined variable and/or any
universal. It doesn't stop at the former because that makes it *easy*
to remove the universals (no running `abbr --erase` twice), and it
doesn't care about globals because, well, they would be gone on
restart anyway.

Fixes #9468.
2023-01-13 16:09:53 +01:00
Fabian Boehm
1d455be9fa Cleanup 2023-01-09 22:53:34 +01:00
Fabian Boehm
5792e4a12b
Make history pager use more entries (#9458)
Like I mentioned in #9089, 12 entries is a bit few.

So, instead, we do like we do for completions before disclosing and
pick half the screen (but at least X, in this case 12).

This avoids filling the entire screen, and will avoid an unsightly "X
more entries" (which requires scrolling down to fully disclose)
because it matches what the pager does.

Note: For multiline commands we can be pushed further upwards, and in
case of a multi-column layout we could fit more lines. That would
require asking the pager to fit as many as possible and give us back
the index of the last matching entry and rewinding the history search.

That's gonna be left as an exercise for later if it turns out to be necessary.
2023-01-09 21:39:55 +01:00
Fabian Boehm
f1a150ed43 postfork: Also check if interpreter is a directory
"#!/bin/"
2023-01-08 12:44:02 +01:00