Commit graph

151 commits

Author SHA1 Message Date
Johannes Altmanninger
8208fc4f87 Cleanup comment to match implementation
This was recently changed to return bool.
2021-12-12 18:21:35 +01:00
Aaron Gyes
ce475c0b4c more int -> bool
all the things
2021-12-09 00:52:45 -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
c94dec5d0e Fix assertion error trying to highlight cmdsubs inside unbalanced quotes
I initially put this logic + assertion in another function, where we
always get balanced quotes. Not for highlighting.
2021-10-31 14:28:54 +01:00
Johannes Altmanninger
db377385f6 Fix copy paste error 2021-10-31 14:28:54 +01: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
Aaron Gyes
dcaa9c7959 fix incorrect error message for 'end --foo' 2021-10-01 04:54:02 -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
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
8939a71ec6 An empty string means we're on the first line
Oops, this broke up-or-search!
2021-07-27 20:11:32 +02:00
Fabian Homborg
35ca42413d Simplify some parse_util functions
Don't just reflexively drop down to wchar_t.
2021-07-27 18:39:56 +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
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
6960a56f29 parse_util_locate_brackets_of_type to only find cmdsubs
Now that we have a separate function for parsing slices, we no longer
need to support parsing slices in the same function as cmdsubs.
2021-07-14 13:59:48 -07:00
ridiculousfish
52c354a60f Simplify slice parsing in highlighting
Factor out parsing of slices, which is only used for highlighting.
2021-07-14 13:59:48 -07:00
ridiculousfish
a2dfd87928 Simplify parse_util_get_parameter_info
We no longer use any part of the "parameter info" except its quote type.
Just return the quote type directly.
2021-07-14 13:59:48 -07:00
ridiculousfish
083d8c5d23 Minor cleanup of certain parsing and quote finding functions
This makes more variables const and removes some suspicious casts.
2021-07-14 13:59:46 -07: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
4908f9bb40 Remove spurious character escape 2021-06-15 01:19:01 +02:00
ridiculousfish
48868e5667 Switch builtin execution to the performer model
In preparation for concurrent execution, introduce a
`get_performer_for_builtin` function. This function itself returns a
function, which when called will run the builtin. The idea is that the
function may be called on a background thread (but not in this commit).
2021-03-28 15:31:25 -07:00
ridiculousfish
fb92ad946b Rework null terminated arrays
Several functions including wgetopt and execve operate on null-terminated
arrays of nul-terminated pointers: a list of pointers to C strings where
the last pointer is null. Prior to this change, each process_t stored its
argv in such an array. This had two problems:

1. It was awkward to work with this type, instead of using std::vector,
etc.
2. The process's arguments would be rearranged by builtins which is
surprising

Our null terminated arrays were built around a fancy type that would copy
input strings and also generate an array of pointers to them, in one big
allocation.

Switch to a new model where we construct an array of pointers over
existing strings. So you can supply a `vector<string>` and now
`null_terminated_array_t` will just make a list of pointers to them. Now
processes can just store their argv in a familiar wcstring_list_t.
2021-03-28 15:31:25 -07:00
Fabian Homborg
c1fe5be0ce parse_util: Remove locate_cmdsubst
We have *3* functions to find command substitutions, this is the most awkward.
2021-03-26 19:32:14 +01:00
Johannes Altmanninger
444c05dfb1 Do not indent after escaped newline in comment
We do something similar in fish_indent.  This fixes the spurious indent
after comments in share/completions/emerge.fish.

See #7720
2021-02-16 18:39:03 +01:00
Johannes Altmanninger
5b3a466fa9 Refactor: collapse if statements 2021-02-13 09:01:41 +01:00
Johannes Altmanninger
5e8a248758 Indent escaped newlines
Similar to what fish_indent does. After typing "echo \" and hitting return,
the cursor will be indented.

A possible annoyance is that when you have multiple indented lines

	echo 1 \
	    2 \
	    3 \
	    4 \

If you remove lines in the middle with Control-k, the lines below
the deleted one will start jumping around, as they are disconnected
from and reconnected to "echo".
2021-02-13 09:01:41 +01:00
Johannes Altmanninger
511747d59e Indent only leaf nodes and in-between gaps
Probably not necessary for the next commit, but this way feels more logical
2021-02-13 09:01:41 +01:00
Johannes Altmanninger
7ee4a3b40d Indent empty lines inside block 2021-02-13 09:01:41 +01:00
Fabian Homborg
b5305ce3d3 Handle backslashes properly in locate_brackets_of_type
This needs to be rewritten, I'm pretty sure we have like 6 of these
kinds of ad-hoc "is this quoted" things lying around.

