Commit Graph

1530 Commits

Author SHA1 Message Date
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
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
2da1a4ae77 completions/git: Fix git-foo commands
Broken in f5711ad5ed, this neglected to
remove the `git-` part from the command

Fixes #9457.
2023-01-09 18:40:24 +01:00
Fabian Boehm
4c39aeed87 abbr: Let --function use a mandatory argument
This now means `abbr --add` has two modes:

```fish
abbr --add name --function foo --regex regex
```

```fish
abbr --add name --regex regex replacement
```

This is because `--function` was seen to be confusing as a boolean flag.
2022-12-24 10:29:26 +01:00
Fabian Boehm
ff800c68e8 tests: Increase one more timeout
Example output from a Cirrus bionic-asan-clang run:

```
fish: Unknown command: man
/tmp/cirrus-ci-build/share/functions/__fish_man_page.fish (line 30):
        if man "$maincmd" &>/dev/null
           ^~^
in function '__fish_man_page'
�

[I] prompt 9>echo TEXT
[I] prompt 9>echo TEXThrAi
[I] prompt 9>echo TEXThrAi
TEXThrAi
```

Yes, this detected escape, waiting *300ms* and then "h" as being below
the escape timeout of 120ms.
2022-12-23 12:18:20 +01:00
Fabian Boehm
3932559409 Fix tests
I always forget that littlecheck escapes these
2022-12-22 17:34:10 +01:00
Fabian Boehm
3005adebd5 Revert "Remove print_hints from builtin_missing_argument and builtin_unknown_option"
Unfortunately print_hints was true *by default* - so for all builtins
that didn't pass it it would now be false instead.

This resulted in the trailer missing, which includes the line number
and context. So if you ran a script that includes `bind -M` the error
message would now just be "bind: -M: option requires an argument",
with no indication as to where.

This reverts commit 8a50d47a46.
2022-12-22 17:24:47 +01:00
Fabian Boehm
bb98cb01c7 abbr: Also show --position
(if not the default)
2022-12-14 18:06:24 +01:00
Fabian Boehm
30a37d9433 abbr: Make show output actually work
This would print

```
abbr -a -- dotdot --regex ^\\.\\.+\$ --function multicd
```

which expands "dotdot" to "--regex ^\\.\\.+\$...".

Instead, we move the name to right before the replacement, and move
the `--` before that:

```
abbr -a --regex ^\\.\\.+\$ --function -- dotdot multicd
```

It might be possible to improve that, but this at least round-trips.
2022-12-13 19:38:58 +01:00
Johannes Altmanninger
9790907ca8 abbr: stop parsing option after first expansion token
Historical behavior is to stop option parsing at the first non-option argument.
Since we have added more options, it seemed impractical to keep that behavior.

