Commit Graph

777 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
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
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
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
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
ridiculousfish
cf2ca56e34 Allow trapping SIGINT and SIGTERM in scripts
This teaches `--on-signal SIGINT` (and by extension `trap cmd SIGINT`)
to work properly in scripts, not just interactively. Note any such
function will suppress the default behavior of exiting. Do this for
SIGTERM as well.
2022-05-28 17:44:13 -07:00
ridiculousfish
5917ae8baf Add a test for trap
Preparation to implement trapping in non-interactive mode.
2022-05-28 14:45:13 -07:00
Fabian Homborg
65b9c26fb4 complete: Print better error for -x -F
-x is a cheesy shortcut for `-rf`, so it conflicts with `-F`.

Fixes #8818.
2022-05-26 14:17:15 +02:00
Fabian Homborg
8f9348ee53 Make eval a reserved keyword
Like `set` and `read` before it, `eval` can be used to set variables,
and so it can't be shadowed by a function without loss of
functionality.

So this forbids it.

Incidentally, this means we will no longer try to autoload an
`eval.fish` file that's left over from an old version, which would
have helped with #8963.
2022-05-18 18:47:10 +02:00
Fabian Homborg
b548e1d8fe Fix tests
Oops, unclean extraction from larger work.
2022-05-17 17:21:42 +02:00
Fabian Homborg
b71416f610 fish_add_path: Also deduplicate the new paths
Previously, running `fish_add_path /foo /foo` would result in /foo
being added to $PATH twice.

Now we check that it hasn't already been given, so we skip the
second (and any further) occurence.
2022-05-17 17:05:56 +02:00
Fabian Homborg
02ee112308 source the files instead
This *might* be a bit faster running under TSAN, otherwise it takes >
400 seconds on Github Actions.

If this doesn't work we need to disable it for TSAN.
2022-04-21 17:40:25 +02:00
Fabian Homborg
43459d1750 Store output
Now we can explain which file printed the error
2022-04-21 17:29:00 +02:00
Fabian Homborg
7e2cba01fb Add a test that runs all available completions
Meaning completions where we have the command.

No completion should be printing anything when sourced.

This could have prevented #8896
2022-04-21 17:19:36 +02:00
Fabian Homborg
c2bca939be Let stderr-nocaret description say it's read-only 2022-04-15 13:42:38 +02:00
Fabian Homborg
49eb07f98f Enable ampersand-nobg-in-token by default
To recap, this means `&` in the middle of a word no longer
backgrounds.

So:

```fish
echo foo&bar # prints foo&bar
echo foo& bar # backgrounds an echo that prints "foo" and runs "bar"
```
2022-04-15 13:42:38 +02:00
Fabian Homborg
74be3e847f Force stderr-nocaret feature flag on
This can no longer be changed. If "no-stderr-nocaret" is in
$fish_features it will simply be ignored.

The "^" redirection that was deprecated in fish 3.0 is now gone for good.

Note: For testing reasons, it can still be set _internally_ by running
"feature_flags_t::set". We simply shouldn't do that.
2022-04-15 13:42:38 +02:00
Fabian Homborg
59c2ed9acf Turn on regex-easyesc by default
This was introduced in fish 3.1. It removes a superfluous round of
escaping in the replacement for `string replace -r`.

Part of #8857.
2022-04-15 13:42:38 +02:00
Fabian Homborg
b0c2d083d6 set: Add special error for set foo=bar
Fixes #8694

Only for setting, erasing with a value makes no sense.
2022-04-08 16:50:34 +02:00
Fabian Homborg
31e2476fc8 Clarify that the variable/mode *name* is invalid
When you do

```fish
set foo-bar baz
```

"foo-baz" isn't usable as a variable *name*. When you just say the
"variable" is invalid that could also be interpreted to be a special
type of variable or something.
2022-04-08 16:38:46 +02:00
Johannes Altmanninger
4b5b56452b Make string syntax error location a bit more precise
String tokens are subdivided by command substitutions. Some syntax errors
can occur in the gap between two command substitutions. Make the caret point
to the start of that gap, instead of the token start.
2022-04-03 16:34:46 +02:00
Johannes Altmanninger
e717b13e75 Fix spurious syntax error on escaped $@ inside quoted command substitution
We detect use of unsupported features like $@ by scanning string tokens
as a whole. With quoted command substitution, this has false positives,
as reported in [1]. We already recursively run the same error checks on
command substitutions, so limit the remaining checks to the gaps in-between
command substitutions.

