Commit Graph

5240 Commits

Author SHA1 Message Date
Johannes Altmanninger
3b15e995e7 str2wcs: encode invalid Unicode characters in the private use area
Rust does not like invalid code points, so let's ease the transition by
treating them like byte sequences that do not map to any code point.
See https://github.com/fish-shell/fish-shell/pull/9688#discussion_r1155089596
2023-04-02 15:17:06 +02:00
ridiculousfish
c67d77fc18 Revert "Speed up executable command completions"
This reverts commit 0b55f08de2.

This was found to have caused regressions in completions in #9699
2023-03-31 20:21:52 -07:00
Clemens Wasser
3ae16a5b95 trace: Port trace to Rust 2023-03-28 20:11:42 -07:00
ridiculousfish
9f7e6a6cd1 Revert "Implement builtin_printf in Rust"
This reverts PR #9666. This had outstanding review comments and should
not have been committed.
2023-03-27 22:03:30 -07:00
ridiculousfish
f096841e4d Remove C++ printf bits
This removes the builtin printf C++ implementation, as it is now in
Rust.
2023-03-26 17:40:24 -07:00
ridiculousfish
3eb6f2ac74 Implement builtin_printf in Rust
This implements builtin_printf in Rust.
2023-03-26 17:40:24 -07:00
ridiculousfish
558baf4957 Implement some locale pieces
This adds locale.rs, which maintains a locale struct sufficient to
support printf.
2023-03-26 17:40:24 -07:00
Johannes Altmanninger
312ae36a34 common.h: remove unused declaration 2023-03-26 17:17:37 +02:00
Fabian Boehm
aa268696bf reader: Skip FreeBSD directory hack for stdin
This can be triggered on linux with:

```js
import { spawn } from 'child_process';
const shell = spawn('/home/alfa/dev/fish-shell/build-c++/fish', []);
```

Under node 19.8.1.

*No clue* how that happens, but since this is a workaround we shall
skip it.
2023-03-25 20:47:38 +01:00
Fabian Boehm
cd7e8c00e1 Silence fstatat errors
These just keep happening, people run haunted computers.

Fixes #9674.
2023-03-21 17:10:23 +01:00
ridiculousfish
732f7284d4 Adopt the new termsize
This eliminates the C++ version.
2023-03-19 16:13:41 -07:00
ridiculousfish
6ec35ce182 Reimplement termsize in Rust
This is not yet adopted by fish.
2023-03-19 16:13:41 -07:00
ridiculousfish
30feef6a72 Migrate env_stack_t::get_or_null to environment_t
Allows it to be used when we only have an environment_t.
2023-03-19 16:13:41 -07:00
ridiculousfish
57f4571a01 Rewrite wait handles and wait handle store in Rust 2023-03-18 18:53:04 -07:00
Fabian Boehm
a16abf22d9 builtins: Don't crash for negative return values
Another from the "why are we asserting instead of doing something
sensible" department.

The alternative is to make exit() and return() compute their own exit
code, but tbh I don't want any *other* builtin to hit this either?

Fixes #9659
2023-03-14 10:53:35 +01:00
Victor Song
ca494778e4 builtins: Port realpath to Rust 2023-03-12 19:50:35 -07:00
Victor Song
77fe9933e2 builtins: Rewrite pwd in Rust
Closes #9625.
2023-03-12 15:18:15 -05:00
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
ridiculousfish
8135c52c13 Abbreviations to support functions
This adds support for the `--function` option of abbreviations, so that the
expansion of an abbreviation may be generated dynamically via a fish
function.
2022-12-10 15:29:04 -08:00
ridiculousfish
d15855d3e3 Abbreviations to support matching via regex
This adds the --regex option to abbreviations, allowing them to match a
pattern of tokens.
2022-12-10 15:29:04 -08:00
ridiculousfish
470153c0df Refactor abbreviation set into its own type
Previously the abbreviation map was just an unordered map; switch it to a
real class so we can hang methods off of it.
2022-12-10 15:29:04 -08:00
ridiculousfish
1402bae7f4 Re-implement abbreviations as a built-in
Prior to this change, abbreviations were stored as fish variables, often
universal. However we intend to add additional features to abbreviations
which would be very awkward to shoe-horn into variables.

Re-implement abbreviations using a builtin, managing them internally.

Existing abbreviations stored in universal variables are still imported,
for compatibility. However new abbreviations will need to be added to a
function. A follow-up commit will add it.

Now that abbr is a built-in, remove the abbr function; but leave the
abbr.fish file so that stale files from past installs do not override
the abbr builtin.
2022-12-10 15:29:03 -08:00
ridiculousfish
d2daa921e9 Introduce re::make_anchored
This allows adjusting a pattern string so that it matches an entire
string, by wrapping the regex in a group like ^(?:...)$

This is a workaround for the fact that PCRE2_ENDANCHORED is unavailable
on PCRE2 prior to 2017, so we have to adjust the pattern instead.

Also introduce an overload of match() which creates its own
match_data_t.
2022-12-10 12:24:43 -08:00
ridiculousfish
fe7d095647 Add maybe_t::value_or
This enables getting the value or returning the passed-in value.
This is helpful for "default if none."
2022-12-10 12:24:43 -08:00
Johannes Altmanninger
892a820672 Make sure that cd to a relative CDPATH results in absolute $PWD
We have had multiple crashes for relative CDPATH entries.  Commit 5e274066e
(Always return absolute path in path_get_cdpath, 2019-10-17) tried to fix
all of them but it failed to do justice to its title.  Let's fix this to
actually return absolute paths, always.  Take care to to normalize the path
because it is used for autosuggestions. The normalization is mostly relevant
for CDPATH=. (the default) but it doesn't hurt others.

Closes #9407
2022-12-10 11:06:54 +01:00
ridiculousfish
b0ec7e07b8 Fix a wgetopt crash and add a test
This has apparently been a problem since forever.
2022-12-09 13:54:00 -08:00
ridiculousfish
35bad1f94c Untangle some pointers in wgetopt
wgetopt had a "nameend" parameter which was a confusing pointer. Make it
into a slightly less confusing size_t.
2022-12-04 14:48:20 -08:00
ridiculousfish
962d1083d3 Remove wgeopter_t::wopterr
wopterr was a feature to allow wgetopt to emit error messages; but we do
not use this and never will. Remove its support. No functional change
expected here.
2022-12-04 12:03:13 -08:00
Johannes Altmanninger
6072ea1900 Fix false positive cd higlighting when token ends in slash
We wrongly highlight this as prefix when actually the trailing slash should
invalidate it. Turns out path normalization drops the slash, so let's
sidestep that.

Fixes #9394
2022-12-03 22:36:56 +01:00
ridiculousfish
39b7f112c7 Remove the "flag" field from woption
The "flag" field enables an option to discover which flag it was invoked
with. However in practice none of our options use multiple flags so this
parameter was always nullptr. Remove it and fix up all the builtins to
stop passing this.

No functional change here.
2022-11-29 16:08:37 -08:00
Mahmoud Al-Qudsi
063450b8f4 Update likely/unlikely macros to avoid double negation
I believe this should be identical to the previous code and handle the same
cases (I'm guessing going by the comment that this came from a C codebase
without `bool` types).

The problem with the previous code is that it tripped up the `clangd` analyzer
into thinking `assert()` expressions can/should be simplified via DeMorgan's to
improve readability (because it was seeing the fully expanded macro).
2022-11-29 13:26:32 -06:00
ridiculousfish
7ee161af8d Fix the flaky tty_ownership test on Mac
The tty_ownership test was sometimes failing. In this test,
`fish_test_helper` creates a child and transfers the tty to it,
"abandoning" the tty. In some cases, the child was running before the
parent; the child claims the tty. When the parent tries to transfer it to
the child, it get SIGTTIN and stops. Fix this by ignoring SIGTTIN and
SIGTTOU.

This only affects macOS and BSDs.
2022-11-28 15:01:12 -08:00
Mahmoud Al-Qudsi
0c111b1c6b Add comments to brace expansion 2022-11-16 14:10:30 -06:00
Fabian Boehm
0f8b9699a1 Fix error for {$}
Fixes #9337
2022-11-15 19:02:30 +01:00
ridiculousfish
f1e73a1839 Increase debounce timeout in debounce test
On slow machines this was spuriously failing.
2022-11-12 14:08:22 -08:00
ridiculousfish
4ab728b3a2 Reduce FISH_MAX_EVAL_DEPTH under tsan
The stack overflow tests are too slow without this.
This is because the tests are essentially quadratic: with 500 jobs, and
each job attempts to reap all jobs.
2022-11-12 14:08:22 -08:00
Johannes Altmanninger
c4a60feff1 Stop attempting to complete inside comments
Inside a comment we offer plain file completions (or command completions if
the comment is in command position). However these completions are broken
because they don't consider any of the surrounding characters. For example
with a command line

    echo # comment
              ^ cursor

we suggest file completions and insert them as

    echo # comsomefile ment

Providing completions inside comments does not seem useful and it can be
misleading. Let's remove the completions; this should communicate better that
we are in a free-form comment that's not subject to fish syntax.

