Commit Graph

1135 Commits

Author SHA1 Message Date
Fabian Homborg
6c1ec98e92 prompt_pwd: full-dirs set to 0 means not even last component is safe
Alternative is to print an error.
2021-08-09 17:42:00 +02:00
Fabian Homborg
af2952dd2f Allow passing directories to prompt_pwd
This allows us to test it without cd-ing about the place.
2021-08-09 17:42:00 +02:00
Fabian Homborg
2087a3ca63 Let visible length work with CR and LF
Because we are, ultimately, interested in how many cells a string
occupies, we *have* to handle carriage return (`\r`) and line
feed (`\n`).

A carriage return sets the current tally to 0, and only the longest
tally is kept. The idea here is that the last position is the same as
the last position of the longest string. So:

abcdef\r123

ends up looking like

123def

which is the same width as abcdef, 6.

A line feed meanwhile means we flush the current tally and start a new
one. Every line is printed separately, even if it's given as one.

That's because, well, counting the width over multiple lines
doesn't *help*.

As a sidenote: This is necessarily imperfect, because, while we may
know the width of the terminal ($COLUMNS), we don't know the current
cursor position. So we can only give the width, and the user can then
figure something out on their own.

But for the common case of figuring out how wide the prompt is, this
should do.
2021-08-04 21:09:47 +02:00
Fabian Homborg
0059192f61 Allow erasing vars via function-scope
This triggered an assert because the remove code had no idea how to
find the function scope.

