Commit Graph

32 Commits

Author SHA1 Message Date
Peter Ammon
7d98cc8850 ast: stop using Node::ptr_eq
This function hid a bug! It converted two Nodes to `*const ()` which discards
the vtable pointer, using only the data pointer; but two nodes can and do have
the same data pointer (e.g. if one node is the first item in another).

Add the (statically dispatched) is_same_node function with a warning comment,
and adopt that instead.
2025-04-20 17:53:43 -07:00
Peter Ammon
cef7c3c5c4 Switch ParseKeyword to Rust naming conventions 2025-04-20 17:53:42 -07:00
kerty
b5c869d5e7 Make parse_util_token_extent return its output instead of mutating input. 2025-01-23 17:09:29 +01:00
Johannes Altmanninger
8208a12a76 Back out "Support help argument in "{ -h""
This backs out commit efce176ceb.
2025-01-19 18:57:21 +01:00
Fabian Boehm
494bdfa013 Revert accidentally pushed fork
Revert "README for this fork"

This reverts commit 97db461e7f.

Revert "Allow foo=bar global variable assignments"

This reverts commit 45a2017580.

Revert "Interpret () in command position as subshell"

This reverts commit 0199583435.

Revert "Allow special variables $?,$$,$@,$#"

This reverts commit 4a71ee1288.

Revert "Allow $() in command position"

This reverts commit 4b99fe2288.

Revert "Turn off full LTO"

This reverts commit b1213f1385.

Revert "Back out "bind: Remove "c-" and "a-" shortcut notation""

This reverts commit f43abc42f9.

Revert "Un-hide documentation of non-fish shell builtins"

This reverts commit 485201ba2e.
2025-01-19 18:34:59 +01:00
Johannes Altmanninger
45a2017580 Allow foo=bar global variable assignments
override fixes
2025-01-19 18:29:07 +01:00
Johannes Altmanninger
4a71ee1288 Allow special variables $?,$$,$@,$# 2025-01-19 18:29:07 +01:00
Johannes Altmanninger
efce176ceb Support help argument in "{ -h"
Unlike other builtins, "{" is a separate token, not a keyword-string
token.

Allow the left brace token as command string; produce it when parsing
"{ -h"/"{ --help" (and nowhere else).  By using a decorated statement,
we reuse logic for redirections etc.

Other syntax elements like "and" are in the builtin list, which
- adds highlighting logic
- adds it to "builtin --names"
- makes it runnable as builtin
  (e.g. "builtin '{'" would hypothetically print the man page)

These don't seem very important (highlighting for '{' needs to match
'}' anyway).

Additionally, making it a real builtin would mean that we'd need to
deactivate a few places that unescape "{" to BRACE_BEGIN.

Let's not add it to the built in list. Instead, simply synthesize
builtin_generic in the right spot.

I'm assuming we want "{ -h" to print help, but '"{" -h' to run an
external command, since the latter is historical behavior.  This works
naturally with the above fake builtin approach which never tries to
unescape the left brace.
2025-01-19 18:29:07 +01:00
Johannes Altmanninger
1bf2b43d30 Allow { } for command grouping, like begin / end
For compound commands we already have begin/end but

> it is long, which it is not convenient for the command line
> it is different than {} which shell users have been using for >50 years

The difference from {} can break muscle memory and add extra steps
when I'm trying to write simple commands that work in any shell.

Fix that by embracing the traditional style too.

---

Since { and } have always been special syntax in fish, we can also
allow

	{ }
	{ echo }

which I find intuitive even without having used a shell that supports
this (like zsh. The downside is that this doesn't work in some other
shells.  The upside is in aesthetics and convenience (this is for
interactive use). Not completely sure about this.

---

This implementation adds a hack to the tokenizer: '{' is usually a
brace expansion. Make it compound command when in command position
(not something the tokenizer would normally know). We need to disable
this when parsing a freestanding argument lists (in "complete somecmd
-a "{true,false}").  It's not really clear what "read -t" should do.
For now, keep the existing behavior (don't parse compound statements).

Add another hack to increase backwards compatibility: parse something
like "{ foo }" as brace statement only if it has a space after
the opening brace.  This style is less likely to be used for brace
expansion. Perhaps we can change this in future (I'll make a PR).

Use separate terminal token types for braces; we could make the
left brace an ordinary string token but since string tokens undergo
unescaping during expansion etc., every such place would need to know
whether it's dealing with a command or an argument.  Certainly possible
but it seems simpler (especially for tab-completions) to strip braces
in the parser.  We could change this.

---

In future we could allow the following alternative syntax (which is
invalid today).

	if true {
	}
	if true; {
	}

Closes #10895
Closes #10898
2025-01-15 11:18:46 +01:00
Johannes Altmanninger
4f3d6427ce Fix regression causing crash in "commandline -j"
Commit 3fcc6482cb (Fix parse_util_process_extent including too much
on the left, 2024-12-24) changed the process extent based on the
observation that "A\n\n\nB" comprises three tokens with ranges 0..1,
1..2 and 4..5. Prior to that commit, the second process extent was
2..5, which seems a bit weird because it includes newlines.

Weirdness aside, the real reason for changing it was this snippet in
the autosuggestion performer, where we compute the process extent
around cursor, and check if the line at process start matches the
cached search string.

        // Search history for a matching item unless this line is not a continuation line or quoted.
        if range_of_line_at_cursor(
            &command_line,
            parse_util_process_extent(&command_line, cursor_pos, None).start,
        ) == search_string_range

Given "A\n\n\nB" and cursor_pos=1 commit 3fcc6482cb changed the output
from 2..5 to 4..5. This brings problems:
1. leading spaces will not be included (which is probably
   inconsequential but still ugly).
2. the specified cursor position is not included in the given range.

We could paper over 2 by computing min(cursor_pos)
but that would leave 1.

For now let's revert and solve the autosuggestion issue in a less
brittle way.
2025-01-12 19:55:17 +01:00
Stefan Boca
dcddffd222 refactor: misc cleanup (#10998)
* refactor EnvVar: Arc<Box<[WString]>> -> Arc<[WString]>

* remove unnecessary `&mut` from EnvVar methods

* clippy: use eq_ignore_ascii_case instead of manual comparison

see https://rust-lang.github.io/rust-clippy/master/index.html#manual_ignore_case_cmp

* clippy: use `is_some_and` and `is_ok_and` instead of `map_or`

see https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or

* clippy: use `assert!()` instead of `assert_eq!()` with booleans
2025-01-04 19:49:44 -06:00
Johannes Altmanninger
3fcc6482cb Fix parse_util_process_extent including too much on the left 2024-12-30 10:50:38 +01:00
Johannes Altmanninger
85404bf7a9 edit_command_buffer: speed up setting cursor position by line/column
alt-e restores the cursor position received from the editor, moving by
one character at a time.  This can be super slow on large commandlines,
even on release builds.  Let's fix that by setting the coordinates
directly.
2024-11-01 20:09:55 +01:00
Johannes Altmanninger
cd541575b4 Fix completion failing on unclosed brace with wildcard
Completion on ": {*," used to work but nowadays our attempt to wildcard-expand
it fails with a syntax error and we do nothing.  This behavior probably only
makes sense for the overflow case, so do that.
2024-10-19 22:04:54 +02:00
Johannes Altmanninger
4c43819d32 Fix crash indenting quoted suffix after command substitution
Commit b00899179 (Don't indent multi-line quoted strings; do indent inside
(), 2024-04-28) made parse_util_compute_indents() crash on `echo "$()"'x`.
After recursively indenting the command substitution, we indent the "'x
suffix.  We skip the quoted part by setting "done=2".  Later we wrongly
index "self.indents[done..range.start+offset+1]" (= "self.indents[2..1]").

Fix this by making sure that "start >= done", thus not setting any indents
for the quoted suffix.  There is no need to do so; only the first character
in each line needs an indent.
2024-09-28 13:36:17 +02:00
Mahmoud Al-Qudsi
5f8f799cf7 Replace C++ doc \return with "Return"
quick_replace '\\\\return(s)? ' 'Return$1 ' src/

Filtered to only lines beginning with //
2024-05-06 14:59:36 -05:00
Mahmoud Al-Qudsi
589639a87d Replace C++-style \p with Markdown backticks
quick_replace '\\\\p ([a-zA-Z0-9_]+)' '`$1`' src/

Filtered to only lines beginning with //
2024-05-06 14:59:23 -05:00
Johannes Altmanninger
e1eeb3177e Silence clippy lint 2024-05-03 09:36:35 +02:00
Johannes Altmanninger
b00899179f Don't indent multi-line quoted strings; do indent inside ()
On a command with multiline quoted string like

    begin
        echo "line1
    line2"
    end

we actually indent line2 which seeems misleading because the indentation
changes the behavior when typed into a script.

This has become more prominent since commits
- a37629f86 (fish_clipboard_copy: indent multiline commands, 2024-04-13)
- 611a0572b (builtins type/functions: indent interactively-defined functions, 2024-04-12)
- 222673f33 (edit_command_buffer: send indented commandline to editor, 2024-04-12)

which add indentation to an exported commandline.

Never indent quoted strings, to make sure the rendering matches the semantics.
Note that we do need to indent the opening quote which is fine because
it's on the same line.

While at it, indent command substitutions recursively.  That feature should
also be added to fish_indent's formatting mode (which is the default).
Fortunately the formatting mode already works fine with quoted strings;
it does not indent them. Not sure how that's done and whether indentation
can use the same logic.
2024-04-30 14:12:48 +02:00
Johannes Altmanninger
2f6ed61833 parse_util_cmdsubst_extent to return an exclusive range
Given "1(23)4", this function returns an inclusive range, from the opening
to the closing parenthesis.  The subcommand is extracted by incrementing
the range start and interpreting the result as an exclusive range.

This is confusing, especially if we want to add multi-character quotes.
Change it to always return the full range (including parentheses) and provide
an easy way to access the command string.

While at it, switch to returning an enum.

This change is perhaps larger and more complex than necessary (sorry)
because it is mainly made with multi-character quotes in mind.  Let's see
if that works out.
2024-04-30 14:12:48 +02:00
Johannes Altmanninger
29be454652 Move parse_util tests to separate file 2024-04-30 14:00:06 +02:00
Johannes Altmanninger
47a446ae18 Teach fish_indent to only indent and unindent
To be used in the following commits.
2024-04-15 08:32:31 +02:00
Johannes Altmanninger
29dc307111 Insert some completions with quotes instead of backslashes
File names that have lots of spaces look quite ugly when inserted as
completions because every space will have a backslash.

Add an initial heuristic to decide when to use quotes instead of
backslash escapes.

Quote when
1. it's not an autosuggestion
2. we replace the token or insert a fresh one
3. we will add a space at the end

In future we could relax some of these requirements.

Requirement 2 means we don't quote when appending to an existing token.
Need to find a natural behavior here.

Re 3, if the completion adds no space, users will probably want to add more
characters, which looks a bit weird if the token has a trailing quote.
We could relax this requirement for directory completions, so «ls so»
completes to «ls 'some dir with spaces'/».

Closes #5433
2024-04-13 15:34:21 +02:00
Johannes Altmanninger
8d88b4d358 Support quoted escaping also when ' or \ is present
Also, if there are more single quotes than double quotes and dollars, use
double quotes for quoting.
2024-04-13 15:33:05 +02:00
Johannes Altmanninger
5b324f8ecb Fix regression in parse_util_process_extent
Found on a two-line commandline

    for file in (path base<TAB>
    echo
2024-03-24 16:34:36 +01:00
Johannes Altmanninger
3cfa09d1bd Make test_init() return a scope guard
To be used in the next commit.
2024-03-24 16:33:35 +01:00
Himadri Bhattacharjee
e014c981f2 Disallow background operator before && or ||
Co-authored-by: Johannes Altmanninger <aclopte@gmail.com>

Closes #10228
Fixes #9911
2024-01-20 11:32:44 +01:00
ridiculousfish
9bd4b3f878 Adopt count_newlines in additional places 2024-01-14 10:04:55 -08:00
Johannes Altmanninger
68d1207d53 Rename flag that fails expansions with command substitutions
SKIP_CMDSUBST does not pass through command substitutions, unlike
SKIP_VARIABLES and SKIP_WILDCARDS.
2024-01-14 13:19:38 +01:00
Fabian Boehm
0a92d03498 Remove L! from sprintf calls
Remove unnecessary L!
2024-01-13 08:52:54 +01:00
Fabian Boehm
09cd7c7ad9 Remove widestring-suffix uses
This removes both the `#[widestrs]` annotation as well as all `"foo"L`
suffixes, and does a `cargo fmt` run on the result
2024-01-13 08:52:54 +01:00
Johannes Altmanninger
3ae20bdba0 Move fish-rust to project root 2024-01-13 03:58:33 +01:00