However people are using options in their abbr expansions ("abbr e emacs
-nw").  To support this, we ignore options. However, we only ignore them
if they are not valid "abbr" options.  Let's ignore all options in the
expansion definition, which is a small price to pay to keep most existing
configurations working.

Fixes #9410

This does not fix other cases which used to work, like

    abbr x -unknown

Those are hopefully not used by anyone, so I don't think we need to maintain
support for that.
2022-12-13 01:39:31 +01:00
ridiculousfish
d8dbb9b259 Switch abbreviation '-r' flag from --rename to --regex
This will be the more common option and provides consistency with
`string`.
2022-12-10 16:21:39 -08:00
ridiculousfish
e08f4db1f9 Rename abbreviation cursor "sentinel" to "marker"
Also default the marker to '%'. So you may write:

    abbr -a L --position anywhere --set-cursor "% | less"

or set an explicit marker:

   abbr -a L --position anywhere --set-cursor=! "! | less"
2022-12-10 16:15:03 -08:00
ridiculousfish
01039537b0 Remove abbreviation triggers
Per code review, this does not add enough value to introduce now.
Leaving the feature in history should want want to revisit this
in the future.
2022-12-10 16:15:00 -08:00
ridiculousfish
35a4688650 Rename abbreviation triggers
This renames abbreviation triggers from `--trigger-on entry` and
`--trigger-on exec` to `--on-space` and `--on-enter`. These names are less
precise, as abbreviations trigger on any character that terminates a word
or any key binding that triggers exec, but they're also more human friendly
and that's a better tradeoff.
2022-12-10 15:38:50 -08:00
ridiculousfish
5841e9f712 Remove '--quiet' feature of abbreviations
Per code review, this is too risky to introduce now. Leaving the feature
in history should want want to revisit this in the future.
2022-12-10 15:38:50 -08:00
ridiculousfish
c51a1f1f60 Implement trigger-on for abbreviations
trigger-on enables abbreviations to trigger only on "entry" (anything
which closes a token, like space) or only on "exec" (typically enter key).
2022-12-10 15:38:50 -08:00
ridiculousfish
7118cb1ae1 Implement set-cursor for abbreviations
set-cursor enables abbreviations to specify the cursor location after
expansion, by passing in a string which is expected to be found in the
expansion. For example you may create an abbreviation like `L!`:

    abbr L! --position anywhere --set-cursor ! "! | less"

and the cursor will be positioned where the "!" is after expansion, with
the "| less" appearing to its right.
2022-12-10 15:38:50 -08:00
ridiculousfish
1d205d0bbd Reimplement abbreviation expansion to support quiet abbreviations
This reimplements abbreviation to support quiet abbreviations. Quiet
abbreviations expand "in secret" before execution.
2022-12-10 15:38:46 -08:00
ridiculousfish
8135c52c13 Abbreviations to support functions
This adds support for the `--function` option of abbreviations, so that the
expansion of an abbreviation may be generated dynamically via a fish
function.
2022-12-10 15:29:04 -08:00
ridiculousfish
d15855d3e3 Abbreviations to support matching via regex
This adds the --regex option to abbreviations, allowing them to match a
pattern of tokens.
2022-12-10 15:29:04 -08:00
ridiculousfish
1402bae7f4 Re-implement abbreviations as a built-in
Prior to this change, abbreviations were stored as fish variables, often
universal. However we intend to add additional features to abbreviations
which would be very awkward to shoe-horn into variables.

Re-implement abbreviations using a builtin, managing them internally.

Existing abbreviations stored in universal variables are still imported,
for compatibility. However new abbreviations will need to be added to a
function. A follow-up commit will add it.

Now that abbr is a built-in, remove the abbr function; but leave the
abbr.fish file so that stale files from past installs do not override
the abbr builtin.
2022-12-10 15:29:03 -08:00
ridiculousfish
635cc3ee8d Add interactive tests for abbreviations 2022-12-10 15:28:48 -08:00
ridiculousfish
5523eb36db Switch functions tests from abbr to vared
abbr was a random function that was tested by this check, but we no
longer have an abbr function so switch to a new one.
2022-12-10 12:24:43 -08:00
Johannes Altmanninger
892a820672 Make sure that cd to a relative CDPATH results in absolute $PWD
We have had multiple crashes for relative CDPATH entries.  Commit 5e274066e
(Always return absolute path in path_get_cdpath, 2019-10-17) tried to fix
all of them but it failed to do justice to its title.  Let's fix this to
actually return absolute paths, always.  Take care to to normalize the path
because it is used for autosuggestions. The normalization is mostly relevant
for CDPATH=. (the default) but it doesn't hurt others.

Closes #9407
2022-12-10 11:06:54 +01:00
ridiculousfish
4159b2a33b Disable shebangless script tests in CI with sanitizers
Sanitizers inject a busted posix_spawn interceptor which mishandles
shebangless scripts. Disable this test under sanitizers.
2022-12-02 17:32:52 -08:00
Fabian Boehm
b8424e425f fixup! 2
That'll teach me
2022-11-15 19:05:18 +01:00
Fabian Boehm
cb48ab882c fixup! 2022-11-15 19:03:06 +01:00
Fabian Boehm
0f8b9699a1 Fix error for {$}
Fixes #9337
2022-11-15 19:02:30 +01:00
ridiculousfish
e9fde96d9c Fix the commandline test
This was tripping over < > redirections.
2022-11-12 14:25:47 -08:00
Johannes Altmanninger
c4a60feff1 Stop attempting to complete inside comments
Inside a comment we offer plain file completions (or command completions if
the comment is in command position). However these completions are broken
because they don't consider any of the surrounding characters. For example
with a command line

    echo # comment
              ^ cursor

we suggest file completions and insert them as

    echo # comsomefile ment

Providing completions inside comments does not seem useful and it can be
misleading. Let's remove the completions; this should communicate better that
we are in a free-form comment that's not subject to fish syntax.

Closes #9320
2022-11-12 22:37:27 +01:00
Johannes Altmanninger
c6e1704f00 pexpect test for commandline --current-process
It was not clear to me hwo this behaves when there are comments.

Include a friendly helper to compute control characters.
No functional change.
2022-11-12 22:34:31 +01:00
Aaron Gyes
e38c9bb062 builtin set --show: put read-only part on same line. 2022-11-12 06:21:36 -08:00
Aaron Gyes
1a0d6ebe59 builtins/printf: use wcsto[i,u]max, check EINVAL, add test
This fixes #9321

IEEE Std 1003.1-2017 Issue 6 added optional error condition
[EINVAL] for if no conversion could be performed.

Switch back to wcstoimax/wcstoumax: do not work around the old FreeBSD
8 issue.

Add a test for printf '%d %d' 1 2 3
2022-10-31 19:58:18 -07:00
Mahmoud Al-Qudsi
8168ed7bf6 Test complete builtin sort of (sorted + unsorted) completions
Like the pexpect-based pager compeltions test `complete-group-order.py`, but for
the `complete` builtin. Verifies the same sort/dedup rules that apply to the
pager are also applied to the output of `complete` and asserts the sort behavior
for multiple `complete -k` calls for the same command and with the same (or with
both passing) preconditions.
2022-10-31 16:52:44 -05:00
Mahmoud Al-Qudsi
4cb19e244b Sort and deduplicate output of complete -C
This addresses a long-standing TODO where `complete -C` output isn't
deduplicated.

With this patch, the same deduplication and sort procedure that is run on actual
pager completions is also executed for `complete -C` completions (with a `-C`
payload specified).

This makes it possible to use `complete -C` to test what completions will
actually be generated by the completions pager instead of it displaying
something completely divorced from reality, improving the productivity of fish
completions developers.

Note that completions that wouldn't be shown in the pager are also omitted from
the results, e.g. `test/buildroot/` and `test/fish_expand_test/` are omitted
from the check matches in `checks/complete_directories.fish` because even if
they were generated, the pager wouldn't have shown them. This again makes
reasoning about and debugging completions much easier and more sane.
2022-10-31 16:52:36 -05:00
Fabian Boehm
8d7662335e function: Don't list empty function names and directories 2022-10-29 10:24:42 +02:00
Aaron Gyes
92698dff48 Unallowed command subst error: add missing newline and simplify
Fixes ommitted newline char shown after complete -n'(foo)'
Also axes the 'contains syntax errors' line before the error.
Update tests

before
> complete -n'(foo)'
complete: Condition '(foo)' contained a syntax error
complete: Command substitutions not allowed⏎

after
> complete -n'(foo)'
complete: -n '(foo)': command substitutions not allowed here
2022-10-26 19:58:40 -07:00
Mahmoud Al-Qudsi
06d9708d40 Add complete -k group order test
Ensure that multiple `-k` completions intermixed with one or more non-`-k`
completions are produced in the expected order with the order of all completions
in a single `-k` completion respected, non-`-k` completions correctly sorted and
interspersed, and the results of multiple `-k` completions in the
reverse-intuitive order (with chronologically later completions coming before
chronologically earlier `-k` counterparts), as per #9221.
2022-10-26 13:22:45 -05:00
Mahmoud Al-Qudsi
125bcb8289 Add pexpect test for status current-commandline 2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
2c870b305d Add eval recursion overflow regression test
This particular variant must be executed as a pexpect test since it relies on
the interactive-only `$history` to trigger the recursion. Note that recursion is
possible via other means (e.g. reading/writing a file), the usage of history
here is just one such example.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
3913b28153 Only retry failed pexpect tests under CI
A false negative while testing locally should be a rare thing, and individual
pexpect tests already take too long in case of a non-match making for a painful
edit-test loop.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
21599a49ea Make CALL_STACK_LIMIT_EXCEEDED_ERR_MSG more generic
We're now using this when a stack overflow is detected during eval/substitution
loops, too.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
07fc04465f Add regression test for trap -p 2022-10-24 15:36:02 -05:00
ridiculousfish
74fd66fcbe Use -- before seq for negative numbers
busybox seq was complaining about the command:

    seq -550 -1

because it was trying to interpret -550 as a flag. Use -- to prevent
this.
2022-10-23 13:53:36 -07:00
Fabian Boehm
8c362c89b5
git prompt: Interpret values of "1", "yes" or "true" as true for bools instead of relying on defined-or-not (#9274)
This allows explicitly turning these settings off by setting the variable to e.g. 0.

See #7120
2022-10-21 20:22:20 +02:00
Mahmoud Al-Qudsi
fb7f2d97e9 Add tests for erasing from multiple scopes 2022-10-20 11:21:05 -05:00
Fabian Boehm
52dcfe11af Make \x the same as \X
Up to now, in normal locales \x was essentially the same as \X, except
that it errored if given a value > 0x7f.

That's kind of annoying and useless.

A subtle change is that `\xHH` now represents the character (if any)
encoded by the byte value "HH", so even for values <= 0x7f if that's
not the same as the ASCII value we would diverge.

I do not believe anyone has ever run fish on a system where that
distinction matters. It isn't a thing for UTF-8, it isn't a thing for
ASCII, it isn't a thing for UTF-16, it isn't a thing for any extended
ASCII scheme - ISO8859-X, it isn't a thing for SHIFT-JIS.

I am reasonably certain we are making that same assumption in other
places.

Fixes #1352
2022-10-09 15:24:01 +02:00
Fabian Boehm
396e276286 Decode multibyte escapes immediately
We forgot to decode (i.e. turn into nice wchar_t codepoints)
"byte_literal" escape sequences. This meant that e.g.

```fish
string match ö \Xc3\Xb6

math 5 \X2b 5
```

didn't work, but `math 5 \x2b 5` did, and would print the wonderful
error:

```
math: Error: Missing operator
'5 + 5'
   ^
```

So, instead, we decode eagerly.
2022-10-05 18:55:01 +02:00
Fabian Boehm
dcf52dbba5 fix path --null-out
Regression from 7bc4c9674b.

Appending `"\0"` to an std::string does nothing.

I blame C++.
2022-10-05 17:25:00 +02:00
Fabian Boehm
cb28b39b24 string shorten: Make max of 0 mean no shortening
This makes it easier to just slot in `string shorten` wherever,
without having to do a weird "if test $max -gt 0" check.
2022-10-04 18:44:21 +02:00
Mahmoud Al-Qudsi
3ebfba7f5b Test return builtin doesn't map negative numbers to zero
Prior to 1811a2d, the return value for negative return codes was UB and I'd
witnessed both expected cases like -256 mapping to a $status of 0 and unexpected
cases like a return value of -1 mapping to a $status of 0. As such, this doesn't
test just one fixed return value but the entire range from negative multiples of
256 all the way down (rather, up!) to -1.
2022-09-25 12:37:10 -05:00
Mahmoud Al-Qudsi
e9908d7d41 Clean up more mktemp usage residue
...for improved cross-platform support.

Following up on the work in c90ac7b. There was one more test that had mktemp in
the littlecheck "shebang" and this also removes a now-unnecessary `env` prefix.
2022-09-23 11:05:58 -05:00
Mahmoud Al-Qudsi
c90ac7bf7f Fix tests on macOS 10.10
All usages of `mktemp` must go through the (fish-only) `mktemp` test function
that abstracts over the differences across multiple platforms/flavors.

Tests can be easily run individually via `ninja -C build test_xxx` and there
isn't a good reason to randomly manually override $HOME and $XDG_CONFIG_HOME for
a test here and a test there.

If it's absolutely necessary, littlecheck.py should be extended to support a
`%temp` variable initialized to a temporary directory and that can be used
instead of calling out to the platform-provided `mktemp` via a subshell.
2022-09-22 17:39:28 -05:00
Fabian Boehm
88e578a9ed Remove superfluous CHECK lines
Oops
2022-09-21 18:37:38 +02:00
Fabian Boehm
3dded49b9b tests/checks/test: Attempt to fix on old Ubuntu
For unknown reasons, the i686 launchpad builders fail on this date,
but apparently not the others.

Let's just remove it, we've tested dates older than the epoch, this is
slightly redundant.
2022-09-21 18:20:05 +02:00
Mahmoud Al-Qudsi
ed67f2d221 Drop a now-incorrect check test from checks/git.fish
As discussed in #9221, a bug in the autocomplete that was fixed in 66391922
caused completions to be incorrectly suppressed. The dropped test/check was
inadvertently relying on the buggy behavior and expected a git invocation to
generate no completions but there are, in fact, completions now that the bug has
been resolved.

cc @faho: I'm not sure if you want to replace this with a different check that
actually doesn't yield any completions or if you're happy with it just being
dropped.
2022-09-20 21:56:54 -05:00
Fabian Boehm
4ffcbe3526 tests/path: Allow a little slack
This was 86400 on some systems but 82800 on mine. I think that's a
timezone thing?
2022-09-20 16:17:32 +02:00
Fabian Boehm
9493e7725f tests/test: Don't use seconds in the mtime
This fails on old Ubuntu with:

> touch: invalid date format ‘190112112040.39’

Because we don't actually need the seconds here, we just use minute
resolution. It's fine.

Also use `path mtime`, because that's a portable way to get the mtime.
2022-09-20 16:10:17 +02:00
Fabian Boehm
8b1da4b63d path: Actually use mtime instead of ctime
Fixes #9222
2022-09-20 16:10:17 +02:00
Mahmoud Al-Qudsi
472fc3ec10 [tests] Fix pre-epoch test workaround on non-Linux
I forgot `stat` is non-portable. There's no great way to portably get a
machine-readable representation of stat(2) for a file. I don't want to ship our
own lstat(2) wrapper executable just for this test and don't want to fork out to
python or perl for this either - I just wanted to get the tests to pass under
WSL :'(

Anyway, just give up and make it skip just for WSL. If another OS fails this
test in the future, the comments and existing workaround will make it easy to
figure out what the problem is and what needs to be done. We'll cross that
bridge when we get there.
2022-09-16 19:38:49 -05:00
Mahmoud Al-Qudsi
613ecfc7e4 Fix pre-epoch test workaround
It turns out that not all systems print an unsigned integer as the output of
`stat -c %Y xxx` and the leading `-` can be misinterpreted as a parameter to
`string match`.
2022-09-16 18:58:21 -05:00
Mahmoud Al-Qudsi
f97650bf9a Fix stale references to getch() 2022-09-16 18:26:49 -05:00
Mahmoud Al-Qudsi
f1266dd8f5 [tests] Add count to "Wacky Handler" text
This makes it easier to figure out where the failure is taking place when the
output mismatches and the contents of the buffer are printed.
2022-09-16 18:26:49 -05:00
Mahmoud Al-Qudsi
32f7f5bd32 [tests] Increase tmux-sleep duration when not under CI
The tmux-complete test would regularly fail for me under WSL (AMD TR 1950X)
without this small increase in sleep time.
2022-09-16 18:26:49 -05:00
Mahmoud Al-Qudsi
30cd330b98 Fix test.fish pre-epoch comparisons on WSL and others
There's no guarantee (nor requirement) that the filesystem support pre-epoch
modification dates. If it doesn't, the `test` tests were failing to get the
expected results.

Skip the test if it seems the fs doesn't support pre-epoch timestamps
(determined by pre-epoch mt of `oldest` evaluating to 0 or the unix epoch).
2022-09-16 16:24:00 -05:00
Mahmoud Al-Qudsi
d2f6c925e1 Add checks for incomplete escape sequences
Also codify in tests the current, case-sensitive behavior of \C vs \c
2022-09-16 15:44:33 -05:00
Maxime Bouillot
d50e9ffff3
Add the possibility to ignore arguments in alliases (#9199)
* Replace ";" with "\n" in alias-generated functions

This can let us add a "#" in our aliases to make
them ignore additional arguments.

* Update changelog about aliases that ignore arguments

* Update test for alias.fish

This is now compliant with the aliases that can
ignore arguments.
2022-09-11 09:55:11 +02:00
ridiculousfish
5cf0778207 Claim the tty unconditionally in reader_data_t::readline
When fish runs with job control enabled, it transfers ownership of the
tty to a child process, and then reclaims the tty after the process
exits. If job control is disabled then fish does not transfer or reclaim
the tty.

It may happen that the child process creates a pgroup and then transfers
the tty to it. In that case fish will not attempt to reclaim the tty, as
fish did not transfer it. Then when fish reads from stdin it will
receive SIGTTIN instead of data.

Fix this by unconditionally claiming the tty in readline().

Fixes #9181
2022-09-09 13:43:29 -07:00
Fabian Boehm
bc1a5ba033 Test division by zero with min
This would actually return any finite argument before!
2022-09-09 18:52:45 +02:00
Fabian Boehm
24fd26ae6e Fix error for vararg functions with zero arguments 2022-09-09 18:52:45 +02:00
Fabian Boehm
c284c4ca99 Add length also for too-many/few-args error 2022-09-09 18:52:45 +02:00
Fabian Boehm
a3ee7da812 math: Add length to missing operator error 2022-09-09 18:52:45 +02:00
Fabian Boehm
52e065e479 math: Add error length
Like we now do for syntax errors, this marks the extent of the error.

Currently for unknown functions only, would be cool for division too
2022-09-09 18:52:45 +02:00
Fabian Boehm
5edba044a3 math: Give a proper error for division by zero
This errored out *later* because the result was infinite or NaN, but
it didn't actually stop evaluation.

I'm not sure if there is a way to get floating point math to turn an
infinity back into something that doesn't depend on a literal
infinity, but division by zero conceptually isn't a thing we can
support.

There's entire branches of maths dedicated to figuring out what
dividing by "basically zero" means and we don't have to get into it.
2022-09-09 18:52:45 +02:00
Fabian Boehm
41c22d5e60 Add string shorten
This is essentially the inverse of `string pad`.
Where that adds characters to get up to the specified width,
this adds an ellipsis to a string if it goes over a specific maximum width.
The char can be given, but defaults to our ellipsis string.
("…" if the locale can handle it and "..." otherwise)

If the ellipsis string is empty, it just truncates.

For arguments given via argv, it goes line-by-line,
because otherwise length makes no sense.

If "--no-newline" is given, it adds an ellipsis instead and removes all subsequent lines.

Like pad and `length --visible`, it goes by visible width,
skipping recognized escape sequences, as those have no influence on width.

The default target width is the shortest of the given widths that is non-zero.

If the ellipsis is already wider than the target width,
we truncate instead. This is safer overall, so we don't e.g. move into a new line.
This is especially important given our default ellipsis might be width 3.
2022-09-09 18:49:57 +02:00
Johannes Altmanninger
3b30d92b62 Commit transient edit when closing pager
When selecting items in the pager, only the latest of those items is kept
in the edit history, as so-called transient edit.  Each new transient edit
evicts any old transient edit (via undo).

If the pager is closed by a command that performs another transient edit
(like history-token-search-backward) we thus inadvertently undo (= remove)
the token inserted by the pager.  Fix this by closing a transient edit
session when closing the pager.  Token search will start its own session.

Fixes #9160
2022-08-31 07:49:49 +02:00
Fabian Boehm
9e9c73e46a tests/signals.py: Kill leftover sleeps from python
This starts two sleep processes and expects them to be killed on
SIGHUP.

Unfortunately, if this ever fails the second run will also fail
because it'll see the old sleep still lying around (because it'll run
for 130 seconds).

So, what we do is:

1. Keep the pids for these specific sleeps
2. Check if any of them are still running (and only fail for them)
3. Kill them from python

Fixes #9152
2022-08-23 18:47:52 +02:00
Fabian Boehm
40733ca25b If relative path was used, use it
This was inadvertently changed in
ed78fd2a5f

Fixes #9143
2022-08-15 20:01:50 +02:00
Fabian Boehm
8d7416048d Don't skip caret for some errors
This checked specifically for "| and" and "a=b" and then just gave the
error without a caret at all.

E.g. for a /tmp/broken.fish that contains

```fish
echo foo

echo foo | and cat
```

This would print:

```
/tmp/broken.fish (line 3): The 'and' command can not be used in a pipeline
warning: Error while reading file /tmp/broken.fish
```

without any indication other than the line number as to the location
of the error.

Now we do

```
/tmp/broken.fish (line 3): The 'and' command can not be used in a pipeline
echo foo | and cat
           ^~^
warning: Error while reading file /tmp/broken.fish
```

Another nice one:

```
fish --no-config -c 'echo notprinted; echo foo; a=b'
```

failed to give the error message!

(Note: Is it really a "warning" if we failed to read the one file we
wer told to?)

We should check if we should either centralize these error messages
completely, or always pass them and remove this "code" system, because
it's only used in some cases.
2022-08-12 18:38:47 +02:00
Fabian Boehm
232ca25ff9 Add length to the parse_util syntax errors 2022-08-12 18:38:47 +02:00
Fabian Boehm
4b921cbc08 Clamp error carets to the end instead of refusing to print
This skipped printing a "^" line if the start or length of the error
was longer than the source.

That seems like the correc thing at first glance, however it means
that the caret line isn't skipped *if the file goes on*.

So, for example

```fish
echo "$abc["
```

by itself, in a file or via `fish -c`, would not print an error, but

```fish
echo "$abc["
true
```

would. That's not a great way to print errors.

So instead we just.. imagine the start was at most at the end.

The underlying issue why `echo "$abc["` causes this is that `wcstol`
didn't move the end pointer for the index value (because there is no
number there). I'd fix this, but apparently some of
our recursive variable calls absolutely rely on this position value.
2022-08-12 18:38:47 +02:00
Fabian Boehm
c3fb927c9a Add more tests
These were correct, but littlecheck escapes quotes!
2022-08-12 18:38:47 +02:00
Fabian Boehm
c1bf06d5b1 Print "^^" for a 2-wide error 2022-08-12 18:38:47 +02:00
Fabian Boehm
eaf92918e6 Fix error offset for command (foo)
This used the decorated statement offset when the expansion errors
refer to the command without decoration.
2022-08-12 18:38:47 +02:00
Fabian Boehm
a4fd3c194e Pass location of the *command* node without decorators
Fixes error location for unknown commands
2022-08-12 18:38:47 +02:00
Fabian Boehm
150409eabd Add acceptable errors to tests 2022-08-12 18:38:47 +02:00
Fabian Boehm
b2eea4b46f complete: Don't load completions if command isn't in $PATH
This stops us from loading the completions for e.g. `./foo` if there
is no `foo` in path.

This is because the completion scripts will call an unqualified `foo`,
and then error out.

This of course means if the script would work because it never calls
the command, we still don't load it.

Pathed completions via `complete --path` should be unaffected because
they aren't autoloaded anyway.

Workaround for #3117
Fixes #9133
2022-08-11 17:05:32 +02:00
Fabian Boehm
2191faf17e Fix tests
Turns out we checked one of the descriptions I had adjusted. Oops!
2022-08-10 18:02:12 +02:00
Fabian Boehm
37f7818bbb printf: Ignore any options
This was misguidedly "fixed" in
9e08609f85, which made printf error out
with any "-"-prefixed words as the first argument.

Note: This means currently `printf --help` doesn't print the help.
This also matches `echo`, and we currently don't have anything to make
a literal `--help` execute a builtin help except for keywords. Oh well.

Fixes #9132
2022-08-10 16:55:56 +02:00
Fabian Boehm
b89249de98 Reset the read byte limit to the default when unset
This used to be kept, so e.g. testing it with

    fish_read_limit=5 echo (string repeat -n 10 a)

would cause the prompt and such to error as well.

Also there was no good way to get back to the default value
afterwards.
2022-08-09 19:59:10 +02:00
Fabian Boehm
eac808a819
string repeat: Don't allocate repeated string all at once (#9124)
* string repeat: Don't allocate repeated string all at once

This used to allocate one string and fill it with the necessary
repetitions, which could be a very very large string.

Now, it instead uses one buffer and fills it to a chunk size,
and then writes that.

This fixes:

1. We no longer crash with too large max/count values. Before they
caused a bad_alloc because we tried to fill all RAM.
2. We no longer fill all RAM if given a big-but-not-too-big value. You
could've caused fish to eat *most* of your RAM here.
3. It can start writing almost immediately, instead of waiting
potentially minutes to start.

Performance is about the same to slightly faster overall.
2022-08-09 19:58:56 +02:00
Johannes Altmanninger
095c093af6 Fix "commandline --paging-mode" false negative when there is no room for pager, attempt 2
The previous fix was reverted because it broke another scenario.  Add tests
for both scenarios.

The first test exposes another problem: autosuggestions are sometimes not
recomputed after selecting the first completion with Tab Tab. Fix that too.
2022-07-31 07:14:56 +02:00
ridiculousfish
2410e27d10 Add a test and CHANGELOG fix for #9096 2022-07-30 10:14:19 -07:00
Michael Forster
6003edfb42 Add test for the default cursor selection mode
Also add documentation for the tests
2022-07-30 09:49:07 -07:00
Michael Forster
ef9994d55a Don't use Python f-strings in tests 2022-07-30 09:49:07 -07:00
Michael Forster
7d198fa404 Add an initial test for fish_cursor_selection_mode 2022-07-30 09:49:07 -07:00
Johannes Altmanninger
83893558f9 Make ESCAPE_NO_PRINTABLES behavior a bit less weird
Since the fix for #3892, this escaping style escapes

	\n to \\n

as well as

	\\ to \\\\
	\' to \\'

I believe these two are the only printable characters that are escaped with
ESCAPE_NO_PRINTABLES.
The rationale is probably to keep the encoding unambiguous and reversible.
However that doesn't justify escaping the single quote. Probably this was
an accident, so let's revert that part.

This has the nice effect that single quotes will no longer be escaped
when rendered in the completion pager (which is consistent with other
special characters). Try it:

    complete : -a "aaa\'\; aaaa\'\;" -f

Also this makes the error output of builtin bind consistent:

    $ bind -e --preset \;
    $ bind -e --preset \'
    $ bind \;
    bind: No binding found for sequence “;”
    $ bind \'
    bind: No binding found for sequence “'”

the last line is clearly better than the old version:

    bind: No binding found for sequence “\'”

In general, the fact that ESCAPE_NO_PRINTABLES escapes the (printable)
backslash is weird but I guess it's fine because it looks more consistent to
users, even though the result is an undocumented subset of the fish language.
2022-07-27 11:24:35 +02:00
Johannes Altmanninger
fe2f6f0c63 Fix Escape in pager not removing the inserted completion if search field was used
command_line_has_transient_edit tracks the actual command line, not the
pager search field. We accidentally reset it after modifying the search field
which causes unexpected behavior - the commandline added by the completion
pager remains even after I press Escape.
2022-07-26 15:29:52 +02:00
Fabian Boehm
ff497e25c0 tests: Rename a function
NetBSD actually has a /usr/bin/error by default, so we ended up
starting that.
2022-07-24 17:53:05 +02:00
Fabian Boehm
407a455cfd realpath: Use physical PWD
This was an inadvertent change from
cc632d6ae9.

Because we used wgetcwd directly before, we always got the "physical"
resolved $PWD.

There's an argument to be made to use the logical $PWD here as well
but I prefer not to make changes lik that in a random commit without
good reason.
2022-07-18 20:45:30 +02:00
Fabian Boehm
5dfb64b547
Add path mtime (#9057)
This can be used to print the modification time, like `stat` with some
options.

The reason is that `stat` has caused us a number of portability
headaches:

1. It's not available everywhere by default
2. The versions are quite different

For instance, with GNU stat it's `stat -c '%Y'`, with macOS it's `stat
-f %m`.

So now checking a cache file can be done just with builtins.
2022-07-18 20:39:01 +02:00
ridiculousfish
fa3ca60111 Add a tmux-sleep to tmux-history-search
This test was failing often on my local Mac; this sleep seems to make it
reliable again.
2022-07-16 17:46:12 -07:00
Aaron Gyes
77f6afa501 Add testcases for [ extensions
Some sanity checks for -ot, -nt, -ef

Try negative mtime values too, there was interesting behavior
there during development.
2022-07-16 12:40:36 -07:00
Fabian Boehm
d920610f96 Fix special readline functions after and/or
Here we needed to handle self-insert immediately, but we ended up
returning it.

Fixes #9051
2022-07-02 09:23:11 +02:00
Fabian Boehm
98ba66ed8e set_color: Print the given colors with --print-colors 2022-07-01 21:28:35 +02:00
Fabian Boehm
bd7934ccbf history: Refuse to merge in private mode
It makes *no* sense.

Fixes #9050.
2022-07-01 20:10:18 +02:00
Fabian Boehm
dde2d33098 set --show: Show the originally inherited value, if any
This adds a line to `set --show`s output like

```
$PATH: originally inherited as |/home/alfa/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/flatpak/exports/bin|
```

to help with debugging.

Note that this means keeping an additional copy of the original
environment around. At most this would be one ARG_MAX's worth, which
is about 2M.
2022-06-27 20:33:26 +02:00
Fabian Boehm
bfeebca75a tests/argparse: Use set -l
This skips history, which takes a lot of time here!
2022-06-27 17:50:40 +02:00
Fabian Boehm
842af06c5d completions/git: Cache subcommand v2
This is sort of slow because it's called hundreds of times.

We used to have a cache, introduced in ad9b4290e, but it was removed
in fee5a9125a because it had
false-positives.

So what we do, because the issue is that this is called hundreds of
times per-commandline, we cache it keyed on the commandline.

This speeds up `complete -C'git sta'` by a factor of 2.3x.
2022-06-27 17:15:30 +02:00
Fabian Boehm
993448d552 argparse: Allow usage without optspecs
It's still useful without, for instance to implement a command that
takes no options, or to check min-args or max-args.

(technically no optspecs, no min/max args and --ignore-unknown does
nothing, but that's a very specific error that we don't need to forbid)

Fixes #9006
2022-06-27 17:02:20 +02:00
Johannes Altmanninger
fee5a9125a Revert "completions/git: cache subcommand computation"
Commit ad9b4290e optimized git completions by adding a completion that would
run on every completion request, which allows to precompute data used by
other completion entries. Unfortunately, the completion entry is not run
when the commandline contains a flag like `git -C`. If we didn't
already load git.fish, we'd error. Additionally, we got false positive
completions for `git diff -c`.

So this hack was a very bad idea. We should optimize in another way.
2022-06-26 23:02:26 +02:00
Fabian Boehm
13a9f6b64e printf: Print special error for invalid octal numbers
(tbh these were always a mistake)

See #9035
2022-06-23 18:12:43 +02:00
Fabian Boehm
045683f927 tests/fd: Error out early if more fds are open
This is simply an error in test setup. There's a limit to how far we
can isolate them from the system.

(it's possible new cmake versions close fds automatically since I
can't reproduce the original issue via `ninja test` or `make test`)

Fixes #9017
2022-06-17 09:33:42 +02:00
Fabian Boehm
8f08fe80fd Restyle codebase
Not a lot of changes, tbh
2022-06-16 18:43:28 +02:00
Fabian Boehm
7810f4e8a1 set: Only warn about uvar shadowing if the set succeeded
Otherwise there's really no point in doing so - we'd tell you that a
universal $status is shadowing a global, but we haven't actually
created one!
2022-06-13 20:53:15 +02:00
ridiculousfish
e0add36488 Revert "Skip tmux tests on Github Actions macOS"
The previous commit switched to using screen-256color instead of
tmux-256color, which makes these tests pass.

This reverts commit 1c4bb214d2.
2022-06-12 14:24:55 -07:00
ridiculousfish
c76ce101b8 Teach isolated-tmux to use screen-256color TERM on Mac
Mac does not ship tmux-256color terminfo, so teach our isolated-tmux
function to populate .tmux.conf with screen-256color instead, only on
macOS.
2022-06-12 14:24:36 -07:00
Fabian Boehm
1c4bb214d2 Skip tmux tests on Github Actions macOS
This lacks the tmux-256color terminfo entry, leading to spurious
warnings like

warning: Could not set up terminal. <= no check matches
warning: TERM environment variable set to \'tmux-256color\'. <= no check matches
warning: Check that this terminal type is supported on this system. <= no check matches
warning: Using fallback terminal type \'ansi\'. <= no check matches
2022-06-09 18:56:20 +02:00
David Adam
c20a71c99f tests: require a newish Python
Specifically, Python 3.5 changed the return value type from
inspect.getouterframes().

Anything older than that is way out of date anyway.
2022-06-08 21:13:09 +08:00
Fabian Boehm
0ea6703661 completions/git: Terminate pathspec magic
Git's pathspec system is kind of annoying:

>  A pathspec that begins with a colon : has special meaning. In the short form, the leading colon : is followed by zero or more "magic signature" letters (which optionally is terminated by another colon :), and the remainder is the pattern to match against the path. The "magic signature" consists of ASCII symbols that are neither alphanumeric, glob, regex special characters nor colon. The optional colon that terminates the "magic signature" can be omitted if the pattern begins with a character that does not belong to "magic signature" symbol set and is not a colon.

So if we complete `:/foo`, that "works" because "f" is alphanumeric
and so the "/" is the only magic character here.

If, however the filename starts with a magic character, that's used as
a magic signature.

So we do what the docs say and terminate the magic signature after the
"/" (which means "from the repo root").

Fixes #9004
2022-06-07 20:10:13 +02:00
Fabian Homborg
f9a170e5f2 git_prompt: Only show untracked files in informative mode if asked
This makes it so

1. The informative status can work without showing untracked
files (previously it was disabled if bash.showUntrackedFiles was
false)
2. If untrackedfiles isn't explicitly enabled, we use -uno, so git
doesn't have to scan all the files.

In a large repository (like the FreeBSD ports repo), this can improve
performance by a factor of 5 or up.
2022-06-07 13:30:03 +02:00
ridiculousfish
480f44cd0f Stop removing unfired one-shot handlers
In b0084c3fc4, we refactored out event handlers get removed. But this
also caused us to remove "one-shot" handlers even if they have not yet
been fired. Fix this.
2022-06-06 12:18:29 -07:00
ridiculousfish
299ed9f903 Allow 'commandline' to set the commandline from the prompt
This means that running `commandline foo` will indeed set the text of
the command line to `foo`; it won't get cleared immediately.

Fixes #8807
2022-06-04 15:33:55 -07:00
ridiculousfish
52cfb66cf7 Add a test for COMPLETE_AUTO_SPACE
Improves our test coverage a bit.
2022-06-02 17:25:59 -07:00
Fabian Homborg
661ea41861 fish_git_prompt: Use "dirty"/"staged" regex like informative
When switching this to use `git status`, I neglected to use the
correct definition of what a "dirty" and a "staged" change is.

So this now showed already staged files still as "dirty".

Fixes #8986
2022-06-01 17:24:08 +02:00
Fabian Homborg
64b34c8cda Allow complete to have multiple conditions
This makes it so `complete -c foo -n test1 -n test2` registers *both*
conditions, and when it comes time to check the candidate, tries both,
in that order. If any fails it stops, if all succeed the completion is offered.

The reason for this is that it helps with caching - we have a
condition cache, but conditions like

```fish
test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] length

test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] sub
```

defeats it pretty easily, because the cache only looks at the entire
script as a string - it can't tell that the first `test` is the same
in both.

So this means we separate it into

```fish
complete -f -c string -n "test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] length" -s V -l visible -d "Use the visible width, excluding escape sequences"
+complete -f -c string -n "test (count (commandline -opc)) -ge 2" -n "contains -- (commandline -opc)[2] length" -s V -l visible -d "Use the visible width, excluding escape sequences"
```

which allows the `test` to be cached.

In tests, this improves performance for the string completions by 30%
by reducing all the redundant `test` calls.

The `git` completions can also greatly benefit from this.
2022-05-30 20:47:14 +02:00
Fabian Boehm
4612343d6e
Merge pull request #8958 from faho/builtin-path
This adds a path builtin to deal with paths.

It offers the following subcommands:

    filter to go through a list of paths and only print the ones that pass some filter - exist, are a directory, have read permission, ...
    is as a shortcut for filter -q to only return true if one of the paths passed the filter
    basename, dirname and extension to print certain parts of the path
    change-extension to change the extension to a different one (as a string operation)
    normalize and resolve to canonicalize the paths in various flavors
    sort to sort paths, also only using the basename or dirname as a key

The definition of "extension" here was carefully considered and should line up with how extensions are actually used - ~/.bashrc doesn't have an extension, but ~/.conf.d does (".d").

These subcommands all compose well - they can read from arguments or stdin (like string), they can use null-delimited input or output (input is autodetected - if a NULL happens in the first PATH_MAX bytes it switches automatically).

It is both a failglob exception (so like set if a glob passed to it fails it just doesn't get any arguments for it instead of triggering an error), and passes output to command substitution buffers explicitly split (like string split0) so newlines are easy to handle.
2022-05-29 20:15:03 +02:00
Fabian Homborg
67b0860fe7 Rename sort --invert to sort --reverse/-r
To match sort(1).
2022-05-29 17:53:03 +02:00
Fabian Homborg
00949fccda Rename --what to --key
More sorty, less generic.
2022-05-29 17:48:40 +02:00
Fabian Homborg
e87ad48f9b Test and document symlink loop 2022-05-29 17:48:40 +02:00
Fabian Homborg
e088c974dd Fix path filter --invert
This would still remove non-existent paths, which isn't a strict
inversion and contradicts the docs.

Currently, to only allow paths that exist but don't pass a type check,
you'd have to filter twice:

path filter -Z foo bar | path filter -vfz

If a shortcut for this becomes necessary we can add it later.
2022-05-29 17:48:12 +02:00
Fabian Homborg
bc3d3de30a Also prepend "./" for filter if a filename starts with "-"
This is now added to the two commands that definitely deal with
relative paths.

It doesn't work for e.g. `path basename`, because after removing the
dirname prepending a "./" doesn't refer to the same file, and the
basename is also expected to not contain any slashes.
2022-05-29 17:48:12 +02:00
Fabian Homborg
c88f648cdf Add sort --unique 2022-05-29 17:48:12 +02:00
Fabian Homborg
4fec045073 sort: Use a stable sort
This allows e.g. sorting first by dirname and then by basename.
2022-05-29 17:48:12 +02:00
Fabian Homborg
640bd7b183 extension: Print empty entry if there is no extension
Because we now count the extension including the ".", we print an
empty entry.

This makes e.g.

```fish
set -l base (path change-extension '' $somefile)
set -l ext (path extension $somefile)
echo $base$ext
```

reconstruct the filename, and makes it easier to deal with files with
no extension.
2022-05-29 17:48:12 +02:00
Fabian Homborg
5cce6d01ad resolve: Normalize
This means "../" components are cancelled out even after non-existent
paths or files.

(the alternative is to error out, but being able to say `path resolve
/path/to/file/../../` over `path resolve (path dirname
/path/to/file)/../../` seems worth it?)
2022-05-29 17:48:11 +02:00
Fabian Homborg
b961afed49 normalize: Add "./" if a path starts with a "-" 2022-05-29 17:48:11 +02:00
Fabian Homborg
55c34cbb7c Use physical $PWD
Yeah, the macOS tests fail because it's started in /private/var... with a
$PWD of /var.... So resolve canonicalizes the path, which makes it no
longer match $PWD.

Simply use pwd -P
2022-05-29 17:48:11 +02:00
Fabian Homborg
23a5e53247 tests: Print $PWD if resolving fails
Seems to be a macOS issue
2022-05-29 17:48:11 +02:00
Fabian Homborg
2b8bb5bd7f path: Rename "real" to "resolve" 2022-05-29 17:48:11 +02:00
Fabian Homborg
479fde27d7 path: Make path real "work" with nonexistent paths
This just goes back until it finds an existent path, resolves that,
and adds the normalized rest on top.

So if you try

/bin/foo/bar////../baz

and /bin exists as a symlink to /usr/bin, it would resolve that, and
normalize the rest, giving

/usr/bin/foo/baz

(note: We might want to add this to realpath as well?)
2022-05-29 17:48:11 +02:00
Fabian Homborg
1c1e643218 WIP path: Make extensions start at the "."
This includes the "." in what `path extension` prints.

This allows distinguishing between an empty extension (just `.`) and a
non-existent extension (no `.` at all).
2022-05-29 17:48:11 +02:00
Fabian Homborg
de0a64a016 Update tests for change-extension's status 2022-05-29 17:48:11 +02:00
Fabian Homborg
ce7281905d Switch strip-extension to change-extension
This allows replacing the extension, e.g.

    > path change-extension mp4 foo.wmv
    foo.mp4
2022-05-29 17:48:11 +02:00
Fabian Homborg
00ed0bfb5d Rename base/dir to basename/dirname
"dir" sounds like it asks "is it a directory".
2022-05-29 17:48:11 +02:00
Fabian Homborg
f6fb347d98 Add "path" builtin
This adds a "path" builtin that can handle paths.

Implemented so far:

- "path filter PATHS", filters paths according to existence and optionally type and permissions
- "path base" and "path dir", run basename and dirname, respectively
- "path extension PATHS", prints the extension, if any
- "path strip-extension", prints the path without the extension
- "path normalize PATHS", normalizes paths - removing "/./" components
- and such.
- "path real", does realpath - i.e. normalizing *and* link resolution.

Some of these - base, dir, {strip-,}extension and normalize operate on the paths only as strings, so they handle nonexistent paths. filter and real ignore any nonexistent paths.

All output is split explicitly, so paths with newlines in them are
handled correctly. Alternatively, all subcommands have a "--null-input"/"-z" and "--null-output"/"-Z" option to handle null-terminated input and create null-terminated output. So

    find . -print0 | path base -z

prints the basename of all files in the current directory,
recursively.

With "-Z" it also prints it null-separated.

(if stdout is going to a command substitution, we probably want to
skip this)

All subcommands also have a "-q"/"--quiet" flag that tells them to skip output. They return true "when something happened". For match/filter that's when a file passed, for "base"/"dir"/"extension"/"strip-extension" that's when something about the path *changed*.

Filtering
---------

`filter` supports all the file*types* `test` has - "dir", "file", "link", "block"..., as well as the permissions - "read", "write", "exec" and things like "suid".

It is missing the tty check and the check for the file being non-empty. The former is best done via `isatty`, the latter I don't think I've ever seen used.

There currently is no way to only get "real" files, i.e. ignore links pointing to files.

Examples
--------

> path real /bin///sh
/usr/bin/bash

> path extension foo.mp4
mp4

> path extension ~/.config
  (nothing, because ".config" isn't an extension.)
2022-05-29 17:48:11 +02:00