[1]: 5f94dfd094/.config/fish/README/bug.md (cannot-use-dollar-anchor-in-sed-regex-in-quoted-command-substitution)
2022-04-03 16:18:47 +02:00
Johannes Altmanninger
3e3f507012 Fix regression expanding \$()
When expanding command substitutions, we use a naïve way of detecting whether
the cmdsub has the optional leading dollar. We check if the last character was
a dollar, which breaks if it's an escaped dollar.  We wrongly expand
\$(echo "") to the empty string. Fix this by checking if the dollar was escaped.

The parse_util_* functions have a bunch of output parameters. We should
return a parameter bag instead (I think I tried once and failed).
2022-04-03 15:54:08 +02:00
Johannes Altmanninger
1b668f5675 Don't use results of quoted command substitution in adjacent variable expansion
Given

    set var a
    echo "$var$(echo b)"

the double-quoted string is expanded right-to-left, so we construct an
intermediate "$varb".  Since the variable "varb" is undefined, this wrongly
expands to the empty string (should be "ab"). Fix this by isolating the
expanded command substitution internally. We do the same when handling
unquoted command substitutions.

Fixes #8849
2022-04-03 11:24:55 +02:00
ridiculousfish
448dd18685 Use head instead of dd in the read test
The read test is now failing on GitHub actions even though it passes on
my Mac. It may be due to differences in dd between these two
environments. Stop using dd and just use head.
2022-04-02 13:44:58 -07:00
ridiculousfish
108fe574a0 Finally track down that cursed read test failure
The read.fish check has a test where it limits the amount of data passed to
`read` to 8192 bytes, and verifies that fish reads exactly that amount.
This check occasionally fails on the OBS builds; it's very hard to repro a
failure locally, but I finally did it.

The amount of data written is limited via `yes` and `dd`:

    yes $line | dd bs=1024 count=(math "$fish_read_limit / 1024")

The bug is that `dd` outputs a fixed number of "blocks" where a block
corresponds to a single read. As `yes` and `dd` are running concurrently,
it may happen that `dd` performs a short read; this then counts as a single
block. So `dd` may output less than the desired amount of data.

This can be verified by removing the 2>/dev/null redirection; on a
successful run dd reports `8+0 records out`, on a failed run it reports
`7+1 records out` because one of the records was short.

Fix this by using `fullblock` so that dd will no longer count a short read
as a single block. `head` would probably be a simpler tool to use but we'll
do this for now.

Happily it's not a fish bug. No need to relnote it.
2022-04-02 11:33:07 -07:00
ridiculousfish
a960a3cde6 Emit an error if time is used past the first command in a pipeline
Fixes #8841
2022-03-31 16:14:59 -07:00
Fabian Homborg
f13979bfbb Move executable-check to C++
This was already apparently supposed to work, but didn't because we
just overrode errno again.

This now means that, if a correctly named candidate exists, we don't
start the command-not-found handler.

See #8804
2022-03-31 15:16:01 +02:00
Fabian Homborg
f9f0ad1ef7 completions/git: Check alias definitions for an option
This allows e.g. defining

    	re = restore --staged

and then getting completions for `restore --staged`, not just `restore`.

Fixes #8843
2022-03-30 18:25:00 +02:00
Fabian Homborg
cc689290cd Autoload: Call the parser directly instead of going via "subshell"
This used to call exec_subshell, which has two issues:

1. It creates a command substitution block which shows up in a stack
trace
2. It does much more work than necessary

This removes a useless "in command substitution" from an error message
in an autoloaded file, and it speeds up autoloading a bit (not
measurable in actual benchmarks, but microbenchmarks are 2x).
2022-03-27 09:35:12 +02:00
David Adam
6a8efa3f15 ulimit: add basic tests 2022-03-24 10:23:04 +08:00
Fabian Homborg
71cfd25c1d Command-not-found: Warn if a file exists but isn't executable
This simply adds a nice error so you can better see if your command
isn't available because it's not executable.