Oops!
2021-08-04 17:55:41 +02:00
Fabian Homborg
733114fefb
Add set --function (#8145)
* Add `set --function`

This makes the function's scope available, even inside of blocks. Outside of blocks it's the toplevel local scope.

This removes the need to declare variables locally before use, and will probably end up being the main way variables get set.

E.g.:

```fish
set -l thing
if condition
    set thing one
else
    set thing two
end
```

could be written as

```fish
if condition
    set -f thing one
else
    set -f thing two
end
```

Note: Many scripts shipped with fish use workarounds like `and`/`or`
instead of `if`, so it isn't easy to find good examples.

Also, if there isn't an else-branch in that above, just with

```fish
if condition
    set -f thing one
end
```

that means something different from setting it before! Now, if
`condition` isn't true, it would use a global (or universal) variable of
te same name!

Some more interesting parts:

Because it *is* a local scope, setting a variable `-f` and
`-l` in the toplevel of a function ends up the same:

```fish
function foo2
    set -l foo bar
    set -f foo baz # modifies the *same* variable!
end
```

but setting it locally inside a block creates a new local variable
that shadows the function-scoped variable:

```fish
function foo3
    set -f foo bar
    begin
        set -l foo banana
        # $foo is banana
    end
    # $foo is bar again
end
```

This is how local variables already work. "Local" is actually "block-scoped".

Also `set --show` will only show the closest local scope, so it won't
show a shadowed function-level variable. Again, this is how local
variables already work, and could be done as a separate change.

As a fun tidbit, functions with --no-scope-shadowing can now use this to set variables in the calling function. That's probably okay given that it's already an escape hatch (but to be clear: if it turns out to problematic I reserve the right to remove it).

Fixes #565
2021-08-01 20:08:12 +02:00
Johannes Altmanninger
66709571ed fish_indent: handle tokens with trailing escaped newlines
Fixes #8197
2021-08-01 18:59:45 +02:00
Johannes Altmanninger
3a375c2399 reader: fix regressions when moving between lines
Fixes some regressions from 35ca42413 ("Simplify some parse_util functions").
The tmux tests are not beautiful but I find them easy to write.
Probably a pexpect test would also be enough here?
2021-08-01 17:50:44 +02:00
Fabian Homborg
dd3cdbcfc9 Fix crash if $PWD is used as for-loop variable
for PWD in foo; true; end

prints:

>..src/parse_execution.cpp:461: end_execution_reason_t parse_execution_context_t::run_for_statement(const ast::for_header_t&, const ast::job_list_t&): Assertion `retval == ENV_OK' failed.

because this used the wrong way to see if something is read-only.
2021-07-30 15:33:04 +02:00
Fabian Homborg
09b8471f5c Test numeric locale
This allows us to test that `test` takes numbers with decimal point even in comma-using locales,
to stop those pesky americans from breaking everything again.

(and yes, we use french to keep myself honest)
2021-07-29 17:20:20 +02:00
Fabian Homborg
b3cdf4afe1 Hardcode $PWD as read-only for set --show
Through a mechanism I don't entirely understand, $PWD is sometimes
writable (so that `cd` can change it) and sometimes not.

In this case we ended up with it writable, which is wrong.

See #8179.
2021-07-28 22:13:22 +02:00
Fabian Homborg
3db78232c6 Show if a var is read-only with set --show
Fixes #8179.
2021-07-28 21:13:03 +02:00
Fabian Homborg
48e696bbb4 Update commandline state before completion
Fixes #8175.
2021-07-27 19:03:35 +02:00
Fabian Homborg
29e9f4838a Run parse_util_detect_errors on -c commands
This didn't do all the syntax checks, so something like

    fish -c 'echo foo; and $status'

complained of a missing command `0` (i.e. $status), and

    fish -c 'echo foo | exec grep'

hit an assert!

So we do what read_ni does, parse each command into an ast, run
parse_util_detect_errors on it if it worked and then eval the ast.

It is possible to do this neater by modifying parser::eval, but I
can't find where.
2021-07-27 18:37:20 +02:00
Fabian Homborg
08209b3d9a Forbid $status as a command
This is slightly unclean. Even tho it would otherwise be syntactically
valid, using $status as a command is very very very likely to be an
error, like

    if not $status

We have reports of this surprisingly regularly, including #2773.

Because $status can only ever be a value from 0 to 255, it is also
very unlikely to be an actual command, and that command is very
unlikely to do what you want.

So we simply point the user towards the "conditions" help section,
that should explain things.
2021-07-27 18:37:20 +02:00
Fabian Homborg
d32e1c12be tinyexpr: Check for nan in ncr
Turns out this takes ages.

Fixes #8170
2021-07-26 18:40:50 +02:00
Johannes Altmanninger
a2b30053dc Teach fish_indent about our feature flags
So it can handle syntax changes that call for different formatting.
2021-07-23 22:58:51 +02:00
Johannes Altmanninger
cc32b4f2a7 Make '&' only background if followed by a separating character
This is opt-in through a new feature flag "ampersand-nobg-in-token".

When this flag and "qmark-noglob" are enabled, this command no longer
needs quoting:

	curl https://example.com/thing?foo=bar&duran=duran

Compared to the previous approach e1570a4 ("Let '&' only separate as
the first char of a word"), this has some advantages:

1. "&&" and "&>" are no longer affected. They are still special, even
   if used between tokens without spaces, like "echo bar&>foo".
   Maybe this is not really *better*, but it avoids risking to annoy
   users by breaking the old variant.

2. "&" is still special if at the end of a token, like in "sleep 1&".

Word movement is not affected by the semantics change, so Alt-F and
friends still stop at every "&".
2021-07-23 22:58:51 +02:00
Fabian Homborg
859edc9c2c Implicitly use $PWD in $CDPATH in completions and highlighting
We already do for the actual cd-ing itself.

Missed in #4484.

Fixes #8161.
2021-07-23 17:22:06 +02:00
ridiculousfish
ce371e1881 Put back support for undocumented -I option to commandline
This allows operating on a user-specified commandline instead of the
true contents. This was inadvertently removed in a32248277f.
2021-07-21 15:35:22 -07:00
Fabian Homborg
3359e5d2e9
Let "return" exit a script (#8148)
Currently, if a "return" is given outside of a function, we'd just
throw an error.

That always struck me as a bit weird, given that scripts can also
return a value.

So simply let "return" outside also exit the script, kinda like "exit"
does.

However, unlike "exit" it doesn't quit an interactive shell - it seems
weird to have "return" do that as well. It sets $status, so it can be
used to quickly set that, in case you want to test something.
2021-07-21 22:33:39 +02:00
ridiculousfish
a32248277f Make commandline state thread safe
Today the reader exposes its internals directly, e.g. to the commandline
builtin. This is of course not thread safe. For example in concurrent
execution, running `commandline` twice in separate threads would cause a
race and likely a crash.

Fix this by factoring all the commandline state into a new type
'commandline_state_t'. Make it a singleton (there is only one command
line
after all) and protect it with a lock.

No user visible change here.
2021-07-21 11:51:46 -07:00
Fabian Homborg
e9a793532e Stop cd "" from crashing
Fixes #8147.
2021-07-17 19:03:15 +02:00
Fabian Homborg
f3f6e4a982 string: Add "--groups-only" to match
This adds a simple way of picking bits from a string that might be a
bit nicer than having to resort to a full `replace`.

Fixes #6056
2021-07-16 20:27:54 +02:00
Fabian Homborg
e013422143 Deduplicate $fish_user_paths automatically
In the variable handler, we just go through the entire thing and keep
every element once.

If there's a duplicate, we set it again, which calls the handler
again.

This takes a bit of time, to be paid on each startup. On my system,
with 100 already deduplicated elements, that's about 4ms (compared to
~17ms for adding them to $PATH).

It's also semantically more complicated - now this variable
specifically is deduplicated? Do we just want "unique" variables that
can't have duplicates?

However: This entirely removes the pathological case of appending to
$fish_user_paths in config.fish (which should be an FAQ entry!), and the implementation is quite simple.
2021-07-14 16:37:30 +02:00
Johannes Altmanninger
405ef31f72 Increase tmux-prompt test timeout in CI
This failed on Ubuntu and Mac.
2021-07-14 08:46:03 +02:00
Johannes Altmanninger
0ab6735450 Support $(cmd) command substitution as alternative to (cmd)
For consistency with "$(cmd)" and with other shells.
2021-07-13 21:33:42 +02:00
Johannes Altmanninger
ec3d3a481b Support "$(cmd)" command substitution without line splitting
This adds a hack to the parser. Given a command

	echo "x$()y z"

we virtually insert double quotes before and after the command
substitution, so the command internally looks like

	echo "x"$()"y z"

This hack allows to reuse the existing logic for handling (recursive)
command substitutions.

This makes the quoting syntax more complex; external highlighters
should consider adding this if possible.

The upside (more Bash compatibility) seems worth it.

Closes #159
2021-07-13 21:33:42 +02:00
Johannes Altmanninger
e50805646e completions/git: define function before use 2021-07-12 23:42:01 +02:00
Johannes Altmanninger
e3d8b315ed Avoid global and user git config leaking into git tests 2021-07-12 23:42:01 +02:00
Fabian Homborg
c8a2837647 Tests: Skip cancel tests on CI
This apparently doesn't work at all under Github Actions with tsan, so let's skip it.

If anyone feels the need to dig deeper into this, have at it. I find
this distracting.
2021-07-12 18:54:40 +02:00
Fabian Homborg
7789651b8a Tests: Increase timeouts even more in CI
Have I ever mentioned I hate this?
2021-07-12 18:45:46 +02:00
Fabian Homborg
e212064978 Tests: Increase timeouts
Yet again, fails on Github Actions with tsan.
2021-07-12 18:16:18 +02:00
ridiculousfish
179073ce62 Clear the control-C cancel flag earlier, allowing event handlers to run
When the user presses control-C, fish marks a cancellation signal which
prevents fish script from running, allowing it to properly unwind.
Prior to this commit, the signal was cleared in the reader. However this
missed the case where a binding would set $fish_bind_mode which would
trigger event handlers: the event handlers would be skipped because of
the cancellation flag was still set. This is similar to #6937.

Let's clear the flag earlier, as soon as we it's set, in inputter_t.
Fixes #8125.
2021-07-11 18:04:44 -07:00
Tair Sabyrgaliyev
8f7ea1f5b6 fix 'socket file name too long' error
In some setups (eg. macports) $tmpdir can expand to more than
100 symbols and tests fail with 'socket file name too long'
errors.

Using relative path to socket file fixes the issue.
2021-07-11 09:28:51 +02:00
Fabian Homborg
0e1f5108ae
string: Allow collect --allow-empty to avoid empty ellision (#8054)
* string: Allow `collect --no-empty` to avoid empty ellision

Currently we still have that issue where

    test -n (thing | string collect)

can return true if `thing` doesn't print anything, because the
collected argument will still be removed.

So, what we do is allow `--no-empty` to be used, in which case we
print one empty argument.

This means

    test -n (thing | string collect -n)

can now be safely used.

"no-empty" isn't the best name for this flag, but string's design
really incentivizes reusing names, and it's not *terrible*.

* Switch to `--allow-empty`

`--no-empty` does the exact opposite for `string split` and split0.

Since `-a`/`--allow-empty` already exists, use it.
2021-07-09 21:20:58 +02:00
ridiculousfish
b395b33776 Migrate remaining calls from debug_safe to FLOGF_SAFE
This removes debug_level and remaining debug bits.

We also simplify some of the exec errors, reducing them to a single
line.
2021-07-05 15:47:56 -07:00
ridiculousfish
92d50414c4 Fix the tmux-prompt test
The tmux-prompt test was failing when run more than once, because
XDG_DATA_HOME has a leading double-dot, causing the uvars file to
leak across sessions. Descend more deeply into our tmpdir to isolate
our XDG_DATA_HOME.
2021-07-04 18:11:49 -07:00
Johannes Altmanninger
62d8f7277b Revert "Avoid excessive polling of universal variable file"
This reverts commit b56b230076.
which somehow made us miss repaints on uvar notifications.

The commit was a workaround for a polling bug which was later properly
fixed by 7c5b8b855 ("Use the uvar notifier pipe timestamp to avoid
excessive polling"), so it's no longer necessary.

Add a system test. If I had a better understanding of the bug I could
probably write a better test.

Fixes #8088
2021-07-03 14:31:37 +02:00
Johannes Altmanninger
874fc439dd Remove stale path validation logic
We used to warn about PATH and CDPATH that are not valid directories,
but only if they contain colons.
However, the warning was a false positive because we would split
those values by colons anyway. So there is nothing left we want to
warn about.

Fixes #8095
2021-07-03 08:45:47 +02:00
Fabian Homborg
a3eea4325e Skip some tests on OpenBSD
sigint2 would hang (probably because of different semantics in signal
delivery?)

wcstod isn't implemented correctly, so math can't do hex numbers.

OpenBSD only passes the filename as argv[0] and doesn't give us another feature I know of, so status fish-path can't work.
2021-06-24 20:46:03 +02:00
Fabian Homborg
66bc6ce77d Try to fix tests for Solaris' ps 2021-06-24 18:19:28 +02:00
Fabian Homborg
49bac252f6 Fix some tests for OpenIndiana
Slightly different output and status - false returns 255, ls doesn't
say it's "ls" in the error.
2021-06-24 18:17:10 +02:00
Johannes Altmanninger
48c1550f61 Point to builtins begin/end when a failed command starts with "{"
Closes #6415
2021-06-23 21:47:40 +02:00
Fabian Homborg
392e48d242 Fix fish_add_path tests
Whoopsie!

I forgot to adjust them for $PATH scope - it now prints a `-g` when
setting $PATH verbosely.
2021-06-23 21:30:10 +02:00
Fabian Homborg
7059eaa4ab Revert "Disallow escaped characters in variable expansion"
This reverts commit 555af37616.
2021-06-10 16:46:17 +02:00
Fabian Homborg
046db09f90
Try to set LC_CTYPE to something UTF-8 capable (#8031)
* Try to set LC_CTYPE to something UTF-8 capable

When fish is started with LC_CTYPE=C (even just effectively, often via
LC_ALL=C!), it's basically broken. There's no way to handle non-ASCII
characters with a C locale unless we want to write our
locale-independent replacements for all of the system functions.

Since we're not going to do that, let's try to find *some locale* for
LC_CTYPE.

We already do that in __fish_setlocale, but that's

- a bit of a weird thing that reads unstandardized system
  configuration files
- allows setting locale to C explicitly

So it's still easily possible to end up in a broken configuration.

Now, the issue with this is that there is (AFAICT) no portable way to
get a list of all allowed locales and C.UTF-8 is not standardized, so
we have no one locale to fall back on and are forced to try a few. The
list we have here is quite arbitrary, but it's a start.

Python does something similar and only tries C.UTF-8, C.utf8 and
"UTF-8".

Once C.UTF-8 is (hopefully) standardized, that will just start
working (tm).

Note that we do not *export* the fixed LC_CTYPE variable, so external
programs still have to deal with the C locale, but we have no real
business messing with the user's environment.

To turn it off: $fish_allow_singlebyte_locale, if set to something true (like "1"),
will re-run the locale initialization and skip the bit where we force
LC_CTYPE to be utf8-capable.

This is mainly used in our tests, but might also be useful if people
are trying to do something weird.
2021-06-06 09:28:32 +02:00
ridiculousfish
c5ec4ef5f9 Reverts noshebang test fixes
The hope is that the noshebang test was fixed on old glibc
through e74b9d53df. Revert the previous optimistic attempts to
fix these through adding sleeps and subshells.

This reverts commit b3da0bd5a2.
This reverts commit 8a86d3452f.
2021-05-31 13:42:26 -07:00
Fabian Homborg
b3da0bd5a2 tests/noshebang: Add some longer sleeps
This still fails on launchpad. Last try, then I'm removing this - it's
not really expected that this particular bit would change a lot.
2021-05-30 17:19:04 +02:00
Fabian Homborg
8a86d3452f tests/noshebang: Do redirections in a new shell process
This is an attempt to solve the test failures on Launchpad's CI.

I'm assuming when we do a redirection like

    foo > file

and then try to execute `file` immediately afterwards, we either
haven't written it soon enough or closed the file, so we get a "text
file busy" error.

So, when we do that in a new fish the file should be closed once it
quits.

See #8021.
2021-05-30 11:08:33 +02:00
Fabian Homborg
7511de8d8d tests/noshebang: Sleep before executing a file we just wrote to
When you try to execute a file directly after you've written to it,
you might, on some systems, get a "text file busy" error.

So we unfortunately have to sleep to avoid it.

See #8021 for where this was added,
537b3f6cb1 for the same problem.
2021-05-26 17:14:15 +02:00