Commit graph

4723 commits

Author SHA1 Message Date
Xiretza
9ac6cbefb1 Port event.cpp to rust
Port src/event.cpp to fish-rust/event.rs and some needed functions.

Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
2023-03-12 14:55:50 -05:00
Xiretza
dd7b177d72 builtins: set_color: remove unhandled -v/--version flag
Invoking `set_color -v` crashes fish.
2023-03-05 16:09:36 +01:00
Mahmoud Al-Qudsi
455b744bca Port fd_monitor tests to rust
This shows some of the ugliness of the rust borrow checker when it comes to
safely implementing any sort of recursive access and the need to be overly
explicit about which types are actually used across threads and which aren't.

We're forced to use an `Arc` for `ItemMaker` (née `item_maker_t`) because
there's no other way to make it clear that its lifetime will last longer than
the FdMonitor's. But once we've created an `Arc<T>` we can't call
`Arc::get_mut()` to get an `&mut T` once we've created even a single weak
reference to the Arc (because that weak ref could be upgraded to a strong ref at
any time). This means we need to finish configuring any non-atomic properties
(such as `ItemMaker::always_exit`) before we initialize the callback (which
needs an `Arc<ItemMaker>` to do its thing).

Because rust doesn't like self-referential types and because of the fact that we
now need to create both the `ItemMaker` and the `FdMonitorItem` separately
before we set the callback (at which point it becomes impossible to get a
mutable reference to the `ItemMaker`), `ItemMaker::item` is dropped from the
struct and we instead have the "constructor" for `ItemMaker` take a reference to
an `FdMonitor` instance and directly add itself to the monitor's set, meaning we
don't need to move the item out of the `ItemMaker` in order to add it to the
`FdMonitor` set later.
2023-03-05 00:33:53 -06:00
Johannes Altmanninger
5dbffa8b6d Add a maybe_t constructor taking std::unique_ptr
CXX does not allow generic types like maybe_t.  When porting a C++ function
that returns maybe_t to Rust, we return std::unique_ptr instead. Let's make
the transition more seamless by allowing to convert back to maybe_t implicitly.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
494f10a5a8 Use the correct type names for forward-declared parser types
This allows using the types in cxx bridges other than the ones that define
them.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
0410bacdf6 clang-format C++ files 2023-03-04 22:24:22 +01:00
ridiculousfish
497073f74e Add an assert in wcharz_t's constructor that it is not null
These strings should never be null.
2023-03-04 13:13:24 -08:00
Xiretza
8427e05bf7 Move escape_string tests to Rust
This way, both the Rust FFI wrapper and the actual C++ implementation are
tested.
2023-03-04 12:42:06 -08:00
Fabian Boehm
1aa3393f05 Test ifind bug with non-ascii codepoints 2023-03-02 16:33:20 +01:00
Fabian Boehm
7c91d009c1 reader: Remove assert in history search
This isn't a great use of `assert` because it turns a benign "oh I
need to search again" bug into a crash.