But for now, at least don't just check if the *previous* character was
a backslash.

Fixes #7685.
2021-02-05 22:03:13 +01:00
ridiculousfish
e43913a547 Stop expanding globs in command position when performing error checking
Before running a command, or before importing a command from bash history,
we perform error checking. As part of error checking we expand commands
including variables and globs. If the glob is very large, like `/**`, then
we could hang expanding it.

One fix would be to limit the amount of expansion from the glob, but
instead let's just not expand command globs when performing error checking.

Fixes #7407
2020-12-22 12:38:51 -08:00
Fabian Homborg
a776b08e84 Use bools, we have the technology 2020-09-24 18:53:19 +02:00
Johannes Altmanninger
fbaa5d193d Declare functions in headers or use internal linkage (static)
Found with gcc's -Wmissing-declarations which gives warnings like

	../src/tinyexpr.cpp:61:5: warning: no previous declaration for ‘int get_arity(int)’ [-Wmissing-declarations]
	   61 | int get_arity(const int type) {

The same warnings show up for builtin functions like builtin_bg because they
currently don't include their own headers. I left that.
Also reformat the touched files.
2020-09-08 22:44:03 +02:00
Johannes Altmanninger
cf075b4179 Teach up-line to cross empty lines
The line offset of a trailing newline on the commandline was computed incorrectly.
As a result, up-arrow did not work for a commandline like the one inserted by:

	commandline -i echo '' ''

Note this and the previous commit in the changelog.
2020-08-29 12:02:18 +02:00
ridiculousfish
a6b8394114 Remove some debugging code which was accidentally left in 2020-08-11 13:11:48 -07:00
ridiculousfish
f6c1ef58df Indent continuations after | and &&
This indents continuations after pipes and conjunctions if they contain
a newline.

Example:

    cmd1 &&
        cmd2

But it avoids the "double indent" if it indented unconditionally:

    cmd1 | begin
        cmd2
    end

More work towards improving #7252
2020-08-09 12:22:15 -07:00
Johannes Altmanninger
b947e360db Allow newlines after && and ||
We do the same for pipes (#1285). This matches POSIX sh behavior.
2020-08-06 21:24:26 +02:00
Johannes Altmanninger
64601fd4d3 Reformat CPP files 2020-08-04 21:44:59 +02:00
ridiculousfish
352062219d More clean up of parse_util_detect_errors_in_argument 2020-07-14 15:51:12 -07:00
ridiculousfish
3532a955a6 Use parse_util_locate_cmdsubst_range when validating arguments
Removes another usage of parse_util_locate_cmdsubst().
2020-07-14 15:34:26 -07:00
ridiculousfish
487de1e6c3 Reduce copying in parse_util_detect_errors
Allow parse_util_detect_errors to accept an already-parsed ast. This
eliminates a copy of the source, which is helpful when executing large
scripts.
2020-07-12 16:57:30 -07:00
ridiculousfish
dfeec433d8 Reduce allocation churn in parse_util_detect_errors
Reuse a single string for storage.
2020-07-12 16:57:30 -07:00
ridiculousfish
9ee5075fc3 Reformat CPP files 2020-07-12 12:21:25 -07:00
ridiculousfish
35cb449aa1 Make parse_statement_decoration_t a class enum 2020-07-07 16:28:39 -07:00
ridiculousfish
0c22f67bde Remove the old parser bits
Now that everything has been migrated to the new AST, remove as much of
the parse_tree bits as possible
2020-07-04 14:58:05 -07:00
ridiculousfish
3534c07584 Adopt the new AST in parse_execution
parse_execution is what turns a parsed tree into jobs, etc. Switch it from
parse_tree to the new AST.
2020-07-04 14:58:05 -07:00
ridiculousfish
202fdfa54a Adopt the new AST in parse_util_detect_errors
This switches parse_util_detect_errors from parsing with parse_tree to
the new ast.
2020-07-04 14:58:05 -07:00
ridiculousfish
7bea5ffa2e Adopt the new AST in parse_util_compute_indents
This switches parse_util_compute_indents from parsing with parse_tree to
the new ast.

It also reworks the parse_util_compute_indents tests, because
parse_util_compute_indents will be the backing for fish_indent.
2020-07-04 14:58:05 -07:00
Rosen Penev
0668513138 Change C casts to C++ ones
Some were kept for compatibility.

Found with -Wold-style-cast

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-05-01 13:30:56 -07:00
Rosen Penev
d9ad5a2627 remove unreachable break statements
Found with clang's -Wunreachable-code-break

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-12 17:02:17 -07:00