Fixes #8804.
2022-03-17 18:06:36 +01:00
Fabian Homborg
cd62771d12 read: Don't use chunking read with --line
Fixes a regression from #8552.
2022-03-14 08:04:35 +01:00
Fabian Homborg
8bcb034422 Disable tmux-history-search test on GH Actions 2022-03-13 11:48:52 +01:00
Fabian Homborg
972752aa1c
Merge branch 'master' into te-refactor 2022-03-13 11:24:31 +01:00
Andrey Mishchenko
59e50f77bc
Allow underscores as separators in the math builtin (#8611)
* Implement fish_wcstod_underscores

* Add fish_wcstod_underscores unit tests

* Switch to using fish_wcstod_underscores in tinyexpr

* Add tests for math builtin underscore separator functionality

* Add documentation for underscore separators for math builtin

* Add a changelog entry for underscore numeric separators
2022-03-13 11:23:35 +01:00
Fabian Homborg
9ada7d9aad read: Also read in chunks when directly redirected
We can't always read in chunks because we often can't bear to
overread:

```fish
echo foo\nbar | begin
    read -l foo
    read -l bar
end
```

needs to have the first read read `foo` and the second read `bar`. So
here we can only read one byte at a time.

However, when we are directly redirected:

```fish
echo foo | read foo
```

we can, because the data is only for us anyway. The stream will be
closed after, so anything not read just goes away. Nobody else is
there to read.

This dramatically speeds up `read` of long lines through a pipe. How
much depends on the length of the line.

With lines of 5000 characters it's about 15x, with lines of 50
characters about 2x, lines of 5 characters about 1.07x.

See #8542.
2022-03-13 11:22:48 +01:00
Fabian Homborg
585d1de653
Merge branch 'master' into string-preserve-missing-newline 2022-03-13 11:21:53 +01:00
Fabian Homborg
cf85bf9be3 Let function-scoped variables be queried
This uses the same logic we use to create the variables to find them -
go through the scopes, the topmost local scope *is* function-scope.

Fixes #8684
2022-03-10 18:28:50 +01:00
Fabian Homborg
f284cdce5b Make byte/unicode escapes with no digits a tokenizer error
This is the simple fix - if we have no valid digit, we have nothing to
return. So instead of returning a NULL, we return an error.

This is already the case for invalid octal escapes (like `\777`).

Fixes #8545
2022-03-03 12:18:13 +01:00
Fabian Homborg
6fcb6f77be Revert changes to time formatting
This reverts commits:

2d9e51b43e
d1d9f147ec
346ce8081b

The box drawing because it's entangled with the rest and we don't
currently use this anywhere I know of. Nor was it gated on terminfo,
so it could have broken things, for subjectively little gain.

Fixes #8727.
2022-02-21 22:48:43 +01:00
Fabian Homborg
b48d8188b9 Change our test emoji
The emoji we used wasn't actually widened-in-9, so we now switch to
one that does.
2022-02-14 22:31:30 +01:00
Nadav Zingerman
9e0f74eb6c Add --escape option to complete -C
An example use case is an external completion pager:

    bind \cg "commandline -rt (complete -C --escape|fzf|cut -d\t -f1)\ "

Fixes #3469
2022-02-09 08:34:03 +01:00
Aaron Gyes
d1d9f147ec Update tests for time output. 2022-02-08 16:57:01 -08:00
Shay Aviv
2ef12af60e Fix comment parsing inside command substitutions and brackets 2022-02-08 16:20:31 +01:00
Johannes Altmanninger
8b9f7dbf45 Commit transient edit when history search ends
A history search ends when you move the cursor, but the commandline inserted by
history search is still marked as transient. This means that the next history
search will clear the transient commandline. This means we are dropping an undo
point, for example:

	echo 11
	echo 1
	echo autosuggestion
	echo^P # commandline is "echo 1"
	^A # stop history search
	^P # commandline is "echo 11"
	^Z # Bug: commandline goes back to "echo", but it should be "echo 1"

In the worst case, we are switching from line-search to token-search (see
the attached test case).  Clearing the transient edit means the line is gone
and only the token is left on the command line.
2022-02-07 17:38:11 +01:00
Johannes Altmanninger
df3b0bd89f Fix commandline state for custom completions with variable overrides
Today, a command like "var=val status " has custom completions
because we skip over the var=val variable override when detecting
the command token.
However if the custom completions read the commandline state (via
"commandline -opc") they do see they variable override, which breaks
them, most likely. Try "a=b git ".

For completions of wrapped commands, we already set a transient
commandline. Do the same for commands with  leading variable overrides;
then git completions for "a=b git " will think the commandline is
"git ".
2022-01-27 03:51:32 +01:00
Juho Eerola
66ef4d5eb5
Add tests for variadic functions and nested calls 2022-01-20 00:19:27 +02:00
Pablo Santiago Blum de Aguiar
6315cf67ec Assert and and or create no new scope 2022-01-18 17:56:33 +01:00
Juho Eerola
bf44ea1350
Fix expected outcome in test
The reported error is now different, so the test is updated accordingly.
2022-01-15 14:46:16 +02:00
Fabian Homborg
0781473564 argparse: Jump to the next option after an unknown one
Previously, when we got an unknown option with --ignore-unknown, we
would increment woptind but still try to read the same contents.

This means in e.g.

```
argparse -i h -- -ooo -h
```

The `-h` would also be skipped as an option, because after the first
`-o` getopt reads the other two `-o` and skips that many options.

This could be handled more extensively in wgetopt, but the simpler fix
is to just skip to the next argv entry once we have an unknown option
- there's nothing more we can do with it anyway!

Additionally, document this and clearly explain that we currently
don't transform the option.

Fixes #8637
2022-01-15 12:17:43 +01:00
ridiculousfish
37625053d4 fish_git_prompt: be careful about git config
fish_git_prompt may run certain git commands which may invoke certain
external programs as specified `.git/config`. Prevent this by suppressing
certain git config options.
2021-12-30 13:11:04 -08:00
Fabian Homborg
940f52d717 math: Report missing operators between the tokens
This affects the caret position. In an expression like

123 456

we previously reported:

123 456
      ^ missing operator

Now we do:

123 456
   ^ missing operator

We do it on the first space, which should be acceptable.

(no need for a changelog entry, we have already ignored #8511)
2021-12-30 13:26:44 +01:00
David Adam
a52305e11c postfork: further updates to error messages
Only show the shebang warning for .fish commands.

Use the phrase "interpreter directive" as the formal name for the
shebang.

Switch from windows to Windows for the operating system.
2021-12-29 22:33:24 +08:00
Johannes Altmanninger
65b34a12c0 Declare that two "not" keywords cancel each other out
"not not return 34" exits with 34, not 1.  This behavior is pretty
surprising but benign. I think it's very unlikely that anyone relies
on the opposite behavior, because using two "not" decorators in one
job is weird, and code that compares not's raw exit code is rare.

The behavior doesn't match our docs, but it's not worth changing the
docs because that would confuse newcomers. Add a test to cement the
behavior and a comment to explain this is intentional.

I considered adding the comment at
parse_execution_context_t::populate_not_process where this behavior
is implemented but the field defintion seems even better, because I
expect programmers to read that first.

Closes #8377
2021-12-28 19:32:30 +01:00
Fabian Homborg
77bac22741 test: Also print proper caret for too many arguments
This case is handled specially for unknown reasons and was missed in #6030.
2021-12-24 16:08:41 +01:00
Aaron Gyes
b05757ee56 Fit status feaetures in 80 columns 2021-12-13 01:24:47 -08:00
Aaron Gyes
f464bbebfe command -v: exit 127 if command not found
Align with the spec
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html

Fixes #8547
2021-12-11 22:15:26 -08:00
Johannes Altmanninger
4a575b26f5 Fix error check for repeated quoted command substitution
Commit e40eba358 (Treat text following quoted command substitution
as quoted) made parse_util_locate_cmdsubst_range() aware of quoted
command substitutions, by skipping surrounding text via quote_end().

However, it was not quite right. We fail to properly parse
two consecutive command substitutions in the same string,
because we don't maintain the quoting context across calls to
parse_util_locate_cmdsubst_range().  Let's track that bit in a
parameter. This allows us to get rid of the quote_end() hack.

Also apply this to the other place where we call
parse_util_locate_cmdsubst_range() in a loop (highlighting).

Fixes #8500
2021-12-04 16:56:07 +01:00
Johannes Altmanninger
b5739ddacf Report sub-token error locations again
This fixes a regression about where we report errors:

	echo error(here
	old: ^
	   fixed: ^

Commit 0c22f67bd (Remove the old parser bits, 2020-07-02) removed
uses of "error_offset_within_token" so we always report errors at
token start. Add it back, hopefully restoring the 3.1.2 behavior.

Note that for cases like

	echo "$("

we report "unbalanced quotes" because we treat the $( as double
quote.  Giving a better error seems hard because of the ambguity -
we don't know if quote is meant to be inside or outside the command
substitution.
2021-12-04 16:52:13 +01:00
Fabian Homborg
3700247b55 Use the full path for noshebang'd scripts
If you make a script called `foo` somewhere in $PATH, and did not give
it a shebang, this would end up calling

    sh foo

instead of

    sh /usr/bin/foo

which might not match up.

Especially if the path is e.g. `--version` or `-` that would end up
being misinterpreted *by sh*.

So instead we simply pass the actual_cmd to sh, because we need it
anyway to get it to fail to execute before.
2021-12-02 21:10:57 +01:00
Johannes Altmanninger
0c76b571c7 Fix tmux-complete test on macOS CI
For some reason, the window dimension parameters are ignored by tmux.
Not even an extra "resize-pane -x 80 -y 10" helps. So let's just drop
that assumption from our tests.
2021-12-02 15:10:13 +01:00
Aaron Gyes
2b736d023f skip tmux-complete on Darwin
There's some kind of weird problem with homebrew's terminfo and
tmux, that is beyond working around AFAICT.
2021-12-02 05:09:04 -08:00
Johannes Altmanninger
0cd3ed4b84 Fix completion pager rendering when there are lines after cursor
When the completion pager fills up all lines of the screen, we subtract
from the pager size the number of lines occupied by the prompt +
command line buffer (typically 1), so the command line is always
visible.  However, we only subtract the number of lines *before* the
cursor, so on some multiline commandlines we draw a pager that is
too large for our screen, clobbering the commandline rendering.
Fix this by counting all lines.

Fixes #8509
Possibly fixes #8405
2021-12-02 04:58:46 +01:00
Fabian Homborg
fbac70ab38 math: For two adjacent numbers, complain about missing operator
Simply a nicer error message.
2021-12-01 16:56:18 +01:00
Aaron Gyes
de0cbd2984 tinyexpr: report errors for extra args in parens correctly.
Usages like `math (1 1)` should report too many arguments,
same as `math 1 1`. Check for these cases and add tests.

Fixes #8511
2021-12-01 04:49:50 -08:00
ridiculousfish
954d0fb042 Output more information in read --nchars test
To try to track down a test failure, improve the error message.
2021-11-27 11:02:03 -08:00
Johannes Altmanninger
745129e825 builtin string: don't print final newline if it's missing from stdin
A command like "printf nonewline | sed s/x/y/" does not print a
concluding newline, whereas "printf nnl | string replace x y" does.
This is an edge case -- usually the user input does have a newline at
the end -- but it seems still better for this command to just forward
the user's data.

Teach most string subcommands to check if stdin is missing the trailing
newline, and stop adding one in that case.
This does not apply when input is read from commandline arguments.

* Most subcommands stop adding the final newline, because they don't
  really care about newlines, so besides their normal processing,
  they just want to preserve user input. They are:
  * string collect
  * string escape/unescape
  * string join¹
  * string lower/upper
  * string pad
  * string replace
  * string repeat
  * string sub
  * string trim

* string match keeps adding the newline, following "grep". Additionally,
  for string match --regex, it's important to output capture groups
  separated by newlines, resulting in multiple output lines for an
  input line. So it is not obvious where to leave out the newline.

* string split/split0 keep adding the newline for the same reason --
  they are meant to output multiple elements for a single input line.

¹) string join0 is not changed because it already printed a trailing
   zero byte instead of the trailing newline. This is consistent
   with other tools like "find -print0".

Closes #3847
2021-11-27 19:11:24 +01:00
Johannes Altmanninger
d1683958cf Expand tildes and variables in command for custom completions
A «complete -C '~/fish-shell/build/fish '» fails to load custom
completions because we do not expand the ~, so
complete_param_for_command() thinks that this command is invalid.
Expand command tokens before loading custom completions.

Fixes #8442
2021-11-27 10:14:13 +01:00
Fabian Homborg
47e45704b1
Allow set --query to check for pathvarness (#8494)
Currently,

    set -q --unpath PATH

simply ignores the "--unpath" bit (and same for "--path").

This changes it, so just like exportedness you can check pathness.
2021-11-26 18:29:10 +01:00
Fabian Homborg
c964edcd68 Use cat instead of ls to skip colorls
We don't really care *which*, we just want to generate some error so
we can see that the redirection worked.

Fixes #8492
2021-11-25 18:46:31 +01:00
Fabian Homborg
707f042fc4 printf: Explain what couldn't be converted 2021-11-20 17:44:05 +01:00
Fabian Homborg
8391f94081 Improve error for redirections to invalid paths
This finds the first broken component, to help people figure out where
they misspelt something.

E.g.

```
echo foo >/usr/lob/systemd/system/machines.target.wants/var-lib-machines.mount
```

will now show:

```
warning: Path '/usr/lob' does not exist
```

which would help with seeing that it should be "/usr/lib".
2021-11-20 17:44:05 +01:00
Johannes Altmanninger
64dddfc6ce Only expand abbreviations if cursor is directly at command token
On a commandline like "ls arg" (cursor at end) we do not expand
abbrevations on enter.  OTOH, on "ls " we do expand. This can be
frustrating because it means that the two obvious ways to suppress
abbrevation expansion (C-Space or post-expansion C-Z) cannot be used to
suppress expansion of a command without arguments.  (One workaround is
"ls #".)

Only expand-on-execute if the cursor is at the command name (no space
in between).

This is a strict improvement for realistic scenarios, because if there
is a space, the user has already expressed the intent to not expand
the abbreviation. (I hope no one is using recursive abbreviations.)

Closes #8423
2021-11-14 11:52:10 +01:00
Fabian Homborg
c16e30931b Fix abbr return status
This was supposed to act like `type -q` or `command -q`, in that it
returns 0 if at least 1 exists.

But because it used the wrong variable it didn't.

Fixes #8431.
2021-11-11 16:46:23 +01:00
ridiculousfish
25f47729e7 math: Correct printing of negative and large values in octal and hex
This fixes printing octal and hex values that are negative or larger
than UINT_MAX.

Negative values get a leading -, like:

    > math --base hex -10
    -0xa

Fixes #8417.
2021-11-07 16:43:30 -08:00
Aaron Gyes
57995abb03 fix 'complete' test 2021-11-04 04:18:54 -07:00
Aaron Gyes
fefb913857 Update tests for changed error output 2021-11-03 22:54:55 -07:00
Johannes Altmanninger
e40eba3585 Treat text following quoted command substitution as quoted
Commit ec3d3a481 (Support "$(cmd)" command substitution without line
splitting, 2021-07-02) started treating an input string like
"a$()b" as if it were "a"$()"b". Yet, we do not actually insert the
virtual quotes. Instead we just adapted the definition of when quotes
are closed - hence the changes to quote_end().

parse_util_locate_cmdsubst_range() is aware
of the changes to quote_end() but some of its
callers like parse_util_detect_errors_in_argument() and
highlighter_t::color_as_argument() are not.  They split strings at
command substitution boundaries without handling the special quoting
rules. (Only the expansion logic did it right.)

Fix this by handling the special quoting rules inside
parse_util_locate_cmdsubst_range(). This is a bit hacky since it
makes it harder for callers to process some substrings in between
command substitutions, but that's okay because current callers only
care about what's inside the command substitutions.

Fixes #8394
2021-10-30 18:02:10 +02:00
ridiculousfish
b9a95a48b4 Test that --on-job-exit functions run even if the job has already exited
If you define a function that you want to be called after a job has
exited, it should run immediately if that job has already exited.
2021-10-28 10:02:48 -07:00
Fabian Homborg
31d6abb177 Don't fire variable set event before entering a for-loop
Since #4376, for-loops would set the loop variable outside, so it
stays valid.

They did this by doing the equivalent of

```fish
set -l foo $foo
for foo in 1 2 3
```

And that first imaginary `set -l` would also fire a set-event.

Since there's no use for it and the variable isn't actually set, we
remove it.

Fixes #8384.
2021-10-28 16:32:58 +02:00
Fabian Homborg
2b8fe280e0 tests: Switch emoji used
widechar_width no longer classifies U+1F41F as widened-in-9, so the
width no longer changes.

Since we're interested in testing the change here, we need a different
emoji.

Just use 🥁, which was introduced in 9 as wide, and therefore widened
in 9.
2021-10-26 18:30:43 +02:00
Fabian Homborg
973739e329 Move CHECKS in loop-test to where they are matched 2021-10-26 17:38:40 +02:00
ridiculousfish
ec244c3975 Add tests for dynamically invoked break and continue 2021-10-25 12:43:30 -07:00
Aaron Gyes
f4377e1a26 necro working tests from 11a373f121 2021-10-21 23:50:42 -07:00
Fabian Homborg
144778dc28 Complete: Fix long-form of "-r" in complete output
This was never `--requires-param`, AFAICT.
2021-10-20 21:05:17 +02:00
Fabian Homborg
e6b75e5947 Add a test to check format strings in translations
This should prevent #8358 from happening again.

Note that, because it's not fixed yet, this test *will* fail.
2021-10-18 17:02:17 +02:00
Erik Serrander
049104e8df Adds sub-command clear-session to history command.
Issue #5791
This clears all history for the current session. Documentation and
autocompletion for the new subcommand is added.
2021-10-17 19:27:46 -07:00
Fabian Homborg
4ffabd44be Don't add expansion error offset twice
Like the $status commit, this would add the offset to already existing
errors, so

```fish
(foo)
(bar)

something
```

would see the "(foo)" error, store the correct error location, then
see the "(bar)" error, and *add the offset of (bar)* to the "(foo)"
error location.

Solve this by making a new error list and appending it to the existing
ones.

There's a few other ways to solve this, including:

- Stopping after the first error (we only display the first anyway, I
think?)
- Making it so the source location has an "absolute" flag that shows
the offset has already been added (but do we ever need to add two offsets?)

I went with the simpler fix.
2021-09-30 18:09:58 +02:00
Fabian Homborg
6774a514fa Don't set error offset for $status
This would break the location of any prior errors without doing
anything of value.

E.g.

```fish
echo foo | exec grep # this exec is not allowed!

$status

somethingelse # The error might be found here!
```

Would apply the offset of `$status` to the offset of `exec`, locating
the error for `exec` somewhere after $status!
2021-09-30 18:09:58 +02:00
ridiculousfish
4f466cb916 broken-symbolic-link test to enter a new directory
This was previously dependent on whatever directory we happened to be
in.
2021-09-24 17:35:45 -07:00
ridiculousfish
0562e599a6 isolated-tmux to more reliably initialize and other fixes
Prior to this change, tmux based tests would call 'isolated-tmux' which would
initialize tmux on first call, an admitted "evil hack." Switch to requiring
an explicit call to 'isolated-tmux-start' which then defines 'isolated-tmux'
and other functions. Add some loop-until-prompt logic into
'isolated-tmux-start'. This improves reliability of the tmux tests on systems
under load; at least it makes the tests pass in the background on my Mac.

Remove the '$sleep' variable, to be replaced with 'tmux-sleep'.
2021-09-24 08:07:17 -07:00
Fabian Homborg
45714eb29d Add function scope to read as well
Fixes #8295.
2021-09-23 17:12:37 +02:00
Fabian Homborg
bb115c847e Handle backspaces for visible width
This makes it so we treat backspaces as width -1, but never go below a
0 total width when talking about *lines*, like in screen or string
length --visible.

Fixes #8277.
2021-09-23 12:58:35 +02:00
Johannes Altmanninger
eae9ee7f35 builtin cd: print error about broken symlinks
When cd is passed a broken symlink, this changes the error message from
"no such directory" to "broken symbolic link".  This scenario probably
won't happen very often since completion won't suggest broken symlinks
but it can't hurt to give a good error.

Fish used to do this until 7ac5932.  This logic used to be in
path_get_cdpath, however, that is only used for highlighting, so we
don't need error messages there. Changing cd is enough.

Reword from "rotten" to "broken" since that's what file(1) uses.
Clean-up leftovers from old "rotten" code (nomen est omen).

See #8264
2021-09-17 00:43:12 +02:00
Fabian Homborg
a78d9d8e9a normalize_path: Squash leading slashes even without allow_leading
This currently changes builtin realpath with the "-s" option:

    builtin realpath -s ///tmp

previously would print "///tmp", now it prints "/tmp".

The only thing "allow_leading_double_slashes" does is allow *two*
slashes.

This is important for `path match`, to be introduced in #8265.
2021-09-09 18:41:11 +02:00
ridiculousfish
5eb5aaf9da tmux-prompt test to wait a bit to allow the first prompt to draw
The tmux-prompt test would sometimes fail because the first call was:

     isolated-tmux capture-pane -p

this would run a capture-pane which would race with starting fish
itself; occasionally the pane would be empty since fish has not yet
drawn a prompt. Add a loop to give fish time to draw the prompt.
2021-09-04 16:59:50 -07:00
Fabian Homborg
aa17ed51ce tests/checks/complete: Do $PWD stuff in the tempdir
This broke the tests on my machine, and doing

```fish
cd $dir
cd -
```

seems wrong in any case.
2021-08-30 17:07:11 +02:00
Fabian Homborg
d62e22dcc0 Correct a realpath test
This used the *logical* $PWD, but realpath would operate on the
physical $PWD if given ".", even with -s. This makes this test fail if the $PWD is
logically different from physical.
2021-08-29 23:10:50 +02:00
Johannes Altmanninger
77c434bc42 Extract setup and teardown for tmux tests
This was long overdue since the setup logic is much more complex than
the actual tests.

tmux-prompt.fish had extra logic to protect against XDG_CONFIG_HOME
with leading double double-dot.  I believe this is no longer necessary
with the new test driver.

We still use our own temp dir because we want to be able to run this
independently of the test driver, This can be useful for debugging
tests.  For example we can insert a "$tmux attach" command in a test,
and then run

	build/fish -C 'source tests/test_functions/isolated-tmux.fish' tests/checks/tmux-bind.fish

This allows to inspect the state of the test and debug interactively.
Attaching to the terminal doesn't work when running inside littlecheck
because littlecheck consumes our output and doesn't give us a terminal.
(Maybe there's an easy way to fix that?)
2021-08-29 20:22:16 +02:00
Johannes Altmanninger
bd79e753ff Fix detection of zombies in test
Due to the second column the old glob no longer worked.
2021-08-29 20:22:16 +02:00
Mahmoud Al-Qudsi
069d396ebc Merge branch 'ctest' 2021-08-29 13:03:16 -05:00
Mahmoud Al-Qudsi
9a071090dc Allow tests/checks/basic.fish to run without test driver
On request of a team member, this patches `basic.fish` to no longer
depend on being invoked by the test driver and started up in a $PWD that
points to a clean temporary directory.
2021-08-29 12:53:37 -05:00
Mahmoud Al-Qudsi
2157d91a5c Re-add explicit littlecheck HOME/XDG_CONFIG_HOME overrides on request
This was requested by a team member who would like for some tests to
remain invokable (in thier own $HOME) directly via littlecheck without
relying on the test driver to prep the environment.

A comment explaining the rationale is also added so this doesn't get
passed down as folklore "you need to include this for tests to run" even
though no one understands why.
2021-08-29 12:38:28 -05:00
Mahmoud Al-Qudsi
e96b6e157c Remove TMPDIR dependency from tests/
Tests are now executed in a test-specific temporary directory, so test
output on failure should be reproducible/reusable as-is without needing
to have TMPDIR defined (as it only exists by default under macOS).
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
ef00344c0e Fix tmux tests error on macOS w/ long TMPDIR 2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
efda4f5c39 Make zombie test smarter
Instead of trying to assert that there are no zombies when the test
starts (which often fails) and to prevent conflating existing or
irrelevant zombies with the ones we are interested in checking for,
have `ps` also emit the parent process id and filter its output to
include only children of the current fish instance.
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
9796b95f48 Eliminate shared temporary directory for tests
Aside from the fact that the shared state could cause problems, tests
were randomly assuming it would be created where that wasn't the case.
In particular, `redirect.fish` and `basic.fish` were failing on only
macOS because `../test/temp` didn't exist yet - it would be created by
other tests later.
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
c35113aef1 Remove now-extraneous re-init of XDG dirs in tests
test_driver.sh is guaranteed to take care of them.
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
77b332221a Fix complete.fish test
It depends on `mktemp -d TAG` returning a relative path, which isn't guaranteed to be the case (and
isn't the case when run by our test driver).
2021-08-29 08:56:12 +02:00