This makes `path basename` a more useful replacement for the stock `basename`
command, which can be used with `-s .ext` to trim `.ext` from the base name.
Previously, this would have required the equivalent of
path change-extension "" (path basename $path)
but now it can be just
path basename -E $path
It is short and simple enough to write yourself if you need it and it encourages
bad behavior by a) always returning owned strings, b) always allocating them in
a vector. If/where possible, it is better to a) use &wstr, b) use an iterator.
In rust, it's an anti-pattern to unnecessarily abstract over allocating
operations. Some of the call sites even called split_string(..).into_iter().
On this binding we fail to disable CSI u
bind c-t '
begin
set -lx FZF_DEFAULT_OPTS --height 40% --bind=ctrl-z:ignore
eval fzf | while read -l r; echo read $r; end
end
'
because for "fzf", ParseExecutionContext::setup_group() returns early with the
parent process group (which should be fish's own) , hence "wants_terminal"
is false. This seems questionable, I don't think the eval should make a
difference here.
For now, don't touch it; use the more accurate way of detecting whether
a process may read keyboard input. In many of such cases "wants_terminal"
is false, like
echo (echo 1\n2\n3 | fzf)
Fixes#10504
This allows running `set` without triggering any event handlers.
That is useful, for example, if you want to set a variable in an event
handler for that variable - we could do it, for example, in the
fish_user_path or fish_key_bindings handlers.
This is something the `block` builtin was supposed to be for, but it
never really worked because it only allows suppressing the event for
the duration, they would fire later. See #9030.
Because it is possible to abuse this, we only have a long-option so
that people see what is up.
[w]open_dir does not pass O_CREAT, so the mode argument to open is never used.
also, O_CREAT | O_DIRECTORY could not be used (portably) to create a directory.
(on POSIX does not specify what should happen, on Linux it is EINVAL.)
This removes IsOkAnd and the is_some_and method.
I cannot actually find is_none_or in the stdlib?
I've kept the trait name to avoid changing it now and then later, maybe this should
be moved elsewhere to avoid claiming it's an stdlib thing?
This allows making something like
```fish
abbr --add gc --position anywhere --command git back 'reset --hard
HEAD^'
```
to expand "gc" to "reset --hard HEAD^", but only if the command is
git (including "command git gc" or "and git gc").
Fixes#9411
This introduces a feature flag, "test-require-arg", that removes builtin test's zero and one argument special modes.
That means:
- `test -n` returns false
- `test -z` returns true
- `test -x` with any other option errors out with "missing argument"
- `test foo` errors out as expecting an option
`test -n` returning true is a frequent source of confusion, and so we are breaking with posix in this regard.
As always the flag defaults to off and can be turned on. In future it will default to on and then eventually be made read-only.
There is a new FLOG category "deprecated-test", run `fish -d deprecated-test` and it will show any test call that would change in future.
While it does need to store the string, we also need to use the string after
storing it, so we aren't getting any advantage from passing by value. Just pass
by reference to simplify the call sites.
I think commit 8386088b3 (Update commandline state changes eagerly as well,
2024-04-11) broke the alt-s binding.
This is because we update the commandline state snapshot (which is consumed
by builtin commandline and others) only at key points. This seems like a
dubious optimization. With the new streamlined bind execution semantics,
this doesn't really work anymore; any shell command can run any number of
commands like "commandline -i foo" which should synchronize.
Do the simple thing of calculating the snapshot whenever needed.
Commit c3cd68dda (Process shell commands from bindings like regular char
events, 2024-03-02) mentions a "weird ordering difference".
The issue is that "commandline -f foo" goes through the input
queue while other commands are executed directly.
For example
bind ctrl-g "commandline -f end-of-line; commandline -i x"
is executed in the wrong order. Fix that.
This doesn't yet work for "commandline -f exit" but that can be fixed easily.
It's hard to imagine anyone would rely on the existing behavior. "commandline
-f" in bindings is mostly used for repainting the commandline.
If a binding was input starting with "\e", it's usually a raw control sequence.
Today we display the canonical version like:
bind --preset alt-\[,1,\;,5,C foo
even if the input is
bind --preset \e\[1\;5C foo
Make it look like the input again. This looks more familiar and less
surprising (especially since we canonicalize CSI to "alt-[").
Except that we use the \x01 representation instead of \ca because the
"control" part can be confusing. We're inside an escape sequence so it seems
highly unlikely that an ASCII control character actually comes from the user
holding the control key.
The downside is that this hides the canonical version; it might be surprising
that a raw-escape-sequence binding can be erased using the new syntax and
vice versa.
It's not clear whether builtin read should be able to do everything
that the normal prompt does but I guess we haven't found a problem yet.
Given that read could be used to read a single character at a type,
it's a bit odd to toggle terminal protocols all the time.
But that's not the typical case (at least not for when stdin is a TTY),
and it seems fine.
Teste with
bind ctrl-4 'echo yay'
Regressed in 8164855b7 (Disable terminal protocols throughout evaluation,
2024-04-02).
See the changelog additions for user-visible changes.
Since we enable/disable terminal protocols whenever we pass terminal ownership,
tests can no longer run in parallel on the same terminal.
For the same reason, readline shortcuts in the gdb REPL will not work anymore.
As a remedy, use gdbserver, or lobby for CSI u support in libreadline.
Add sleep to some tests, otherwise they fall (both in CI and locally).
There are two weird failures on FreeBSD remaining, disable them for now
https://github.com/fish-shell/fish-shell/pull/10359/checks?check_run_id=23330096362
Design and implementation borrows heavily from Kakoune.
In future, we should try to implement more of the kitty progressive
enhancements.
Closes#10359
To do so add an ad-hoc "commandline --search-field" to operate on pager
search field.
This is primarily motivated because a following commit reuses the
fish_clipboard_paste logic for bracketed paste. This avoids a regression.
A long standing issue is that bindings cannot mix special input functions
and shell commands. For example,
bind x end-of-line "commandline -i x"
silently does nothing. Instead we have to do lift everything to shell commands
bind x "commandline -f end-of-line; commandline -i x"
for no good reason.
Additionally, there is a weird ordering difference between special input
functions and shell commands. Special input functions are pushed into the
the queue whereas shell commands are executed immediately.
This weird ordering means that the above "bind x" still doesn't work as
expected, because "commandline -i" is processed before "end-of-line".
Finally, this is all implemented via weird hack to allow recursive use of
a mutable reference to the reader state.
Fix all of this by processing shell commands the same as both special input
functions and regular chars. Hopefully this doesn't break anything.
Fixes#8186Fixes#10360Closes#9398
This is resistant to misuse by including O_DIRECTORY in the open flags and it is
a separate function from {w,}open_cloexec() in preparation for making that one
return a `File` instead of an `OwnedFd`.
* builtin/test: Split Token enum into 2-level hierarchy
* builtin/test: Rearrange the Token enum hierarchy
* builtin/test: Separate Token into Unary and Binary
* builtin/test: import IsOkAnd polyfill
* builtin/test: Rename enum variants one more time
The regex struct is pretty large at 560 bytes, with the entire
Abbreviation being 664 bytes.
If it's an "Option<Regex>", any abbr gets to pay the price. Boxing it
means abbrs without a regex are over 500 bytes smaller.