Fixes #9628
2023-03-02 16:29:49 +01:00
Johannes Altmanninger
14f3a5f79a Re-add highlighter tests
These were removed by accident.
2023-03-02 08:54:58 +01:00
Clemens Wasser
17c1fa9d64
Port bg builtin to Rust (#9621)
* bg: Port bg builtin to Rust
2023-02-28 16:42:12 -06:00
Victor Song
c7ea768a74
Rewrite wrealpath from wutil in Rust (#9613)
* wutil: Rewrite `wrealpath` in Rust

* Reduce use of FFI types in `wrealpath`

* Addressed PR comments regarding allocation

* Replace let binding assignment with regular comparison
2023-02-26 20:13:40 -07:00
Clemens Wasser
6f5be9bae4 block: Port block builtin to Rust
Closes #9612.
2023-02-26 14:16:55 -06:00
Clemens Wasser
330e8a86c7 block: Use an integer to count blocks 2023-02-26 14:12:57 -06:00
Mahmoud Al-Qudsi
562eeac43e
Port job_group to rust (#9608)
More ugliness with types that cxx bridge can't recognize as being POD. Using
pointers to get/set `termios` values with an assert to make sure we're using
identical definitions on both sides (in cpp from the system headers and in rust
from the libc crate as exported).

I don't know why cxx bridge doesn't allow `SharedPtr<OpaqueRustType>` but we can
work around it in C++ by converting a `Box<T>` to a `shared_ptr<T>` then convert
it back when it needs to be destructed. I can't find a clean way of doing it
from the cxx bridge wrapper so for now it needs to be done manually in the C++
code.

Types/values that are drop-in ready over ffi are renamed to match the old cpp
names but for types that now differ due to ffi difficulties I've left the `_ffi`
in the function names to indicate that this isn't the "correct" way of using the
types/methods.
2023-02-25 16:42:45 -06:00
Neeraj Jaiswal
f52569a800 abbr: port abbreviation and abbr builtin to rust 2023-02-25 12:24:58 +01:00
Neeraj Jaiswal
e384e63b24 re: port regex make anchored to rust and helper ffi funtions for regex 2023-02-25 12:24:57 +01:00
Johannes Altmanninger
b7041ad89b clang-format C++ files 2023-02-25 12:24:25 +01:00
Johannes Altmanninger
b6ede1c2a3 complete.cpp: re-use constant in try_complete_variable 2023-02-25 11:53:43 +01:00
Neeraj Jaiswal
3b60bc1de0 contains: port contains builtin to rust 2023-02-22 18:32:27 +01:00
Xiretza
77a474ee37 Move POD components of library_data_t to separate struct
This allows them to be accessed as regular fields from Rust, rather than having
to create setter/getter methods for each of them.
2023-02-20 11:32:12 +01:00
Mahmoud Al-Qudsi
aaf2d1c19d Use * const u8 instead of * const c_void
The way cxx bridge works, it doesn't recognize any types from another module as
being shared cxx bridge types with generations native to both C++ and Rust,
meaning every module that was going to use function pointers would have to
define its own `c_void` type (because cxx bridge doesn't recognize any of
libc::c_void, std::ffi::c_void, or autocxx::c_void).

FFI on other platforms has long used the equivalent of `uint8_t *` as an
alternative to `void *` for code where `void` was not available or was
undesirable for some reason. We can join the club - this way we can always use
`* {const|mut} u8` in our rust code and `uint8_t *` in our C++ code to pass
around parameters or values over the C abi.
2023-02-19 15:42:07 -06:00
Mahmoud Al-Qudsi
ce559bc20e Port fd_monitor (and its needed components)
I needed to rename some types already ported to rust so they don't clash with
their still-extant cpp counterparts. Helper ffi functions added to avoid needing
to dynamically allocate an FdMonitorItem for every fd (we use dozens per basic
prompt).

I ported some functions from cpp to rust that are used only in the backend but
without removing their existing cpp counterparts so cpp code can continue to use
their version of them (`wperror` and `make_detached_pthread`).

I ran into issues porting line-by-line logic because rust inverts the behavior
of `std::remove_if(..)` by making it (basically) `Vec::retain_if(..)` so I
replaced bools with an explict enum to make everything clearer.

I'll port the cpp tests for this separately, for now they're using ffi.

Porting closures was ugly. It's nothing hard, but it's very ugly as now each
capturing lambda has been changed into an explicit struct that contains its
parameters (that needs to be dynamically allocated), a standalone callback
(member) function to replace the lambda contents, and a separate trampoline
function to call it from rust over the shared C abi (not really relevant to
x86_64 w/ its single calling convention but probably needed on other platforms).

I don't like that `fd_monitor.rs` has its own `c_void`. I couldn't find a way to
move that to `ffi.rs` but still get cxx bridge to consider it a shared POD.
Every time I moved it to a different module, it would consider it to be an
opaque rust type instead. I worry this means we're going to have multiple
`c_void1`, `c_void2`, etc. types as we continue to port code to use function
pointers.

Also, rust treats raw pointers as foreign so you can't do `impl Send for * const
Foo` even if `Foo` is from the same module. That necessitated a wrapper type
(`void_ptr`) that implements `Send` and `Sync` so we can move stuff between
threads.

The code in fd_monitor_t has been split into two objects, one that is used by
the caller and a separate one associated with the background thread (this is
made nice and clean by rust's ownership model). Objects not needed under the
lock (i.e. accessed by the background thread exclusively) were moved to the
separate `BackgroundFdMonitor` type.
2023-02-19 15:42:03 -06:00
Fabian Boehm
4fd1458d85 Port random to rust 2023-02-19 21:01:46 +01:00
ridiculousfish
27f5490a55 Merge branch 'riir'
This merges the Rust bits.
2023-02-19 08:57:47 -08:00
Neeraj Jaiswal
1adfce18ee builtins: port return/exit to rust 2023-02-18 18:53:40 +01:00
Xiretza
ba0bfb9df7 functions: list caller-exit handlers correctly
`functions --handlers-type caller-exit` did not list any functions, while
`functions --handlers-type process-exit` listed both process-exit and
caller-exit handlers:

$ echo (function foo --on-job-exit caller; end; functions --handlers-type caller-exit | grep foo)

$ echo (function foo --on-job-exit caller; end; functions --handlers-type process-exit | grep foo)
caller-exit foo
2023-02-18 18:35:40 +01:00
Mahmoud Al-Qudsi
a1a8bc3d8d Port timer.cpp to rust 2023-02-14 15:54:18 -06:00
esdmr
a607421912
functions --copy: store file and lineno (#9542)
Keeps the location of original function definition, and also stores
where it was copied. `functions` and `type` show both locations,
instead of none. It also retains the line numbers in the stack trace.
2023-02-13 09:59:28 -06:00
ridiculousfish
15c3698258 Mark Dup2List as a struct, not a class
Fixes clang warnings "class 'Dup2List' was previously declared as a
struct."
2023-02-11 12:13:51 -08:00
ridiculousfish
b7de768c73 Allow custom completions to have leading dots
By default, fish does not complete files that have leading dots, unless the
wildcard itself has a leading dot. However this also affected completions;
for example `git add` would not offer `.gitlab-ci.yml` because it has a
leading dot.

Relax this for custom completions. Default file expansion still
suppresses leading dots, but now custom completions can create
leading-dot completions and they will be offered.

Fixes #3707.
2023-02-11 11:27:14 -08:00
Xiretza
5a76c7d3b1 Port emit builtin to rust 2023-02-11 15:04:57 +01:00
Fabian Boehm
b1b2294390 Add workaround for Midnight Commander's issue with prompt extraction
When we draw the prompt, we move the cursor to the actual
position *we* think it is by issuing a carriage return (via
`move(0,0)`), and then going forward until we hit the spot.

This helps when the terminal and fish disagree on the width of the
prompt, because we are now definitely in the correct place, so we can
only overwrite a bit of the prompt (if it renders longer than we
expected) or leave space after the prompt. Both of these are benign in
comparison to staircase effects we would otherwise get.

Unfortunately, midnight commander ("mc") tries to extract the last
line of the prompt, and does so in a way that is overly naive - it
resets everything to 0 when it sees a `\r`, and doesn't account for
cursor movement. In effect it's playing a terminal, but not committing
to the bit.

Since this has been an open request in mc for quite a while, we hack
around it, by checking the $MC_SID environment variable.

If we see it, we skip the clearing. We end up most likely doing
relative movement from where we think we are, and in most cases it
should be *fine*.
2023-02-11 14:18:10 +01:00
Johannes Altmanninger
39f3c894d7 Port tokenizer.cpp to Rust
In hindsight, I should probably have split this into three different commits.
2023-02-09 00:37:22 +01:00
Johannes Altmanninger
7f8d247211 Port parse_constants.h to Rust 2023-02-09 00:37:22 +01:00
Johannes Altmanninger
25816627de Port redirection.cpp to Rust 2023-02-09 00:37:22 +01:00
Johannes Altmanninger
9ca160eac2 Convert parse_error_code_t to a scoped enum
This will make the Rust port's diff smaller.
2023-02-08 21:49:54 +01:00
Johannes Altmanninger
8fd1db06ed Remove unused parse error code 2023-02-08 21:49:54 +01:00
Johannes Altmanninger
4639f7ec40 Follow Rust naming convention for some types
But don't do it for enum variants just yet.
2023-02-08 21:49:54 +01:00
Johannes Altmanninger
47cc98fd57 wutil.h: enable implicit conversion from wcharz_t to wcstring
This allows to write

    wcstring result = some_rust_function_that_returns_wcharz_t();
2023-02-08 21:49:41 +01:00
Xiretza
a16e2ecb1b Port echo builtin to Rust 2023-02-07 22:25:47 +01:00
Xiretza
4b85c2f6db builtin: propagate status from Rust builtins
The return type of `builtin_run_rust()` reflects that of C++ builtins.
2023-02-07 22:25:47 +01:00
Xiretza
cfb5bb2505 builtin: correctly flush streams after running Rust builtin 2023-02-07 22:25:47 +01:00
Fabian Boehm
e90f003d2d Silence ENODEV errors for fstatat
Some broken gdrive filesystem can return these.

Fixes #9550
2023-02-06 21:49:07 +01:00
ridiculousfish
c2df63f586 Remove an errant printf from fish_tests 2023-02-04 11:24:54 -07:00
Johannes Altmanninger
83fd7ea7c4 Port future_feature_flags.cpp to Rust
This is early work but I guess there's no harm in pushing it?
Some thoughts on the conventions:

Types that live only inside Rust follow Rust naming convention
("FeatureMetadata").

Types that live on both sides of the language boundary follow the existing
naming ("feature_flag_t").
The alternative is to define a type alias ("using feature_flag_t =
rust::FeatureFlag") but that doesn't seem to be supported in "[cxx::bridge]"
blocks. We could put it in a header ("future_feature_flags.h").

"feature_metadata_t" is a variant of "FeatureMetadata" that can cross
the language boundary. This has the advantage that we can avoid tainting
"FeatureMetadata" with "CxxString" and such. This is an experimental approach,
probably not what we should do in general.
2023-02-03 18:55:06 +01:00
Johannes Altmanninger
132d99a27b Call rust_init() in fish_indent too
The initial port of feature flags requires a global initialization. Since
fish_indent accesses feature flags, let's make sure to initialize them here.
In future, we can stop initializing things fish_indent doesn't need (like
the topic monitor) but that's no big deal. Global initialization should
always be a benign addition.
2023-02-03 18:55:06 +01:00
Johannes Altmanninger
517d53dc46 Port util.cpp to Rust
The original implementation without the test took me 3 hours (first time
seriously looking into this)

The functions take "wcharz_t" for smooth integration with existing C++ callers.
This is at the expense of Rust callers, which would prefer "&wstr".  Would be
nice to declare a function parameter that accepts both but I don't think
that really works since "wcharz_t" drops the lifetime annotation.
2023-02-03 18:55:06 +01:00
ridiculousfish
76adfed0e7 Implement builtin_wait in Rust
This implements builtin_wait in Rust.
2023-02-02 19:34:48 -07:00
ridiculousfish
f38543ccb7 Rename ast::job_t to ast::job_pipeline_t
This works around an autocxx limitations where different types cannot
have the same name even if they live in different namespace.

ast::job_t conflicts with job_t.
2023-02-02 19:34:48 -07:00
ridiculousfish
55f655f003 Add a gettext wrapper in Rust
This allows the wgettext! macro, which calls into C++.
2023-02-02 19:34:48 -07:00
ridiculousfish
681a165721 Add an FFI test facility
This allow testing Rust functions (from fish_tests.cpp) which need to
cross the FFI. See the example in smoke.rs.
2023-02-02 19:34:48 -07:00
ridiculousfish
d843b67d2d Initial Rust commit 2023-02-02 19:34:47 -07:00
Fabian Boehm
7f2cb47437 fish_key_reader: Don't translate things to "\v" and friends
This translated ctrl-k to "\v", which is a "vertical tab", and ctrl-l
to "\f" and ctrl-g to "\a".

There is no "vertical tab" or "alarm" or "\f" *key*, so these
shouldn't be translated. Just drop these and call them `\ck` and such.

(vertical tab specifically is utterly useless and I would be okay with
dropping it entirely, I have never seen it used anywhere)
2023-01-27 17:07:18 +01:00
Fabian Boehm
bd871c5372 Fix last PCRE2_UCHAR32
See #9502
2023-01-23 20:03:29 +01:00
Eddie Lebow
00692bcdfe Include subsequence matches in history-pager
If a `contains` search yields no results, try again with `contains_subsequence`.
2023-01-22 16:11:46 +01:00
Fabian Boehm
9043008933 abbr: Clarify universal variable message
And give explicit upgrade instructions.
2023-01-21 16:53:59 +01:00
Fabian Boehm
52d2087dd3 re: Use the variable-width pcre2 type
This was what we always did in string. It makes it match the
annoyingly variable width of wchar_t.

Fixes #9502
2023-01-21 10:49:44 +01:00
Johannes Altmanninger
e84f588d11 reader: make Escape during history search restore commandline again
Commit 3b30d92b6 (Commit transient edit when closing pager, 2022-08-31)
inadvertently introduced two regressions to history search:

1. It made Escape keeps the selected history entry,
   instead of restoring the commandline before history search.
2. It made history search commands add undo entries.

Fix both of this issues.
2023-01-17 09:31:04 +01:00
Fabian Boehm
6df09b3753
completions: Offer ../ and ./ again (#9477)
Inadvertently broken in a2d816710f,
this made `cd .` no longer offer `cd ../` (same for general file completions
like `ls .`, which only offers dotfiles)
2023-01-16 10:05:01 +01:00
Fabian Boehm
077118d983 abbr: Fix crash when no name has been given
This crashed for

```fish
abbr --add --regex '{\d+..\d+}' --function foo
```

i.e. a regex and a function but no name - that's 0 additional
arguments.
2023-01-15 10:50:09 +01:00
Fabian Boehm
da0c640750 abbr: Warn when -U is given
This prints a warning to stderr and then still does the thing.

Because of the error trailer, it points to the abbr help page.
2023-01-14 22:27:28 +01:00
Fabian Boehm
5c56fa0e6f Remove str2wcs special case for MB_CUR_MAX
This meant we didn't actually do our weird en/decoding scheme for e.g.
a C locale, which meant that, when you then switch to a proper locale
the previous variables were broken.

I don't know how to test this automatically - none of my attempts seem
to ever *fail* with the old code, here's what you'd do manually:

- Run fish with an actual C locale (LC_ALL=C
fish_allow_singlebyte_locale=1 fish)
- `set -gx foo 💩`
- `set -e LC_ALL`
- `echo $foo` outputs "💩" if it works and "ð⏎" if it's broken.

Fixes #2613
2023-01-14 22:27:16 +01:00
ridiculousfish
7fa13e4451 Remove enum_iter_t
This was unused.
2023-01-14 12:58:20 -08:00
Fabian Boehm
9ef7fe1a15 Make one error translatable
This is now the same as in `read`
2023-01-13 17:57:04 +01:00
Fabian Boehm
dad8c527e0 read: Error on read-only variables
Fixes #9346
2023-01-13 17:56:28 +01:00
Fabian Boehm
1b1cf73b60 abbr: Stop escaping the name for abbr --list
This is so we can pass it to `abbr --erase`.

Fixes #9470
2023-01-13 16:38:34 +01:00
Fabian Boehm
572a568268 abbr: Erase the old universal variable with abbr --erase
This means cleaning out old universal variables is now just:

```fish
abbr --erase (abbr --list)
```

which makes upgrading much easier.

Note that this erases the currently defined variable and/or any
universal. It doesn't stop at the former because that makes it *easy*
to remove the universals (no running `abbr --erase` twice), and it
doesn't care about globals because, well, they would be gone on
restart anyway.

Fixes #9468.
2023-01-13 16:09:53 +01:00
Fabian Boehm
1d455be9fa Cleanup 2023-01-09 22:53:34 +01:00
Fabian Boehm
5792e4a12b
Make history pager use more entries (#9458)
Like I mentioned in #9089, 12 entries is a bit few.

So, instead, we do like we do for completions before disclosing and
pick half the screen (but at least X, in this case 12).

This avoids filling the entire screen, and will avoid an unsightly "X
more entries" (which requires scrolling down to fully disclose)
because it matches what the pager does.

Note: For multiline commands we can be pushed further upwards, and in
case of a multi-column layout we could fit more lines. That would
require asking the pager to fit as many as possible and give us back
the index of the last matching entry and rewinding the history search.

That's gonna be left as an exercise for later if it turns out to be necessary.
2023-01-09 21:39:55 +01:00
Fabian Boehm
f1a150ed43 postfork: Also check if interpreter is a directory
"#!/bin/"
2023-01-08 12:44:02 +01:00
Fabian Boehm
ead0b03108 postfork: Also check shebang/interpreter for EACCESS
This happens e.g. with a shebang of "#!/bin/" - we would complain
about EACCESS, even tho accessing *the file to run* worked.
2023-01-08 12:44:02 +01:00
Aaron Gyes
6ce0b93851 tinyexpr.h: rename __TINYEXPR_H__ include guard
Identifiers that start with _ or include two consecutive underscores
are reserved for the implementation
2023-01-01 03:20:01 -08:00
ridiculousfish
30c708e8a5 builtin_print_help to take its error argument by reference
This fixes a confusing use of pointers.
2022-12-31 10:13:03 -08:00
ridiculousfish
5c216e3d8c Remove unused 'end' variable from SHLVL calculation 2022-12-30 13:38:47 -08:00
ridiculousfish
7ff0e7d0f7 Remove bogus job_chain_is_fully_constructed declaration
This member function no longer exists.
2022-12-30 13:35:33 -08:00
Aaron Gyes
7340761b21 subsequence_in_string: fix broken optimization
haystack.size() > haystack.size() is always false

change it to needle.size() > haystack.size() as seems intended
2022-12-29 01:02:44 -08:00
Fabian Boehm
4c39aeed87 abbr: Let --function use a mandatory argument
This now means `abbr --add` has two modes:

```fish
abbr --add name --function foo --regex regex
```

```fish
abbr --add name --regex regex replacement
```

This is because `--function` was seen to be confusing as a boolean flag.
2022-12-24 10:29:26 +01:00
Fabian Boehm
3005adebd5 Revert "Remove print_hints from builtin_missing_argument and builtin_unknown_option"
Unfortunately print_hints was true *by default* - so for all builtins
that didn't pass it it would now be false instead.

This resulted in the trailer missing, which includes the line number
and context. So if you ran a script that includes `bind -M` the error
message would now just be "bind: -M: option requires an argument",
with no indication as to where.

This reverts commit 8a50d47a46.
2022-12-22 17:24:47 +01:00
ridiculousfish
5f23da9939 Add a TSAN workaround and re-enable the test
This reverts commit 865602e8d1.
2022-12-19 15:54:23 -08:00
ridiculousfish
8a50d47a46 Remove print_hints from builtin_missing_argument and builtin_unknown_option
The print_hints variable was always false, so just remove it.

This caused a cascade of other changes where the parser_t variable
becomes unused, so remove it from the call sites.

No functional change expected here.
2022-12-19 15:05:51 -08:00
Johannes Altmanninger
224f81e250 fish_tests: use default argument for abbreviation tests
Some tests place the cursor at the end of the command line.  This is the
obvious default, so let's make it a default argument.
2022-12-17 18:09:54 +01:00
Johannes Altmanninger
2df8bde5eb fish_tests: test that make_anchored regex helper actually anchors 2022-12-17 18:09:54 +01:00
Johannes Altmanninger
b225ab42aa builtin: fix typo in builtin description 2022-12-17 18:09:54 +01:00
Johannes Altmanninger
f6db6c41e6 reader: clarify bounds check when probing for cached highlighting
When we insert characters that don't yet have highlighting, we use the
highlighting to the left, unless there is nothing to our left.  The logic to
check if we are the leftmost character uses an overly loose comparison. Let's
make it more specific.
No functional change.
2022-12-17 18:09:54 +01:00
Johannes Altmanninger
0b6eab4ec3 event: include handler name in event log output
When there are multiple event handlers for a single event, we would print
the same log statement twice. Let's add the function name to make this
less confusing.
2022-12-17 18:09:54 +01:00
Fabian Boehm
bb98cb01c7 abbr: Also show --position
(if not the default)
2022-12-14 18:06:24 +01:00
Fabian Boehm
30a37d9433 abbr: Make show output actually work
This would print

```
abbr -a -- dotdot --regex ^\\.\\.+\$ --function multicd
```

which expands "dotdot" to "--regex ^\\.\\.+\$...".

Instead, we move the name to right before the replacement, and move
the `--` before that:

```
abbr -a --regex ^\\.\\.+\$ --function -- dotdot multicd
```

It might be possible to improve that, but this at least round-trips.
2022-12-13 19:38:58 +01:00
Johannes Altmanninger
9790907ca8 abbr: stop parsing option after first expansion token
Historical behavior is to stop option parsing at the first non-option argument.
Since we have added more options, it seemed impractical to keep that behavior.

However people are using options in their abbr expansions ("abbr e emacs
-nw").  To support this, we ignore options. However, we only ignore them
if they are not valid "abbr" options.  Let's ignore all options in the
expansion definition, which is a small price to pay to keep most existing
configurations working.

Fixes #9410

This does not fix other cases which used to work, like

    abbr x -unknown

Those are hopefully not used by anyone, so I don't think we need to maintain
support for that.
2022-12-13 01:39:31 +01:00
Johannes Altmanninger
c120305b8d
Merge pull request #9313 from ridiculousfish/mega-abbr
Enhances abbreviations with extra features
- global abbreviations
- trigger on regex match as alternative to literal match
- the ability to expand abbreviations with a user-defined function  
- the ability to set cursor position after expansion
2022-12-12 23:56:11 +01:00
ridiculousfish
6bc545d503 Use actual enum names in wgetopt
No functional change here.
2022-12-11 10:26:39 -08:00
ridiculousfish
d8dbb9b259 Switch abbreviation '-r' flag from --rename to --regex
This will be the more common option and provides consistency with
`string`.
2022-12-10 16:21:39 -08:00
ridiculousfish
e08f4db1f9 Rename abbreviation cursor "sentinel" to "marker"
Also default the marker to '%'. So you may write:

    abbr -a L --position anywhere --set-cursor "% | less"

or set an explicit marker:

   abbr -a L --position anywhere --set-cursor=! "! | less"
2022-12-10 16:15:03 -08:00
ridiculousfish
01039537b0 Remove abbreviation triggers
Per code review, this does not add enough value to introduce now.
Leaving the feature in history should want want to revisit this
in the future.
2022-12-10 16:15:00 -08:00
ridiculousfish
35a4688650 Rename abbreviation triggers
This renames abbreviation triggers from `--trigger-on entry` and
`--trigger-on exec` to `--on-space` and `--on-enter`. These names are less
precise, as abbreviations trigger on any character that terminates a word
or any key binding that triggers exec, but they're also more human friendly
and that's a better tradeoff.
2022-12-10 15:38:50 -08:00
ridiculousfish
5841e9f712 Remove '--quiet' feature of abbreviations
Per code review, this is too risky to introduce now. Leaving the feature
in history should want want to revisit this in the future.
2022-12-10 15:38:50 -08:00
ridiculousfish
c51a1f1f60 Implement trigger-on for abbreviations
trigger-on enables abbreviations to trigger only on "entry" (anything
which closes a token, like space) or only on "exec" (typically enter key).
2022-12-10 15:38:50 -08:00
ridiculousfish
7118cb1ae1 Implement set-cursor for abbreviations
set-cursor enables abbreviations to specify the cursor location after
expansion, by passing in a string which is expected to be found in the
expansion. For example you may create an abbreviation like `L!`:

    abbr L! --position anywhere --set-cursor ! "! | less"

and the cursor will be positioned where the "!" is after expansion, with
the "| less" appearing to its right.
2022-12-10 15:38:50 -08:00
ridiculousfish
1d205d0bbd Reimplement abbreviation expansion to support quiet abbreviations
This reimplements abbreviation to support quiet abbreviations. Quiet
abbreviations expand "in secret" before execution.
2022-12-10 15:38:46 -08:00