Closes #9320
2022-11-12 22:37:27 +01:00
Aaron Gyes
e38c9bb062 builtin set --show: put read-only part on same line. 2022-11-12 06:21:36 -08:00
Mahmoud Al-Qudsi
093ee6def5 Drop global variable shadowing warning on universal var unset
When unsetting, the scope indicates the scope that was *removed* not
set, so the warning is incorrectly triggered. If anything, the confusion
is now removed or we emit a warning that the variable is still present
in another scope (but don't do that!).

Closes #9338.
2022-11-10 21:25:01 -06:00
Fabian Boehm
311e1aa968 Revert "builtin string: push_back \n chars rather than append strings"
This reverts commit 3739c53bcf.

It misses the point of e69be38235 and reintroduces a lot of write calls.

See #9229
2022-11-07 22:37:53 +01:00
Aaron Gyes
3739c53bcf builtin string: push_back \n chars rather than append strings
prefer
    streams.out.append(foo)
    streams.out.push_back(L'\n')

vs e.g.
    foo.append(L"\n");
    streams.out.append(foo)
2022-11-07 13:34:52 -08:00
Fabian Boehm
33edac2c0c path: Show main path docs for path subcommand --help
Fixes #9334
2022-11-07 20:47:07 +01:00
Aaron Gyes
1a0d6ebe59 builtins/printf: use wcsto[i,u]max, check EINVAL, add test
This fixes #9321

IEEE Std 1003.1-2017 Issue 6 added optional error condition
[EINVAL] for if no conversion could be performed.

Switch back to wcstoimax/wcstoumax: do not work around the old FreeBSD
8 issue.

Add a test for printf '%d %d' 1 2 3
2022-10-31 19:58:18 -07:00
Mahmoud Al-Qudsi
4cb19e244b Sort and deduplicate output of complete -C
This addresses a long-standing TODO where `complete -C` output isn't
deduplicated.

With this patch, the same deduplication and sort procedure that is run on actual
pager completions is also executed for `complete -C` completions (with a `-C`
payload specified).

This makes it possible to use `complete -C` to test what completions will
actually be generated by the completions pager instead of it displaying
something completely divorced from reality, improving the productivity of fish
completions developers.

Note that completions that wouldn't be shown in the pager are also omitted from
the results, e.g. `test/buildroot/` and `test/fish_expand_test/` are omitted
from the check matches in `checks/complete_directories.fish` because even if
they were generated, the pager wouldn't have shown them. This again makes
reasoning about and debugging completions much easier and more sane.
2022-10-31 16:52:36 -05:00
Mahmoud Al-Qudsi
8750f9ccb7 fixup! Reintroduce trivially copyable maybe_t impl
`git revert --no-commit` leaving the repo in a "middle of revert" state
tripped me up and my changes weren't included in the commit. Mea culpa.
2022-10-29 11:39:33 -05:00
Mahmoud Al-Qudsi
4f46abec9d Reintroduce trivially copyable maybe_t impl
This reverts commit 1c92d4c5db and
reintroduces support for trivially copyable `maybe_t` impls but with a
GCC version check to disable the optimization for GNU GCC compiler
versions 9 and below.

GCC 8.3.0 armhf builds seem to have a problem with the trivially
copyable `maybe_t` impl that introduces odd heisenbugs that cause the
tests to fail. GDB reveals that `maybe_t` function parameters received
in the callee differ from what was passed-in by the caller.

This behavior appears to be (but has not been confirmed as) a
platform-specific compiler bug. Under the same system (32-bit Debian 10
armhf), compiling with clang 7.0.1 does not result in any bugs and
causes all the tests to pass while compiling with GCC 10.2 under 32-bit
Debian 11 armhf also doesn't run into any problems, so just expand the
existing GCC version check that gates support for trivially copyable
`maybe_t` impls to encompass both the troublesome GCC 8 version and the
untested GCC 9 version.
2022-10-29 11:26:34 -05:00
Mahmoud Al-Qudsi
1c92d4c5db Revert "maybe_t: make maybe_t<T> trivially copyable if T is"
This reverts commit 9d303a74e3.
This reverts commit 0305c842e6.

9d303a7 broke 32-bit armhf builds for unknown reasons, specifically in
settings where a trivial copy of `maybe_t<int>` was performed. A caller
would pass a literal int in the place of a `maybe_t<int>` parameter and
the callee would see a populated `maybe_t` but with a value of `0`
rather than the actual value that was passed in. It was too painful to
debug to a resolution under qemu.
2022-10-29 10:12:41 -05:00
Fabian Boehm
8d7662335e function: Don't list empty function names and directories 2022-10-29 10:24:42 +02:00
Aaron Gyes
daf5e11179 Spelling fixes
Found with scspell
2022-10-28 20:10:09 -07:00
Aaron Gyes
b7593a377a fish_key_reader: stop looping on SIGHUP
Using the machinery in reader.cpp rather than going back to
intalling our own handlerss

(see 89644911a1)

Fixes #9309
2022-10-27 17:17:05 -07:00
Johannes Altmanninger
0305c842e6 Fix build on CentOS 7
This fixes a regression in 9d303a74e (maybe_t: make maybe_t<T> trivially
copyable if T is, 2022-10-26). I subscribed to the launchpad repo now -.-
2022-10-27 09:28:52 +02:00
Aaron Gyes
efa2cf0cb6 Replace fallthrough comments with __fallthrough__
Defined in config.h
2022-10-26 21:02:48 -07:00
Aaron Gyes
df546e01f6 IWYU fixup 2022-10-26 20:04:04 -07:00
Aaron Gyes
92698dff48 Unallowed command subst error: add missing newline and simplify
Fixes ommitted newline char shown after complete -n'(foo)'
Also axes the 'contains syntax errors' line before the error.
Update tests

before
> complete -n'(foo)'
complete: Condition '(foo)' contained a syntax error
complete: Command substitutions not allowed⏎

after
> complete -n'(foo)'
complete: -n '(foo)': command substitutions not allowed here
2022-10-26 19:58:40 -07:00
Aaron Gyes
b2a4a50daf Run include-what-you-use 2022-10-26 19:58:40 -07:00
ridiculousfish
a4aaa4f59b Fix the Xenial build
The Xenial build was failing due to a missing default constructor
in maybe_t. Add it.
2022-10-26 14:19:01 -07:00
Mahmoud Al-Qudsi
f7da014602 Optimize storage of completion entries
This is a salvage of the "no functional changes" part of #9221, and cherry-picks
storing completion entries in a vector instead of a linked list. The legacy
"reverse intuitive" group ordering is kept by iterating in reverse order.

Tests pass but don't actually cover group order, which needs another test.
2022-10-26 12:48:31 -05:00
Mahmoud Al-Qudsi
7133285c88 Move parser status vars to their own struct
Instead of using an enum + array, just use a struct and drop the getter and
setter methods from `parser_t`.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
6ac18defd2 Add status current-commandline
Makes it possible to retrieve the currently executing command line as
opposed to the currently executing command (`status current-command`).

Closes #8905.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
e01eb2e615 Add proper way of storing value for status current-command
There should be no functional changes in this commit.

The global variable `$_` set in the parser variables by `reader.cpp` and
read by the `status` builtin was deprecated in fish 2.0 but kept around
internally because there's no good way to store/share/forward parser
variables.

A new enum is added that identifies the status variable and they are
stored in a private array in the parser. There is no need for
synchronization because they are only set during job init and never
thereafter. This is currently asserted via ASSERT_IS_MAIN_THREAD() but
that assert can be dropped in the interest of making the parser possible
to clone and use from worker threads.

The old `$_` global variable is still kept for backwards compatibility,
though it will be dropped in a future release.
2022-10-26 12:15:02 -05:00
Johannes Altmanninger
f637fb31b5 highlight: underline prefixes of valid paths only if at cursor
As the user is typing an argument, fish continually checks if the input is
the prefix of a valid file path. If yes, the input is underlined.

The same prefix-logic is used for all tokens on the command line, even for
"finished" tokens. This means we highlight any token that happens to be
a prefix of a valid file path. We actually want this to only apply to the
token that the user is currently typing.

Let's use the prefix-logic only for tokens adjacent to the cursor.  This should
better match user expectations (and reduce IO traffic). I don't think this is
the perfect criteria but I don't know how else we can determine if a token is
"unfinished".
2022-10-26 16:12:43 +02:00
Johannes Altmanninger
6667c9f50c highlighter: pass the cursor position to the highlighter
This allows the next commit to correct highlighting based on the cursor
position.
2022-10-26 16:11:00 +02:00
Johannes Altmanninger
861ac00a61 highlighter: underline valid "cd" arguments also if they come from CDPATH
When visiting the "cd" node, we mark invalid paths as error, but don't
underline valid paths.  This works fine most of the time because we later
underline paths (for any command, not just "cd").
However the latter check fails to honor CDPATH.  Let's correct that, which
also allows to simplify the logic.
2022-10-26 16:11:00 +02:00
Johannes Altmanninger
dfb0c00d72 highlighter: stop performing IO if canceled
The next commit wants to move the "Underline every valid path" logic into the
visit() methods. The logic currently polls the cancel checker before checking
each path. If that's valid, it should probably have the same behavior inside
visit(). Since we currently can't cancel an AST-visitation, the next best
thing seems to suspend all IO operations, the rest should be very fast anyway.

I'm not sure if the motivation is strong enough; a conceivable alternative
would be to stop using the cancel checker altogether for highlighting.
2022-10-26 16:11:00 +02:00
Johannes Altmanninger
9c6f46a808 highlighter: remove redundant check if we can do io
It's done a few lines above.
2022-10-26 16:09:02 +02:00
Johannes Altmanninger
acb47f70d2 history_file.cpp: remove an unused variable
Now that maybe_t<size_t> no longer has a user-defined destructor, the compiler
can better detect an unused variable of this type.
2022-10-26 16:09:02 +02:00
Johannes Altmanninger
9d303a74e3 maybe_t: make maybe_t<T> trivially copyable if T is
When passing a value of type maybe_t<size_t>, clangd complains:

    Parameter 'cursor' is passed by value and only copied once; consider
    moving it to avoid unnecessary copies (fix available)

We get this warning because maybe_t<size_t> is not trivially copyable
because it has a user-defined destructor and copy-constructor.  Let's remove
them if the contained type is trivially copyable, to avoid such warnings.
No functional change.
2022-10-26 16:09:02 +02:00
Johannes Altmanninger
1ce2961561 maybe_t: remove user-defined destructor
The destructor is equivalent to the compiler-generated one.  The user-defined
destructor prevents maybe_t<size_t> from bearing the predicate "trivially
copyable". Let's remove it. No functional change.
2022-10-26 14:54:33 +02:00
Johannes Altmanninger
45da77c5c5 Format some C++ files with clang-format 2022-10-26 14:53:06 +02:00
Mahmoud Al-Qudsi
21599a49ea Make CALL_STACK_LIMIT_EXCEEDED_ERR_MSG more generic
We're now using this when a stack overflow is detected during eval/substitution
loops, too.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
175caab583 Prevent stack overflow from eval/substitution recursion
It seems to have originally been thought that the only possible way a stack
overflow could happen is via function calls, but there are other possibilities.

Issue #9302 reports how `eval` can be abused to recursively execute a string
substitution ad infinitum, triggering a stack overflow in fish.

This patch extends the stack overflow check to also check the current
`eval_level` against a new constant `FISH_MAX_EVAL_DEPTH`, currently set to a
conservative but hopefully still fair limit of 500. For future reference, with
the default stack size for the main/foreground thread of 8 MiB, we actually have
room for a stack depth around 2800, but that's only with extremely minimal state
stored in each stack frame.

I'm not entirely sure why we don't check `eval_depth` regardless of block type;
it can't be for performance reasons since it's just a simple integer comparison
- and a ridiculously easily one for the branch predictor handle, at that - but
maybe it's to try and support non-recursive nested execution blocks of greater
than `FISH_MAX_STACK_DEPTH`? But even without recursion, the stack can still
overflow so may be we should just bump the limit up some (to 500 like the new
`FISH_MAX_EVAL_DEPTH`?) and check it all the time?

Closes #9302.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
e7bf98adc1 Make block_t moveable
The presence of the explicit constructor (even though it did nothing) prevented
the compiler from generating a move constructor for `block_t`.
2022-10-24 22:06:30 -05:00
Mahmoud Al-Qudsi
84b53b4cae Significantly reduce size of block_t
A `block_t` instance is allocated for each live block type in memory when
executing a script or snippet of fish code. While many of the items in a
`block_t` class are specific to a particular type of block, the overhead of
`maybe_t<event_t>` that's unused except in the relatively extremely rare case of
an event block is more significant than the rest, given that 88 out of the 216
bytes of a `block_t` are set aside for this field that is rarely used.

This patch reorders the `block_t` members by order of decreasing alignment,
bringing down the size to 208 bytes, then changes `maybe_t<event_t>` to
`shared_ptr<event_t>` instead of allocating room for the event on the stack.
This brings down the runtime memory size of a `block_t` to 136 bytes for a 37%
reduction in size.

I would like to investigate using inheritance and virtual methods to have a
`block_t` only include the values that actually make sense for the block rather
than always allocating some sort of storage for them and then only sometimes
using it. In addition to further reducing the memory, I think this could also be
a safer and saner approach overall, as it would make it very clear when and
where we can expect each block_type_type_t-dependent member to be present and
hold a value.
2022-10-24 21:04:17 -05:00
Mahmoud Al-Qudsi
44c9c51841 Disable leak detection in test_autosuggest_suggest_special() under CI
This is a false positive as a result of disabling TLS support in LSAN due to an
incompatibility with newer versions of glibc.

Also remove the older workaround (because it didn't work).
2022-10-24 19:02:49 -05:00
Mahmoud Al-Qudsi
fed64999bc Allow erasing in multiple scopes in one go 2022-10-20 11:21:05 -05:00
Mahmoud Al-Qudsi
99bc112de0 Fix unqualified calls to std::move
`using` is for types, not functions :(
2022-10-19 12:31:55 -05:00
Mahmoud Al-Qudsi
920ded26b9 history: Handle Ctrl-C/SIGINT or other errors on output append
When there are multiple screens worth of output and `history` is writing to the
pager, pressing Ctrl-C at the end of a screen doesn't exit the pager (`q` is
needed for that) but previously caused fish to emit an error ("write:
Interrupted system call) until we starting silently handling SIGINT in
`fd_output_stream_t::append()`.

This patch makes `history` detect when the `append()` call returns with an error
and causes it to end early rather than repeatedly trying (and failing) to write
to the output stream.
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
83636fa599 Silently handle fd_output_stream_t append errors in case of SIGINT
If EINTR caused by SIGINT is encountered while writing to the
`fd_output_stream_t` output fd, mark the output stream as errored and return
false to the caller but do not visibly complain.

Addressing the outstanding TODO notwithstanding, this is needed to avoid
littering the tty with spurious errors when the user hits Ctrl-C to abort a
long-running builtin's output (w/ the primary example being `history`).
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
8e97fcb22c Make output_stream_t::append() fallible
Allow errors encountered by certain implementations of `output_stream_t` when
writing to the output sink to be bubbled back to the caller.
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
b94b896503 Shrink size of env_mode_flags_t 2022-10-15 15:15:04 -05:00
Fabian Boehm
52dcfe11af Make \x the same as \X
Up to now, in normal locales \x was essentially the same as \X, except
that it errored if given a value > 0x7f.

That's kind of annoying and useless.

A subtle change is that `\xHH` now represents the character (if any)
encoded by the byte value "HH", so even for values <= 0x7f if that's
not the same as the ASCII value we would diverge.

I do not believe anyone has ever run fish on a system where that
distinction matters. It isn't a thing for UTF-8, it isn't a thing for
ASCII, it isn't a thing for UTF-16, it isn't a thing for any extended
ASCII scheme - ISO8859-X, it isn't a thing for SHIFT-JIS.

I am reasonably certain we are making that same assumption in other
places.

Fixes #1352
2022-10-09 15:24:01 +02:00
Mahmoud Al-Qudsi
85d4834b35 Make maybe_t safer against accidental misuse
Closes #9240.

Squash of the following commits (in reverse-chronological order):

commit 03b5cab3dc40eca9d50a9df07a8a32524338a807
Author: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Date:   Sun Sep 25 15:09:04 2022 -0500

    Handle differently declared posix_spawnxxx_t on macOS

    On macOS, posix_spawnattr_t and posix_spawn_file_actions_t are declared as void
    pointers, so we can't use maybe_t's bool operator to test if it has a value.

commit aed83b8bb308120c0f287814d108b5914593630a
Author: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Date:   Sun Sep 25 14:48:46 2022 -0500

    Update maybe_t tests to reflect dynamic bool conversion

    maybe_t<T> is now bool-convertible only if T _isn't_ already bool-convertible.

commit 2b5a12ca97b46f96b1c6b56a41aafcbdb0dfddd6
Author: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Date:   Sun Sep 25 14:34:03 2022 -0500

    Make maybe_t a little harder to misuse

    We've had a few bugs over the years stemming from accidental misuse of maybe_t
    with bool-convertible types. This patch disables maybe_t's bool operator if the
    type T is already bool convertible, forcing the (barely worth mentioning) need
    to use maybe_t::has_value() instead.

    This patch both removes maybe_t's bool conversion for bool-convertible types and
    updates the existing codebase to use the explicit `has_value()` method in place
    of existing implicit bool conversions.
2022-10-08 11:56:38 -05:00
Johannes Altmanninger
485873b19b Share logic between move constructor/assignment of dir_iter_t
The parent commit made the destructor of the DIR* member close it if necessary
(i.e. only if it's not null).  This means that we can use the same logic in
the move constructor (where the source DIR* is null) and for move assignment
(where it might not be).

No functional change.
2022-10-08 17:32:12 +02:00
Johannes Altmanninger
da5d93b4de dir_iter_t to use unique_ptr for closing directory
dir_iter_t closes its DIR* member in two places: the move assignment and
the destructor. Simplify this by closing it in the destructor of the DIR*
member which is called in both places. Use std::unique_ptr, which is shorter
than a dedicated wrapper class. Conveniently, it calls the deleter only if
the pointer is not-null.  Unfortunately, std::unique_ptr requires explicit
conversion to DIR* when interacting with C APIs but it's probably still
better than a wrapper class.

This means that the noncopyable_t annotation is now implied due to the
unique_ptr member.
Additionally, we could probably remove the user-declared move constructor
and move assignment (the compiler-generated ones should be good enough). To
be safe, keep them around since they also erase the fd (though I hope we
don't rely on that behavior anywhere).

We should perhaps remove the user-declared destructor entirely but
dir_iter_t::entry_t also has one, I'm not sure why. Maybe there's a good
reason, like code size.

No functional change.
2022-10-08 17:31:47 +02:00
Johannes Altmanninger
f82537bcdc color_string_internal to use a sentinel value that's definitely invalid
I think -1 is slightly more elegant than 0 because 0 could be a valid offset.

No functional change.
2022-10-05 22:27:00 -05:00
Johannes Altmanninger
5868b3c380 read_unquoted_escape: remove dead loop condition
This was recently converted to a while-loop. However, we only
loop in a specific case when (by hitting "continue") so a
loop condition is not necessary.

No functional change.
2022-10-05 22:27:00 -05:00
Fabian Boehm
e7a7a58030 Remove use of maybe_t that makes gcc grumpy
We have a state machine here already, we can just use the state where
the variable is valid.
2022-10-05 22:34:19 +02:00
Fabian Boehm
460f56f95a Revert "Silence gcc warning"
This reverts commit 8ab437a989.

It introduced a warning for clang - because that read the GCC pragma and didn't understand it.
2022-10-05 22:29:04 +02:00
Fabian Boehm
8ab437a989 Silence gcc warning
This complained that the variable might be uninitialized *right* after
the check that it wasn't, because it doesn't understand maybe_t.
2022-10-05 19:07:41 +02:00
Fabian Boehm
396e276286 Decode multibyte escapes immediately
We forgot to decode (i.e. turn into nice wchar_t codepoints)
"byte_literal" escape sequences. This meant that e.g.

```fish
string match ö \Xc3\Xb6

math 5 \X2b 5
```

didn't work, but `math 5 \x2b 5` did, and would print the wonderful
error:

```
math: Error: Missing operator
'5 + 5'
   ^
```

So, instead, we decode eagerly.
2022-10-05 18:55:01 +02:00
Sergei Shilovsky
e274ef6c0d
commandline --selection-start and --selection-end implementation
Fixes #9197
2022-10-05 18:51:00 +02:00
Fabian Boehm
dcf52dbba5 fix path --null-out
Regression from 7bc4c9674b.

Appending `"\0"` to an std::string does nothing.

I blame C++.
2022-10-05 17:25:00 +02:00
Fabian Boehm
cb28b39b24 string shorten: Make max of 0 mean no shortening
This makes it easier to just slot in `string shorten` wherever,
without having to do a weird "if test $max -gt 0" check.
2022-10-04 18:44:21 +02:00
Fabian Boehm
cdf1a94e29 ifdef DT_WHT 2022-10-04 17:00:04 +02:00
ridiculousfish
757c117591 Handle symlink loops in descend_unique_hierarchy
descend_unique_hierarchy is used for the cd autosuggestion: if a directory
contains exactly one subdirectory and no other entries, then propose that
as part of the cd autosuggestion.

This had a bug: if the subdirectory is a symlink to the parent, we would
chase that, going around the loop suggesting a longer path until we hit
PATH_MAX.

Fix this by using the new API which provides the inode "for free," and
track whether we've seen this inode before. This is technically too
conservative since the inode may be for a directory on a different device,
but devices are not available for free so this would incur a cost. In
practice encountering the same inode twice with different devices in a
unique hierarchy is unlikely, and should it happen the consequences are
merely cosmetic: we fail to suggest a longer path.
2022-10-02 18:56:46 -07:00
ridiculousfish
0b47ba0642 Remove wreaddir and wreaddir_resolving
dir_iter_t has replaced these functions; we can remove them.
2022-10-02 18:48:16 -07:00
ridiculousfish
a2d816710f Adopt dir_iter_t in wildcard.cpp
Migrate wildcard's directory iteration to the new dir_iter_t.
Remove a now-unused function.
2022-10-02 18:48:16 -07:00
ridiculousfish
749d71288d Adopt dir_iter_t in descend_unique_hierarchy
Migrate this function from wreaddir_resolving to dir_iter_t
2022-10-02 18:48:16 -07:00
ridiculousfish
2a9366f938 Migrate highlight.cpp usage of wreaddir to dir_iter_t
Switch to the new API instead of using opendir directly.
2022-10-02 18:48:16 -07:00
ridiculousfish
36fbfef74c Switch uses of dir_t to dir_iter_t
dir_t was a thin wrapper around readdir; switch to the new dir_iter_t API
and remove dir_t.
2022-10-02 18:48:16 -07:00
ridiculousfish
b684f7b076 Introduce dir_iter_t
This introduces dir_iter_t, a new class for iterating the contents of a
directory. dir_iter_t encapsulates the logic that tries to avoid using
stat() to determine the type of a file, when possible.
2022-10-02 18:48:16 -07:00
Fabian Boehm
942308bf72 highlight: Unicode above 0x10FFFF is an error
This should really just be using read_unquoted_escape, where this was
changed in #1107
2022-09-29 17:16:42 +02:00
Fabian Boehm
5ada59996f Reduce write() calls for explicitly separated buffers
This can improve performance for `string split ""` for up to 1.8x.
2022-09-27 16:33:47 +02:00
ridiculousfish
9a3a67ba31 Migrate PUA constants out of wutil.h
These defines are only used inside the .cpp file. Place them in there
and switch to an enum.
2022-09-26 10:21:45 -07:00
Fabian Boehm
e726627993 Upgrade widechar_width to Unicode 15 2022-09-26 17:17:17 +02:00
Mahmoud Al-Qudsi
5d64b56127 Remove needless usage of maybe_t
builtin_function() never returns `none()`; this must have been leftover from a
previous version of the code.
2022-09-25 14:40:49 -05:00
Mahmoud Al-Qudsi
ff00d3ca08 fixup! Fix stomping of last_option_requires_param
Fix accidental misuse of maybe_t boolean operator instead of maybe_t payload.
2022-09-25 13:33:33 -05:00
Mahmoud Al-Qudsi
1811a2d725 Prevent undefined behavior by intercepting return -1
While we hardcode the return values for the rest of our builtins, the `return`
builtin bubbles up whatever the user returned in their fish script, allowing
invalid return values such as negative numbers to make it into our C++ side of
things.

In creating a `proc_status_t` from the return code of a builtin, we invoke
W_EXITCODE() which is a macro that shifts left the return code by some amount,
and left-shifting a negative integer is undefined behavior.

Aside from causing us to land in UB territory, it also can cause some negative
return values to map to a "successful" exit code of 0, which was probably not
the fish script author's intention.

This patch also adds error logging to help catch any inadvertent additions of
cases where a builtin returns a negative value (should one forget that unix
return codes are always positive) and an assertion protecting against UB.
2022-09-25 12:33:40 -05:00
Fabian Boehm
ccca5b553f Disable VQUIT for shell modes
This allows binding ctrl+\ by default.

Fixes #9234
2022-09-25 13:27:01 +02:00
ridiculousfish
bc4e7c3fea 'C_' function to use g_empty_string
Use the global empty string instead of having its own.
2022-09-23 14:32:20 -07:00
Mahmoud Al-Qudsi
1f41ce9446 Change localized_desc() to return a reference
Bubble up the reference returned by `C_()`.

This is a prerequisite for a bigger change I'm working on.
2022-09-23 14:01:02 -05:00
Mahmoud Al-Qudsi
1f91056539 Always return a const wcstring reference from _C()
This was always the case if HAVE_TEXT wasn't defined, but if it was then we were
coercing the result of `_C()` to a `const wchar_t *` pointer, because we were
returning the address of a constant zero-length wchar_t pointer. This reserves a
local static `wcstring` variable that we can return as the "no text" sentinel
and bubbles back the `wcstring` reference rather than decomposing it into a
pointer.

This is a prerequisite for a bigger change I'm working on.
2022-09-23 14:00:42 -05:00
Mahmoud Al-Qudsi
67c0a1db85 Reduce size of complete_entry_opt_t
It's gone from 136 bytes to a 128 bytes by rearranging the items in order of
decreasing alignment requirements. While this reduces the memory consumption
slightly (by around 6%) for each completion we have in-memory, that translates
to only around ~8KiB of savings for a command with 1000 possible completions,
which is nice but ultimately not that big of a deal.

The bigger benefit is that a single `complete_entry_t` might now fit in a cache
line, hopefully making the process of testing completions for matches more
cache friendly (and maybe even faster).
2022-09-23 12:09:26 -05:00
Mahmoud Al-Qudsi
0e9371cf24 complete_entry_opt_t: Rename list member condition to conditions
We used both a singular "condition" and a plural "condition" with the latter
referring to a list of the former. Clean that up.
2022-09-23 12:03:02 -05:00
Fabian Boehm
e69be38235 string: Reduce write() calls
The impact here depends on the command and how much output it
produces.

It's possible to get up to 1.5x - `string upper` being a good example,
or a no-op `string match '*'`.

But the more the command actually needs to do, the less of an effect
this has.
2022-09-22 22:41:35 +02:00
Fabian Boehm
7bc4c9674b builtins: Reduce streams.out.append/push_back calls
This basically immediately issues a "write()" if it's to a pipe or the
terminal.

That means we can reduce syscalls and improve performance, even by
doing something like

```c++
streams.out.append(somewcstring + L"\n");
```

instead of

```c++
streams.out.append(somewcstring);
streams.out.push_back(L'\n');
```

Some benchmarks of the

```fish
for i in (string repeat -n 2000 \n)
    $thing
end
```

variety:

1. `set` (printing variables) sped up 1.75x
2. `builtin -n` 1.60x
3. `jobs` 1.25x (with 3 jobs)
4. `functions` 1.20x
5. `math 1 + 1` 1.1x
6. `pwd` 1.1x

Piping yields similar results, there is no real difference when
outputting to a command substitution.
2022-09-22 22:41:35 +02:00
Fabian Boehm
c5b5dd7563 printf: Buffer output
This writes the output once per argument instead of once per format or
escaped char.

An egregious case:

```fish
printf (string repeat -n 200 \\x7f)%s\n (string repeat -n 2000 aaa\n)
```

Has been sped up by ~20x by reducing write() calls from 40000 to 200.

Even a simple

```fish
printf %s\n (string repeat -n 2000 aaa\n)
```

should now be ~1.2x faster by issuing 2000 instead of 4000 write
calls (the `\n` was written separately!).
2022-09-22 22:41:35 +02:00
Fabian Boehm
64927677c8 complete: Write each completion at once for --do-complete
This at least halves the number of "write()" calls we do if it goes to
a pipe or the terminal, or reduces them by 75% if there is a
description.

This makes

```fish
complete -c foo -xa "(seq 50000)"
complete -C"foo "
```

faster by 1.33x.
2022-09-22 22:41:35 +02:00
Mahmoud Al-Qudsi
42e177dc1b Fix build on macOS 10.10 Yosemite 2022-09-22 14:00:58 -05:00
Fabian Boehm
6a93d58797 wildcard: Use wreaddir_resolving if directories are needed
This uses wreaddir_resolving, which tries to use the dirent d_type
field if it exists. In that way, it can skip the `stat` to determine
if the given file is a directory.

This allows `cd` completions to skip stat in most cases:

```fish
strace -Ce newfstatat fish --no-config -c 'complete -C"cd /tmp/completion_test/"' >/dev/null
```

prints before:
```
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100,00    0,002627           2      1033         4 newfstatat
```

after:

```
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100,00    0,000054           1        31         3 newfstatat
```

for a directory with 1000 subdirectories.

(just `fish --no-config -c exit` does 26 newfstatat)

This should improve the situation with slow filesystems like fuse or
network fsen.

In case we have no d_type, we use `stat`, which would yield about the
same results.

The worst case is that we need directories *and* descriptions or the
"executable" flag (which we don't currently check for cd, if I read
this right?).
2022-09-21 19:49:17 +02:00
Fabian Boehm
a277f9aa93 WSL: Only skip ".dll" files for *executable* completions
This was overzealous and didn't allow anything named ".dll" in any
file completions.

This allows us to now add the cd completion fast path for WSL
2022-09-21 19:49:17 +02:00
Fabian Boehm
8b9a051b93 wreaddir_resolving: Don't add "/" for empty paths
This could end up trying to `stat()` a file in /, like "/glassdoor",
if the dir_path was empty.
2022-09-21 19:49:17 +02:00
Mahmoud Al-Qudsi
429534496a fixup! Fix stomping of last_option_requires_param 2022-09-20 22:37:17 -05:00
Mahmoud Al-Qudsi
663919228b Fix stomping of last_option_requires_param
This flag determines whether or not more shortopt switches will be offered up as
potential completions (vs only the payload for the last-parsed shortopt switch).

Previously, it was being stomped before it was determined whether or not two
`complete` rules with different `result_mode.requires_param` values were
actually resolved against the current command line or not, and the last
evaluated completion rule would win out.

There are two changes here:
* `last_option_requires_param` is only assigned if all associated conditions for
  a potential completion are also met, and
* If already assigned by a conflicting rule (which can only be user/developer
  error), `last_option_requires_param` is allowed to change from true to false
  but not the other way around (i.e. in case of a conflict, generate both
  payloads and other shortopt completions)

The first change is immediately noticeable and affects many of our own
completions, see the discussion in #9221 for an example regarding `git` where
`-c` has any of about a million different possible meanings depending on which
completion preconditions have been met. The second change should only happen if
a dev/user mistakenly enters a `complete -c ...` rule for the same shortopt more
than once, both with conditions matching, sometimes requiring an argument and
not sometimes not. It should be a rare occurence.
2022-09-20 21:49:30 -05:00
ridiculousfish
e7de342259 Remove a variable name in a defaulted function
This fixes a g++ 4.8 warning.
2022-09-20 14:41:22 -07:00
ridiculousfish
81c29d8891 clang-format and minor cleanup of tinyexpr.cpp
Clarifies some code and fixes some g++ 4.8 warnings.
2022-09-20 14:41:22 -07:00
ridiculousfish
5f4583b52d Revert "Re-implement macro to constexpr transition"
This reverts commit 3d8f98c395.

In addition to the issues mentioned on the GitHub page for this commit,
it also broke the CentOS 7 build.

Note one can locally test the CentOS 7 build via:

    ./docker/docker_run_tests.sh ./docker/centos7.Dockerfile
2022-09-20 11:58:37 -07:00
Fabian Boehm
8b1da4b63d path: Actually use mtime instead of ctime
Fixes #9222
2022-09-20 16:10:17 +02:00
Mahmoud Al-Qudsi
3d8f98c395 Re-implement macro to constexpr transition
Be more careful with sign extension issues stemming from the differences in how
an untyped literal is promoted to an integer vs how a typed (and signed) `char`
is promoted to an integer.
2022-09-19 18:10:41 -05:00
Mahmoud Al-Qudsi
7c3e4a7ccb Revert "Convert constant macros to constexpr expressions"
This reverts commit e1626818f7.
2022-09-19 17:42:11 -05:00
Mahmoud Al-Qudsi
e1626818f7 Convert constant macros to constexpr expressions
Also convert some `const[expr] static xxx` to `const[expr] xxx` where it makes
sense to let the compiler deduce on its own whether or not to allocate storage
for a constant variable rather than imposing our view that it should have STATIC
storage set aside for it.

A few call sites were not making use of the `XXX_LEN` definitions and were
calling `strlen(XXX)` - these have been updated to use `const_strlen(XXX)`
instead.

I'm not sure if any toolchains will have raise any issues with these changes...
CI will tell!
2022-09-19 17:17:09 -05:00
ridiculousfish
9ec2e42e0e Revert "Reduce memory allocations for deduping completions"
The optimization takes references to strings which are stored in a vector,
and stores those references in a set; but the strings are simultaneously
being moved within the vector, which may invalidate those references.

It's  probably safe if you work through which particular strings are being
moved,  but as a matter of principle we shouldn't take references to elements
of a vector while the vector is being rearranged, absenet a clear improvement
on a benchmark.

This reverts commit d5561623aa.
2022-09-17 11:57:44 -07:00
Mahmoud Al-Qudsi
d5561623aa Reduce memory allocations for deduping completions
Instead of adding the completions themselves to an `unordered_set` to
see if any are duplicates, just add a reference to the item instead.
2022-09-16 21:36:50 -05:00
Mahmoud Al-Qudsi
3ef047f242 Remove needless rank comparison
We've already removed any ranks that aren't equal to `best_rank` at this
point, so why are we comparing them again?
2022-09-16 21:34:10 -05:00
Johannes Altmanninger
31f7be3c8d fixup! reader: when updating commandline, also update rendered highlighting 2022-09-16 19:36:58 -05:00
Johannes Altmanninger
6a0bb7d6de reader: when updating commandline, also update rendered highlighting
Whenever the command line changes, we redraw it with the previously computed
syntax highlighting. At the same time we start recomputing highlighting in
a background thread.

On some systems, the highlighting computation is slow, so the stale syntax
highlighting is visible.

The stale highlighting was computed for an old commandline.  When the user
had inserted or deleted some characters in the middle, then the highlighting
is wrong for the characters to the right.  This is because the characters
to the right have shifted but the highlighting hasn't.  Fix this by also
shifting highlighting.

This means that text that was alrady highlighted will use the same
highlighting until a new one is computed. Newly inserted text uses the color
left of the cursor.

This is implemented by giving editable_line_t ownership of the highlighting.
It is able to perfectly sync text and highlighting; they will invariably
have the same length.

Fixes #9180
2022-09-16 19:21:21 -05:00
Johannes Altmanninger
de353d3e04 reader: stop requiring edit_t to be an rvalue reference
While its true that we only ever call this with temporaries, there is no
fundamental reason for this restriction.  Taking by value is simpler and
more flexible. I think it does not change the generated code.

No functional change.
2022-09-16 19:21:21 -05:00
Johannes Altmanninger
be64c53888 reader: inline dangerous function
The idea for this function was that it stands as the one place that modifies
the text without push_edit. In practice I don't think it helps.

No functional change.
2022-09-16 19:21:21 -05:00
Johannes Altmanninger
8b4b24428c reader: make undo history private to editable_line_t
reader handles way too much state itself. Let's move the undo handling to
editable_line_t entirely.

No functional change.
2022-09-16 19:17:04 -05:00
Johannes Altmanninger
2b2f64c045 reader: move private members to the bottom
No functional change.
2022-09-16 19:17:04 -05:00
Johannes Altmanninger
0ffb0fb786 reader: move function definition out-of-line
Happily, clangd provides a code action to do this.

No functional change.
2022-09-16 19:17:04 -05:00
Johannes Altmanninger
b3a8e85b0f complete: use remove_if+erase instead of raw loop to remove leading decorators
In theory this does less work so we should generally use this style.
In practice it looks uglier so I'm not sure. Maybe wait for stdlib ranges...

No functional change.
2022-09-16 19:17:04 -05:00
Mahmoud Al-Qudsi
9cf56047fb Prevent anyone else from wasting time w/ sigqueue(2)
It turns out there *is* an obviously portable way... except it's
not-so-obviously not portable after all.

POSIX specifies that sigqueue(2) can be used to validate pid and signo
separately, returning EINVAL in the specific case of an invalid or unsupported
signal number. This would be perfect... if only it were actually implemented.
2022-09-16 18:53:05 -05:00
Mahmoud Al-Qudsi
67ac23c70e Fix signal starvation in readch_timed under WSLv1
It seems that the WSLv1 implementation of pselect(2) does not check for
undelivered signals after the temporary sigmask is un-applied from the thread in
question.
2022-09-16 18:26:49 -05:00
Mahmoud Al-Qudsi
f97650bf9a Fix stale references to getch() 2022-09-16 18:26:49 -05:00
Mahmoud Al-Qudsi
351500e42d Emit more specific error for incomplete escape sequences
This replaces "Invalid token ..." with "Incomplete escape sequence ..." for
bare \c, \u, \U, \x, and \X escapes.
2022-09-16 15:44:33 -05:00
Fabian Boehm
787ba6d951 path: Don't try to find empty commands
This would e.g. cause highlighting to be broken if you added an
executable file to $PATH
2022-09-14 18:18:08 +02:00
Fabian Boehm
cfecc4cc35 command_not_found: Add special error for ENOTDIR 2022-09-14 18:01:01 +02:00
Aaron Gyes
e927ad367f Add IWYU pragma
Fixes #9206
2022-09-13 06:56:52 -07:00
Aaron Gyes
168d74ab0e IWYU 2022-09-12 18:34:19 -07:00
Aaron Gyes
864bd4a9cb builtin bind: highlight output.
This highlights `bind` output, which is commands to reproduce the
current bind state, for interactive sessions ala builtin complete.
2022-09-12 15:33:07 -07:00
ridiculousfish
5cf0778207 Claim the tty unconditionally in reader_data_t::readline
When fish runs with job control enabled, it transfers ownership of the
tty to a child process, and then reclaims the tty after the process
exits. If job control is disabled then fish does not transfer or reclaim
the tty.

It may happen that the child process creates a pgroup and then transfers
the tty to it. In that case fish will not attempt to reclaim the tty, as
fish did not transfer it. Then when fish reads from stdin it will
receive SIGTTIN instead of data.

Fix this by unconditionally claiming the tty in readline().

Fixes #9181
2022-09-09 13:43:29 -07:00
ridiculousfish
331bb9024b clang-format reader.cpp
We had an errant newline incompatible with our format.
2022-09-09 11:35:06 -07:00
Fabian Boehm
24fd26ae6e Fix error for vararg functions with zero arguments 2022-09-09 18:52:45 +02:00
Fabian Boehm
c284c4ca99 Add length also for too-many/few-args error 2022-09-09 18:52:45 +02:00
Fabian Boehm
a3ee7da812 math: Add length to missing operator error 2022-09-09 18:52:45 +02:00
Fabian Boehm
52e065e479 math: Add error length
Like we now do for syntax errors, this marks the extent of the error.

Currently for unknown functions only, would be cool for division too
2022-09-09 18:52:45 +02:00
Fabian Boehm
5edba044a3 math: Give a proper error for division by zero
This errored out *later* because the result was infinite or NaN, but
it didn't actually stop evaluation.

I'm not sure if there is a way to get floating point math to turn an
infinity back into something that doesn't depend on a literal
infinity, but division by zero conceptually isn't a thing we can
support.

There's entire branches of maths dedicated to figuring out what
dividing by "basically zero" means and we don't have to get into it.
2022-09-09 18:52:45 +02:00
Fabian Boehm
41c22d5e60 Add string shorten
This is essentially the inverse of `string pad`.
Where that adds characters to get up to the specified width,
this adds an ellipsis to a string if it goes over a specific maximum width.
The char can be given, but defaults to our ellipsis string.
("…" if the locale can handle it and "..." otherwise)

If the ellipsis string is empty, it just truncates.

For arguments given via argv, it goes line-by-line,
because otherwise length makes no sense.

If "--no-newline" is given, it adds an ellipsis instead and removes all subsequent lines.

Like pad and `length --visible`, it goes by visible width,
skipping recognized escape sequences, as those have no influence on width.

The default target width is the shortest of the given widths that is non-zero.

If the ellipsis is already wider than the target width,
we truncate instead. This is safer overall, so we don't e.g. move into a new line.
This is especially important given our default ellipsis might be width 3.
2022-09-09 18:49:57 +02:00
Aaron Gyes
08129537e8 timer.cpp: iwyu; update includes
after aaf50099f2
2022-08-30 23:56:33 -07:00
Aaron Gyes
c35b935e61 fallback.cpp: iwyu; update includes 2022-08-30 23:55:26 -07:00
Johannes Altmanninger
3b30d92b62 Commit transient edit when closing pager
When selecting items in the pager, only the latest of those items is kept
in the edit history, as so-called transient edit.  Each new transient edit
evicts any old transient edit (via undo).

If the pager is closed by a command that performs another transient edit
(like history-token-search-backward) we thus inadvertently undo (= remove)
the token inserted by the pager.  Fix this by closing a transient edit
session when closing the pager.  Token search will start its own session.

Fixes #9160
2022-08-31 07:49:49 +02:00
Fabian Boehm
26285280a9 Remove some dead code 2022-08-27 20:33:39 +02:00
Fabian Boehm
b08490f051 Replace our use of strncpy
strncpy will fill the entire buffer with NUL.

In this case we have a 128 byte buffer and write "empty" - 5 bytes -
into it.

So now instead of writing 6 bytes it'll write 128 bytes. Especially
wasteful because we already did memset before
2022-08-27 17:47:18 +02:00
Fabian Boehm
227e1f6300 color: Use convert_digit
I can't believe how many "read this one hex digit" functions we have.
2022-08-27 11:41:29 +02:00
Fabian Boehm
5e0f5eff37 Remove wcsdup fallback
2a0e0d6721 removed the last use of it,
and in most cases we'd probably prefer to use a wcstring instead
2022-08-27 11:36:15 +02:00
Fabian Boehm
4dfcd4cb4e reader: Check bounds for color
This fixes a crash when you open the history pager and then do
history-token-search-backward (e.g. alt+. or alt-up).

It would sometimes crash because the `colors.at(i)` was an
out-of-bounds access.

Note: This might still leave the highlighting offset in some
cases (not quite sure why), but at least it doesn't *crash*, and the
search generally *works*.
2022-08-26 15:02:05 +02:00
Fabian Boehm
a42a651d0a Use color for $fish_color_valid_path if it exists
This otherwise threw away the color. Since that's just information
that is thrown away, let's just use it.

Fixes #9159.
2022-08-25 17:42:42 +02:00
Aaron Gyes
50d37527a9 Revert "I need to take a break. Fixup."
This reverts commit 3e556b984c.

Revert "Further fix the issue and add the assert that'd have prevented it."

This reverts commit 056502001e.

Revert "Fix actual issue with allow_use_posix_spawn."

This reverts commit 85b9f3c71f.

Revert "Stop using posix_spawn when it is not allowed"

This reverts commit 9c896e1990.

Revert "don't even set up a fish_use_posix_spawn handler if unsupported"

This reverts commit 8b14ac4a9c.
2022-08-22 14:11:52 -07:00
Aaron Gyes
3e556b984c I need to take a break. Fixup. 2022-08-22 13:55:44 -07:00
Aaron Gyes
056502001e Further fix the issue and add the assert that'd have prevented it.
Surprise: because FISH_USE_POSIX_SPAWN was from postfork.h, we
also were disabling things when we don't want to as well.
2022-08-22 13:53:41 -07:00
Aaron Gyes
85b9f3c71f Fix actual issue with allow_use_posix_spawn.
We were testing the function pointer, not evaluating the function.

This should be the proper fix. Thanks @ridiculousfish
2022-08-22 13:30:51 -07:00
ridiculousfish
9c896e1990 Stop using posix_spawn when it is not allowed
Commit 8b14ac4a9c started using
posix_spawn even if allow_use_posix_spawn() returns false. Stop doing
that.

This may be reproduced with:

    ./docker/docker_run_tests.sh ./docker/centos7.Dockerfile

as centos7 has a too-old glibc.
2022-08-21 16:25:26 -07:00
ridiculousfish
aaf50099f2 Stop using a static vector for timers
This is thread unsafe. Just use a captured local variable instead.
2022-08-21 15:30:13 -07:00
ridiculousfish
3eae0a9b6a clang-format all C++ files
This mostly re-sorts headers that got desorted after the IWYU
application in 14d2a6d8ff.
2022-08-21 15:02:19 -07:00
ridiculousfish
c260c1259e Stop exporting kDefaultPath
This is used only within path.cpp; make it a static.
2022-08-21 14:43:28 -07:00
ridiculousfish
1d0c22b390 Remove unused 'vars' variable in path_get_path_core
This became unused deliberately in 40733ca25b.
2022-08-21 14:42:59 -07:00
Aaron Gyes
8b14ac4a9c don't even set up a fish_use_posix_spawn handler if unsupported
Also remove extern 'C' { gnu_get_libc_version }, it's no longer
used. allow_use_posix_spawn is determined true or false at
compile time.
2022-08-21 14:19:34 -07:00
Aaron Gyes
1198a05299 assert: identify the hot path
Does result in code that branches a little differently.
2022-08-21 05:55:34 -07:00
Aaron Gyes
14d2a6d8ff IWYU-guided #include rejiggering.
Let's hope this doesn't causes build failures for e.g. musl: I just
know it's good on macOS and our Linux CI.

It's been a long time.

One fix this brings, is I discovered we #include assert.h or cassert
in a lot of places. If those ever happen to be in a file that doesn't
include common.h, or we are before common.h gets included, we're
unawaringly working with the system 'assert' macro again, which
may get disabled for debug builds or at least has different
behavior on crash. We undef 'assert' and redefine it in common.h.

Those were all eliminated, except in one catch-22 spot for
maybe.h: it can't include common.h. A fix might be to
make a fish_assert.h that *usually* common.h exports.
2022-08-20 23:55:18 -07:00
Fabian Boehm
7988cff6bd Increase the string chunk size to increase performance
This is a *tiny* commit code-wise, but the explanation is a bit
longer.

When I made string read in chunks, I picked a chunk size from bash's
read, under the assumption that they had picked a good one.

It turns out, on the (linux) systems I've tested, that's simply not
true.

My tests show that a bigger chunk size of up to 4096 is better *across
the board*:

- It's better with very large inputs
- It's equal-to-slightly-better with small inputs
- It's equal-to-slightly-better even if we quit early

My test setup:

0. Create various fish builds with various sizes for
STRING_CHUNK_SIZE, name them "fish-$CHUNKSIZE".
1. Download the npm package names from
https://github.com/nice-registry/all-the-package-names/blob/master/names.json (I
used commit 87451ea77562a0b1b32550124e3ab4a657bf166c, so it's 46.8MB)
2. Extract the names so we get a line-based version:

```fish
jq '.[]' names.json | string trim -c '"' >/tmp/all
```

3. Create various sizes of random extracts:

```fish
for f in 10000 1000 500 50
    shuf /tmp/all | head -n $f > /tmp/$f
end
```

(the idea here is to defeat any form of pattern in the input).

4. Run benchmarks:

hyperfine -w 3 ./fish-{128,512,1024,2048,4096}"
    -c 'for i in (seq 1000)
            string match -re foot < $f
        end; true'"

(reduce the seq size for the larger files so you don't have to wait
for hours - the idea here is to have some time running string and not
just fish startup time)

This shows results pretty much like

```
Summary
'./fish-2048     -c 'for i in (seq 1000)
          string match -re foot < /tmp/500
      end; true'' ran
  1.01 ± 0.02 times faster than './fish-4096     -c 'for i in (seq 1000)
          string match -re foot < /tmp/500
      end; true''
  1.02 ± 0.03 times faster than './fish-1024     -c 'for i in (seq 1000)
          string match -re foot < /tmp/500
      end; true''
  1.08 ± 0.03 times faster than './fish-512     -c 'for i in (seq 1000)
          string match -re foot < /tmp/500
      end; true''
  1.47 ± 0.07 times faster than './fish-128     -c 'for i in (seq 1000)
          string match -re foot < /tmp/500
      end; true''
```

So we see that up to 1024 there's a difference, and after that the
returns are marginal. So we stick with 1024 because of the memory
trade-off.

----

Fun extra:

Comparisons with `grep` (GNU grep 3.7) are *weird*. Because you both
get

```
'./fish-4096 -c 'for i in (seq 100); string match -re foot < /tmp/500; end; true'' ran
11.65 ± 0.23 times faster than 'fish -c 'for i in (seq 100); command grep foot /tmp/500; end''
```

and

```
'fish -c 'for i in (seq 2); command grep foot /tmp/all; end'' ran
66.34 ± 3.00 times faster than './fish-4096 -c 'for i in (seq 2);
string match -re foot < /tmp/all; end; true''
100.05 ± 4.31 times faster than './fish-128 -c 'for i in (seq 2);
string match -re foot < /tmp/all; end; true''
```

Basically, if you *can* give grep a lot of work at once (~40MB in this
case), it'll churn through it like butter. But if you have to call it
a lot, string beats it by virtue of cheating.
2022-08-15 20:16:12 +02:00
Fabian Boehm
40733ca25b If relative path was used, use it
This was inadvertently changed in
ed78fd2a5f

Fixes #9143
2022-08-15 20:01:50 +02:00
Aaron Gyes
2b2f772790 clarify "…variable is shadowed by the global variable of the same name"
Rephrase this to more explicitly indicate that the uvar actually
was successfully set. I believe the prior phrasing can leave some
ambiguity as far as wether set just failed with an error, whether it
has done anything or not.
2022-08-14 16:16:38 -07:00
Aaron Gyes
aacc71e585 builtin set: make error messages more consistent.
Now uses the same macro other builtins use for a missing -e arg,
and the error message show the short or long option as it was used.

e.g. before
    $ set -e
    set: Erase needs a variable name

after
    $ set --erase
    set: --erase: option requires an argument
    $ set -e
    set: -e: option requires an argument
2022-08-14 15:34:58 -07:00
ridiculousfish
2a0e0d6721 Remove the intern'd strings component
Intern'd strings were intended to be "shared" to reduce memory usage but
this optimization doesn't carry its weight. Remove it. No functional
change expected.
2022-08-13 12:51:36 -07:00
ridiculousfish
082f074bb1 Switch filenames from intern'd strings to shared_ptr
We store filenames in function definitions to indicate where the
function comes from. Previously these were intern'd strings. Switch them
to a shared_ptr<wcstring>, intending to remove intern'd strings.
2022-08-13 12:51:36 -07:00
Johannes Altmanninger
3dfacf4b39 builtin printf: suppress warnings about unused variables
No functional change.
2022-08-13 21:11:54 +02:00
Johannes Altmanninger
c031e6f193 Highlight shell commands in history pager
This solution is quite hacky. I added a comment that suggests a better
solution, which shouldn't be hard to implement.
2022-08-13 21:11:31 +02:00
Johannes Altmanninger
b64cec1d7e Use Unicode symbols for rendering control characters in pager
The history pager will show multiline commands in single-line cells.
We escape newline characters as \\n but that looks awkward if the next line
starts with a letter. Let's render control characters using their corresponding
symbol from the Control Pictures Unicode block.

This means there is also no need to escape backslashes, which further improves
the history pager - now the rendering has exactly as many backslashes as
the eventual command.

This means that (multiline) commands in the history pager will be rendered
with the same amount of characters as are in the actual command (unless
they contain funny nonprintables).  This makes it easy for the next commit
to highlight multiline commands correctly in the history pager.

The font size for these symbols (for example ␉) is quite small, but that's
okay since for the proposed uses it's not so important that they readable.
The important thing is that the stand out from surrounding text.
2022-08-13 21:11:31 +02:00
Fabian Boehm
5fe43accef Add special error for set -o 2022-08-12 21:28:11 +02:00
Fabian Boehm
8d7416048d Don't skip caret for some errors
This checked specifically for "| and" and "a=b" and then just gave the
error without a caret at all.

E.g. for a /tmp/broken.fish that contains

```fish
echo foo

echo foo | and cat
```

This would print:

```
/tmp/broken.fish (line 3): The 'and' command can not be used in a pipeline
warning: Error while reading file /tmp/broken.fish
```

without any indication other than the line number as to the location
of the error.

Now we do

```
/tmp/broken.fish (line 3): The 'and' command can not be used in a pipeline
echo foo | and cat
           ^~^
warning: Error while reading file /tmp/broken.fish
```

Another nice one:

```
fish --no-config -c 'echo notprinted; echo foo; a=b'
```

failed to give the error message!

(Note: Is it really a "warning" if we failed to read the one file we
wer told to?)

We should check if we should either centralize these error messages
completely, or always pass them and remove this "code" system, because
it's only used in some cases.
2022-08-12 18:38:47 +02:00
Fabian Boehm
232ca25ff9 Add length to the parse_util syntax errors 2022-08-12 18:38:47 +02:00
Fabian Boehm
4b921cbc08 Clamp error carets to the end instead of refusing to print
This skipped printing a "^" line if the start or length of the error
was longer than the source.

That seems like the correc thing at first glance, however it means
that the caret line isn't skipped *if the file goes on*.

So, for example

```fish
echo "$abc["
```

by itself, in a file or via `fish -c`, would not print an error, but

```fish
echo "$abc["
true
```

would. That's not a great way to print errors.

So instead we just.. imagine the start was at most at the end.

The underlying issue why `echo "$abc["` causes this is that `wcstol`
didn't move the end pointer for the index value (because there is no
number there). I'd fix this, but apparently some of
our recursive variable calls absolutely rely on this position value.
2022-08-12 18:38:47 +02:00
Fabian Boehm
c1bf06d5b1 Print "^^" for a 2-wide error 2022-08-12 18:38:47 +02:00
Fabian Boehm
eaf92918e6 Fix error offset for command (foo)
This used the decorated statement offset when the expansion errors
refer to the command without decoration.
2022-08-12 18:38:47 +02:00
Fabian Boehm
a4fd3c194e Pass location of the *command* node without decorators
Fixes error location for unknown commands
2022-08-12 18:38:47 +02:00
Fabian Boehm
5ef457cfd3 Make tokenizer delimiter errors one long
This makes the awkward case

	    fish: Unexpected end of string, square brackets do not match
	    echo f[oo # not valid, no matching ]
	          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

(that `]` is simply the last character on the line, it's firmly in a comment)

less awkward by only marking the starting brace.

The implementation here is awkward mostly because the tok_t
communicates two things: The error location and how to carry on.

So we need to store the error length separately, and this is the first
time we've done so.

It's possible we can make this simpler.
2022-08-12 18:38:47 +02:00
Fabian Boehm
bf47d469d4 Add command substitution error length 2022-08-12 18:38:47 +02:00
Fabian Boehm
3f27febc4c Mark the entire error location with a squiggle
This makes it so instead of marking the error location with a simple
`^`, we mark it with a caret, then a run of `~`, and then an ending `^`.

This makes it easier to see where exactly an error occured, e.g. which
command substitution was meant.

Note: Because this uses error locations that haven't been exposed like
that, it's likely to shake out weirdnesses and inaccuracies. For that
reason I've not adjusted the tests yet.
2022-08-12 18:38:47 +02:00
Fabian Boehm
7b2f4f666d expand: If skip_variables is given, put back quoted $ as well
Actually fixes #9137
2022-08-12 17:51:59 +02:00
Fabian Boehm
db20356a6c Add wcwidth non_characters
These were added to widechar_width kinda late.

Fixes #9137
2022-08-12 17:25:31 +02:00
Fabian Boehm
b2eea4b46f complete: Don't load completions if command isn't in $PATH
This stops us from loading the completions for e.g. `./foo` if there
is no `foo` in path.

This is because the completion scripts will call an unqualified `foo`,
and then error out.

This of course means if the script would work because it never calls
the command, we still don't load it.

Pathed completions via `complete --path` should be unaffected because
they aren't autoloaded anyway.

Workaround for #3117
Fixes #9133
2022-08-11 17:05:32 +02:00
Fabian Boehm
37f7818bbb printf: Ignore any options
This was misguidedly "fixed" in
9e08609f85, which made printf error out
with any "-"-prefixed words as the first argument.

Note: This means currently `printf --help` doesn't print the help.
This also matches `echo`, and we currently don't have anything to make
a literal `--help` execute a builtin help except for keywords. Oh well.

Fixes #9132
2022-08-10 16:55:56 +02:00
Fabian Boehm
7d8009e9d6
Disclose pager to half of screen height immediately (#9105)
* Disclose pager to screen height immediately

This removes that bit where we only show 4 rows at most at first,
instead we disclose between half of terminal height up to the full terminal height (but still at least 4 rows).

This results in less pressing of tab to get the other results, and
better visibility of results.

Unlike moving it to the actual top of the screen, it's not as jarring and doesn't push terminal history off-screen as much.

Fixes #2698
2022-08-09 20:05:08 +02:00
Fabian Boehm
b89249de98 Reset the read byte limit to the default when unset
This used to be kept, so e.g. testing it with

    fish_read_limit=5 echo (string repeat -n 10 a)

would cause the prompt and such to error as well.

Also there was no good way to get back to the default value
afterwards.
2022-08-09 19:59:10 +02:00
Fabian Boehm
eac808a819
string repeat: Don't allocate repeated string all at once (#9124)
* string repeat: Don't allocate repeated string all at once

This used to allocate one string and fill it with the necessary
repetitions, which could be a very very large string.

Now, it instead uses one buffer and fills it to a chunk size,
and then writes that.

This fixes:

1. We no longer crash with too large max/count values. Before they
caused a bad_alloc because we tried to fill all RAM.
2. We no longer fill all RAM if given a big-but-not-too-big value. You
could've caused fish to eat *most* of your RAM here.
3. It can start writing almost immediately, instead of waiting
potentially minutes to start.

Performance is about the same to slightly faster overall.
2022-08-09 19:58:56 +02:00
ridiculousfish
e0a4d49ef3 Bravely stop appending a newline in reader_shell_test
This newline apparently dates back to when we required all statements to
be terminated; but our AST no longer requires that so we can remove
this. No functional change expected here.
2022-08-07 14:03:33 -07:00
ridiculousfish
1dff1cb2c4 Factor out handling of readline_cmd_t::execute
This reduces the size of handle_readline_command.
No functional change.
2022-08-07 13:37:56 -07:00
Michael Nickerson
b08a962edb Fix compile error on OpenBSD 2022-08-04 08:13:19 +02:00
Johannes Altmanninger
095c093af6 Fix "commandline --paging-mode" false negative when there is no room for pager, attempt 2
The previous fix was reverted because it broke another scenario.  Add tests
for both scenarios.

The first test exposes another problem: autosuggestions are sometimes not
recomputed after selecting the first completion with Tab Tab. Fix that too.
2022-07-31 07:14:56 +02:00
Aaron Gyes
7b18a70724 Revert "Fix "commandline --paging-mode" false negative when there is no room for pager"
This reverts commit 1edcd8ab29.

The commit broke hitting <TAB> to show the pager, followed by
down-or-search.
2022-07-30 18:15:10 -07:00
Johannes Altmanninger
a447cc38a9 Hint at more matches at the bottom of the history pager 2022-07-30 23:27:24 +02:00
Johannes Altmanninger
1af9b8e430 Prefix history pager results with a fake prompt
This makes it easy to see where the individual commands start.  Perhaps we
can get rid of this once we have syntax highlighting for the commands in
the history pager, or if we add timestamps as descriptions.
2022-07-30 23:27:24 +02:00
Johannes Altmanninger
453aac14af Advance pager history search with Control-R/Control-S
Note that every change to the search field still starts a new search, from
the end of history. We could change this in future but it's unclear to me
what the expected behavior is. I don't find the traditional readline behavior
very intuitive.
2022-07-30 23:27:24 +02:00
Johannes Altmanninger
24e04daa22 Teach history search to move forward in time
Will use this for forward incremental search.

No functional change.
2022-07-30 23:27:24 +02:00
Johannes Altmanninger
dcff0a2f2b Add Control+R incremental history search in pager
This reimplements ridiculousfish/control_r which is a more future-proof
approach than #6686.
Pressing Control+R shows history in our pager and allows to search filter
commands with the pager search field.

On the surface, this works just like in other shells; though there are
some differences.

- Our pager shows multiple results at a time.
- Other shells allow to use up arrow/down arrow to select adjacent entries
  in history. Shouldn't be hard to implement but the hidden state might
  confuse users and it doesn't play well with up-or-search, so this is
  left out.

Users might expect the history pager to use subsequence matching (fuzzy
matching) like the completion pager, however due to the history pager design it
uses substring matching.  We could change this in future, however that means
we would also want to change the ordering from "reverse-chronological" to
"longest common subsequence" (e.g. what fuzzy finders do), because otherwise
a query "fis" might give this ordering:

            fsck /dev/disk/by-partlabel/Linux\x20filesystem
            fish

which is probably not what the user wants.

The pager shows only a small number of history items at a time.  This is
because, as explained above, the history pager does not support subsequence
matching, so navigating it does not scale well.

Closes #602
2022-07-30 23:27:24 +02:00
Johannes Altmanninger
b0233c9aa7 Revert "Refactor: inline clear_pager()"
The next patch wants to add state that should be reset when we clear the
pager, which will happen in this function.

This reverts commit b25b291d38.

No functional change.
2022-07-30 23:27:24 +02:00
Johannes Altmanninger
9a0d8e67df Extract function for smartcase history search
To be used in the commit after next.

No functional change.
2022-07-30 23:27:24 +02:00
Johannes Altmanninger
3954200555 Centralize how we invalidate pager rendering after completions change
The pager's rendering_needs_update() function detects some but not all
scenarios where a rendering is stale. In particular, it does not compare
the completion strings.

To make this work, we manually invalidate the pager rendering whenever we
update completion strings. The history pager needs the same functionality,
so let's move it into the pager.

No functional change.
2022-07-30 23:27:24 +02:00
Baspar
ec8fd628bd Generate job & process exit events for background jobs 2022-07-30 10:06:33 -07:00
Michael Forster
f09d2c4e6e Use env_dispatch to update cursor selection mode 2022-07-30 09:49:07 -07:00
Michael Forster
7d198fa404 Add an initial test for fish_cursor_selection_mode 2022-07-30 09:49:07 -07:00
Michael Forster
5cf67c2d61 Use dedicated variable to configure selection size
This addresses code review feedback to not couple the purely visual
concept of cursor style with the logical concept of the selection size.
Instead this now uses a dedicated variable
`$fish_select_char_after_cursor` to determine whether to extend the
selection beyond the cursor:

* fish_select_char_after_cursor = 1 or unset -> extend selection
* all other cases -> place the selection end that the cursor
2022-07-30 09:49:07 -07:00
Michael Forster
a7d943793e Consider cursor width when updating selection
This fixes the handling of the right end of the selection. Currently the
right end is considered to be at the cursor position + 1. When using a
`block` or `underline` cursor this is arguably correct, because the
cursor has a width of 1 and spans from the current position to the next:
```
    x x [x x x̲] x
```

This is incorrect though (or at least very unintuitive), when using a
`line` cursor:
```
    x x [x x|x] x
```

This commit changes the strategy for determining the end of the
selection in the following way:

* If the current cursor as determined by `$fish_cursor_<bind_mode>` is
  set to `line`, then a cursor width of `0` is assumed.
* In all other cases, including `block` and `underscore` as well as when
  no value is set we retain the previous behavior of assuming a cursor
  width of `1`.
```
    x x [x x x̲] x
    x x [x x|]x x
```

This change should not affect many users, because the selection is
probably used most by vi-mode users, who are also likely to use a
block cursor.
2022-07-30 09:49:07 -07:00
Johannes Altmanninger
1edcd8ab29 Fix "commandline --paging-mode" false negative when there is no room for pager
The pager still works even if there is no room to render it.  So let's make
"commandline --paging-mode" return true if there is an off-screen pager.

This fixes the problem with the upcoming history-pager described in
https://github.com/fish-shell/fish-shell/pull/9089#issuecomment-1196945456
2022-07-28 22:08:33 +02:00
Johannes Altmanninger
a584fc51d9 Explain edge case in select_completion_in_direction()
No functional change.
2022-07-28 10:41:00 +02:00
Johannes Altmanninger
1fc3d51dde Fix misleading comment in set_buffer_maintaining_pager()
This function used to clear the pager search field but it no longer does.

No functional change.
2022-07-28 10:40:54 +02:00
Johannes Altmanninger
2e8ecfdb44 Clarify escaping of ASCII control characters
We use "c > 0" but we actually mean "c != 0".  The former looks like the
other code path handles negative c.  Yet if c is negative, our code would
print a single escaped byte (\xXY) which is wrong because a negative value
has "sizeof wchar_t" bytes which is at least 2.

I think on platforms with 16-bit wchar_t it's possible that we actually
get a negative value but I haven't checked.
2022-07-27 11:24:35 +02:00
Johannes Altmanninger
f1b4366222 Consolidate logic in escape_string_script()
No functional change.
2022-07-27 11:24:35 +02:00
Johannes Altmanninger
83893558f9 Make ESCAPE_NO_PRINTABLES behavior a bit less weird
Since the fix for #3892, this escaping style escapes

	\n to \\n

as well as

	\\ to \\\\
	\' to \\'

I believe these two are the only printable characters that are escaped with
ESCAPE_NO_PRINTABLES.
The rationale is probably to keep the encoding unambiguous and reversible.
However that doesn't justify escaping the single quote. Probably this was
an accident, so let's revert that part.

This has the nice effect that single quotes will no longer be escaped
when rendered in the completion pager (which is consistent with other
special characters). Try it:

    complete : -a "aaa\'\; aaaa\'\;" -f

Also this makes the error output of builtin bind consistent:

    $ bind -e --preset \;
    $ bind -e --preset \'
    $ bind \;
    bind: No binding found for sequence “;”
    $ bind \'
    bind: No binding found for sequence “'”

the last line is clearly better than the old version:

    bind: No binding found for sequence “\'”

In general, the fact that ESCAPE_NO_PRINTABLES escapes the (printable)
backslash is weird but I guess it's fine because it looks more consistent to
users, even though the result is an undocumented subset of the fish language.
2022-07-27 11:24:35 +02:00
Johannes Altmanninger
8729623cec Make ESCAPE_ALL the default and call its inverse ESCAPE_NO_PRINTABLES
ESCAPE_ALL is not really a helpful name. Also it's the most common flag.
Let's make it the default so we can remove this unhelpful name.

While at it, let's add a default value for the flags argument, which helps
most callers.

The absence of ESCAPE_ALL makes it only escape nonprintable characters
(with some exceptions). We use this for displaying strings in the completion
pager as well as for the human-readable output of "set", "set -S", "bind"
and "functions".

No functional change.
2022-07-27 11:24:35 +02:00
Johannes Altmanninger
e5d5391687 Remove useless escaping of variable names
When listing variables, "set" tries to escape variable names.
Since variable names cannot have special characters, this doesn't do anything.

The escaping is one of the few places that does not use ESCAPE_ALL.  This has
complex behavior; let's alleviate the problem by getting rid of this call.

No functional change.
2022-07-27 11:24:35 +02:00
Johannes Altmanninger
3f90efca38 clang-format C++ files
Or should we stop using it?

I'm fine with either always or never using auto-formatting but our current
way of using it only sometimes is confusing.

No functional change.
2022-07-27 10:05:41 +02:00
Johannes Altmanninger
0c97fea5c4 Make pager refilter completions after undo/redo in search field
Almost all edits to our commandline are funneled through
reader_data_t::push_edit(). Notable exceptions are undo/redo (which move
across existing edits instead). Due to an oversight, undo/redo fail to
trigger commandline update hooks. Fix that.

Our behavior of triggering hooks only for the search field looks weird. I
reckon that the command line eventually catches up, but this means we trigger
some hooks redundantly. Once we figure that out we can remove the new function.
2022-07-26 15:29:52 +02:00
Johannes Altmanninger
fe2f6f0c63 Fix Escape in pager not removing the inserted completion if search field was used
command_line_has_transient_edit tracks the actual command line, not the
pager search field. We accidentally reset it after modifying the search field
which causes unexpected behavior - the commandline added by the completion
pager remains even after I press Escape.
2022-07-26 15:29:52 +02:00
Johannes Altmanninger
3d8f643a5e Remove duplicate logic to clear the transient bit when inserting into commandline
This is already done by the above call to insert_char.

No functional change.
2022-07-26 15:20:35 +02:00
Johannes Altmanninger
671ad1f4a6 Fix typo 2022-07-26 15:20:19 +02:00
Johannes Altmanninger
bd5610349d Fix pager backwards movement on half-filled last column
If the completion pager renders as

	foo1 bar1 baz1 qux1
	foo2 bar2 baz2
	foo3 bar3 baz3

and we go backwards from "foo1" (using left arrow), we'll end up at "baz3",
not "qux1". Pretty smart!

If however we go backwards once more, nothing happens.

The root cause is that there are two different kinds of selection indices:
the one before rendering (9/qux1) and the one after we cleverly subtract
the half-filled last column (8/baz3). The backwards movement ends up
decrementing the first, so it moves from 9 to 8 and nothing changes in
the rendering.

Fix this by using the selection index that we actually rendered.

There is another caller that relies on the old behavior of using the unrendered
selection index. Make it use a dedicated overload that does not depend on
the rendering.
2022-07-24 17:12:28 +02:00
Johannes Altmanninger
12d4b50d5f Remove unused parameter from set_fully_disclosed() 2022-07-24 17:11:48 +02:00
Johannes Altmanninger
368b68ff47 Minor simplification of term_donate/term_steal
No functional change.
2022-07-24 17:11:48 +02:00
Fabian Boehm
bcd84c6908 Check for waitstatus orientation via cmake
Yeah we need the long way around because old glibc versions have weird WEXITSTATUS.
2022-07-24 16:40:33 +02:00
Fabian Boehm
122b6c1734 status: Only realpath if we got an absolute path
Otherwise realpath would add the cwd, which would be broken if fish
ever cd'd.

We could add the original cwd, but even that isn't enough, because we
need *the parent's* idea of cwd and $PATH.

Or, alternatively, what we need is for the OS to give us the actual
path to ourselves.
2022-07-24 14:31:15 +02:00
Fabian Boehm
d241f0853e status: Do add the command name to the error 2022-07-24 13:17:06 +02:00
Fabian Boehm
4f1c62ff43 status: Realpath the executable path
get_executable_path says: "This needs to be realpath'd"

So how about we do that? The only other place we use it is fish.cpp,
and we realpath it there already.

See #9085
2022-07-24 12:36:32 +02:00
Fabian Boehm
2cb0cada86 Remove sys/mount.h include
This seems to be unnecessary?
2022-07-24 12:24:42 +02:00
Johannes Altmanninger
8b378e9a44 Make complete-or-search select the first candidate
Our pager computes the selected completion based on its rendering. The number
of rows affect the selection, in particular when moving left from the top
left cell.  This computation breaks if the number of rows is zero, which
happens in at least
two scenarios:
1. If the completion pager was not shown (as is the case for complete-or-search)
2. If the search field had filtered away every candidate but not anymore.
I believe in these scenarios the selected completion index is always 0,
so let's fix the selection for that case.

Probably too minor for a changelog entry.

Closes #9080
2022-07-24 10:23:13 +02:00
Samuel Venable
e4c7211cd6
Fix NetBSD executable path to not use procfs (#9085)
* Fix NetBSD executable path to not use procfs

* Update common.cpp
2022-07-24 09:26:33 +02:00
Fabian Boehm
a98301b021 Allow for EWOULDBLOCK instead of EAGAIN
Posix allows this as an alternative with the same semantics for read.

Found in conjunction with #9067.

Should be no functional difference on other systems.
2022-07-23 23:16:44 +02:00
Fabian Boehm
df5489e0a4 Allow for systems where wait status is signal/return
The wait status value, which we also use internally, is read by a
bunch of macros.

Unfortunately because we want to *create* such a value, and some
systems lack the "W_EXITCODE" macro to do that, we need to figure out
how it's encoded.

So we simply check a specific value, and assume the encoding from
that.

On Haiku the return status is in the lower byte, on other systems it's
typically the upper byte.

TODO: Test on musl (that's the other system without W_EXITCODE).

Fixes #9067
2022-07-23 23:16:44 +02:00
Fabian Boehm
64adfdee40 Remove wrong UNUSED annotation
This does in fact use streams
2022-07-23 18:02:46 +02:00
Fabian Boehm
407a455cfd realpath: Use physical PWD
This was an inadvertent change from
cc632d6ae9.

Because we used wgetcwd directly before, we always got the "physical"
resolved $PWD.

There's an argument to be made to use the logical $PWD here as well
but I prefer not to make changes lik that in a random commit without
good reason.
2022-07-18 20:45:30 +02:00
Fabian Boehm
5dfb64b547
Add path mtime (#9057)
This can be used to print the modification time, like `stat` with some
options.

The reason is that `stat` has caused us a number of portability
headaches:

1. It's not available everywhere by default
2. The versions are quite different

For instance, with GNU stat it's `stat -c '%Y'`, with macOS it's `stat
-f %m`.

So now checking a cache file can be done just with builtins.
2022-07-18 20:39:01 +02:00
Aaron Gyes
763240f1af Just remove the dumb comment. 2022-07-17 14:41:35 -07:00
Aaron Gyes
8f91ee7f6b builtin test: Implement -ot, -nt, -ef
These are non-POSIX extensions other test(1) utilities implement,
which compares the modification time of two files as proposed for
fish in #3589: testing if one file is newer than another file.

-ef is a common extension to test(1) which checks if two paths refer
to the same file, by comparing the dev and inode numbers.
2022-07-16 12:40:36 -07:00
Johannes Altmanninger
7bdc712615 Clean up weird edge-case for escaping unescaped brackets
As explained by the comment, this was dead code.  If it were ever executed,
it would cause very weird behavior because it would make some completions
randomly affect others.

Let's just print a warning (maybe this is better than crashing?).
2022-07-16 16:42:34 +02:00
Johannes Altmanninger
12cf31de96 Remove a redundant comment
Also add an issue reference since the commit message doesn't have one.
Of course a test would be even better.
2022-07-16 16:42:19 +02:00
Moheeb Aljaroudi
d4d0ac95b0 Fixed problem where fish would escape '~' when completing an unescaped
']'
2022-07-16 16:17:51 +02:00
SeekingBlues
173914af65
Highlight history searches correctly (#9066)
Previously, the search text is used to find out which part of the
updated command line should be highlighted during a history search. This
approach will cause the incorrect part to be highlighted when the line
contains multiple instances of the search text.

To address this, we have to find out exactly where to highlight, i.e.
the offset of the current token in the command line (0 if not a token
search) plus the offset of the search text in the match.
2022-07-13 16:48:04 +02:00
Fabian Boehm
cc632d6ae9 realpath: Use the parser's working dir
Future proofing, similar to what we do in `path resolve`.
2022-07-12 20:53:57 +02:00
Fabian Boehm
526b7e3b1b readdir_for_dirs: Actually filter out non-dirs
This function is supposed to return "the next directory". Because this
is imperfect, it only tries to.

Except it went to all the trouble of figuring out the type and then
just... returned it anyway.

This has nice speedups in globs with directory components like `*/` or
`**`. I have observed 1.1x to 2.0x.

We could also return when we know it's definitely a directory and then
skip a stat() later, but preliminary testing seemed to show that's not
worth much.
2022-07-12 16:50:00 +02:00
ridiculousfish
a9964cd6d0 Remove usage of PCRE2_SUBSTITUTE_LITERAL
We don't need this flag and this ties us to a newer version of PCRE2
than we would like. Fixes #9061.
2022-07-10 11:17:19 -07:00
Aaron Gyes
cbd0ec568c builtins/path.cpp: remove <glob.h>
I don't believe we use any system glob faciltiies.
2022-07-09 21:11:43 -07:00
Aaron Gyes
3e0f3c9f45 path.cpp: include its actual header with the prototype
path.h: fix that header so it can compile.
2022-07-09 21:04:03 -07:00
ridiculousfish
f7c411d5a5 Further cleanup of builtin_string regex matching
Take advantage of additional cleanup unlocked by this refactoring,
including eliminating unneeded error returns and simplifying some
control flow.

No user-visible behavior change expected here.
2022-07-09 16:44:12 -07:00
ridiculousfish
d46f402cea Adopt the new re in builtin_string
This switches builtin_string from using PCRE2 directly, to using the new re
component. This simplifies some code and removes redundancy.

No user-visible behavior change expected here.
2022-07-09 16:41:15 -07:00
ridiculousfish
7ae1727359 Factor out PCRE2 into new re component
This migrates our PCRE2 dependency from builtin/string.cpp to new files
re.h/re.cpp, allowing regexes to be used in other places in fish.

No user-visible behavior change expected here.
2022-07-09 16:37:20 -07:00
ridiculousfish
61b09ff4a7 Stop using a static unordered_map for string flag handlers
This switches the flag_to_function from a map to just an ordinary switch
statement. This saves some memory/startup time and removes some
relocations. No functional change here.
2022-07-04 13:40:55 -07:00
ridiculousfish
ffded81a00 Correct a misleading comment 2022-07-02 11:30:59 -07:00
Fabian Boehm
60f87ef3be Add error for EBADARCH
That's apparently errno 86 on macOS, and it's triggered when the
architecture is wrong.

I'll leave other macOS errors to the macOS users.

See #9052.
2022-07-02 10:11:00 +02:00
Fabian Boehm
d920610f96 Fix special readline functions after and/or
Here we needed to handle self-insert immediately, but we ended up
returning it.

Fixes #9051
2022-07-02 09:23:11 +02:00
Fabian Boehm
98ba66ed8e set_color: Print the given colors with --print-colors 2022-07-01 21:28:35 +02:00
Fabian Boehm
bd7934ccbf history: Refuse to merge in private mode
It makes *no* sense.

Fixes #9050.
2022-07-01 20:10:18 +02:00
Fabian Boehm
dde2d33098 set --show: Show the originally inherited value, if any
This adds a line to `set --show`s output like

```
$PATH: originally inherited as |/home/alfa/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/flatpak/exports/bin|
```

to help with debugging.

Note that this means keeping an additional copy of the original
environment around. At most this would be one ARG_MAX's worth, which
is about 2M.
2022-06-27 20:33:26 +02:00
Fabian Boehm
04f6306a35 argparse: Stop reconverting to null_terminated_array_t
We already have a perfectly cromulent null_terminated_array here, so
just use it.

No visible changes here, possibly some memory use?
2022-06-27 17:45:08 +02:00
Fabian Boehm
993448d552 argparse: Allow usage without optspecs
It's still useful without, for instance to implement a command that
takes no options, or to check min-args or max-args.

(technically no optspecs, no min/max args and --ignore-unknown does
nothing, but that's a very specific error that we don't need to forbid)

Fixes #9006
2022-06-27 17:02:20 +02:00
Aaron Gyes
b73091b27b proc.cpp, fish_tests.cpp: use snprintf()
Resolves this warning:

> warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
2022-06-25 16:27:04 -07:00
Fabian Boehm
13a9f6b64e printf: Print special error for invalid octal numbers
(tbh these were always a mistake)

See #9035
2022-06-23 18:12:43 +02:00
Fabian Boehm
a78d085df2 Try to use xterm{-256color,} if $TERM could not be used
This is very very very likely to result in an almost fully functional
terminal, as opposed to a "minimally functional" one.
2022-06-21 21:12:04 +02:00
ridiculousfish
137a4ecdf5 Clear signals after running initial commands
If you run an initial command via `fish -c`, and that command is
cancelled e.g. via control-C, then ensure that the cancellation signal
is cleared before running config files.

Fixes #9024
2022-06-20 13:28:58 -07:00
ridiculousfish
f19a2711d4 run_command_list to stop accepting its commands by pointer
There was no reason for this. No functional change here.
2022-06-20 12:55:33 -07:00
ridiculousfish
0230420983 Stop initializing principal parser at global scope
Avoid the risk of global constructors by making this a function-level
static.
2022-06-20 12:31:36 -07:00
ridiculousfish
06de0f79a1 Minor cleanup of setup_user
No functional change
2022-06-20 12:31:36 -07:00
ridiculousfish
50f6b06251 Replace a bunch of ASSERT_IS_MAIN_THREAD
Switch these to a new function parser.assert_can_execute(), in
preparation for allowing execution off of the main thread.
2022-06-20 12:31:36 -07:00
ridiculousfish
e2e340823a Bravely replace ttyname with ttyname_r
This is more thread safe. We'll see if any platforms don't have this.
2022-06-20 12:31:35 -07:00
ridiculousfish
da020c0641 Remove some stuff from global_safety.h
These bits were unused and/or unnecessary.
2022-06-19 15:38:13 -07:00
ridiculousfish
96b3a86b87 Remove iothread drain flag
This was intended to support a mode where we "drain threads before fork"
but that ship has long sailed and it proved unnecessary.
2022-06-19 15:15:20 -07:00
ridiculousfish
e2782ac322 Remove iothread_perform_on_main
iothread_perform_on_main is deadlock-prone under concurrent execution.
We no longer use it, so remove it.
2022-06-19 15:15:20 -07:00
ridiculousfish
bfa83470d4 Reimplement autosuggestion-triggered completion loading
This concerns what happens if the user types e.g. `grep --i` and grep or
its completions have not yet been loaded. Previously we would "bounce to
the main thread" from within the autosuggestion thread to load grep's
completions. However under concurrent execution, this may deadlock as the
main thread is waiting for something else.

In the new implementation, complete simply records the commands that it
would autoload, and returns them back to the caller, where the caller can
decide how to handle them.

In general iothread_perform_on_main risks deadlock under concurrent
execution and we should try to get rid of it.

There should be no user-visible change from this fix.
2022-06-19 15:15:17 -07:00
ridiculousfish
0fee2fb293 Minor cleanup of complete_param_for_command 2022-06-19 11:23:10 -07:00
ridiculousfish
17bd7d0e40 Switch completion_request_options_t from a list of flags to a struct
This is simpler and allows potentially hanging more fields off of it
later.
2022-06-19 11:23:10 -07:00
Fabian Boehm
7d3127ac2b Use variable 2022-06-16 18:43:57 +02:00
Fabian Boehm
8f08fe80fd Restyle codebase
Not a lot of changes, tbh
2022-06-16 18:43:28 +02:00
Fabian Boehm
6e0653af93 status fish-path: Remove "(deleted)" suffix
Fixes #9018.
2022-06-16 16:36:05 +02:00
Fabian Boehm
cf8b51b2a5 Use bool instead of int 2022-06-16 15:48:46 +02:00
Fabian Boehm
f41e41026c echo: Use convert_digit
Simply removes some duplicated code, no functional change.
2022-06-16 15:43:46 +02:00
Fabian Boehm
90e763b279 printf: Remove duplicated conversion functions 2022-06-16 15:43:46 +02:00
Fabian Boehm
89996c0c8a Remove debug_shared
The last remnant of the old debug system, this was only used in
show_stackframe.

Because that's only ever called with an "E" level currently I've
removed the level argument entirely. If it's needed we'd have to pass
a flog category here.
2022-06-16 15:43:42 +02:00
David Adam
0431f21bb2 docs: list reserved keywords 2022-06-16 19:45:55 +10:00
Fabian Boehm
7810f4e8a1 set: Only warn about uvar shadowing if the set succeeded
Otherwise there's really no point in doing so - we'd tell you that a
universal $status is shadowing a global, but we haven't actually
created one!
2022-06-13 20:53:15 +02:00
Fabian Boehm
d00a2db5f1 Check for interactive session correctly for no-config bindings
This only looked for "--interactive", and failed when implicitly interactive.
2022-06-13 17:17:29 +02:00
ridiculousfish
9f2cc4df36 Save the screen status more often
The fix for #3481 caused us to save the screen status after external
commands were run, fixing an unnecessary abandon-line when switching
modes. But we may also run commands not directly as part of a binding,
but instead via an on-variable event, e.g. for fish_bind_mode.

Extend this fix to all bindings, guarded by changes to exec_count. Now
any time an external command runs as part of a binding we should pick up
changes to the tty and not abandon the line.

Fixes #3481 again.
2022-06-12 13:16:29 -07:00
ridiculousfish
480f44cd0f Stop removing unfired one-shot handlers
In b0084c3fc4, we refactored out event handlers get removed. But this
also caused us to remove "one-shot" handlers even if they have not yet
been fired. Fix this.
2022-06-06 12:18:29 -07:00
ridiculousfish
b8ad117e87 Save the screen status after running command bindings
This concerns running a key binding which invokes a command. If that
command modifies the tty, then fish will spot the modification later and
then react to it by redrawing the prompt. However tty modifications may
be benign or desirable; for example switching the cursor from a line to
a block. Fix this by re-fstating the tty after running external
commands.

Fixes #3481
2022-06-06 11:47:27 -07:00
ridiculousfish
299ed9f903 Allow 'commandline' to set the commandline from the prompt
This means that running `commandline foo` will indeed set the text of
the command line to `foo`; it won't get cleared immediately.

Fixes #8807
2022-06-04 15:33:55 -07:00
SeekingBlues
cf620c829b Improve newline behavior of kill-whole-line
Previously, `kill-whole-line` kills the line and its following
newline. This is insufficient when we are on the last line, because
it would not actually clear the line. The cursor would stay on the
line, which is not the correct behavior for bindings like `dd`.

Also, `cc` in vi-mode used `kill-whole-line`, which is not correct
because it should not remove any newlines. We have to introduce
another special input function (`kill-inner-line`) to fix this.
2022-06-04 13:45:25 -07:00
ridiculousfish
c0c108c870 Clean up a stale comment 2022-06-04 11:43:28 -07:00
ridiculousfish
0e2966d6dd Remove complete_is_valid_option/argument declarations
These functions don't exist any more; remove them. No functional change
here.
2022-06-02 21:41:14 -07:00
ridiculousfish
8ff07d46c2 add_option to take new option by rvalue reference
Saves some allocations/copying. No functional change here.
2022-06-02 17:25:59 -07:00
Fabian Homborg
e2edc5f899 path: Add missing newlines to errors 2022-06-01 19:57:30 +02:00
ridiculousfish
b4cc30530d Use a singly-linked list for completion options
When the user adds a completion for a command, we push it to the front
of the completion list so it appears first; for that reason we don't
want to use a vector. However we can do better than std::list; try using
std::forward_list which is singly linked. No functional change here (but
we will see if this breaks any old platforms in which case it's fine to
revert this).
2022-06-01 10:02:09 -07:00
ridiculousfish
9fa8fa5165 Use a map instead of a set for completions
Prior to this change, the list of completions was stored as a
std::unordered_set, using some funny comparators and suspicious
const_cast to make it map-like. Use a real map instead, simplifying
the code. No functional change here.
2022-06-01 10:02:09 -07:00
ridiculousfish
46678f2eac complete_add to take const wcstring& instead of const wchar_t *
An oversight that this wasn't done earlier. No functional change here.
2022-06-01 10:02:09 -07:00
ridiculousfish
738a6df77d Switch complete_flags_t to uint8 and stop skipping 1<<1 2022-06-01 10:02:09 -07:00
ridiculousfish
4e42740ca3 Propertly type flags arguments
Instead of `int flags` write `complete_flags_t flags`, etc.
No functional change here.
2022-06-01 10:02:09 -07:00
ridiculousfish
1127d7d68f clang-format C++ files
No functional change (hopefully!)
2022-06-01 10:02:09 -07:00
ridiculousfish
f45e16e59d Try to rationalize universal variable syncing
Prior to this commit, setting a universal variable may trigger syncing
against the file which will modify other universal variables. But if we
want to support multiple environments we need the parser to decide when to
sync uvars. Shift the decision of when to sync to the parser itself. When a
universal variable is modified, now we just set a flag and it's up to the
(main) parser when to pick it up. This is hopefully just a refactoring with
no user-visible changes.
2022-05-30 14:09:06 -07:00
Fabian Homborg
64b34c8cda Allow complete to have multiple conditions
This makes it so `complete -c foo -n test1 -n test2` registers *both*
conditions, and when it comes time to check the candidate, tries both,
in that order. If any fails it stops, if all succeed the completion is offered.

The reason for this is that it helps with caching - we have a
condition cache, but conditions like

```fish
test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] length

test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] sub
```

defeats it pretty easily, because the cache only looks at the entire
script as a string - it can't tell that the first `test` is the same
in both.

So this means we separate it into

```fish
complete -f -c string -n "test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] length" -s V -l visible -d "Use the visible width, excluding escape sequences"
+complete -f -c string -n "test (count (commandline -opc)) -ge 2" -n "contains -- (commandline -opc)[2] length" -s V -l visible -d "Use the visible width, excluding escape sequences"
```

which allows the `test` to be cached.

In tests, this improves performance for the string completions by 30%
by reducing all the redundant `test` calls.

The `git` completions can also greatly benefit from this.
2022-05-30 20:47:14 +02:00
Fabian Boehm
4612343d6e
Merge pull request #8958 from faho/builtin-path
This adds a path builtin to deal with paths.

It offers the following subcommands:

    filter to go through a list of paths and only print the ones that pass some filter - exist, are a directory, have read permission, ...
    is as a shortcut for filter -q to only return true if one of the paths passed the filter
    basename, dirname and extension to print certain parts of the path
    change-extension to change the extension to a different one (as a string operation)
    normalize and resolve to canonicalize the paths in various flavors
    sort to sort paths, also only using the basename or dirname as a key

The definition of "extension" here was carefully considered and should line up with how extensions are actually used - ~/.bashrc doesn't have an extension, but ~/.conf.d does (".d").

These subcommands all compose well - they can read from arguments or stdin (like string), they can use null-delimited input or output (input is autodetected - if a NULL happens in the first PATH_MAX bytes it switches automatically).

It is both a failglob exception (so like set if a glob passed to it fails it just doesn't get any arguments for it instead of triggering an error), and passes output to command substitution buffers explicitly split (like string split0) so newlines are easy to handle.
2022-05-29 20:15:03 +02:00
Fabian Homborg
67b0860fe7 Rename sort --invert to sort --reverse/-r
To match sort(1).
2022-05-29 17:53:03 +02:00
Fabian Homborg
c5aa796d91 Invert takes no argument 2022-05-29 17:48:40 +02:00
Fabian Homborg
c6bffe7ceb Clarify comment for resolve 2022-05-29 17:48:40 +02:00
Fabian Homborg
1d4d238577 Rename func to keyfunc 2022-05-29 17:48:40 +02:00
Fabian Homborg
8e38ee884f Undo "+=" thing
oh no this made no sense given that it was *prepending* to `rest`.
2022-05-29 17:48:40 +02:00
Fabian Homborg
00949fccda Rename --what to --key
More sorty, less generic.
2022-05-29 17:48:40 +02:00
Fabian Homborg
3991af9ed6 Use += instead of temporaries
clang-tidy explains this is better. I hate C++.
2022-05-29 17:48:40 +02:00
Fabian Homborg
633fd5000e Remove useless c_str 2022-05-29 17:48:40 +02:00
Fabian Homborg
b9bd0ce3a3 Use path_apply_working_directory
Using getcwd is naughty here because we want to separate these things
in future.
2022-05-29 17:48:40 +02:00
Fabian Homborg
e088c974dd Fix path filter --invert
This would still remove non-existent paths, which isn't a strict
inversion and contradicts the docs.

Currently, to only allow paths that exist but don't pass a type check,
you'd have to filter twice:

path filter -Z foo bar | path filter -vfz

If a shortcut for this becomes necessary we can add it later.
2022-05-29 17:48:12 +02:00
Fabian Homborg
a9034610e1 Fix --invert long form 2022-05-29 17:48:12 +02:00
Fabian Homborg
bc3d3de30a Also prepend "./" for filter if a filename starts with "-"
This is now added to the two commands that definitely deal with
relative paths.

It doesn't work for e.g. `path basename`, because after removing the
dirname prepending a "./" doesn't refer to the same file, and the
basename is also expected to not contain any slashes.
2022-05-29 17:48:12 +02:00
Fabian Homborg
c88f648cdf Add sort --unique 2022-05-29 17:48:12 +02:00
Fabian Homborg
4fec045073 sort: Use a stable sort
This allows e.g. sorting first by dirname and then by basename.
2022-05-29 17:48:12 +02:00
Fabian Homborg
640bd7b183 extension: Print empty entry if there is no extension
Because we now count the extension including the ".", we print an
empty entry.

This makes e.g.

```fish
set -l base (path change-extension '' $somefile)
set -l ext (path extension $somefile)
echo $base$ext
```

reconstruct the filename, and makes it easier to deal with files with
no extension.
2022-05-29 17:48:12 +02:00
Fabian Homborg
5cce6d01ad resolve: Normalize
This means "../" components are cancelled out even after non-existent
paths or files.

(the alternative is to error out, but being able to say `path resolve
/path/to/file/../../` over `path resolve (path dirname
/path/to/file)/../../` seems worth it?)
2022-05-29 17:48:11 +02:00
Fabian Homborg
dfded633c6 Fix woption 2022-05-29 17:48:11 +02:00
Fabian Homborg
b961afed49 normalize: Add "./" if a path starts with a "-" 2022-05-29 17:48:11 +02:00
Fabian Homborg
9fdfad1d45 WIP Add path sort
This sorts paths by basename, dirname or full path - in future
possibly size or age.

It takes --invert to invert the sort and "--what=basename|dirname|..."
to specify what to sort

This can be used to implement better conf.d sorting, with something
like

```fish
set -l sourcelist
for file in (path sort --what=basename $__fish_config_dir/conf.d/*.fish $__fish_sysconf_dir/conf.d/*.fish $vendor_confdirs/*.fish)
```

which will iterate over the files by their basename. Then we keep a
list of their basenames to skip over anything that was already
sourced, like before.
2022-05-29 17:48:11 +02:00
Fabian Homborg
e429f76e9f append_with_separation: Default to wanting a newline
The recent change to skip the newline for `string` changed this, and
it also hit builtin path (which is in development separately, so it's
not like it broke master).

Let's pick a good default here.
2022-05-29 17:48:11 +02:00
Fabian Homborg
d13ba046b0 resolve: Use the new real path
This failed for

/bin/foo/bar

if /bin is a symlink to /usr/bin and foo doesn't exist.

It returned /bin/foo/bar instead of the correct /usr/bin/foo/bar.
2022-05-29 17:48:11 +02:00
Fabian Homborg
2b8bb5bd7f path: Rename "real" to "resolve" 2022-05-29 17:48:11 +02:00
Fabian Homborg
479fde27d7 path: Make path real "work" with nonexistent paths
This just goes back until it finds an existent path, resolves that,
and adds the normalized rest on top.

So if you try

/bin/foo/bar////../baz

and /bin exists as a symlink to /usr/bin, it would resolve that, and
normalize the rest, giving

/usr/bin/foo/baz

(note: We might want to add this to realpath as well?)
2022-05-29 17:48:11 +02:00
Fabian Homborg
4fced3ef5a Remove sticky filter
This isn't super useful, and having a caveat in the docs that it might
cause the entire filter to fail is awkward.

So just remove it.
2022-05-29 17:48:11 +02:00
Fabian Homborg
1c1e643218 WIP path: Make extensions start at the "."
This includes the "." in what `path extension` prints.

This allows distinguishing between an empty extension (just `.`) and a
non-existent extension (no `.` at all).
2022-05-29 17:48:11 +02:00
Fabian Homborg
17a8dd8f62 Move path to src/builtins 2022-05-29 17:48:11 +02:00
Fabian Homborg
ce7281905d Switch strip-extension to change-extension
This allows replacing the extension, e.g.

    > path change-extension mp4 foo.wmv
    foo.mp4
2022-05-29 17:48:11 +02:00
Fabian Homborg
00ed0bfb5d Rename base/dir to basename/dirname
"dir" sounds like it asks "is it a directory".
2022-05-29 17:48:11 +02:00
Fabian Homborg
268a9d8db3 Prevent some copies 2022-05-29 17:48:11 +02:00
Fabian Homborg
359b487793 Use wchar overload of find_last_of
C++ is a silly language.
2022-05-29 17:48:11 +02:00
Fabian Homborg
8b27a69ae4 Reword comments to be about path, not string
No idea why this mentioned string so much.
2022-05-29 17:48:11 +02:00
Fabian Homborg
efb3ae6d49 Add path is shorthand for path filter -q
This replaces `test -e` and such.
2022-05-29 17:48:11 +02:00
Fabian Homborg
b23548b2a6 Add "-rwx" and "-fdl" shorthand
These are short flags for "--perm=read" and "--type=link" and such.

Not every type or permission has a shorthand - we don't want "-s" for
"suid". So just the big three each get one.
2022-05-29 17:48:11 +02:00
Fabian Homborg
48ac2ea1e0 Address feedback 2022-05-29 17:48:11 +02:00
Fabian Homborg
3f7e125b57 Also give path nullglob behavior
This is needed because you might feasibly give e.g. `path filter`
globs to further match, and they might already present no results.
It's also well-handled since path simply does nothing if given no paths.
2022-05-29 17:48:11 +02:00
Fabian Homborg
39d4a7d13a Actually name the switches "--null-in" and out
These were officially called "--null-input", but I just used
"--null-in" everywhere, which worked because getopt allows unambiguous abbreviations.

But since *I* couldn't keep it straight and the "put" is just
superfluous, let's remove it.
2022-05-29 17:48:11 +02:00
Fabian Homborg
0ff25d581c Infer splitting on NULL if one appears in the first PATH_MAX bytes
This is theoretically sound, because a path can only be PATH_MAX - 1
bytes long, so at least the PATH_MAXest byte needs to be a NULL.

The one case this could break is when something has a NULL-output mode
but doesn't bother printing the NULL for only one path, and that path
contains a newline. So we leave --null-in there, to force it on.
2022-05-29 17:48:11 +02:00
Fabian Homborg
3a9c52cefa Add --invert to filter/match
Like `grep -v`/`string match -v`.
2022-05-29 17:48:11 +02:00
Fabian Homborg
f6fb347d98 Add "path" builtin
This adds a "path" builtin that can handle paths.

Implemented so far:

- "path filter PATHS", filters paths according to existence and optionally type and permissions
- "path base" and "path dir", run basename and dirname, respectively
- "path extension PATHS", prints the extension, if any
- "path strip-extension", prints the path without the extension
- "path normalize PATHS", normalizes paths - removing "/./" components
- and such.
- "path real", does realpath - i.e. normalizing *and* link resolution.

Some of these - base, dir, {strip-,}extension and normalize operate on the paths only as strings, so they handle nonexistent paths. filter and real ignore any nonexistent paths.

All output is split explicitly, so paths with newlines in them are
handled correctly. Alternatively, all subcommands have a "--null-input"/"-z" and "--null-output"/"-Z" option to handle null-terminated input and create null-terminated output. So

    find . -print0 | path base -z

prints the basename of all files in the current directory,
recursively.

With "-Z" it also prints it null-separated.

(if stdout is going to a command substitution, we probably want to
skip this)

All subcommands also have a "-q"/"--quiet" flag that tells them to skip output. They return true "when something happened". For match/filter that's when a file passed, for "base"/"dir"/"extension"/"strip-extension" that's when something about the path *changed*.

Filtering
---------

`filter` supports all the file*types* `test` has - "dir", "file", "link", "block"..., as well as the permissions - "read", "write", "exec" and things like "suid".

It is missing the tty check and the check for the file being non-empty. The former is best done via `isatty`, the latter I don't think I've ever seen used.

There currently is no way to only get "real" files, i.e. ignore links pointing to files.

Examples
--------

> path real /bin///sh
/usr/bin/bash

> path extension foo.mp4
mp4

> path extension ~/.config
  (nothing, because ".config" isn't an extension.)
2022-05-29 17:48:11 +02:00
ridiculousfish
cf2ca56e34 Allow trapping SIGINT and SIGTERM in scripts
This teaches `--on-signal SIGINT` (and by extension `trap cmd SIGINT`)
to work properly in scripts, not just interactively. Note any such
function will suppress the default behavior of exiting. Do this for
SIGTERM as well.
2022-05-28 17:44:13 -07:00
ridiculousfish
d83e51a8a2 Rename check_cancel_from_fish_signal to fish_is_unwinding_for_exit
"unwinding_for_exit" mixes up SIGHUP handling and also the exit builtin;
this is still pretty messy.
2022-05-28 16:35:40 -07:00
ridiculousfish
d88bee3a57 Teach fish_test_helper to sigint_self
Preparation for more tests around signals.
2022-05-28 16:08:17 -07:00
ridiculousfish
79255dfe9b Make s_observed_signals accurate
s_observed_signals is used to inform the signal handler which signals may
have --on-signal functions attached to them, as an optimization. Prior to
this change it was latched: once we started observing a signal we assume we
will keep observing that signal. Make it properly increment and decrement,
in preparation for making trap work non-interactively.
2022-05-28 14:45:13 -07:00
Fabian Homborg
65b9c26fb4 complete: Print better error for -x -F
-x is a cheesy shortcut for `-rf`, so it conflicts with `-F`.

Fixes #8818.
2022-05-26 14:17:15 +02:00
ridiculousfish
ec6fd088f2 Migrate initializing CMD_DURATION from reader to env
This puts the initialization of CMD_DURATION at home with other
default-initialized variables. No user-visible change expected from
this.
2022-05-22 12:29:51 -07:00
ridiculousfish
4d3261dadc Bravely stop initializing the term size from reader_init
The terminal size in all cases should have been initialized in env_init,
so no reason to do it here. No user visible change expected from this.
2022-05-22 12:28:05 -07:00
Fabian Homborg
8f9348ee53 Make eval a reserved keyword
Like `set` and `read` before it, `eval` can be used to set variables,
and so it can't be shadowed by a function without loss of
functionality.

So this forbids it.

Incidentally, this means we will no longer try to autoload an
`eval.fish` file that's left over from an old version, which would
have helped with #8963.
2022-05-18 18:47:10 +02:00
ridiculousfish
ba7c84fe3b Add an error message when cd fails with ELOOP
This error is emitted if you try to `cd` into a symlink loop or very
long chain.
2022-05-15 11:58:40 -07:00
ridiculousfish
1893204067 event_fire_generic to take its arguments directly
Just mild refactoring, no functional change.
2022-05-14 10:33:47 -07:00
ridiculousfish
b0084c3fc4 Refactor event handler firing
This concerns what happens if one event handler removes another, when
both are responding to the same event. Previously we had a "double lock"
where we would traverse the list twice. Now track directly in the
handler when it is removed; this simplifies the code a lot. No
functional changes expected here.
2022-05-14 10:33:47 -07:00
ridiculousfish
31567cea63 Mild refactoring of how received signals are stored
No functional change here, just some cleanup.
2022-05-14 10:33:47 -07:00
Johannes Altmanninger
bfd5e8dfbe Do not stomp token if tab-expansion of wildcards exceeds limit or is canceled
Hitting tab on "echo **" will often result in more than 256 matches.
Commit 143757e8c (Expand wildcards on tab, 2021-11-27) describes this scenario

> If the expansion would produce more than 256 items, we flash the command
> line and do nothing, since it would make the commandline overfull.

Yet we actually erase the "**" token, which seems wrong since we already
flash the command line. Fix this, at the cost of making the code a bit uglier.

I tried to write a test in tests/pexpects/wildcard_tab.py but that doesn't
seem to work because pexpect provides only a "dumb" terminal.  I wonder if we
can test what we write to the screen without depending on a terminal emulator.
2022-05-14 14:31:30 +02:00
Fabian Homborg
32aef855b7 Initialize variable
gcc 12.1 complains this might be used uninitialized.
2022-05-11 21:28:26 +02:00
ridiculousfish
11cfa85a2a Correctly fire process_exit events even if the job has not yet exited
c4fb857dac (in 3.4.1) introduced a regression where process_exit
events would only fire once the job itself is complete. Allow
process_exit events to fire before that. Fixes #8914.
2022-05-08 15:27:25 -07:00
ridiculousfish
9efde28350 Revert "Optimize exit event generation"
This reverts commit 1b6ef6670f.

This optimimzation did not carry its weight in complexity.
2022-05-08 15:08:28 -07:00
ridiculousfish
1f7d4c7441 Fix CPU usage percentage calculation as reported by jobs
This rationalizes our types for computing CPU usage percentage and
fixes the computation. Fixes #8919.
2022-05-07 15:29:56 -07:00
Fabian Homborg
770a2582de Give special error for when file failed to execute but is executable
This is after we've tried to find the interpreter, so we would already
have complained about e.g. /usr/bin/pthyon not existing.

Realistically the most common case here is things that don't start
with a shebang like ELFs. Writing special extraction code here is
overkill, and I can't see a good function to do it for us.

But this should point you in the right direction.

Fixes #8938
2022-05-07 14:53:03 +02:00
Fabian Boehm
dd95e0a0ea
Setup $USER if passwd for $USER has different uid (#8879)
This gets the passwd entry for $USER (if it is set). If that gives the
same uid that geteuid() gives us, we assume the data is correct.

If not, we reset $USER (and $HOME if it's empty) from the passwd value for our UID.

This allows using $USER in a prompt even if you've `su`d. Bash gets around this by having a special escape in its $PS1 DSL that checks passwd instead.

Fixes #8583
2022-05-02 17:15:52 +02:00
Johannes Altmanninger
71ff8780c6 Revert "Fix inconsistent noexcept-ness between header/implementation"
This reverts commit ccb6cb1abe.

CI fails with

    /home/runner/work/fish-shell/fish-shell/src/autoload.cpp:148:1: error: function ‘autoload_t::autoload_t(autoload_t&&)’ defaulted on its redeclaration with an exception-specification that differs from the implicit exception-specification ‘’
      148 | autoload_t::autoload_t(autoload_t &&) noexcept = default;
          | ^~~~~~~~~~
    make[2]: *** [CMakeFiles/fishlib.dir/build.make:96: CMakeFiles/fishlib.dir/src/autoload.cpp.o] Error 1
    make[1]: *** [CMakeFiles/Makefile2:369: CMakeFiles/fishlib.dir/all] Error 2
    make: *** [Makefile:139: all] Error 2

Not sure what's wrong - it compiles fine on my machine. Will check later.
2022-04-24 21:46:01 +02:00
Johannes Altmanninger
ccb6cb1abe Fix inconsistent noexcept-ness between header/implementation
Even though we disable exceptions, we use noexcept in some
places to enable certain optimizations in std::vector, see
https://en.cppreference.com/w/cpp/utility/move_if_noexcept.

Some methods have noexcept only at their declaration (or only at the
definition).  This will be an error when compiling with "g++ -std=c++17". Make
both signatures match.
2022-04-24 21:31:51 +02:00
ridiculousfish
ed78fd2a5f Rationalize path-getting
This cleans up the path_get_path function which is used to resolve a
command name against $PATH, by removing the dependence on errno and
being explicit about which error is returned.

Should be no user-visible change here.
2022-04-23 15:24:27 -07:00
Fabian Homborg
4d8de32a16 Tests: Skip autosuggest_special harder
For some reason this still crashed? WTF?
2022-04-17 13:35:09 +02:00
Fabian Homborg
12e6a41423 Tests: Skip autosuggest_suggest_special under ASAN
This crashes on Ubuntu 20.04, which Github Actions uses.
2022-04-17 12:06:09 +02:00
ridiculousfish
bd9c6a64e3 Be careful to not touch curses variables if cur_term is null
Curses variables like `enter_italics_mode` are secretly defined to
dereference through the `cur_term` variable. Be sure we do not read or
write these curses variables if cur_term is NULL. See #8873, #8875.

Add a regression test.
2022-04-16 13:26:56 -07:00
ridiculousfish
1da952450f Migrate the "Apple Term hacks" from set_color to init_curses
Apple's terminfo has missing support for enter_italics_mode,
exit_italics_mode, and enter_dim_mode. Previously we would hack in such
support in set_color; migrate that to init_curses so we do it up-front
instead of opportunistically.
2022-04-16 13:26:42 -07:00
ridiculousfish
4b96dd9908 Mild refactoring of initialize_curses_using_fallbacks
No functional change here.
2022-04-16 12:45:25 -07:00
ridiculousfish
3d98fd4308 clang-format env.cpp and env_dispatch.cpp 2022-04-16 12:22:44 -07:00
ridiculousfish
1a4b1c3298 Remove the is_first parameter from tok_is_string_character
This parameter is unused now that carets are no longer special, per
7f905b082.
2022-04-16 10:47:01 -07:00
Fabian Homborg
2fa51f1843 Add $EUID and use it in fish_is_root_user
Fixes #8866
2022-04-15 15:58:39 +02:00
Fabian Homborg
c2bca939be Let stderr-nocaret description say it's read-only 2022-04-15 13:42:38 +02:00
Fabian Homborg
49eb07f98f Enable ampersand-nobg-in-token by default
To recap, this means `&` in the middle of a word no longer
backgrounds.

So:

```fish
echo foo&bar # prints foo&bar
echo foo& bar # backgrounds an echo that prints "foo" and runs "bar"
```
2022-04-15 13:42:38 +02:00
Fabian Homborg
7f905b082d Remove caret redirection code
It's dead, Jim.
2022-04-15 13:42:38 +02:00
Fabian Homborg
74be3e847f Force stderr-nocaret feature flag on
This can no longer be changed. If "no-stderr-nocaret" is in
$fish_features it will simply be ignored.

The "^" redirection that was deprecated in fish 3.0 is now gone for good.

Note: For testing reasons, it can still be set _internally_ by running
"feature_flags_t::set". We simply shouldn't do that.
2022-04-15 13:42:38 +02:00
Fabian Homborg
59c2ed9acf Turn on regex-easyesc by default
This was introduced in fish 3.1. It removes a superfluous round of
escaping in the replacement for `string replace -r`.

Part of #8857.
2022-04-15 13:42:38 +02:00
Michael Jarvis
970cf45166 Remove test for italics_mode and dim_mode on Apple
This resolves an issue where fish crashes with SIGSEGV if the TERM environment
variable is not set.

See:
- https://github.com/fish-shell/fish-shell/issues/8873
- https://github.com/microsoft/vscode/issues/147320
2022-04-14 15:05:13 +02:00
Fabian Homborg
fd942e04cd Also change the MAX_ARG_STRLEN message
Missed in 1326c286fa
2022-04-13 17:07:42 +02:00
Fabian Homborg
a5ce01cc38 Print a hint if the exported variables appear too large
If we get an E2BIG while executing a process, we check how large the
exported variables are. We already did this, but then immediately
added it to the total.

So now we keep the tally just for the variables around, and if it's
over half (which is an atypical value if your system has an ARG_MAX of
2MB), we mention that in the error.

Figuring out which variable is too big (in case it's just one) is probably too complicated,
but we can at least complain if things seem suspect.

Untested because I don't know *how* to do so portably
2022-04-12 19:41:26 +02:00
Fabian Homborg
1326c286fa Reword ARG_MAX error messages
We're the shell. The "environment list" is our exported variables
2022-04-12 19:37:15 +02:00
Fabian Homborg
29e02ac7a5 Add missing argument to MAX_ARG_STRLEN error
This was missed in b395b33776.

No need to relnote, it's trivial
2022-04-12 15:23:45 +02:00
ridiculousfish
143757e8c6 Expand wildcards on tab
Prior to this change, if you tab-completed a token with a wildcard (glob), we
would invoke ordinary completions. Instead, expand the wildcard, replacing
the wildcard with the result of expansions. If the wildcard fails to expand,
flash the command line to signal an error and do not modify it.

Example:

    > touch file(seq 4)
    > echo file*<tab>

becomes:

    > echo file1 file2 file3 file4

whereas before the tab would have just added a space.

Some things to note:

1. If the expansion would produce more than 256 items, we flash the command
line and do nothing, since it would make the commandline overfull.

2. The wildcard token can be brought back through Undo (ctrl-Z).

3. This only kicks in if the wildcard is in the "path component
   containing the cursor." If the wildcard is in a previous component,
   we continue using completions as normal.

Fixes #954.
2022-04-10 13:53:22 -07:00
ridiculousfish
1023d322e5 Rationalize tilde unexpansion
When fish expands a string that starts with a tilde, like `~/stuff/*`, it
first must resolve the tilde (e.g. to the user's home directory) before
passing it to wildcard expansion. The wildcard expansion will produce full
paths like `/home/user/stuff/file`. fish then "unexpands" the home directory
back to a tilde.

Previously this was only used during completions, but in the next commit
we plan to use it for string expansions as well.

Rationalize this behavior by adding an explicit flag to request it and
explain some subtleties about completions.
2022-04-10 13:41:21 -07:00
ridiculousfish
2d945afd58 Factor applying completions out of handle_readline_command
The handle_readline_command function is getting unwieldy, so factor it
better to reduce its length. No functional change here.
2022-04-10 13:41:21 -07:00
ridiculousfish
cb027bfdc0 str2hex to work in std::string instead of malloc
Reimplement a test function using nicer C++ types. No functional change here.
2022-04-09 15:19:18 -07:00
ridiculousfish
031b26584b Revert "input.cpp: remove unused describe_char()"
This reverts commit 99cfca8498.

describe_char is quite useful for debugging.
2022-04-09 13:48:03 -07:00
ridiculousfish
1c7b934402 Revert "Replace some simple loops with STL algorithms"
This commit was problematic for a few reasons:

1. It silently changed the behavior of argparse, by switching which
characters were replaced with `_` from non-alphanumeric to punctuation.
This is a potentially breaking change and there doesn't appear to be any
justification for it.

2. It combines a one-line if with a multi-line else which we should try
   to avoid.

This reverts commit 63bd4eda55.
This reverts commit 4f835a0f0f.
2022-04-09 12:12:16 -07:00
ridiculousfish
735962d306 Remove macros for block descriptions
These macros were historically used only in internal error messages which
should never happen! Now we are able to enforce they never happen at
compile time so we can remove them.

No functional change here.
2022-04-09 11:42:58 -07:00
Aaron Gyes
0118eafee1 Remove unused functions, members (and a variable)
If we ever need any of these... they're in this commit:

fish_wcswidth_visible()
status_cmd_opts_t::feature_name
completion_t::is_naturally_less_than()
parser_t::set_empty_var_and_fire()
parser_t::get_block_desc()
parser_keywords_skip_arguments()
parser_keywords_is_block()
job_t::has_internal_proc()
fish_wcswidth_visible()
2022-04-09 10:10:44 -07:00
Aaron Gyes
63bd4eda55 iswpunct not available in std:: namespace on some machines
Fixes the tests
2022-04-08 19:54:42 -07:00
Aaron Gyes
4f835a0f0f Replace some simple loops with STL algorithms
src/builtins/argparce.cpp: replace_if
src/builtins/set.cpp: count_if
src/topic_monitor.h: any_of
2022-04-08 17:59:09 -07:00
Aaron Gyes
7d1d43744a trivial cleanup 2022-04-08 17:59:09 -07:00
Aaron Gyes
99cfca8498 input.cpp: remove unused describe_char() 2022-04-08 17:59:09 -07:00
Aaron Gyes
9c1b3d6712 fix cppcheck missing return errors 2022-04-08 17:59:09 -07:00
Fabian Homborg
b0c2d083d6 set: Add special error for set foo=bar
Fixes #8694

Only for setting, erasing with a value makes no sense.
2022-04-08 16:50:34 +02:00
Fabian Homborg
31e2476fc8 Clarify that the variable/mode *name* is invalid
When you do

```fish
set foo-bar baz
```

"foo-baz" isn't usable as a variable *name*. When you just say the
"variable" is invalid that could also be interpreted to be a special
type of variable or something.
2022-04-08 16:38:46 +02:00
Aaron Gyes
7031a736a7 don't check if unsigned el->position() < 0 2022-04-07 10:16:26 -07:00
Aaron Gyes
77d02c1bd6 parse_execution: remove unused 'job' parameters 2022-04-07 09:36:54 -07:00
Aaron Gyes
8ea2be2648 decrease scope of a couple variables, prefix incr non-primitives 2022-04-07 09:25:16 -07:00
Aaron Gyes
5861358238 const size_t vals[4] 2022-04-07 09:25:16 -07:00
Aaron Gyes
b514ec5fe6 append_narrow_buffer takes const reference 2022-04-07 09:25:16 -07:00
Aaron Gyes
c06d85d175 proc.cpp: remove unused s_is_within_fish_initialization 2022-04-07 09:25:16 -07:00
Johannes Altmanninger
4b5b56452b Make string syntax error location a bit more precise
String tokens are subdivided by command substitutions. Some syntax errors
can occur in the gap between two command substitutions. Make the caret point
to the start of that gap, instead of the token start.
2022-04-03 16:34:46 +02:00
Johannes Altmanninger
e717b13e75 Fix spurious syntax error on escaped $@ inside quoted command substitution
We detect use of unsupported features like $@ by scanning string tokens
as a whole. With quoted command substitution, this has false positives,
as reported in [1]. We already recursively run the same error checks on
command substitutions, so limit the remaining checks to the gaps in-between
command substitutions.

[1]: 5f94dfd094/.config/fish/README/bug.md (cannot-use-dollar-anchor-in-sed-regex-in-quoted-command-substitution)
2022-04-03 16:18:47 +02:00
Johannes Altmanninger
3e3f507012 Fix regression expanding \$()
When expanding command substitutions, we use a naïve way of detecting whether
the cmdsub has the optional leading dollar. We check if the last character was
a dollar, which breaks if it's an escaped dollar.  We wrongly expand
\$(echo "") to the empty string. Fix this by checking if the dollar was escaped.

The parse_util_* functions have a bunch of output parameters. We should
return a parameter bag instead (I think I tried once and failed).
2022-04-03 15:54:08 +02:00
Johannes Altmanninger
1b668f5675 Don't use results of quoted command substitution in adjacent variable expansion
Given

    set var a
    echo "$var$(echo b)"

the double-quoted string is expanded right-to-left, so we construct an
intermediate "$varb".  Since the variable "varb" is undefined, this wrongly
expands to the empty string (should be "ab"). Fix this by isolating the
expanded command substitution internally. We do the same when handling
unquoted command substitutions.

Fixes #8849
2022-04-03 11:24:55 +02:00
ridiculousfish
1a0b1ae238 Rename indent test test_t to indent_test_t
This satifies VSCode's C++ extension which otherwise throws up a bogus
error. No functional change here.
2022-04-02 19:07:27 -07:00
ridiculousfish
a80e680125 Clean up woption
1. Bravely use a real enum for has_arg, despite the warnings.

2. Use some C++11 initializers so we don't have to pass an int for this
   parameter.

No functional change expected here.
2022-04-02 11:28:30 -07:00
ridiculousfish
002c2b6170 Correct a cast when measuring history file size
If the history file is larger than 4GB on a 32 bit system, fish will
refuse to read it. However the check was incorrect because it cast the
file size to size_t, which may be 32 bit. Switch to using uint64.
2022-04-01 10:25:05 -07:00
ridiculousfish
a91e1a8cab Revert "history_file_contents_t::create: remove constant comparison"
This reverts commit d7b4193978.

off_t may be wider than size_t on a 32 bit system so the comparison is
justified (though the cast is not).
2022-04-01 10:18:06 -07:00
Aaron Gyes
d7b4193978 history_file_contents_t::create: remove constant comparison
static_cast<unsigned long>(off_t len) is always < SIZE_MAX
2022-04-01 09:23:44 -07:00
ridiculousfish
338d587f2a Correct bug causing early teardown of fd_monitor
fd_monitor is used when an external command pipes into a buffer, e.g. for
command substitutions. It monitors the read end of the external command's
pipe in the background, and fills the buffer as data arrives. fd_monitor is
multiplexed, so multiple buffers can be monitored at once by a single
thread.

It may happen that there's no active buffer fill; in this case fd_monitor
wants to keep its thread alive for a little bit in case a new one arrives.
This is useful for e.g. handling loops where you run the same command
multiple times.

However there was a bug due to a refactoring which caused fd_monitor to
exit too aggressively. This didn't affect correctness but it meant more
thread creation and teardown.

Fix this; this improves the aliases.fish benchmark by about 20 msec.

No need to changelog this IMO.
2022-03-31 20:41:58 -07:00
ridiculousfish
a960a3cde6 Emit an error if time is used past the first command in a pipeline
Fixes #8841
2022-03-31 16:14:59 -07:00
ridiculousfish
247d4b2c8f Rename EXEC_ERR_MSG to INVALID_PIPELINE_CMD_ERR_MSG
This error message was used for more than exec.
No functional change here.
2022-03-31 15:49:15 -07:00
Fabian Homborg
f13979bfbb Move executable-check to C++
This was already apparently supposed to work, but didn't because we
just overrode errno again.

This now means that, if a correctly named candidate exists, we don't
start the command-not-found handler.

See #8804
2022-03-31 15:16:01 +02:00
Aaron Gyes
9c96986b36 set_color: only fixup sitm/ritm/dim if NULL/empty
So we'll skip the hack should someone have a fixed terminfo or
only do it on the first set_color command.
2022-03-28 11:26:17 -07:00
Fabian Homborg
cc689290cd Autoload: Call the parser directly instead of going via "subshell"
This used to call exec_subshell, which has two issues:

1. It creates a command substitution block which shows up in a stack
trace
2. It does much more work than necessary

This removes a useless "in command substitution" from an error message
in an autoloaded file, and it speeds up autoloading a bit (not
measurable in actual benchmarks, but microbenchmarks are 2x).
2022-03-27 09:35:12 +02:00
Fabian Homborg
7469495459 complete: Stop wcslen just to figure out if string is not empty 2022-03-25 16:15:28 +01:00
Fabian Homborg
351cd5bd4b set: Skip a wcslen 2022-03-25 16:06:10 +01:00
Fabian Homborg
bac2eef496 Remove useless use of wcslen 2022-03-25 16:06:10 +01:00
Fabian Homborg
42ea2758b6 Overload fish_wcstod for wcstring and length
This lets us skip wcslen a bunch
2022-03-25 16:06:10 +01:00
Fabian Homborg
fa1ecb8c67 reader: Some light stringification 2022-03-25 16:06:10 +01:00
Fabian Homborg
f98398b418 event: Pass name as wcstring
This passed a wchar_t, only to then construct a wcstring out of it.
Instead let's just pass it directly and move it.
2022-03-25 16:06:10 +01:00
ridiculousfish
ac888ac6af Migrate 'within_fish_init' to a parser-local variable
We need special handling when reporting backtraces for commands run
during startup, i.e. config.fish. Previously we had a global variable;
make it local to the parser to eliminate a global.

No functional change here.
2022-03-24 21:43:58 -07:00
David Adam
a7eebff916 ulimit: return a specific error if option is not supported by the OS 2022-03-24 10:23:04 +08:00
David Adam
8c4c526698 ulimit: add new limits from FreeBSD/NetBSD
Short option names are taken from sh for those platforms where possible.
2022-03-24 10:23:04 +08:00
David Adam
2c2b87af07 ulimit: add new limits from Linux
Short options are taken from prlimit(1) where appropriate.

Closes #8786.
2022-03-24 10:23:04 +08:00
David Adam
ee69a2467e ulimit: some corrections to descriptions and documentation 2022-03-24 10:23:04 +08:00
Fabian Homborg
2101dd4add Let nextd-or-forward-word binding move like normal forward_word
Broken in #8358, this caused nextd-or-forward-word to actually be
nextd-or-forward-bigword.

See #8790.
2022-03-22 22:09:42 +01:00
Fabian Homborg
1f997de8bf Fix job run flog
The arguments didn't match the format string.
2022-03-21 16:26:01 +01:00
ridiculousfish
d0d5c62ec7 Fix case-changing autosuggestions generated mid-token
This fixes a bug where a case-changing autosuggestion generated from the
middle of a token would append too much to the end of the token.

Fixes #8820
2022-03-20 20:16:01 -07:00
ridiculousfish
1763e7d3bc Remove some dead code
These functions were unused.
2022-03-20 14:48:44 -07:00
ridiculousfish
7b1321f9a1 Remove cancellation groups
Cancellation groups were meant to reflect the following idea: if you ran a
simple block:

    begin
        cmd1
        cmd2
    end

then under job control, cmd1 and cmd2 would get separate groups; however if
either exits due to SIGINT or SIGQUIT we also want to propagate that to the
outer block. So the outermost block and its interior jobs would share a
cancellation group. However this is more complex than necessary; it's
sufficient for the execution context to just store an int internally.

This ought not to affect anything user-visible.
2022-03-20 14:39:00 -07:00
Fabian Homborg
5926a75cc5 highlight: Also use the fallback variable if the main is empty
Currently, when a variable like $fish_color_command is set but empty:

    set -g fish_color_command

what happens is that highlight parses it and ends up with a "normal"
color.

Change it so instead it sees that the variable is empty and goes
on to check the fallback variable, e.g. fish_color_normal.

That makes it easier to make themes that override variables.

This means that older themes that expect an empty variable to be
"normal" need to be updated to set it to "normal".

Following from this, we could make writing .theme files easier by no
longer requiring them to list all variables with specific values.
Either the theme reader could be updated to implicitly set known color
variables to empty, or the themes could feature empty values.

See #8787.
2022-03-20 17:04:28 +01:00
ridiculousfish
3e5284aaf2 Stop restoring tty modes when run non-interactively
fish reads the tty modes at startup, and tries to restore them to the
original values on exit, to be polite. However this causes problems when
fish is run in a pipeline with another process which also messes with the
tty modes. Example:

    fish -c 'echo foo' | vim -

Here vim's manipulation of the tty would race with fish, and often vim
would end up with broken modes.

Only restore the tty if we are interactive. Fixes #8705.
2022-03-19 14:55:54 -07:00
ridiculousfish
df2cbe321c Refactor tty transfer to be more deliberate
This is a big cleanup to how tty transfer works. Recall that when job
control is active, we transfer the tty to jobs via tcsetpgrp().

Previously, transferring was done "as needed" in continue_job. That is, if
we are running a job, and the job wants the terminal and does not have it,
we will transfer the tty at that point.

This got pretty weird when running mixed pipelines. For example:

    cmd1 | func1 | cmd2

Here we would run `func1` before calling continue_job. Thus the tty
would be transferred by the nested function invocation, and also restored
by that invocation, potentially racing with tty manipulation from cmd1 or
cmd2.

In the new model, migrate the tty transfer responsibility outside of
continue_job. The caller of continue_job is then responsible for setting up
the tty. There's two places where this gets done:

1. In `exec_job`, where we run a job for the first time.

2. In `builtin_fg` where we continue a stopped job in the foreground.

Fixes #8699
2022-03-19 14:48:36 -07:00
ridiculousfish
3f585cddfc Refactor job pgroup assignment
This is a cleanup of job groups, rationalizing a bunch of stuff. Some
notable changes (none user-visible hopefully):

1. Previously, if a job group wanted a pgid, then we would assign it to the
   first process to run in the job group. Now we deliberately mark which
   process will own the pgroup, via a new `leads_pgrp` flag in process_t. This
   eliminates a source of ambiguity.

2. Previously, if a job were run inside fish's pgroup, we would set fish's
   pgroup as the group of the job. But this meant we had to check if the job
   had fish's pgroup in lots of places, for example when calling tcsetpgrp.
   Now a job group only has a pgrp if that pgrp is external (i.e. the job is
   under job control).
2022-03-19 14:06:18 -07:00
Fabian Homborg
0bc6a7b2ed
Make --no-config mode more comfortable (#8493)
* Turn on default bindings for --no-config mode

The fallback bindings are super awkward to use.

This was called out specifically in #7921, I'm going for the targeted
fix for now.

* Only change keybindings when interactive

That's also when we'd source them normally.
2022-03-17 19:02:12 +01:00
Fabian Homborg
ef28931293 Stop migrating legacy uvar paths
These were changed in fish 3.0 in December 2018.

This means upgrading from fish 2.7.1 or earlier to the next fish
version will require users to set their universal variable again.
2022-03-17 18:15:11 +01:00
Fabian Homborg
a7b80c9881 Remove misleading comment 2022-03-17 18:15:11 +01:00
Fabian Homborg
03c188086c Remove wcsndup and wcslcpy
We no longer use these anywhere.
2022-03-17 18:15:11 +01:00
Fabian Homborg
753f29df4c Stringify reformat_for_screen
This is the only usage of wcsndup, and we can just use wcstring::substr.
2022-03-17 18:15:11 +01:00
Fabian Homborg
534646f9d3 read: Actually only fire fish_read, not fish_prompt event
Fixes #8797.
2022-03-16 20:14:59 +01:00
Fabian Homborg
4e2ce0af4e pwd: Add newline to error message
This would keep the cursor on the same line, which is annoying.
2022-03-16 19:20:58 +01:00
Fabian Homborg
695e20c47f Fix build on NetBSD
This missed a change to "dir_remoteness_t" from bool

Fixes #8788
2022-03-14 18:13:39 +01:00
Fabian Homborg
a76ed9942d Fix tparm kludge
This just defines a constant to whichever tparm implementation we're
using (either the actual, working one the system provides, or our
kludge to paper over Solaris' inadequacies).

This means that there won't be so much ping-ponging of what "tparm"
stands for. "tparm" is the system's function. Only we don't use it,
just like we don't use wcstod directly.

Fixes #8780
2022-03-14 15:36:17 +01:00
Fabian Homborg
cd62771d12 read: Don't use chunking read with --line
Fixes a regression from #8552.
2022-03-14 08:04:35 +01:00
joao-vitor-sr
4ae4ea0169
New -n flag for string join. (#8774)
* New -n flag for string join command.

This is an argument that excludes empty result items. Fixes #8351

* New documentation for string-join.

The new argument --no-empty was added at string-join manpage.

* New completions for the new -n flag for string join.

* Remove the documentation of the new -n flag of string join0

The reason to remove this new argument in the join0 is that this flag basically doesn't make any difference in the join0.

* Refactor the validation for the string join.

The string join command was using the length of the argument, this commit changes the validation to use the empty function.

* Revert #4b56ab452

The reason for the revert is thath the build broke on the ubuntu in the Github actions.

* Revert #e72e239a1

The reason the compilation on GitHub broke is that the test was weird, it didn't even run it, Common CI systems are typically very very resource-constrained.

* Resolve conflicts in the string-join.rst.

* Resolve conflicts in the "string-join.rst".

commit #1242d0fd7 not fixed all conflicts.
2022-03-13 11:47:33 +01:00
Fabian Homborg
a7859191b2 Remove is_color_escape_seq
This is supposed to detect color escape sequences, to figure out how
long an escape sequence is, for use in width calculations.

However, the typical color sequences are already taken care of by
is_csi_style_escape_seq because they look like a csi sequence starting
with `\e[` and ending in `m`.

In the entire terminfo database shipped with ncurses 6.3, these are
the terminals that have non-csi color sequences:

at-color
atari-color
atari_st-color
d220-dg
d230-dg
d230c-dg
d430-dg
d430-unix
d430-unix-25
d430-unix-s
d430-unix-sr
d430-unix-w
d430c-dg
d430c-unix
d430c-unix-25
d430c-unix-s
d430c-unix-sr
d430c-unix-w
d470-dg
d470c-dg
dg+fixed
dgmode+color
dgmode+color8
dgunix+fixed
emu
fbterm
i3164
ibm3164
linux-m1b
linux-m2
minitel1
minitel1b
putty-m1b
putty-m2
st52-color
tt52
tw52
tw52-color
xterm-8bit

Most of these were discontinued in the 90s and their manufacturers no
longer exist (like Data General, which went defunct in 1999). The last one is a special mode for xterm that is
fundamentally UTF-8 incompatible because it encodes a CSI as \X9b.

The linux/putty m1b and m2 entries (also for minitel) don't support
color to begin with and the sequences they have in their terminfo
entries are control characters anyway, so the calculation would still
add up.

In turn, what we gain from this is much faster width calculations with
unrecognized escapes -
e.g. `string length -V \efoo` is sped up by a factor of 20.

An alternative would be to skip this if max_colors is > 16 as that is
the most any of these entries can do. The runtime scales linearly with
the number of colors so on those systems it would be reasonably quick anyway.

But given just *how* outdated these are I believe it is okay to just
remove support outright. I do not believe anyone has ever run fish on
any of these.
2022-03-13 11:32:53 +01:00
Fabian Homborg
972752aa1c
Merge branch 'master' into te-refactor 2022-03-13 11:24:31 +01:00
Andrey Mishchenko
59e50f77bc
Allow underscores as separators in the math builtin (#8611)
* Implement fish_wcstod_underscores

* Add fish_wcstod_underscores unit tests

* Switch to using fish_wcstod_underscores in tinyexpr

* Add tests for math builtin underscore separator functionality

* Add documentation for underscore separators for math builtin

* Add a changelog entry for underscore numeric separators
2022-03-13 11:23:35 +01:00
Fabian Homborg
9ada7d9aad read: Also read in chunks when directly redirected
We can't always read in chunks because we often can't bear to
overread:

```fish
echo foo\nbar | begin
    read -l foo
    read -l bar
end
```

needs to have the first read read `foo` and the second read `bar`. So
here we can only read one byte at a time.

However, when we are directly redirected:

```fish
echo foo | read foo
```

we can, because the data is only for us anyway. The stream will be
closed after, so anything not read just goes away. Nobody else is
there to read.

This dramatically speeds up `read` of long lines through a pipe. How
much depends on the length of the line.

With lines of 5000 characters it's about 15x, with lines of 50
characters about 2x, lines of 5 characters about 1.07x.

See #8542.
2022-03-13 11:22:48 +01:00
Fabian Homborg
a0e639e1fa read: Remove super old TODO
This was never a problem. If we need it, it's in the git log
2022-03-13 11:22:48 +01:00
Fabian Homborg
585d1de653
Merge branch 'master' into string-preserve-missing-newline 2022-03-13 11:21:53 +01:00
Fabian Homborg
cf85bf9be3 Let function-scoped variables be queried
This uses the same logic we use to create the variables to find them -
go through the scopes, the topmost local scope *is* function-scope.

Fixes #8684
2022-03-10 18:28:50 +01:00
Fabian Homborg
c1900ed41c Disable history race test on Github Actions
Same as ever: Flaky test, makes reviews more annoying. It should be
fixed, but until that happens it's better not to have it fail in
unrelated PRs.
2022-03-05 18:36:26 +01:00
Fabian Homborg
f284cdce5b Make byte/unicode escapes with no digits a tokenizer error
This is the simple fix - if we have no valid digit, we have nothing to
return. So instead of returning a NULL, we return an error.

This is already the case for invalid octal escapes (like `\777`).

Fixes #8545
2022-03-03 12:18:13 +01:00
Fabian Homborg
6fcb6f77be Revert changes to time formatting
This reverts commits:

2d9e51b43e
d1d9f147ec
346ce8081b

The box drawing because it's entangled with the rest and we don't
currently use this anywhere I know of. Nor was it gated on terminfo,
so it could have broken things, for subjectively little gain.

Fixes #8727.
2022-02-21 22:48:43 +01:00
Johannes Altmanninger
2f5edfd617 Call pthread_attr_destroy even if pthread_create failed
As suggested in
63bfab9975 (commitcomment-66542462)

Also, check for errors.
2022-02-19 14:15:22 +01:00
Fabian Homborg
34f4be1149 Update widecharwidth
This updates widechar_width.h to one generated from
15e782aa3df9dfef436516f66f745a90b421329.

The change here is a rationalization of doublewide vs widened-in-9.

Many emoji have been moved to widened-in-9 because we now use the
correct version (this uses the *emoji* version, and emoji version 3.0
corresponds to Unicode 9).
2022-02-14 22:19:28 +01:00
ridiculousfish
133e359d70 Add a test that stdin is always handed-off as blocking
No functional change here, just closing a gap in our coverage.
2022-02-12 11:41:03 -08:00
Johannes Altmanninger
210e7a9cc9 Correct error on when complete -C is used without argument
The new --escape option means that -C is not necessarily the last option;
We have this scenario where we produce a bogus error

    $ fish -c 'complete -C --escape'
    complete: --escape: option requires an argument

--escape doesn't take arguments, so let the error message say -C.
2022-02-09 08:57:05 +01:00
Nadav Zingerman
9e0f74eb6c Add --escape option to complete -C
An example use case is an external completion pager:

    bind \cg "commandline -rt (complete -C --escape|fzf|cut -d\t -f1)\ "

Fixes #3469
2022-02-09 08:34:03 +01:00
Aaron Gyes
d1d9f147ec Update tests for time output. 2022-02-08 16:57:01 -08:00
Aaron Gyes
63bfab9975 Start threads detached. 2022-02-08 16:44:20 -08:00
Aaron Gyes
e0c8e1cd70 iothread: Remove most of a comment
Remove the narrative here that can set a reader up for confusion.

018e51c935
2022-02-08 16:44:20 -08:00
Aaron Gyes
346ce8081b time: use box drawing characterts for the separator
This spruces up output slightly to render a solid
line instead of a bunch of dashes for the horizontal
rule shown in time output.
2022-02-08 16:44:20 -08:00
Aaron Gyes
2d9e51b43e builtin time: Use more familiar time unit abbreviations
Use ms, μs as opposed to "millis", etc.
2022-02-08 16:44:20 -08:00
Shay Aviv
2ef12af60e Fix comment parsing inside command substitutions and brackets 2022-02-08 16:20:31 +01:00
ridiculousfish
627033f447 fish_wcswidth_visible to use int instead of size_t
Credit to lilyball for spotting this.
2022-02-07 22:17:47 -08:00
Johannes Altmanninger
8b9f7dbf45 Commit transient edit when history search ends
A history search ends when you move the cursor, but the commandline inserted by
history search is still marked as transient. This means that the next history
search will clear the transient commandline. This means we are dropping an undo
point, for example:

	echo 11
	echo 1
	echo autosuggestion
	echo^P # commandline is "echo 1"
	^A # stop history search
	^P # commandline is "echo 11"
	^Z # Bug: commandline goes back to "echo", but it should be "echo 1"

In the worst case, we are switching from line-search to token-search (see
the attached test case).  Clearing the transient edit means the line is gone
and only the token is left on the command line.
2022-02-07 17:38:11 +01:00
ridiculousfish
7f31acbf9b Prevent fish_title output from triggering a bel
fish outputs the result of fish_title inside an escape sequence, which
happens to be terminated by \a (BEL). It may happen that the initial
output is interrupted; fish then emits the closing BEL and that makes an
annoying beep. Output the fish_title all at once, even if a signal is
delivered (so we don't get "stuck inside" the sequence).

This is related to #8628 in that it's a "torn escape sequence."
2022-02-05 13:18:37 -08:00
ridiculousfish
1bdd629326 Prevent signals from tearing multi-char bindings
Say the user has a multi-char binding (typically an escape sequence), and a
signal arrives partway through the binding. The signal has an event handler
which enques some readline event, for example, `repaint`. Prior to this
change, the readline event would cause the multi-char binding to fail. This
would cause bits of the escape sequence to be printed to the screen.

Fix this by noticing when a sequence was "interrupted" by a non-char event,
and then rotating a sequence of such interruptions to the front of the
queue.

Fixes #8628
2022-02-05 13:18:36 -08:00
ridiculousfish
43e5004b6e readch_timed to block signals
readch_timed is called after reading the escape character \x1b. The escape
char may be a standalone key press or part of an escape sequence; fish
waits for a little bit (per the fish_escape_delay_ms variable) to see if
something else arrives, before treating it as standalone escape-key press.

It may happen that a signal is delivered while fish waits. Prior to this
change we would treat this signal as a "nothing was read" event, causing
escape to be wrongly treated as standalone.

Avoid this by using pselect() with a full signal mask, to ensure this call
completes.
2022-02-05 13:17:45 -08:00
ridiculousfish
8a4ed096ed Stop passing check_exit events to match key bindings
check_exit events are generated to give the reader a chance to respond to
commands, or otherwise to return control to the reader loop. Prior to this
change they were being passed to match key bindings. This is useless since
no key binding can match a check_exit event. FLOG noisily complains about
unmatched events. So just don't pass these to mapping_execute.
2022-02-05 13:17:45 -08:00
Mahmoud Al-Qudsi
d059c3b5b2 src/reader.cpp: Remove needless use of macro 2022-01-31 16:28:21 -06:00
Mahmoud Al-Qudsi
05cdacc8d4 Prevent queued-up flash() calls from blocking input
Closes #8610.
2022-01-31 16:25:42 -06:00
Aaron Gyes
c6166f8ced Shorten more.
More vain attempts to get a bare <TAB> showing as 2 columns in the
pager. This now happens in a 101 column terminal.
2022-01-27 16:21:22 -08:00
ridiculousfish
2369eb61e2 Try to fix the launchpad build
A recent change used a C++14 overload of std::string::assign which
defaulted the last parameter. Explicitly pass npos to make it C++11
friendly again.
2022-01-26 22:29:06 -08:00
Johannes Altmanninger
c48b02e418 fixup! Fix commandline state for custom completions with variable overrides
The previous commit added transient commandlines when completing
commands with variable overrides. Transient commandlines require a
parser, but perform_one_completion_cd_test() asked for completions
without giving a parser, which is only okay when asking for
autosuggestions (like perform_one_autosuggestion_cd_test() does).
Let's pass a parser to fix the test.
2022-01-27 04:19:30 +01:00
Johannes Altmanninger
df3b0bd89f Fix commandline state for custom completions with variable overrides
Today, a command like "var=val status " has custom completions
because we skip over the var=val variable override when detecting
the command token.
However if the custom completions read the commandline state (via
"commandline -opc") they do see they variable override, which breaks
them, most likely. Try "a=b git ".

For completions of wrapped commands, we already set a transient
commandline. Do the same for commands with  leading variable overrides;
then git completions for "a=b git " will think the commandline is
"git ".
2022-01-27 03:51:32 +01:00
Aaron Gyes
275601665f Shorten more commands
We're at 2 columns @ 115-wide terminal.
2022-01-22 21:21:21 -08:00
Aaron Gyes
81c46183fd breakpoint: shorter 2022-01-22 21:18:24 -08:00
Aaron Gyes
1262469aea Shorten two more command's descriptions
Two columns at 119 width.
2022-01-22 21:04:26 -08:00
Aaron Gyes
cd47411bbb Shorten breakpoint description 2022-01-22 20:52:29 -08:00