The special input functions self-insert, self-insert-not-first, and
and or used to be handled by inputter_t::readch, but they aren't
anymore with `commandline -f`.
I am unsure if these *would* have worked, I can't come up with a use.
So, for now, do nothing instead of panicking.
This would crash if you ran `commandline -f backward-jump`.
The C++ version would read a char (but badly), this doesn't anymore.
So, at least instead of crashing, just do nothing.
One issue with fish_add_path at the moment is that it is sometimes a bit too intransparent.
You'll try to add a path, but it won't appear - was that because it wasn't a directory,
or because it doesn't exist, or because it was already included?
If it isn't usable after, did fish_add_path not add it because of something or did something *else* remove it?
So we give more explanations - "skipping this because it's a file", "not setting anything because no paths are left to add", ...
fish_add_path can be used either interactively, in the commandline,
or in config.fish. That's its greatest strength, it's a very
DWIM-style command.
One of the compromises that entails, however, is that it can't really
be very loud about what it does. If it skips a path, it can't write a
warning because it might be used in config.fish.
But it *can* if it's used interactively. So we try to detect that case
and enable verbose mode automatically.
That means if you do
```fish
fish_add_path /opt/mytool/bin/mytool
```
it may tell you "Skipping path because it is a file instead of a
directory:".
The check isn't perfect, it goes through status current-command and
isatty, but it should be good for most cases (and be false in config.fish).
The prompt regex for pexpect was:
```
return re.compile(
r"""(?:\r\n?|^) # beginning of line
(?:\x1b[\d[KB(m]*)* # optional colors
(?:\x1b[\?2004h) # Bracketed paste
(?:\x1b[>4;1m) # XTerm's modifyOtherKeys
(?:\x1b[>5u) # CSI u with kitty progressive enhancement
(?:\x1b=) # set application keypad mode, so the keypad keys send unique codes
(?:\[.\]\ )? # optional vi mode prompt
"""
+ (r"prompt\ %d>" % counter) # prompt with counter
+ r"""
(?:\x1b[\d\[KB(m]*)* # optional colors
""",
re.VERBOSE,
)
```
This has a terrible bug: an accidentally unescaped bracket here:
(?:\x1b[>4;1m) # XTerm's modifyOtherKeys
^
This bracket then extends throughout the entire regex, and is
accidentally terminated here:
(?:\x1b[\d\[KB(m]*)* # optional colors
^
Thus the whole regex is busted; in particular the prompt counters are
not being tested correctly.
A second issue is that these escape sequences are not emitted before the
first prompt, so correcting the regex will cause every test to fail.
Fix this by ignoring all of the escape sequences and merely look for
the "prompt %d>" portion.
THIS DELIBERATELY CAUSES TEST FAILURES.
The tests were already broken and falsely reported as passing.
These will be fixed in followup commits.
Good news is that the tests should become way more reliable after
this is fixed - hopefully no more introducing random sleep() calls.
This doesn't pull its weight. Block size is not a particularly big
problem,
and this both complicates the code a bit and would arbitrarily cause issues
if a fish script exceeded 65k lines.
This reverts commit edd6533a14.
This doesn't have any effect on the size of the struct (due to alignment
requirements and padding) but reduces the complexity by turning
Block::wants_pop_env into an emergent property dependent on the type rather than
something we have to manually manage.
We only increment it and check if it's non-zero, we never decrement or check the
actual count. As such, change it to a bool and bring the size of `Block` down
from 32 to 24 bytes.
We almost never access any of this and having it stored directly in the `Block`
struct increases its size (reducing how many we can fit in L1 and L2, and
increasing memory copy traffic).
Gets rid of BlockData::None so we can avoid allocating a Box at all when we have
no data (at the cost of yet-another-wrapper-type), which is the usual case.
This has a few advantages,
* We now statically assert that all fields used by a particular block type are
correctly initialized (i.e. you can't assign the function name but forget to
assign its arguments),
* Conversely, we can match directly on `BlockData` and be guaranteed that the
fields we want to access are initialized and present,
* We reduce the number of assertions, effectively "unwrapping" only once based
off the block type instead of each time we try to access a conditional field,
* We reduce the size of the `Block` struct by coalescing fields that cannot
co-exist, bringing it down from 104 bytes to 88 bytes.
It would be nice to make all of `Block` itself an enum, but it currently
requires `Copy` and we take advantage of that to copy it around everywhere.
Putting these fields directly in `Block` directly would mean a lot more memory
traffic just checking block types.
There's no need for two separate block types when one is merely a variant of the
other. This may have been required under C++ but thanks to sum types (rust's
enums) we don't need to do that any more.
The value completions were rendered almost entirely useless due to the forced
inclusion of file completions at all tokens, including in the head/command
position thanks to the use of `__fish_complete_subcommand` which doesn't
understand the semantics of `env` and expects something like `ssh`. But we don't
need it at all.
If the backgrounded/stopped job was using the tty, sending it SIGCONT first
might cause it to immediately wake and try to use the tty (which fish still has
control over), causing it to immediately stop again after receiving a SIGTTOU.
We are supposed to send SIGHUP first so that when the process resumes it sees
the queued SIGHUP and executes its registered handler!
Don't fork/exec an external process, especially one performing IO, if we don't
have to.
This, in turn, speeds up __fish_source_cached_completions which is rather slow
under WSL (and slower than it needs to be on other platforms).
Use "directories" explicitly instead of "components" to make it more
clear that the arguments need to be directories, not files.
Also a bit on intent and variable scope.
There's no guarantee that a condition variable is stateful. The docs for
`Condvar::notify_one()` actually say the opposite:
> If there is a blocked thread on this condition variable, then it will be woken
> up from its call to wait or wait_timeout. Calls to notify_one are not buffered
> in any way.
This test was relying on the main loop obtaining the lock and entering the
condition variable sleep before the thread was scheduled and got around to
notifying the condition variable. If this non-deterministic behavior was not
upheld, the test would time out since it would obtain the lock (either before or
after the variable were updated) then call `condvar.wait()` *after* the variable
had been updated and the condvar signalled, but without (atomically or even at
all) checking to see if the desired wake precondition was fulfilled. As the
child thread had already run and the wake notification was NOT buffered, there
was nothing to wake the running thread.
There really wasn't any way to salvage the test as originally written, since the
write to `ctx.val` was not in any way linked to the acquire/release of the mutex
so regardless of whether or not the main thread obtained the mutex and checked
the value precondition before calling `condvar.wait()`, the child thread's write
could have happened after the check but before the wait() call. As such, the
test has been rewritten to use `wait_while()` but then also updated to bail in
case of a timeout instead of hanging indefinitely (since neither the `ctest`
runner nor the `cargo test` harness was timing out; `cargo test` would only
report that the test had exceeded 60 seconds but as long as it was not executed
with `cargo test -- -Z --ensure-time` (which is only available under nightly),
the test would not halt.
If this test were *intentionally* written to test the scenario that was timing
out, it should be written deterministically in such a way that the main loop
did not run until after it was guaranteed that the variable had been updated
(i.e. by looping until val became 5 or waiting for an AtomicBool indicating the
update had completed to be set), but I'm not sure what the benefit in that would
be since the docs actually guarantee the opposite behavior (the notified state
is explicitly not cached/buffered).
If we have fish code written with the assumption that condvar notifications
prior to *any* call to `Condvar::wait()` *are* buffered, then that code should
of course be revisited in light of this.