Commit Graph

40 Commits

Author SHA1 Message Date
Johannes Altmanninger
d3c37de753 Back out "Always treat brace at command start as compound statement"
This backs out commit 98750e1ae5.
2025-01-19 18:57:21 +01:00
Johannes Altmanninger
98750e1ae5 Always treat brace at command start as compound statement 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
e678fb8578 Fix autosuggestions on quoted subcommand keyword
The commandline "and fis" rightly gets command autosuggestions whereas
"'and' fis" wrongly gets file autosuggestions.  The former works via
a hack. Extend it to quoted keywords.
2025-01-15 10:54:18 +01:00
Johannes Altmanninger
b6c249be0c Back out "Escape : and = in file completions"
If you don't care about file paths containing '=' or ':', you can
stop reading now.

In tokens like

	env var=/some/path
	PATH=/bin:/usr/local/b

file completion starts after the last separator (#2178).

Commit db365b5ef8 (Do not treat \: or \= as file completion anchor,
2024-04-19) allowed to override this behavior by escaping separators,
matching Bash.

Commit e97a4fab71 (Escape : and = in file completions, 2024-04-19)
adds this escaping automatically (also matching Bash).

The automatic escaping can be jarring and confusing, because separators
have basically no special meaning in the tokenizer; the escaping is
purely a hint to the completion engine, and often unnecessary.

For "/path/to/some:file", we compute completions for "file" and for
"/path/to/some:file".  Usually the former already matches nothing,
meaning that escaping isn't necessary.

e97a4fab71 refers us to f7dac82ed6 (Escape separators (colon and
equals) to improve completion, 2019-08-23) for the original motivation:

	$ ls /sys/bus/acpi/devices/d<tab>
	$ ls /sys/bus/acpi/devices/device:
	device:00/ device:0a/ …

Before automatic escaping, this scenario would suggest all files from
$PWD in addition to the expected completions shown above.

Since this seems to be mainly about the case where the suffix after
the separator is empty, 

Let's remove the automatic escaping and add a heuristic to skip suffix
completions if:
1. the suffix is empty, to specifically address the above case.
2. the whole token completes to at least one appending completion.
   This makes sure that "git log -- :!:" still gets completions.
   (Not sure about the appending requirement)

This heuristic is probably too conservative; we can relax it later
should we hit this again.

Since this reverts most of e97a4fab71, we address the code clone
pointed out in 421ce13be6 (Fix replacing completions spuriously quoting
~, 2024-12-06). Note that e97a4fab71 quietly fixed completions for
variable overrides with brackets.

	a=bracket[

But it did so in a pretty intrusive way, forcing a lot of completions
to become replacing. Let's move this logic to a more appropriate place.

---

Additionally, we could sort every whole-token completion before every
suffix-completion.  That would probably improve the situation further,
but by itself it wouldn't address the immediate issue.

Closes #11027
2025-01-13 09:50:13 +01:00
Johannes Altmanninger
0cfc95993a Swap code blocks for completing separator suffix resp. whole token
Mainly to make the next commit's diff smaller. Not much functional
change: since file completions never have the DONT_SORT flag set,
these results will be sorted, and there are no data dependencies --
unless we're overflowing the max number of completions.  But in that
case the whole-token completions seem more important anyway.
2025-01-13 09:50:13 +01:00
Johannes Altmanninger
f9febba2b0 Fix replacing completions with a -foo prefix
Fixes #10904
2024-12-14 09:31:20 +01:00
Mahmoud Al-Qudsi
b570c7f6a6 Reduce allocations when deduping completions in place
This is still suboptimal because we are allocating a vector of indices to be
removed (but allocation-free in the normal case of no duplicates) but
significantly better than the previous version of the code that duplicated the
strings (which are larger and spread out all over the heap).

The ideal code (similar to what we had in the C++ version, iirc) would look like
this, but it's not allowed because the borrow checker hates you:

```
fn unique_in_place_illegal(comps: &mut Vec<Completion>) {
    let mut seen = HashSet::with_capacity(comps.len());
    let mut idx = 0;
    while idx < comps.len() {
        if !seen.insert(&comps[idx].completion) {
            comps.remove(idx);
            continue;
        }
        idx += 1;
    }
}
```
2024-11-22 14:11:01 -06:00
Johannes Altmanninger
2e4f98b51c Do not add a space after completing inside brace expansion
Another everyday annoyance, has been for many years.
2024-10-19 22:06:05 +02: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
Fabian Boehm
de13e6f9af complete: Only describe commands if the function exists
This shells out to __fish_describe_command, but if the install is
incomplete that will trigger the command-not-found handler.
2024-10-15 13:09:02 +02:00
Fabian Boehm
5e8adb18f4 complete: Sort --keep-order completions smaller
This should make the sort have a strict weak ordering, which rust
requires since 1.81 (or it will panic).

Note: This changes the order, but that's *fine* since the current
order is random weirdness anyway.

Fixes #10763
2024-10-05 13:53:02 +02:00
Peter Ammon
974ad882fa Clean up fish-printf in preparation for publishing
Make fish-printf no longer depend on the widestring crate, as other clients
won't use it; instead this is an optional feature.

Make format strings a generic type, so that both narrow and wide strings can
serve. This removes a lot of the complexity around converting from narrow to
wide.

Add a README.md to this crate.
2024-09-21 17:52:11 -07:00
Johannes Altmanninger
5432ee1aa9 Relax history autosuggestion and highlighting if cd is wrapped
For implementation reasons, we special-case cd in several ways
1. it gets different completions (handle_as_special_cd)
2. when highlighting, we honor CDPATH
3. we discard autosuggestions from history that don't have valid path arguments

There are some third-party tools like zoxide that redefine cd ("function cd
--wraps ...; ...; end"). We can't support this in general but let's try to
make an effort.

zoxide tries to be a superset of cd, so special case 1 is still
valid but 2 and 3 are not, because zoxide accepts some paths
that cd doesn't accept.

Let's add a hack to detect when "cd" actually means something else by checking
if there is any --wraps argument.

A cleaner solution is definitely possible but more effort.

Closes #10719
2024-09-14 08:51:42 +02:00
Mahmoud Al-Qudsi
50a6dfd10d Replace a HashMap w/ a BTreeMap
The HashMap is used to generate the __fish_describe_command integration
completions. Given the nature of the allocations and the numbers that we use, a
BTreeMap would theoretically perform better. Benchmarks show a 2-9%
improvement in completion times consistently in favor of BTreeMap.
2024-08-31 14:13:41 -05:00
Johannes Altmanninger
5918bca1eb Make "complete -e" prevent completion autoloading
We do the same for functions.

Closes #6716
2024-08-24 08:30:52 +02:00
Peter Ammon
204663f1b8 Minor cleanup of apply_var_assignments
Simplify the function signature and calls sites.
2024-06-30 15:27:49 -07:00
Peter Ammon
b5fd8d697b Minor refactor of completer perform_for_commandline 2024-06-30 13:59:22 -07:00
Peter Ammon
6b4dbf3b05 Remove additional dead code 2024-06-29 18:03:52 -07:00
Mahmoud Al-Qudsi
0adebdfbc4 Fix completely broken __fish_describe_command integration
Command completion descriptions were not being generated from `apropos`. Well,
they were being generated but that was not being correctly used by fish core.

Not sure when this was broken, but there's a possibility it was during the rust
port.

In addition to simply not working, it seems the old code tried to avoid
allocations but String::split_at_mut() allocates a new string (since one
allocation from the global allocator can't be split into two allocations to be
freed separately). Use `String::as_mut_utfstr()` before splitting the &wstr
instead of splitting the &str to actually do this alloc-free.
2024-06-27 20:43:14 -05:00
Peter Ammon
7fcbe5b8ab Thread variables into autoload_names
Stop fetching a global set of variables.
2024-06-23 16:39:39 -07:00
ridiculousfish
d36f94d96c Remove additional call to Parser::shared() 2024-06-23 16:39:39 -07:00
ridiculousfish
832ed31687 Start removing calls to Parser::shared()
Parser::shared() gets an Rc to a Parser, but we can do without it.
Let's aim to get rid of the cyclic ref.
2024-06-23 16:39:39 -07:00
ridiculousfish
838ff86ae7 Rename printf crate to fish-printf
Preparing to publish to crates.io
2024-06-09 12:29:09 -07:00
Mahmoud Al-Qudsi
d90d924c8c Remove parser library_data_pod_t ffi workaround
We don't need to separate POD fields from the main parser libdata any more.
2024-06-02 20:27:44 -05:00
ridiculousfish
f16a1361c5 Adopt the new printf crate
This drops our usage of printf-compat.
2024-05-26 16:07:27 -04:00
Mahmoud Al-Qudsi
3d648e6e04 Remove Arc from environment::globals() (take 2)
We don't forward this variable for storage in any structs, so there's no reason
to go through an Arc instead of returning the `&'static EnvStack` directly.

NB: This particular change was safe, and passes all tests on its own.
2024-05-16 21:17:15 -05:00
Mahmoud Al-Qudsi
45e249dd94 Revert removal of Arc from principal() and global()
This reverts commit c6d3bde0c6.
This reverts commit 4ce13f0adb.
2024-05-16 21:08:06 -05:00
Mahmoud Al-Qudsi
c6d3bde0c6 Remove Arc from environment::globals()
We don't forward this variable for storage in any structs, so there's no reason
to go through an Arc instead of returning the `&'static EnvStack` directly.
2024-05-16 20:50:23 -05: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
e97a4fab71 Escape : and = in file completions
This is similar to f7dac82ed (Escape separators (colon and equals) to improve
completion, 2019-08-23) except we only escape : and = if they are the result of
file completions.  This way we avoid issues with custom completions like dd.
This also means that it won't work for things like __fish_complete_suffix
[*] but that can be fixed later, once we can serialize the DONT_ESCAPE flag.

By moving the escaping step earlier, this causes some unit test changes
which should not result in actual behavior change.

See also #6099

[*]: The new \: and \= does not leak from "complete -C" because that command
unescapes its output  -- unless --escape is given.
2024-04-20 13:34:08 +02:00
Johannes Altmanninger
db365b5ef8 Do not treat \: or \= as file completion anchor
Partially reapplies f7dac82ed (Escape separators (colon and equals) to
improve completion, 2019-08-23) which has been reverted.
2024-04-20 13:34:08 +02:00
Johannes Altmanninger
232483d89a History pager to only operate on the line at cursor
Multiline search strings are weirdly broken (inserting control characters
in the command line) and probably not very useful anyway.
On the other hand I often want to compose a multi-line command
from single-line commands I ran previously.

Let's support this case by limiting the initial search string to the current
line; and replace only that line.

Alternatively this could operate on jobs (that is, replace a surrounding
"foo | bar") instead of using line boundaries.
2024-03-23 09:54:18 +01:00
Johannes Altmanninger
54bc196918 Only use fuzzy option completion if there is a leading -
Commit b768b9d3f (Use fuzzy subsequence completion for options names as well,
2024-01-27) allowed completing "oa" to "--foobar", which is a false positive,
especially because it hides other valid completions of non-option arguments.
Let's at least require a leading dash again before completing option names.
2024-01-30 09:09:45 +01:00
Johannes Altmanninger
b768b9d3f5 Use fuzzy subsequence completion for options names as well
Version 2.1.0 introduced subsequence matching for completions but as the
changelog entry mentions, "This feature [...] is not yet implemented for
options (like ``--foobar``)".  Add it. Seems like a strict improvement,
pretty much.
2024-01-27 17:57:48 +01:00
Johannes Altmanninger
033f64fde6 Fix indentation in bitflags macro 2024-01-27 17:57:48 +01: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
Johannes Altmanninger
3ae20bdba0 Move fish-rust to project root 2024-01-13 03:58:33 +01:00