Compare commits

...

432 Commits

Author SHA1 Message Date
Johannes Altmanninger
65556ac2ae Increase grace period for decoding escape sequences
Historically, fish has treated input bytes [0x1b, 'b'] as alt-b (rather than
"escape,b") if the second byte arrives within 30ms of the first.

Since we made builtin bind to match key events instead of raw byte sequences
key events (as per the kitty keyboard protocol), we have another place where
we do similar disambiguation: when we read keys such as alt-left ("\e[1;3D"),
we only consider bytes to be part of this sequence if stdin is immediately
readable (actually after a 1ms timeout since e1be842 (Work around
torn byte sequences in qemu kbd input with 1ms timeout, 2025-03-04)).

This is technically wrong but has worked in practice (for Kakoune etc.).

Issue #11668 reports two issues on some Windows terminals with a remote fish shell:
- the "bracketed paste finished" sequence may be split into multiple packets,
  which causes a delay of > 1ms between individual bytes being readable.
- AutoHotKey scripts simulating seven "left" keys result in sequence tearing
  as well.

Try to fix the paste case by increasing the timeout when parsing escape
sequences.

Also increase the timeout for terminals that support the kitty keyboard
protocol.  The user should only notice the delay caused by the timeout after
presses one of escape,O, escape,P, escape,[, or escape,] while the kitty
keyboard protocol is disabled (e.g. while an external command is running).
This case also virtually increases fish_escape_delay_ms; hopefully this edge
case is not ever relevant.

Part of #11668
2025-07-25 11:47:18 +02:00
Johannes Altmanninger
25e5cc23c1 Block interrupts and uvar events while decoding key
readb() has only one caller that passes blocking=false: try_readb().
This function is used while decoding keys; anything but a successful read
is treated as "end of input sequence".

This means that key input sequences such as \e[1;3D
can be torn apart by
- signals (EINTR) which is more likely since e1be842 (Work around torn byte
  sequences in qemu kbd input with 1ms timeout, 2025-03-04).
- universal variable notifications (from other fish processes)

Fix this by blocking signals and not listening on the uvar fd.  We do
something similar at the next higher level -- key sequence matching --
so extract a function to reuse for key decoding.

Ref: https://github.com/fish-shell/fish-shell/issues/11668#issuecomment-3101341081
2025-07-25 11:47:18 +02:00
Johannes Altmanninger
4012345ba9 Reduce MaybeUninit lifetime 2025-07-25 11:47:18 +02:00
Johannes Altmanninger
43d583d991 Fix regression causing \e[ to be interpreted as ctrl-[
Fixes 3201cb9f01 (Stop parsing invalid CSI/SS3 sequences as alt-[/alt-o,
2024-12-30).
2025-07-25 11:47:18 +02:00
Johannes Altmanninger
d69886efe0 completions/protontricks: coding style, translations 2025-07-25 11:15:05 +02:00
Johannes Altmanninger
bd8cc6d317 Merge pull request #11375 2025-07-25 11:10:38 +02:00
Johannes Altmanninger
9c5b3f3d57 Merge pull request #11674 2025-07-25 11:03:53 +02:00
Johannes Altmanninger
5970f34a60 Retry some writes on EINTR again
I guess?
Fixes f0e007c439 (Relocate tty metadata and protocols and clean it up,
2025-06-19).
2025-07-25 10:23:48 +02:00
Johannes Altmanninger
eaa837effa Refresh TTY timestamps again in most cases
See commit 081c3282b7 (Refresh TTY timestamps also in some rare cases,
2025-01-15) and others.
Fixes d27f5a5293 (Adopt TtyHandoff in remaining places, 2025-06-21)
Fixes #11671
2025-07-25 10:23:48 +02:00
Johannes Altmanninger
e52cf2f6a7 Try to restore TTY protocols more reliably after SIGTERM
We might
1. set TTY_PROTOCOLS_ACTIVE to false
2. receive `SIGTERM`
3. due to 1 fail to disable TTY protocols

Fix this by making sure that the disabling of protocols happens-before we
set TTY_PROTOCOLS_ACTIVE to false.

See 37c04745e6 (Avoid potential contention on SIGTERM while enabling terminal
protocols, 2024-10-08).
Fixes d27f5a5293 (Adopt TtyHandoff in remaining places, 2025-06-21)
2025-07-25 10:23:48 +02:00
Johannes Altmanninger
8c7568c0cb Reapply "Disable focus reporting on non-tmux again for now" 2024-04-18
Reapply bdd478bbd0. Amendment to f0e007c439 (Relocate tty metadata and
protocols and clean it up, 2025-06-19).
2025-07-25 10:23:48 +02:00
Johannes Altmanninger
07979782a6 Fix iTerm2 detection on non-iTerm2 terminals
Fixes f0e007c439 (Relocate tty metadata and protocols and clean it up,
2025-06-19).
2025-07-25 10:23:48 +02:00
Johannes Altmanninger
59b43986e9 build_tools/style.fish: fail if formatters are not available
build_tools/check.sh is supposed to fail on formatting violations.  I don't
think we have a good reason for running build_tools/style.fish outside
check.sh.

black is the only formatter not versioned in CI -- but we can probably
satisfy all realistic versions.

Ref: https://github.com/fish-shell/fish-shell/pull/11608#discussion_r2173176621
2025-07-25 10:23:48 +02:00
phisonate
51f3722e02 Fix funced to not expand or execute function name when interactive
Due to unnecessary quotes in the prompt command given to `read` by `funced` when
editing a function interactively (using `-i`), the name of the function to edit
would be evaluated, expanded and even executed (when using command substitution
for example), which is at least annoying when using unusual but valid and
allowed function names like '*' or 'head (cat)'. This commit delays the function
name expansion so that this should no longer happen.
2025-07-24 01:03:02 +02:00
Peter Ammon
db0f9c1d53 Minor refactoring of make_wait_handle 2025-07-20 13:40:22 -07:00
Peter Ammon
c9901398ed Switch DISOWNED_PIDS from MainThread to Mutex
Preparation for concurrent execution. These can be reaped on any thread.
2025-07-19 17:56:58 -07:00
Peter Ammon
6181ba3b56 Fix an 1.70 clippy 2025-07-19 16:49:51 -07:00
Peter Ammon
d27f5a5293 Adopt TtyHandoff in remaining places
This adopts the tty handoff in remaining places. The idea is to rationalize
when we enable and disable tty protocols (such as CSI-U).

In particular this removes the tty protocol disabling in Parser::eval_node
- that is intended to execute pure fish script and should not be talking to
the tty.
2025-07-19 16:04:13 -07:00
Peter Ammon
c1d165de9d Adopt TtyHandoff in fish_key_reader
Prepare to remove terminal_protocols_enable/disable_ifn
2025-07-19 16:04:13 -07:00
Peter Ammon
f0e007c439 Relocate tty metadata and protocols and clean it up
fish-shell attempts to set up certain terminal protocols (bracketed paste,
CSI-U) while it is in control of the tty, and disable these when passing
off the tty to other processes. These terminal protocols are enabled or
disabled by emitting certain control sequences to the tty.

Today fish-shell does this in a somewhat haphazard way, tracking whether
the protocols are enabled or disabled. Functions like `Parser::exec_node`
then just toggle these, causing data to be written to the terminal in
unexpected places. In particular this is very bad for concurrent execution:
we don't want random threads talking to the tty.

Fortunately we have a controlled place where we can muck with the tty:
`TtyTransfer` which controls handoff of ownership to child processes (via
`tcsetpgrp`). Let's centralize logic around enabling and disabling terminal
protocols there. Put it in a new module and rename it to `TtyHandoff` which is a
little nicer.

This commit moves code around and does some cleanup; it doesn't actually
pull the trigger on centralizing the logic though. Next commit will do that.
2025-07-19 16:04:13 -07:00
Peter Ammon
65a4cb5245 Revert "Restore terminal state on SIGTERM again"
This reverts commit 1d6fa258f6.

This reintroduces commit 941701da3d, which was then reverted in
941701da3d8; this commit reverts the revert to reintroduce 941701da3d.

The reason is that the existing logic in terminal_protocols_disable_ifn does a
bunch of stuff for which nobody has thought about its signal safety, such as
accessing the reader stack (clearly not async signal safe).
Even functions which happen to be safe now may become unsafe in the future.

This is just the nature of signal handling code. We must ensure that only
async-signal safe syscalls are run, and only functions which are themselves
async-signal safe, which we (try) to designate with the "safe_" prefix.
2025-07-19 15:37:00 -07:00
rosavi
c7262d6c05 Add completions for cpan and t-rec
Closes #11647
2025-07-19 22:15:24 +02:00
Johannes Altmanninger
f3c264722d Merge pull request #11666 2025-07-19 22:15:24 +02:00
Johannes Altmanninger
39742cafa0 Merge pull request #11663 2025-07-19 22:15:24 +02:00
Johannes Altmanninger
295d2bd218 update translations for completions/fish_indent 2025-07-19 22:15:24 +02:00
Johannes Altmanninger
3588b41744 Merge pull request #11662 2025-07-19 22:15:24 +02:00
Johannes Altmanninger
82e3311756 Merge pull request #11659 2025-07-19 22:15:24 +02:00
Johannes Altmanninger
b611c96cdd Merge pull request #11654 2025-07-19 22:15:24 +02:00
Johannes Altmanninger
1d6fa258f6 Restore terminal state on SIGTERM again
Commit 941701da3d (Restore some async-signal discipline to SIGTERM,
2025-06-15) made two changes
1. removed a mutex lock in signal handler (regression from 55fd43d86c
   (Port reader, 2023-12-22))
2. removed some SIGTERM cleanup

I'm not sure what's the reason for 2, so let's revert it I guess.  This code
path already uses FLOG_SAFE for async-signal safety.

There is an avoidable panic when `Outputter::stdoutput()` is already
borrowed. Fix that.

Closes #11597
2025-07-19 22:15:24 +02:00
Johannes Altmanninger
6312b1dbd8 Format test_driver.py 2025-07-19 22:15:24 +02:00
Peter Ammon
5fa2f62536 test_driver: increase open file limit
Prevent failures due to file handle exhaustion.
2025-07-19 11:14:37 -07:00
Peter Ammon
bbf7568ebd test_driver.py: Properly report exceptions
If a test fails by throwing an exception (in this case, "Too many open files")
then that exception would propagate, be uncaught, and then the remaining tests
would not be await'ed, leading to a hang.

Fix this by properly catching and reporting exceptions.
2025-07-19 11:01:48 -07:00
Rhidian De Wit
72347517b2 Fix missing bool to string cast causing errors 2025-07-17 20:17:52 +02:00
may
95475c35ff update translation files 2025-07-16 16:36:09 +02:00
may
560d21cd86 complete git rebase --keep-base 2025-07-16 15:49:38 +02:00
nick
bef453f69b fish_indent -c/--check completions
Manpage `fish_indent(1)` documents the `-c/--check` option, which checks
if a file is already indented as `fish_indent` would. This option is now
included in the completions for `fish_indent`.
2025-07-15 15:44:36 -05:00
vcalv
fa832ead65 add suspend-then-hibernate to systemctl.fish
suspend-then-hibernate was missing
2025-07-14 18:09:32 -04:00
Azamat Dinaev
eb7afd2a9c Update __fish_print_hostnames.fish
There was an issue in autocomplete of ssh. 

When you put in ~/.ssh/config line like this:

"Include Include ${HRL_SSH}/onprem_config"

and then trying to use fish complete for ssh, for example:

"ssh -J" and press key <Tab> it throughs an error that fish cannot understand ${HRL_SSH} with brackets.
2025-07-12 14:18:43 +03:00
Johannes Altmanninger
f4ddcfa694 Merge pull request #11652 2025-07-11 12:11:17 +02:00
Johannes Altmanninger
1605d8d6ce Merge pull request #11644 2025-07-11 12:10:49 +02:00
Johannes Altmanninger
a7559a62c4 completions/cjpm: format with fish_indent 2025-07-11 12:09:58 +02:00
Johannes Altmanninger
e9327d234d Merge pull request #11641 2025-07-11 12:08:37 +02:00
Daniel Rainer
a3d03fc0fb Avoid duplicate flag values
Both `SKIP_CMDSUBST` and `NO_SPACE_FOR_UNCLOSED_BRACE` used `1 << 14` as their
value accidentally, resulting from `SKIP_CMDSUBST` not being sorted correctly.
Resolve this by using the next (and last in u16) unused bit for `SKIP_CMDSUBST`
and moving it to the end.

Fixes #11651.
2025-07-10 18:52:10 +02:00
Daniel Rainer
1e981a9827 Support upper/lower casing selection
Fixes #11639.
2025-07-10 16:57:17 +02:00
Daniel Rainer
770f4ce6d1 Add docs for casing shortcuts in normal mode 2025-07-06 20:15:25 +02:00
Daniel Rainer
aa782bdad7 Fix vi mode docs for moving to beginning of line 2025-07-06 20:10:21 +02:00
Jiangqiu Shen
e4c55131c7 Update translation 2025-07-04 18:31:39 -04:00
Jiangqiu Shen
e6ad78cda7 update 2025-07-04 00:30:28 -04:00
Jiangqiu Shen
578e162f35 Add completion for Cangjie programing language
add completion of cjpm
2025-07-04 00:29:11 -04:00
Johannes Altmanninger
e9bb150a41 Merge pull request #11633 2025-07-03 15:19:51 +02:00
Johannes Altmanninger
b5eccdf9f6 Merge pull request #11632 2025-07-03 15:19:51 +02:00
Johannes Altmanninger
75716bd6b0 Merge pull request #11631 2025-07-03 15:19:51 +02:00
Johannes Altmanninger
9e628995da Merge pull request #11629 ("Add completions for tmuxp") 2025-07-03 15:19:51 +02:00
Daniel Müller
5b39efc96d Support incrementing/decrementing the number below the cursor
Vim supports incrementing & decrementing the number below the cursor (or
after it) via Ctrl-a and Ctrl-x, respectively. Given fish's Vi mode
support, it makes sense to provide similar functionality when working on
the command line, to provide a more natural environment for Vim users.
With this change we add the necessary functionality.

Closes: #8320
Closes #11570
2025-07-03 14:38:42 +02:00
Johannes Altmanninger
b5bb50d742 builtin commandline: apply commandline+cursor to first top-level reader
Historically, `fish -C "commandline echo"` was silently ignored.  Make it do
the expected thing.  This won't affect subsequent readers because we only do
it for top-level ones, and reader_pop() will clear the commandline state again.

This improves consistency with the parent commit.  We probably don't want to
support arbitrary readline commands before the first reader is initialized,
but setting the initial commandline seems useful: first, it would have helped
me in the past for debugging fish.  Second, it would allow one to rewrite
an application launcher:

	 foot --app-id my-foot-launcher -e fish -C '
	 	set fish_history launcher
	 	bind escape exit
	 	bind ctrl-\[ exit
	-	function fish_should_add_to_history
	-		false
	-	end
	-	for enter in enter ctrl-j
	-		bind $enter '\''
	-			history append -- "$(commandline)"
	-			commandline "setsid $(commandline) </dev/null >/dev/null 2>&1 & disown && exit"
	-			commandline -f execute
	-		'\''
	-	end
	+	commandline "setsid  </dev/null >/dev/null 2>&1 & disown && exit"
	+	commandline --cursor $(string length "setsid ")
	 '

which is probably not desirable today because it will disable autosuggestions.
Though that could be fixed eventually by making autosuggestions smarter.

If we find a generally-useful use case, we should mention this in the changelog.

Ref: https://github.com/fish-shell/fish-shell/pull/11570#discussion_r2144544053
2025-07-03 14:38:42 +02:00
Daniel Müller
32c36aa5f8 builtins commandline/complete: allow handling commandline before reader initialization
Commands like "commandline foo" silently fail, and "complete -C" fails with
a weird "option requires an argument" error.

I think at least the first one can be useful in edge cases, e.g. to test
code that does not separate the `commandline` input and output (#11570),
and to set fish's initial commandline, see the next commit.

I don't think there are super strong reasons to allow these, but if the
existing state is merely due to "no one has ever thought of doing this",
then we should try changing it.

For consistency, also allow "complete -C". I guess an argument for that is
that it's weird to make a command behave differently in non-interactive shells.

For now, keep the historical behavior of disabling access to the command
line in non-interactive shells. If we find a good reason for allowing that
(which seems unlikely), we can.

Ref: https://github.com/fish-shell/fish-shell/pull/11570#discussion_r2144544053

Co-authored-by: Johannes Altmanninger <aclopte@gmail.com>
2025-07-03 14:16:18 +02:00
merceyz
fc37d8d5a8 feat: add completions for volta 2025-06-29 16:23:49 +02:00
merceyz
8d361b4290 feat: add completions for k9s 2025-06-29 16:18:41 +02:00
merceyz
9789e6b731 feat: add completions for cilium and hubble 2025-06-29 16:09:27 +02:00
Johannes Altmanninger
4d67ca7c58 Add ctrl-alt-h compatibility binding
Historically, ctrl-i sends the same code as tab, ctrl-h sends backspace and
ctrl-j and ctrl-m behave like enter.

Even for terminals that send unambiguous encodings (via the kitty keyboard
protocol), we have kept bindings like ctrl-h, to support existing habits.

We forgot that pressing alt-ctrl-h would behave like alt-backspace (and can
be easier to reach) so maybe we should add that as well.

Don't add ctrl-shift-i because at least on Linux, that's usually intercepted
by the terminal emulator.

Technically there are some more such as "ctrl-2" (which used to do the same as
"ctrl-space") but I don't think anyone uses that over "ctrl-space".

Closes #https://github.com/fish-shell/fish-shell/discussions/11548
2025-06-28 14:19:10 +02:00
Patryk Bratkowski
fbe5a53dc9 Add completions for tmuxp 2025-06-28 14:58:37 +03:00
Johannes Altmanninger
dcd93e4c52 Fix compatibility with Python 3.6 for OpenSUSE Leap 15.6
Nightlies for opensuse/leap:15.6 are failing because their /bin/python3
is Python 3.6 (the "python311" package creates only /bin/python311).
Python3.6 has been EOL for 3.5 years but OpenSuse leap is not even EOL.
Given that we don't write a lot of Python, let's support this for now.
2025-06-28 13:36:31 +02:00
Johannes Altmanninger
7acd20dc7e Fix opensuse docker file file extension 2025-06-28 13:27:30 +02:00
Johannes Altmanninger
1d893b77d3 Also flag MSRV rustc/clippy warnings in CI 2025-06-28 11:04:29 +02:00
Johannes Altmanninger
b451650faa Flag stable rustc/clippy warnings in CI
Today, when a change introduces warnings, the change author might not see
them. Fix that by making clippy fail on warnings.

AFAICT, "clippy --deny-warnings" will also fail on rustc warnings.
I'd imagine this is what most respectable Rust projects do.

Pin stable rust so we won't get unrelated failures. Alternatively, we could
keep using "dtolnay/rust-toolchain@stable", that should be fine too (as long
as we have the capacity to quickly silence/iron out clippy failures).

While at it, remove some unneeded dependencies. Keep gettext because that
one might enable some cfg-directives (?).
Other cfgs like feature="benchmark" and target_os != "linux" are not yet checked in CI.

See #11584
2025-06-28 11:02:19 +02:00
Johannes Altmanninger
3e0a53ae4f Resolve an uninlined_format_args warning 2025-06-28 11:02:19 +02:00
Johannes Altmanninger
e01aafab1c Extract github actions for interesting rust toolchain versions
Extract a github action to reduce the number of references to our MSRV and
stable (to be pinned in the next commit).

While at it, use the MSRV for macOS builds; this means that we'll be less
like accidentally to break the macOS build when bumping the MSRV.  I don't
think there is a reason for using 1.73 specifically, other than "it's the
highest we can use on old macOS", so using an even older one should be fine.
2025-06-28 09:50:18 +02:00
Johannes Altmanninger
fd0fba83b9 Fix inconsistency in docker file lint override 2025-06-28 09:50:18 +02:00
Johannes Altmanninger
6644cc9b0e Use statvfs on NetBSD again to fix build
From commit ba00d721f4 (Correct statvfs call to statfs, 2025-06-19):

> This was missed in the Rust port

To elaborate:

- ec176dc07e (Port path.h, 2023-04-09) didn't change this (as before,
 `statvfs` used `ST_LOCAL` and `statfs` used `MNT_LOCAL`)
- 6877773fdd (Fix build on NetBSD (#10270), 2024-01-28) changed the `statvfs`
  call to `statfs`, presumably due to the libc-wrapper for
  `statvfs` being missing on NetBSD.  This change happens
  to work fine on NetBSD because they do [`#define ST_LOCAL
  MNT_LOCAL`](https://github.com/fish-shell/fish-shell/pull/11486#discussion_r2092408952)
  But it was wrong on others like macOS and FreeBSD, which was fixed by
  ba00d721f4 (but that broke the build on NetBSD).
- 7228cb15bf (Include sys/statvfs.h for the definition of ST_LOCAL (Rust
  port regression), 2025-05-16)
  fixed a code clone left behind by the above commit (incorrectly assuming
  that the clone had always existed.)

Fix the NetBSD build specifically by using statfs on that platform.

Note that this still doesn't make the behavior equivalent to commit LastC++11.
That one used ST_LOCAL if defined, and otherwise MNT_LOCAL if defined.

If we want perfect equivalence, we could detect both flags in `src/build.rs`.
Then we would also build on operating systems that define neither. Not sure.

Closes #11596
2025-06-28 09:50:18 +02:00
adamanteye
f5370e6f22 Add colorful disassembler output completion for objdump
As desribed in objdump(1), --disassembler-color can be applied to
enable or disable the use of syntax highlighting in disassembly
output.

The options are:

--disassembler-color=off
--disassembler-color=terminal
--disassembler-color=on|color|colour
--disassembler-color=extened|extended-color|extened-colour

Signed-off-by: adamanteye <ada@adamanteye.cc>

Closes #11615
2025-06-28 09:50:18 +02:00
Patryk Bratkowski
d62fb9cc74 Add 'ollama stop' completions.
- Added the '__fish_ollama_ps' function to list running models.
- Added the 'stop' subcommand to ollama completions.
- Added running models as arguments to 'stop'.
2025-06-28 09:50:18 +02:00
Johannes Altmanninger
88ab024d7d Merge pull request #11627 2025-06-28 09:29:11 +02:00
Johannes Altmanninger
1cc900ab7f Merge pull request #11625 2025-06-28 09:28:58 +02:00
Dezhi Wu
144725e947 fix(echo): handle overflow in octal/hex escape parsing
Use wrapping arithmetic when parsing octal and hex escapes in echo to
prevent panics on overflow and ensure consistent behavior with other
shells. This change allows echo to process escape sequences like \5555
without crashing, keeping the same behavior as 3.7.1.

```
$ ./fish --version
fish, version 3.7.1
$ ./fish -c 'echo -e "\5555"'
m5
```
2025-06-28 11:15:42 +08:00
Dezhi Wu
d969577f0b fix(fmt): Resolve Rust 1.88 clippy warnings
Update formatting macros to use the new inline variable syntax as
recommended by Rust 1.88 clippy.
2025-06-28 09:10:27 +08:00
Johannes Altmanninger
3e098249a5 docker/fish_run_tests.sh: add check command to bash history
Closes #11600
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
7cd7f31a93 build_tools/check.sh: ignore modifications to the running script
I sometimes want to run this script in multiple docker containers concurrently,
and possibly modify it while another instance is already running.  The behavior
after modification is unpredictable; let's change it to read the whole script
up-front (like Python/fish do).
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
5e12d4e99c Use sync::OnceCell for terminal modes, fixing memory leak
My

    $ sudo docker/docker_run_tests.sh --shell-after docker/jammy-asan.Dockerfile

shows a lot of complaints about

    Direct leak of 60 byte(s) in 1 object(s) allocated from:

because some unit tests call reader_init() and reader_deinit().  Work around
this by initializing this value only once.  AFAICT, OnceCell is async-signal
safe (unlike Mutex), although I don't think documentation promises that.

It doesn't feel great to change implementation code to accomodate tests but
I think for this specific issue that's what we usually do.  Alternatively,
we could add to lsan_suppressions.txt.
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
f98d1779dd build_tools/check.sh: respect inherited RUSTFLAGS/RUSTDOCFLAGS
No particular motivation. Seems better?
Also, use long options I guess.
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
6f18a1b314 Also namespace target/man -> target/fish-man
If cargo ever wants to write to "target/man", it would collide with our
use of this path.  Let's make this less likely by prefixing the name with
"fish-".  This also makes it more obvious that this is fish's invention.
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
8b102f2571 Stop using Cargo's OUT_DIR
(Note: this commit should technically have preceded the "Fix config paths
for disjoint build-dirs and in-tree installs" one, to make that one easier
to follow, but I wasn't 100% sure if this commit is right.)

From https://doc.rust-lang.org/cargo/reference/environment-variables.html

> OUT_DIR — If the package has a build script, this is set to the folder
> where the build script should place its output. See below for more
> information. (Only set during compilation.)

so OUT_DIR is something like "target/debug/build/fish-41da27d587f48978".
Whenever build.rs is re-run, we get a new one.

I don't think we need this flexibility anywhere.  It wouldn't protect
concurrent "cargo test" from interfering with each other - that's handled
by a file lock taken by Cargo.

Use "target/" instead (or CMAKE_BINARY_DIR if set).
Namespace the files better, so we don't create weird paths like

	target/test/complete_test/...
	target/fish_root/
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
514eebb002 build_tools/update_translations.fish: move po/template.po to /tmp
With the upcoming tests/checks/gettext.fish test from #11583, my

	sudo docker/docker_run_tests.sh --shell-after docker/focal.Dockerfile

fails writing to "po/template.po" because "/fish-source" is mounted as
read-only.  (There should be no need for tests to write to the source tree.)

Since commit 6239cba1e4 (Add dry-run mode to update_translations.fish,
2025-05-30), "build_tools/update_translations.fish" always removes that
template file when done, even without "--dry-run".

I'm not sure if we still have a need for keeping around "po/template.po".
To add a new translation, you can run "build_tools/update_translations
po/xy.po". It could serve as a cache but that would only work if we integrated
it into a build system.

Move it to /tmp, fixing the docker tests.
2025-06-24 12:52:35 +02:00
Johannes Altmanninger
41eb0a2fd0 build_tools/update_translations.fish: protect against universally-set $tmpdir 2025-06-24 12:51:17 +02:00
Johannes Altmanninger
290d957ab6 build_tools/update_translations.fish: remove forward reference
cleanup_exit references variables that are only defined later.  Fix that.
Also move the definition one block up, to help the next commit.
2025-06-24 12:33:28 +02:00
Johannes Altmanninger
08b03a733a docker_run_tests.sh: stop using cmake
Use test_driver directly instead of CMake in the docker tests.

Deal with the read-only "/fish-source" by exporting
"CARGO_TARGET_DIR=$HOME/fish-build".  It seems correct to also inject this
environment variable into the interactive debugging shells.  Add some logging
to make this override more obvious to the user.

Adopt "build_tools/check.sh", because that defines the full set of checks
that we (eventually) want to run in CI.

In particular, this will also run "tests/checks/po-files-up-to-date.fish"
which "cargo b && cargo t && tests/test_driver.py" does not, due to the
REQUIRES clause.

Since most docker images have some lints/warnings today, disable those for
now. Use "docker_run_tests.sh --lint" to override. The default may be changed
in future.
2025-06-24 12:32:42 +02:00
Johannes Altmanninger
19a17fa981 Fix docker warning by using "ENV key=value" syntax
- LegacyKeyValueFormat: "ENV key=value" should be used instead of
	legacy "ENV key value" format (line 4)
2025-06-24 12:32:42 +02:00
Johannes Altmanninger
13c00c9f79 Fix config paths for disjoint build-dirs and in-tree installs
Commit 89282fd9bc (Use CARGO_MANIFEST_DIR to see if we're running from
build dir, 2024-01-20) did

    -if exec_path.starts_with(OUT_DIR)
    +if exec_path.starts_with(CARGO_MANIFEST_DIR)

where OUT_DIR is the cmake build directory ("./build")
and CARGO_MANIFEST_DIR is our top level source tree.

This allowed "target/debug/fish" to work, but it broke
1. CMake build directories outside the source tree, e.g. "docker/docker_run_tests.sh".
   Those incorrectly fall back to the compiled-in-path (/usr/local/share etc)
2. Installations iside the source tree, e.g.
   "mkdir build && cd build && cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/../install".
   These installations incorrectly use "share/" etc. from the source tree.

Fix this by
1. respecting the CMake-specific FISH_BUILD_DIR, ad
2. if that's not set, use $CARGO_MANIFEST_DIR/target
2025-06-24 12:32:42 +02:00
Johannes Altmanninger
19eceff3bc bulid.rs respect CARGO_TARGET_DIR in man output 2025-06-24 12:32:42 +02:00
Johannes Altmanninger
6a4d3a59ab build.rs: extract constant for cargo manifest dir 2025-06-24 12:32:42 +02:00
Johannes Altmanninger
3b0d5c342b build.rs: extract function for canonicalizing paths
This probably means we should enable Rust backtraces.. not sure though.
2025-06-24 12:32:42 +02:00
Johannes Altmanninger
884a2d100c build.rs: remove redundant include dir
This include was added for config.h in 618834c4b5 (Port
UVAR_FILE_SET_MTIME_HACK, 2023-09-15), but that file no longer exists.
Remove it.
2025-06-24 12:04:57 +02:00
Johannes Altmanninger
a4d355634d docker_run_tests: fix failed build exiting prematurely
My bad; the "set +e" is only active inside the subshell.
The outer shell uses "set -e", which means that it will
exit upon seeing the subshell fail.
2025-06-24 12:04:57 +02:00
Johannes Altmanninger
3c620f56ee test_driver.py: fix compatibility with Python 3.8 / Ubuntu Focal 2025-06-24 12:04:57 +02:00
Johannes Altmanninger
7679be3126 test_driver.py: fix confusing help output 2025-06-24 12:02:13 +02:00
Johannes Altmanninger
49926cfbac Standardize shell script indent level
We have a mixture of 2 and 4 space indent.

    4 benchmarks/driver.sh
    2 build_tools/check.sh
    4 build_tools/git_version_gen.sh
    4 build_tools/mac_notarize.sh
    2 build_tools/make_pkg.sh
    2 build_tools/make_tarball.sh
    2 build_tools/make_vendor_tarball.sh
    4 docker/docker_run_tests.sh
    4 osx/install.sh
    2 tests/test_functions/sphinx-shared.sh

Our editorconfig file specifies 2, with no explicit reason.
Our fish and Python scripts use 4, so let's use that.
2025-06-24 12:02:13 +02:00
Johannes Altmanninger
963c3425a3 Merge pull request #11593 2025-06-24 12:02:13 +02:00
ndrew222
55bddac90a added completion for uv and uvx
Closes #11601
2025-06-24 12:02:13 +02:00
Illia Ostapyshyn
20c67692e1 completions/journalctl: Add --pager-end
Closes #11604
2025-06-24 12:02:13 +02:00
Johannes Altmanninger
1e7088fb6b Merge pull request #11605 2025-06-24 12:02:13 +02:00
Johannes Altmanninger
0f75df7c35 history: remove flush()/fsync() and don't write after each appended item
Commit 5c0fddae70 (Refactor history flushing, 2025-03-28) made three changes:
1. call fsync() when we are finished writing the history file.
2. when appending to (as opposed to vacuuming) history, call write(2)
   (followed by flush() and sync()) for each item. Previously, we'd only
   call write(2) if our 64k buffer was full, or after processing the last
   history item.
3. actually check the return value of flush() (which would retry when flushing
   fails -- but std::fs::File::flush() never fails!).

The motivation was to potentially fix #10300 which didn't succeed (see
https://github.com/fish-shell/fish-shell/issues/10300#issuecomment-2876718382).

As for 1 and 2, I don't think the way we use fsync really helps, and flushing
eagerly should not make a difference.

As for 3, there are some explanations in comments, commit message and a [PR
comment](https://github.com/fish-shell/fish-shell/pull/11330#discussion_r2020171339).
To summarize, 5c0fddae70 wants to address the scenario where file.flush()
fails. Prior to that commit we would ostensibly carry on with a corrupted
"first_unwritten_new_item_index" (corrupted because it doesn't match what's
written to disk), which can cause various issues.  However this doesn't
ever happen because std::fs::File::flush() never fails because it doesn't
do anything -- std::fs::File::write() does not buffer writes, it always
delegates to write(2).

There can definitely be scenarios like the one described in
https://github.com/fish-shell/fish-shell/pull/11330#discussion_r2020171339
where the disk is full. In that case, either write(2) fails, which we
already check.  Or close(3p) fails with EIO, which we have never checked. We
should probably check that.

Undo all three changes for now.

Closes #11495
2025-06-24 12:02:13 +02:00
Asuka Minato
edb0617d13 Update git.fish
Closes #11606
2025-06-24 12:02:12 +02:00
Johannes Altmanninger
d2f7d238f3 Remove obsolete translation entries
I doubt these are very helpful; most of them won't be used again.  We can
still find them in history with "git log -Gpart.of.msgid".
2025-06-24 11:44:46 +02:00
Volodymyr Chernetskyi
a7bed39c1e Add info on formatting fish_git_prompt output 2025-06-23 18:46:54 +02:00
Johannes Altmanninger
06646998db fixup! alias: fix indentation 2025-06-23 14:18:15 +02:00
Johannes Altmanninger
096f225579 alias: fix indentation
Fixes #11602
2025-06-23 13:53:43 +02:00
Johannes Altmanninger
ebec8c15ab Merge pull request #11599 2025-06-23 13:46:34 +02:00
Daniel Rainer
92d9646631 Simplify CMake Tests
Remove dependency on CTest. Parallel execution is handled by `test_driver.py`
internally now, so CTest is no longer relevant for performance.

This also removes CMake targets for single tests. As a replacement,
`test_driver.py` can be called directly with the path to the build directory as
the first argument and the path to the desired test as the second argument.
Ensuring that the executables in the build directory are up to date needs to be
done separately.
For a pure cargo build, an example of running a single test would be:
`cargo b && tests/test_driver.py target/debug tests/checks/abbr.fish`

The recommended way of running tests is `build_tools/check.sh`, which runs more
extensive tests and does not depend on CMake. That script does not work in CI
yet, so CMake testing is retained for now.

Update CI config to use the new `FISH_TEST_MAX_CONCURRENCY`.
Also update the FreeBSD version, since the previous one is outdated and does not
support the semaphore logic in `test_driver.py`.
2025-06-22 22:44:46 +02:00
Daniel Rainer
ab1307c63b Do not mmap with len 0
`mmap` should fail when the length argument is 0. Checking this in advance
allows returning early, without performing unnecessary syscalls.

This also fixes an issue observed on FreeBSD 13.2 where `mmap` does not always
fail when the length is 0, resulting in the `assert!(len > 0)` in
`MmapRegion::new` failing.
https://github.com/fish-shell/fish-shell/issues/11595
2025-06-21 22:19:27 +02:00
Johannes Altmanninger
bebf3c129f Merge pull request #11594 2025-06-21 18:54:22 +02:00
Johannes Altmanninger
60881f1195 __fish_complete_list: only unescape "$(commandline -t)"
Commit cd3da62d24 (fix(completion): unescape strings for __fish_complete_list,
2024-09-17) bravely addressed an issue that exists in a lot of completions.
It did so only for __fish_complete_list. Fair enough.

Unfortunately it unescaped more than just "$(commandline -t)".

This causes the problem described at
https://github.com/fish-shell/fish-shell/issues/11508#issuecomment-2889088934
where completion descriptions containing a backslash followed by "n" are
interpreted as newlines, breaking the completion parser.  Fix that.
2025-06-21 18:53:50 +02:00
Johannes Altmanninger
320ebb6859 __fish_complete_list: strip "--foo=" prefix from replacing completions
Given a command line like

	foo --foo=bar=baz=qux\=argument

(the behavior is the same if '=' is substituted with ':').

fish completes arguments starting from the last unescaped separator, i.e.

	foo --foo=bar=baz=qux\=argument
			 ^
__fish_complete_list provides completions like

	printf %s\n (commandline -t)(printf %s\n choice1 choice2 ...)

This means that completions include the "--foo=bar=baz=" prefix.

This is wrong. This wasn't a problem until commit f9febba (Fix replacing
completions with a -foo prefix, 2024-12-14), because prior to that, replacing
completions would replace the entire token.
This made it too hard to writ ecompletions like

	complete -c foo -s s -l long -xa "hello-world goodbye-friend"

that would work with "foo --long fri" as well as "foo --long=frie".
Replacing the entire token would only work if the completion included that
prefix, but the above command is supposed to just work.
So f9febba made us replace only the part after the separator.

Unfortunately that caused the earlier problem.  Work around this.  The change
is not pretty, but it's a compromise until we have a better way of telling
which character fish considers to be the separator.

Fixes #11508
2025-06-21 18:53:50 +02:00
Daniel Rainer
9bf6112b60 Add option to limit concurrency of tests
The main purpose of this is avoiding timeouts in CI.

Passing `--max-concurrency=n` to `test_driver.py` will result in at most `n`
tests running concurrently, where `n` is a positive integer.
Not specifying the argument preserves the old behavior of running all tests
concurrently without a limit.
2025-06-21 02:36:06 +02:00
Daniel Rainer
ef1a6aba26 Remove unused NEVER_MMAP 2025-06-20 00:44:50 +02:00
Peter Ammon
ba00d721f4 Correct statvfs call to statfs
This was missed in the Rust port - C++ had statfs for MNT_LOCAL and not statvfs.
The effect of this is that fish never thought its filesystem was local on macOS
or BSDs (Linux was OK). This caused history race tests to fail, and also could
in rare cases result in history items being dropped with multiple concurrent
sessions.

This fixes the history race tests under macOS and FreeBSD - we weren't locking
because we thought the history was a remote file.
2025-06-19 15:30:36 -07:00
Peter Ammon
fe8909e8f2 Fix an off-by-one error in reporting dropped history items
This was introduced in the Rust port. The original C++ was pretty gnarly to be
fair.
2025-06-19 11:08:50 -07:00
Lorenzo Albano
d369614ad9 Use $GIT_COMMON_DIR for stashes detection.
Within a linked worktree, `$GIT_DIR` and `$GIT_COMMON_DIR` have different
values (see [git-worktree docs](https://git-scm.com/docs/git-worktree#_details)).
The two serve different purposes, in case of stashes `$GIT_COMMON_DIR`
should be used, this way stash detection in the git prompt works also
when inside a `git worktree`.

Closes #11591
2025-06-19 11:13:09 +02:00
Johannes Altmanninger
4f4d941760 Merge pull request #11588 2025-06-19 11:13:09 +02:00
Johannes Altmanninger
9b19db5c5f Merge pull request #11492 2025-06-19 11:13:09 +02:00
Johannes Altmanninger
4f46d369c4 completions/git: fix spurious error when no subcommand is in $PATH
Systems like NixOS might not have "git-receive-pack" or any other "git-*"
executable in in $PATH -- instead they patch git to use absolute paths.
This is weird. But no reason for us to fail. Silence the error.

Fixes #11590
2025-06-19 11:13:09 +02:00
Daniel Rainer
977459949f Obtain history file path in HistoryImpl::save
Eliminates some code duplication between the two different saving
implementations. These changes are based on
https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2149438316.

One extra change is included here, namely the early return on an empty file
name, indicating private mode. Without this, `history_path.unwrap()` fails in
some tests. Returning early is probably what we want in such situations anyway.
2025-06-18 21:05:29 +02:00
Daniel Rainer
8cbcfc0b3a Stop caching whether to lock
The cached information might become outdated. It is important that all fish
processes use the same mutual exclusion logic (either `flock`-based or the
fallback), because the two methods do not provide mutual exclusion from one
another.
Avoiding caching makes the behavior independent on previous system states,
resulting in fish instances performing file operations at the same time to use
the same locking logic.

More detailed discussion in
https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2134543447
2025-06-18 21:05:00 +02:00
Daniel Rainer
77738fd646 Remove obsolete comments
If arguments always have the same value they do not need to be arguments.
For `HistoryImpl::add`, the comments are incorrect (assuming they should
indicate the value of the argument), since both arguments can be true or false
independently.
`History::add` is only called at one location in a test with a constant value of
`false` for `pending`. This might mean that the parameter could be deleted, or
maybe even the entire function, if testing can work without it.
2025-06-18 20:54:38 +02:00
Daniel Rainer
f438e80f9b Use shared file locking logic
Both history files and universal variables files are accessed by multiple
processes, which need a way to synchronize their accesses.
This synchronization logic is mixed in with the logic for reading and updating
the files' contents, which results in messy code, duplicated locking
implementations, and inconsistencies.
Moreover, the existing implementations are flawed which has resulted in file
corruption (e.g. https://github.com/fish-shell/fish-shell/issues/10300).

The new approach separates the synchronization logic from the rest.

There are two approaches to synchronization.
- The primary one is using `flock(2)` to lock the directory containing the file
  which requires synchronized access. We do not lock the file holding the data
  directly because this file might be replaced, which can result in locking
  succeeding when it should block. Locking the directory solves this problem.
  To avoid inconsistent file states, changes are first written to a temporary
  file, which is then renamed into place while still holding the lock.
- In some situations `flock` locks are unavailable or take a long time. This
  mostly applies to remote file systems. If we think that a directory is located
  on a remote file system, we do not attempt to use `flock`.
  As a fallback, we have a lockless approach, which uses file metadata (device,
  inode, size, ctime, mtime) to identify file versions.
  We then read from the file, write the updated data to a temporary file,
  check if the file id for the path is the same as before we started reading,
  and if so we rename the temporary file such that it replaces the old file.
  Note that races are possible between the file id check and the rename syscall.
  If we detect a file id mismatch, we retry, up to a predetermined number of
  attempts.

The operations which should be performed are passed to the functions handling
synchronization as `Fn`s. Because we might have to run these operations
repeatedly when retrying, they should be executable arbitrarily often without
causing side-effects relevant to the program. This requires some changes to
functions accessing these files. In many cases, they have to work with
non-mutable references, which requires that they return the data which should be
updated in the program state, instead of directly assigning to the appropriate
location.

Locking via `O_EXLOCK`, which was used for the universal variable file, is no
longer supported. That version of locking locks the file operated on directly,
instead of its directory. According to the man pages of {Open,Free,Net}BSD
and macOS, these locks have flock semantics. So if flock is available, we can
use it, and if it is not, the `O_EXLOCK` flag does not help.
2025-06-18 20:48:27 +02:00
Daniel Rainer
ccb9c8225f Remove CHAOS_MODE
This is dead code. It is never set to true.
2025-06-18 20:31:28 +02:00
Daniel Rainer
33b651ad91 Get remoteness of correct directory
The history file is stored in the data dir, not the config dir, so the
remoteness of the former is the one which matters.
2025-06-18 20:31:28 +02:00
Daniel Rainer
a20712b51d Avoid mutable references for mmap creation
This is preparatory work for refactoring the file synchronization approach.

`read_exact` will fail if the file length does not match the expected one, which
means zero padding is useless. (On any reasonable OS it was also useless before,
because anonymous memory mapping would be zero-pages.)
2025-06-18 20:31:28 +02:00
Daniel Rainer
da426a1b03 Improve error handling in src/history/file.rs
Use `std::io::Result` instead of `Option` as the return type where appropriate,
to allow for better-informed error handling.

Remove explicit checks about the length to be mapped being 0.
From `mmap(3)`:
> If len is zero, mmap() shall fail and no mapping shall be established.
2025-06-18 20:31:28 +02:00
Daniel Rainer
fbb2fcdb06 Improve error handling in src/history.rs
This allows for more informative error handling.

In some cases, the `?` operator can now be applied sensibly instead of more
verbose local error handling.
2025-06-18 20:31:28 +02:00
Daniel Rainer
537b1c3dd5 Extract code for creating temporary files
There is no need for separate implementations for history and uvar file
handling. Having a shared implementation ensures that creating temporary files
is handled consistently and removes clutter from the source files which want to
create temporary files.
2025-06-18 20:31:28 +02:00
Daniel Rainer
b4d0538892 Reduce state mutation in load_from_file
This is another step towards making the `load_from_file` function callable
without modifying internal data of `self`. Instead, the required updates for
a successful load should be returned.

For now, `self.last_read_file_id` is still modified
within `load_from_file`, which means it still needs a mutable reference to
`self`.
2025-06-18 20:31:28 +02:00
Daniel Rainer
9222381769 Update self.vars outside of acquire_variables
This is done as a step towards enabling loading from the variables file without
affecting internal variables, such that retrying becomes possible without
issues.
2025-06-18 20:31:28 +02:00
Daniel Rainer
f2f54919af Remove unnecessary mut specifier 2025-06-18 20:31:28 +02:00
Daniel Rainer
f40e31f675 Return callbacks via return value
Callbacks are generated by
`src/env_universal_common.rs:generate_callbacks_and_update_exports`.
This function only pushes to the `Vec`, so the content of the `Vec` passed to it
does not matter within this function.
The generated callbacks are used in `src/env/environment.rs:universal_sync`,
which calls `generate_callbacks_and_update_exports` via
`EnvUniversal::sync`,
(optionally `EnvUniversal::load_from_path_narrow`),
`EnvUniversal::load_from_file`.

The only other code making use of these callbacks is in tests.
Because the only real use passes an empty `Vec`, there is no need to to pass the
`Vec` as a mutable reference to the function at all. Instead, we create the `Vec`
in `generate_callbacks_and_update_exports` and return it from there, which is
what the new code does.

This change is made because we want loading from a file to be performed without
mutating data which does not come directly from the file.
Then, we can safely retry loading from the file as many times as we want,
without worrying about side-effects on our data structures.
We want to be able to do this in the case where we cannot properly lock the file
and fall back to lockless reading, where we check file metadata before and after
reading to detect modifications, and retry if modifications are detected.

This fallback logic is not in place yet, and further changes are required for
side-effect free loading.
2025-06-18 20:31:28 +02:00
Fabio José Bohnenberger
43fbfa9a0f Extract __fish_cached function (#11526)
- extract __fish_cached function
- add cache for winetricks verb completion
2025-06-18 10:29:00 +02:00
Daniel Rainer
f6dbf17446 Decode WString in FLOG
This allows converting non-UTF-8-conforming bytes from their PUA encoding back
to the original bytes before outputting.

Due to the way Rust handles trait implementations, we cannot use
`impl<T: std::fmt::Display> FloggableDisplay for T`
anymore, as that would result in a conflicting implementation for the types
which get a custom implementation.
Instead, explicitly implement the trait for all types which need it.
2025-06-17 23:37:59 +02:00
Johannes Altmanninger
06578bd03d Merge pull request #11565 2025-06-16 12:25:08 +02:00
Johannes Altmanninger
6491518b97 Merge pull request #11571 2025-06-16 12:23:39 +02:00
Johannes Altmanninger
7e03bebf97 Merge pull request #11582 2025-06-16 12:23:21 +02:00
Peter Ammon
941701da3d Restore some async-signal discipline to SIGTERM
The changes to enable terminal protocols (CSI-U, etc) also attempts to
re-disable these when fish exits. In particular it attempts to disable these
from a SIGTERM handler.

Unfortunately none of that machinery is async-signal safe. Indeed our SIGTERM
handler has gotten rather sketchy, with taking a mutex and some other stuff.

Remove the async-signal-unsafe stuff and make SIGTERM manifestly safe.
Unfortunately this means that terminal protocols will remain set after SIGTERM
but that's probably unavoidable.
2025-06-15 19:06:47 -07:00
Peter Ammon
eb211e1d10 Bravely remove calls to redirect_tty_output
Calls to redirect_tty_output were added in many places when certain tty-syscalls
returned EIO. See commit 396bf1235d

This was intended to work around a glibc bug in wide character output, but it
was never really justifiable or tested, and we no longer use glibc wide
character output.

Bravely remove these, except in the case where we got SIGHUP and we don't want
to trigger SIGTTIN or SIGTTOU.
2025-06-15 18:09:53 -07:00
Daniel Rainer
a317a6acd9 Unconditionally include gettext message
Definitions of localizable strings should not be guarded by `cfg`, because then
they might not end up being exported, depending on the compilation config.
2025-06-15 23:43:31 +02:00
Daniel Rainer
d3f287c520 Retain attributes in localizable_consts
These attributes (such as doc comments) should be retained.
2025-06-15 23:43:31 +02:00
Daniel Rainer
80131acff2 Add PO file update check to tests
The PO file updates can now run in a normal test, eliminating the need for
special handling.

Rename the `check-translations.fish` script, to clarify which part of the checks
happens in it.
2025-06-15 23:43:31 +02:00
Daniel Rainer
85fb937a4d Add --use-existing-template argument
This is intended to allow translation updates in contexts where building within
the `fish_xgettext.fish` script is undesirable.

Specifically, this allows checking for PO file updates in the tests run by
`test_driver.py`. Because these use a tmpdir for `$HOME`, building within such a
test requires installing the entire Rust toolchain and doing a clean build,
which is a waste of resources.
With this argument, it is possible to build the template before running the
tests and passing the file path into the script.
2025-06-15 23:43:31 +02:00
Daniel Rainer
1e571263a0 Ensure translation script is CWD-independent 2025-06-15 23:43:31 +02:00
Daniel Rainer
1a0a6f544d Do not export test strings
When including the tests in the build, string literals passed to `wgettext!`
would be included in the gettext template file, which we do not want here,
because the strings should not be localized for this test.
2025-06-15 23:43:31 +02:00
Daniel Rainer
413ce9fdb3 Call cursor_position() lazily
This function does not need to run when the pager is not focused. Calling it
lazily eliminates the overhead of calling it when it is not needed.
This code runs on each keypress when entering a command, so it makes sense to
keep it as lean as possible. (At the very least it avoids spam when trying to
debug/analyze gettext behavior.)
2025-06-15 23:16:22 +02:00
Daniel Rainer
03e3d0aa3f Split up sphinx HTML and MAN file generation
This test is the one with the longest runtime. Splitting the two targets into
separate tests allows them to run in parallel, which can speed up the tests.
2025-06-15 18:44:58 +02:00
Peter Ammon
00c528c13f Remove parser.assert_can_execute
We don't need this; Rust's Send safety means that a Parser never changes its
thread.
2025-06-14 16:05:54 -07:00
Peter Ammon
60dbb9c8ba Fix a misleading comment. 2025-06-14 15:18:18 -07:00
Peter Ammon
2104f8a18a Remove Rc from Parser's vars
This will help enable Parser to be Send, which will be important for
concurrent execution.
2025-06-14 13:59:17 -07:00
Peter Ammon
6f18a362e6 Remove the process argument to ProcPerformer
Processes can't cross threads, so this doesn't belong here.
Preparation for concurrent execution.
2025-06-14 13:34:04 -07:00
Peter Ammon
d67fdd1f02 Make Job store boxed process list instead of Vec 2025-06-14 12:04:52 -07:00
Creeperxie
d92bb57418 Add description for gzip -d completion 2025-06-14 10:59:44 -07:00
Peter Ammon
eb4cec1fe2 Clean up pgroup assignment and tighten up some post-fork code 2025-06-14 10:34:33 -07:00
Peter Ammon
ef2e30cdc1 Clean up pids
Use OnceLock more often in place of atomics. Tighten up async signal safety.
2025-06-14 10:34:27 -07:00
Peter Ammon
294d589d2f Clean up ProcStatus
Don't need all of these atomics.

In particular use OnceLock in InternalProc as this doesn't doesn't need
locking if there's only a single writer.
2025-06-14 10:34:20 -07:00
Peter Ammon
415232631a Continued refactoring of some exec functions 2025-06-14 10:34:15 -07:00
Peter Ammon
e10a12c0f2 Rationalize certain edge cases for function execution
This concerns edge cases when executing a function. Historically, when we parse
fish script, we identify early whether or not it's a function; but only record
the function's name and not its properties (i.e. not its source).

This means that the function can change between parsing and execution. Example:

    function foo; echo alpha; end
    foo (function foo; echo beta; end)

This has historically output "beta" because the function is replaced as part of
its own arguments.

Worse is if the function is deleted:

    function foo; echo alpha; end
    foo (functions --erase foo)

This outputs an error but in an awkward place; that's OK since it's very rare.

Let's codify this behavior since someone might be depending on it.
2025-06-14 10:34:10 -07:00
Peter Ammon
6fffb76937 Move Process's block node into its Type
Previously, for Processes which were BlockNodes, we stored the node separately
in the Process via an Option; just promote this to a real field of the
ProcessType::BlockNode.

No user visible changes expected.
2025-06-14 10:34:05 -07:00
Peter Ammon
36e385e1fb Make ProcessType not Eq or PartialEq
We are going to give it fields shortly.
2025-06-14 10:33:58 -07:00
Peter Ammon
e598010020 Clean up some Node representations
Use NodeRef more pervasively, leading to simplifications.
2025-06-14 10:33:53 -07:00
Peter Ammon
eba4c906ae Minor cleanup of process creation
Remove some useless types and unnecessary boxing.
2025-06-14 10:33:48 -07:00
Peter Ammon
fbb4a8d853 Adopt Rust naming conventions in JobControl and ProcessType 2025-06-14 10:33:46 -07:00
Peter Ammon
10e525c49c Fix rustdoc warnings on macOS 2025-06-14 10:32:41 -07:00
Johannes Altmanninger
ec27b418e4 test_driver: support Python 3.8 for now
Our docker tests are currently broken since we no longer seem to install
"build_root".  When I sidestep this issue for now and run

	sudo docker/docker_run_tests.sh --shell-before docker/focal.Dockerfile
	cd /fish-source
	CARGO_TARGET_DIR=$HOME/out
	tests/test_driver.py ~/out/debug

the test driver fails in various ways.
This is because Ubuntu Focal provides Python 3.8.

Fix some of the typing incompatibilities.  Fix a hang in tests like
"tests/checks/init-command.fish"; apparently fish believes it's interactive
because Python 3.8's create_subprocess_shell() makes the fish child believe
that stdin is a TTY, so it's implicitly interactive.
2025-06-13 15:04:31 +02:00
Johannes Altmanninger
535a09a5b3 Silence error in check-all-fish-files
Our docker/docker_run_tests.sh script runs tests in a container with the fish
source tree mounted as read-only.  We have a hack to speed up repeated runs
of the check-all-fish-files test that assumes the source tree is writable.
Paper over this by silencing the error for now.

  There were no remaining checks left to match stderr:1:
    touch: cannot touch '/fish-source/tests/.last-check-all-files': Read-only file system
2025-06-13 14:56:02 +02:00
Johannes Altmanninger
d584f36f5d Remove support for elf-patching LOCALEDIR
Commit bf65b9e3a7 (Change `gettext` paths to be relocatable (#11195),
2025-03-30) is difficult to follow because it combines code movement with
two behavior changes. Our parent commit fixed the first behavior change.

The second behavior change made us tolerate trailing NUL bytes in LOCALEDIR.
This was motivated because conda wants to use binary patching to change
the effective prefix at runtime, presumably so the user can move around the
"fish" executable program arbitraily.

This turned out to be unnecessary because fish is already "relocatable"
(see our parent commit).

Let's remove the special case for LOCALEDIR. Treat it like other paths.

Closes #11574
Closes #11474
2025-06-13 11:22:15 +02:00
Johannes Altmanninger
c3740b85be config_paths: fix compiled-in locale dir
Fish uses this logic to find paths to functions etc.:

1. if $(status fish-path) starts with $CARGO_MANIFEST_DIR,
   we use $CARGO_MANIFEST_DIR/share etc.

   Aside: this also has the unintended effect that "cmake
   -DCMAKE_INSTALL_PREFIX=$PWD/prefix" will not use "$PWD/prefix/share" but
   "$PWD/share", at least since eacbd6156d (Port and adopt main written in
   Rust, 2023-08-18).

2. Else if $(status fish-path) ends with "bin/fish",
   and $(status fish-path)/../share/fish exists, we use that, since 4912967eab
   (Large set of changes related to making fish relocatable, and improving
   the build and install story, 2012-07-08)

3. Else if $(status fish-path) ends in "fish" (which is very likely),
   and $(status fish-path)/share exists, we use that, since
   c2a8de4873 (Make fish find config directories in source tree, 2016-09-23).
   I think this is for running (without installing) in-tree builds ("cmake .");
   this is not recommended but it is used, see
   https://github.com/fish-shell/fish-shell/pull/10330

4. If none of the above worked, either because the fish binary has been
   moved into a weird directory, or if we fail to get $(status fish-path)
   (e.g. on OpenBSD, where "argv[0]" is not available),
   then we fall back to reasonable default paths determined at compiled
   time.

   These paths include data_dir=$PREFIX/share.
   We recently added locale_dir too in bf65b9e3a7 (Change `gettext` paths
   to be relocatable (#11195), 2025-03-30).

In case 1, we use               locale: manifest_dir.join("share/locale"),
In case 2 and 3, we use         locale: data_dir.join("locale"),
In case 4, we use               locale: data_dir.join("share"),

The last one seems wrong (there is not "/usr/share/share"). Fix that.

Alternatively, we could revert bf65b9e3a7 (and redo the parts we want to keep).
2025-06-13 11:22:15 +02:00
Johannes Altmanninger
d840fd9a7f config_paths: remove code clone
Another evident problem from bf65b9e3a7 (Change `gettext` paths to be
relocatable (#11195), 2025-03-30). How disrespectful.
2025-06-13 11:22:15 +02:00
Johannes Altmanninger
592b059c30 config_paths: inline function 2025-06-12 11:20:56 +02:00
Johannes Altmanninger
86b9a0b876 test_driver: use isinstance chain to replace Python 3.10's match statement
We still want to support Python 3.9 (debian-oldstable); it's still used by
our (outdated) FreeBSD CI, and, more importantly by (nightly) builders on OBS.

Ref: https://github.com/fish-shell/fish-shell/pull/11560#discussion_r2134556573
2025-06-12 11:20:55 +02:00
Johannes Altmanninger
6822a772fb Merge pull request #11573 2025-06-12 10:29:11 +02:00
Daniel Rainer
912d93c99d Remove tmpdirs at the end of tests 2025-06-11 22:33:32 +02:00
Johannes Altmanninger
74f4742565 Merge pull request #11567 2025-06-11 14:02:07 +02:00
Johannes Altmanninger
a47dcad1ea Clean up staticbuild CI action
- This action does not use CMake or CTest, so remove associated environment variables.
- Remove a seemingly unnecessary check

Tested with "gh --repo krobelus/fish-shell workflow run staticbuild.yml --ref=tmp", see
https://github.com/krobelus/fish-shell/actions/runs/15583255106/job/43883294589
2025-06-11 13:22:09 +02:00
Johannes Altmanninger
69bd7cc9a5 Merge pull request #11561 2025-06-11 11:14:56 +02:00
Daniel Rainer
b56ee16aa9 Parallelize test_driver.py
This uses Python's `asyncio` to run tests in parallel, which speeds up test
execution significantly.

The timeout is removed. It would be possible to add a timeout to
`asyncio.as_completed()` if we want that.
2025-06-10 20:11:43 +02:00
Daniel Rainer
679cef9c0e Add async versions of littlecheck tests
These will be used by a parallelized version of `test_driver.py`.

The old, non-async versions are kept, but just a wrappers around the async
versions.
2025-06-10 20:11:43 +02:00
Daniel Rainer
01b623efce Do not modify env vars in test_driver.py
Such modifications would break tests when they run concurrently, as they will
when this script is parallelized using `asyncio`.
2025-06-10 20:11:36 +02:00
Daniel Rainer
aa627ea935 Allow specifying env for running test
This can be used instead of the default operating system variables.
Useful for running multiple tests which need different environments.
2025-06-10 19:37:47 +02:00
Daniel Rainer
c15a900f31 Fail on compilation failure 2025-06-10 19:37:47 +02:00
Daniel Rainer
1136e656e0 Remove --cachedir for test_driver.py
This was only used to cache `fish_test_driver`, which can be built in a few tens
of milliseconds on most systems.

This avoids using outdated binaries for testing and simplifies the code and its
usage.
2025-06-10 19:37:47 +02:00
Daniel Rainer
456c9254fa Annotate more run_test parameters
This helps with static analysis.

Rename the second argument to clarify what it refers to.
2025-06-10 19:37:47 +02:00
Daniel Rainer
ebc16e51d7 Build fish_test_helper at most once
If no `--cachedir` is specifed for `test_driver.py`, it would build
`fish_test_helper` once per test it runs. This is unnecessary. Instead, build it
once in the beginning before running any tests and then use the binary in all
tests.
2025-06-10 19:37:41 +02:00
Daniel Rainer
2d7a6063b9 Remove unnecessary trailing space 2025-06-10 17:08:44 +02:00
Daniel Rainer
7c57b746d0 Use Path for some paths
The added type annotations help with static analysis and constructing paths gets
some syntactic sugar.
2025-06-10 17:07:19 +02:00
Daniel Rainer
64442cb464 Use with syntax for tmpdir root 2025-06-10 16:20:56 +02:00
Lorenzo Albano
07ead04890 Improve fish_git_prompt stashes detection.
When the informative status is disabled, the stashstate variable was
set to 1 if the $git_dir/logs/refs/stash file existed and was readable,
even if the file itself was empty (i.e., no stashes). Now the stashstate
variable is set only if the file is NOT empty.
2025-06-09 13:16:24 +02:00
Johannes Altmanninger
5346d3d491 check-all-fish-files: don't glob the entire worktree
Commit 22c0054c1e (Add check to test all fish files with -n, 2020-02-17)
added a test that runs "fish --no-execute" on all fish files in share/**.fish

Commit 329cd7d429 (Make functions, completions and tests resilient to
running on an embed-data fish, 2025-03-25) change this to run it on **.fish.

Evidently "the tests are exempt because they contain syntax errors" is no
longer true - this is because we have since changed those files to recursively
run 'fish -c "syntax-error"', which makes it easier to test for multiple
syntax-errors in a single test file. Remove the comment.

Globbing everything seems a bit crass, and there's no explicit
motivation.

	$ time find -name '*.fish' >/dev/null
	Executed in  431.93 millis
	$ time find * -name '*.fish' >/dev/null
	Executed in   39.98 millis

Let's go back to testing only directories where we currently have Git-tracked
fish files.  This makes uncached "check-all-fish-files.fish" go from 26
seconds to 5 seconds.
2025-06-09 10:28:49 +02:00
Johannes Altmanninger
138c6c4c40 check-all-fish-files: remove unneeded fallback
According to commit 8a07db8e8f (Revert "Revert "Speed up check-all-fish-files
when executed locally"", 2021-03-06), we can assume "find -newer" is supported.
2025-06-09 10:28:49 +02:00
Johannes Altmanninger
f8751a4f97 check-all-fish-files: fix caching logic
check-all-fish-files takes a long time (>20 seconds here); which is why we
have a (hacky) optimization to avoid checking files we already checked.
This optimization hasn't worked since commit e96b6e157c (Remove TMPDIR
dependency from tests/, 2021-07-30) which started each test invocation in
a private tmpdir. Fix that.

The optimization is useful because this test is, by far, the bottleneck
for parallel test execution (#11561):

	$ cargo b && time tests/test_driver.py target/debug
	...
	checks/tmux-complete.fish                      PASSED    8465 ms
	checks/check-completions.fish                  PASSED   10948 ms
	checks/check-sphinx.fish                       PASSED   12949 ms
	checks/check-all-fish-files.fish               PASSED   29828 ms
	200 / 200 passed (0 skipped)
	________________________________________________________
	Executed in   31.00 secs    fish           external
	   usr time   81.02 secs  462.00 micros   81.02 secs
	   sys time   26.41 secs  272.00 micros   26.41 secs

A cache miss for check-all-fish-files.fish takes 24 seconds (though the
grandchild commit will speed this up), a cache hit 0.5 seconds.
2025-06-09 10:28:49 +02:00
Johannes Altmanninger
cdc2db5eae Update translations for git completions 2025-06-08 14:07:17 +02:00
Johannes Altmanninger
aea9cd6165 completions/git: sort stash completions after branches and others
Completions like "stash@{1}" don't give a lot of information, unlike local
branches which are sorted by recency so let's put those first.
2025-06-08 13:42:01 +02:00
Johannes Altmanninger
d0a490d76b completions/git: extract logic 2025-06-08 13:42:01 +02:00
Johannes Altmanninger
b4392f6f7d completions/git: extract function for adding arbitrary-revision-completion
Most Git commands take arbitrary revisions.  AFAICT, we usually want the same
order, e.g. list local branches before remote branches before commit IDs etc.
I think there is no particular reason why this order is inconsistent between
various subcommands.

Let's extract a function. This standardizes the order and adds various
revision-types that were missing for some subcommands.
2025-06-08 13:42:01 +02:00
Johannes Altmanninger
7f2f5bb2f4 completions/git: remove code clone 2025-06-08 13:26:12 +02:00
Johannes Altmanninger
c47ecf9677 completions/git: rebase --onto requires a revision argument 2025-06-08 13:21:55 +02:00
Johannes Altmanninger
cd45a8c5cc completions/git: add more special refs
These are things like .git/HEAD, i.e. the ones that are typically not
namespaced under .git/refs.  The list is taken from gitrevisions(7).
2025-06-08 13:21:55 +02:00
Johannes Altmanninger
99f78fb0b1 completions/git: fix copy-paste error
This variable is never defined. It was copied from Git's
contrib/completion/git-completion.bash where $match is probably equivalent
to $(commandline -t). I could not measure a significant speedup from passing
this filter to "git for-each-ref", so let's remove it for now.
2025-06-08 13:21:55 +02:00
Johannes Altmanninger
235108e2df CI rust_checks: cargo --workspace obsoletes --all
This flag exists since 1.39, see
https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-139-2019-11-07

While at it, remove the "--all" option from "cargo fmt",
since it's not needed for formatting the entire workspace,
and because it would also format path-dependencies, see
https://github.com/fish-shell/fish-shell/pull/11550#discussion_r2133674330
2025-06-08 13:21:12 +02:00
Johannes Altmanninger
e66b13ac3d Merge pull request #11560 2025-06-08 12:09:41 +02:00
Johannes Altmanninger
0c211cbffb Merge pull request #11564 2025-06-08 11:27:01 +02:00
Johannes Altmanninger
da5a394178 Merge pull request #11566 2025-06-08 11:25:41 +02:00
Johannes Altmanninger
59bfd3ba6c Merge pull request #11563 2025-06-08 11:25:32 +02:00
Daniel Rainer
631bde1081 Revert "Hide some calls to localize() via Deref/AsRef"
This reverts commit 894139933d.

Rationale in this comment thread:
https://github.com/fish-shell/fish-shell/pull/11547#discussion_r2133625349
2025-06-08 02:52:01 +02:00
cyclopentane
383d2aa3e9 Fix behaviour upon repeating a vi-mode t/T jump 2025-06-08 01:03:06 +02:00
Daniel Rainer
cac3d0ef16 Build before running style.fish
This makes the latest versions of fish_indent (and fish) available to
`style.fish`.
2025-06-07 20:21:29 +02:00
Daniel Rainer
4721ffe512 Remove unused variables 2025-06-07 19:31:06 +02:00
Daniel Rainer
df097b114c Put test tmpdirs under common root tmpdir
This is done to prepare for running the tests in parallel.
With this approach the root tmpdir can be created before any test starts, each
test can create its home dir under the root tmpdir,
and when all tests are done the root tmpdir can be deleted.
Deletion of per-test dirs is more difficult in an async context.
2025-06-07 19:30:44 +02:00
Daniel Rainer
2ebe3134cf Extract function for running tests
This is done to prepare for running tests concurrently.

Align output and prevent flushing stdout between test name and result.
2025-06-07 19:28:58 +02:00
David Adam
d663f553df document alt-s binding programs more clearly 2025-06-07 22:47:56 +08:00
Shayan
dcde198c94 completions/adb: add listing device files for exec-out subcommand 2025-06-07 22:44:57 +08:00
Daniel Rainer
b5c393dc39 Add simple script for running checks
This is intended as a way to run all available checks with a single command.

The script can be used locally and in CI. It is intended to replace
`cmake/Tests.cmake` (but this script also runs checks not present there).
At the moment, `ctest` is not used, which could be added to speed up tests.

Address and thread sanitizers are not run by this script.
2025-06-07 15:34:53 +02:00
Daniel Rainer
f0a54510c3 Format files using build_tools/style.fish 2025-06-07 15:34:53 +02:00
Daniel Rainer
d18d414745 Improve style.fish
Add flags to control behavior.
- `--check` to fail if changes would be made by formatters
- `--force` to skip the prompt about uncommitted changes

Fix behavior when `--all` is not specified. It used to operate on `$files`,
which did not get set in that case.

Not all fish files are considered, mainly because some tests might test how fish
behaves on weirdly formatted files.

For Rust files, `cargo fmt` is used when `--all` is specified.
The `--check` flag for `cargo fmt` is used when appropriate.

Do not try to build `fish_indent`. `make fish_indent` does not work anymore. Let
the user handle building and installing/setting `$PATH`.
2025-06-07 15:34:53 +02:00
Johannes Altmanninger
ac44b3da91 build_tools/fish_xgettext.fish: fix formatting 2025-06-07 11:15:44 +02:00
Johannes Altmanninger
0903e7a8f2 Merge pull request #11557 2025-06-07 10:20:30 +02:00
Johannes Altmanninger
894139933d Hide some calls to localize() via Deref/AsRef
As suggested in https://github.com/fish-shell/fish-shell/pull/11547#discussion_r2133625349
AsRef is needed for OutputStream::append which has this signature:

	pub fn append<Str: AsRef<wstr>>(&mut self, s: Str) -> bool
2025-06-07 10:20:30 +02:00
Johannes Altmanninger
1aec1d3955 Merge pull request #11547
Supersedes previous approaches:
Closes #11543
Closes #11536
2025-06-07 10:20:30 +02:00
Daniel Rainer
a138bc328b Fix eager cloning
https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned
2025-06-07 00:22:52 +02:00
Daniel Rainer
b9583bb16a Document call sites of from_external_source
This is intended to provide information to programmers where localizations might
be coming from, and potentially help with analyzing issues with localizations.
2025-06-07 00:10:10 +02:00
Daniel Rainer
80033adcf5 Use LocalizableString for gettext
This new wrapper type can be constructed via macros which invoke the
`gettext_extract` proc macro to extract the string literals for PO file
generation.

The type checking enabled by this wrapper should prevent trying to obtain
translations for a string for which none exist.

Because some strings (e.g. for completions) are not defined in Rust, but rather
in fish scripts, the `LocalizableString` type can also be constructed from
non-literals, in which case no extraction happens.
In such cases, it is the programmer's responsibility to only construct the type
for strings which are available for localization.

This approach is a replacement for the `cargo-expand`-based extraction.

When building with the `FISH_GETTEXT_EXTRACTION_FILE` environment variable set,
the `gettext_extract` proc macro will write the messages marked for extraction
to a file in the directory specified by the variable.

Updates to the po files:
- This is the result of running the `update_translations.fish` script using the
  new proc_macro extraction. It finds additional messages compared to the
  `cargo-expand` based approach.
- Messages IDs corresponding to paths are removed. The do not have localizations
  in any language and localizing paths would not make sense. I have not
  investigated how they made it into the po files in the first place.
- Some messages are reordered due to `msguniq` sorting differing from `sort`.

Remove docs about installing `cargo-expand`
These are no longer needed due to the switch to our extraction macro.
2025-06-07 00:10:05 +02:00
Daniel Rainer
51a57870eb Make help error message localizable 2025-06-07 00:02:31 +02:00
Daniel Rainer
98b3ba5e8e Remove concat! macro from localized strings
This is done in preparation for a proc macro which extracts strings which are
passed to `gettext`. Because the `concat!` macro would get expanded after the
proc macro, the proc macro would still see the `concat!`, which it cannot
handle.
2025-06-07 00:02:14 +02:00
Johannes Altmanninger
08bf5c92a9 Merge pull request #11545 2025-06-06 12:54:55 +02:00
Johannes Altmanninger
a84048511e Merge pull request #11542 2025-06-06 11:54:45 +02:00
Johannes Altmanninger
46e8f12dbf Merge pull request #11554 2025-06-05 14:28:36 +02:00
Dennis Huang
7fe92be405 Add --all option to path
- Add --all option to path
- Add tests
- Add doc
2025-06-05 14:10:47 +02:00
Chinmay Dalal
366034940f Add run0 to alt-s commands
https://www.freedesktop.org/software/systemd/man/devel/run0.html
Since everyone using a systemd distro will have this, it's added
at the end so that it's tried last
2025-06-04 20:00:52 +05:30
Daniel Rainer
6239cba1e4 Add dry-run mode to update_translations.fish
This mode is intended for testing if the PO files are up-to-date and
well-formed.

At the moment, we only check translations in CI, where this is not particularly
relevant. Once we no longer need `cargo-expand`
(e.g. via https://github.com/fish-shell/fish-shell/pull/11536)
we can extend the `check_translations.fish` test to run
`update_translations.fish --dry-run` and fail if the exit status is nonzero.
2025-06-02 03:18:25 +02:00
Daniel Rainer
8c5de9acfb Remove manual contains
See https://rust-lang.github.io/rust-clippy/master/index.html#manual_contains.

The old code results in a clippy warning on Rust 1.87.
2025-05-31 12:56:58 +02:00
Daniel Rainer
75d243faaa Check rustdocs in CI
Setting `RUSTDOCFLAGS='-D warnings'` is needed to fail on warnings.
For `cargo test --doc` no equivalent option seems to exist.
See https://github.com/rust-lang/cargo/issues/14802.
2025-05-30 21:32:40 +02:00
Daniel Rainer
ba86028aaa Fix rustdoc warning 2025-05-30 21:32:40 +02:00
Johannes Altmanninger
7a79728df3 kitty keyboard protocol: fall back to base layout key
On terminals that do not implement the kitty keyboard protocol "ctrl-ц" on
a Russian keyboard layout generally sends the same byte as "ctrl-w". This
is because historically there was no standard way to encode "ctrl-ц",
and the "ц" letter happens to be in the same position as "w" on the PC-101
keyboard layout.

Users have gotten used to this, probably because many of them are switching
between a Russian (or Greek etc.) and an English layout.

Vim/Emacs allow opting in to this behavior by setting the "input method"
(which probably means "keyboard layout").

Match key events that have the base layout key set against bindings for
that key.

Closes #11520

---

Alternatively, we could add the relevant preset bindings (for "ctrl-ц" etc.)
but
1. this will be wrong if there is a disagreement on the placement of "ц" between two layouts
2. there are a lot of them
3. it won't work for user bindings (for better or worse)
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
4cbd1b83f1 fish_key_reader: unopinionated description for bind notation variants
As explained in the parent commit, "alt-+" is usually preferred over
"alt-shift-=" but both have their moments. We communicate this via a comment
saying "# recommended notation". This is not always true and not super helpful,
especially as we add a third variant for #11520 (physical key), which is
the recommended one for users who switch between English and Cyrillic layouts.

Only explain what each variant does. Based on this the user may figure out
which one to use.
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
3ab6fcf21c fish_key_reader: show most specific key notation first
As of the parent commit, "ctrl-shift-x" bindings will take precedence over
"ctrl-X". Have fish_key_reader imply this via the ordering The next commit
will make this more explicit.
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
08c8afcb12 Match bindings with explicit shift first
The new key notation canonicalizes aggressively, e.g.  these two bindings
clash:

	bind ctrl-shift-a something
	bind shift-ctrl-a something else

This means that key events generally match at most one active binding that
uses the new syntax.

The exception -- two coexisting new-syntax binds that match the same key
event -- was added by commit 50a6e486a5 (Allow explicit shift modifier for
non-ASCII letters, fix capslock behavior, 2025-03-30):

	bind ctrl-A 'echo A'
	bind ctrl-shift-a 'echo shift-a'

The precedence was determined by definition order.
This doesn't seem very useful.

A following patch wants to resolve #11520 by matching "ctrl-ц" events against
"ctrl-w" bindings. It would be surprising if a "ctrl-w" binding shadowed a
"ctrl-ц" one based on something as subtle as definition order.  Additionally,
definition order semantics (which is an unintended cause of the implementation)
is not really obvious.  Reverse definition order would make more sense.

Remove the ambiguity by always giving precedence to bindings that use
explicit shift.

Unrelated to this, as established in 50a6e486a5, explicit shift is still
recommended for bicameral letters but not typically for others -- e.g. alt-+
is typically preferred over alt-shift-= because the former also works on a
German keyboard.

See #11520
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
3951a858dd reader: do not send queries if stdout is not a terminal
Interactive fish with output redirected ("fish >/dev/null")
is not a common use case but it is valid.

Perhaps surprisingly, "fish >some-file" *does* print terminal escape codes
(colors, cursor movement etc.) even if terminal output is not a TTY.
This is typically harmless, and potentially useful for debugging.

We also send blocking terminal queries but those are not harmless in this case.
Since no terminal will receive the queries, we hang; indefinitely as of today,
but we should give up after a timeout and print an error.  Either way that
seems needlessly surprising. Suppress queries in this case.

In future, we should probably do something similar if stdin is not a terminal;
though in that case we're even less likely to be interactive (only "-i"
I think).
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
c7a19a00ab reader: minor simplification 2025-05-29 17:57:38 +02:00
Johannes Altmanninger
e5fdd77b09 input: remove unnecessary check in bracketed paste code path
When "self.paste_is_buffering()" is true, "parse_escape_sequence()" explicitly
returns "None" instead of "Some(Escape)".  This is irrelevant because this
return value is never read, as long as "self.paste_is_buffering()" remains
true until "parse_escape_sequence()" returns, because the caller will return
early in that case. Paste buffering only ends if we actually read a complete
escape sequence (for ending bracketed paste).

Remove this extra branch.
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
3fcdbe1a19 Discard input queue when ctrl-c is pressed while waiting for query response
On startup, we block until the terminal responds to our primary device
attribute query.
As an escape hatch, ctrl-c makes us stop waiting.

No keys are discarded; even ctrl-c is still enqueued.  Usually this isn't
noticed because typing "echo<ctrl-c>" will insert a "echo" only to immediately
clear it.

The double interpretation of ctrl-c seems odd.
Additionally, the queuing seems unsafe considering that when typing something
like "echo hello<enter><ctrl-c>" the command will be executed.

Clear the queue instead, including ctrl-c.
This matches other programs like gdb, Kakoune and possibly others.
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
2071df126c Idiomatic type for reader_readline nchars argument 2025-05-29 17:57:38 +02:00
Johannes Altmanninger
4b5650ee4f completions/git: improve idempotency in case of double load
As mentioned in the previous few commits and in #11535, running
"set fish_complete_path ..."  and "complete -C 'git ...'"  may result in
"share/completions/git.fish" being loaded multiple times.

This is usually fine because fish internally erases all cached completions
whenever fish_complete_path changes.

Unfortunately there is at least global variable that grows each time git.fish
is sourced. This doesn't make a functional difference but it does slow
down completions.  Fix that by resetting the variable at load time.
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
5657f093e7 Test case for autoload + erase + autoload
Commit 5918bca1eb (Make "complete -e" prevent completion autoloading,
2024-08-24) has a weird "!removed" check; it was added because "complete
-e" only needs to create the tombstone if we removed nothing.  Otherwise the
autoloader will usually take care of not loading the removed completions again.
We should probably get rid of "!removed"..  for now add a test to demonstrate
this behavior.
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
a7c04890c9 Fix "set fish_complete_path" accidentally disabling autoloading
Commit 5918bca1eb (Make "complete -e" prevent completion autoloading,
2024-08-24) makes "complete -e foo" add a tombstone for "foo", meaning we
will never again load completions for "foo".

Due to an oversight, the same tombstone is added when we clear cached
completions after changing "fish_complete_path", preventing completions from
being loaded in that case.  Fix this by restoring the old behavior unless
the user actually used "complete -e".
2025-05-29 17:57:38 +02:00
Johannes Altmanninger
52f23b9752 autoload: add more details to autoload-result log 2025-05-29 17:50:48 +02:00
Johannes Altmanninger
6737872fb7 embed-data: naturalize generated_completions-hack to prevent repeated autoloading
As reported in https://github.com/fish-shell/fish-shell/issues/11535#issuecomment-2915440295,
a command like "complete -C'git '" gets progressively slower every time.

A diff of "fish_trace=1" output shows that each completion invocation added
more stuff to the global "__fish_git_aliases", resulting in output like:

	--> for s db
	...
	--> for s db s db
	...
	--> for s db s db s db

Reproducer:

	$ touch ~/.local/share/fish/generated_completions/foo.fish
	$ cargo install --path . --debug
	$ ~/.cargo/bin/fish -d autoload -c 'function foo; end; for i in 1 2; complete -C"foo "; end'

We redundantly autoload the embedded file, which, by definition doesn't change.
This happens when
1. the "embed-data" feature is enabled (default for "cargo install")
2. there is a completion file in generated_completions

which triggers a hack to give precedence to "embedded:completions/git.fish"
over "generated_completions/git.fish".

Since we always load all file-based files first, we clobber the autoload cache
("self.autoloaded_files") with the mtime of the generated completion file, even
if we're never gonna return it.  This makes the embed-data logic think that
the asset has changed (which is impossible! But of course it is possible that
"fish_complete_path" changes and causes a need to load "embedded:git.fish").

Fix that by treating embedded files more like normal files.  This is closer
to historical behavior where $__fish_data_dir/{functions,completions}
are normal directories. Seems like this should fix a false negative in
"has_attempted_autoload" which feels useful.

Add a dead test, I guess. It's not run with feature="embed-data" yet. In
future we should test this in CI.
2025-05-29 17:38:42 +02:00
Johannes Altmanninger
f88f7e8dd6 autoload: remove code clone 2025-05-29 16:39:52 +02:00
Johannes Altmanninger
b3dbdb90c2 On enter, insert any failed search into the command line
This might help with use cases such as https://github.com/fish-shell/fish-shell/pull/11450.
Not sure.
2025-05-29 16:39:52 +02:00
Johannes Altmanninger
dc129add9e Assert that autosuggestions are always valid
This documents an invariant established by 532abaddae (Invalidate stale
autosuggestions eagerly, 2024-12-25). It was initially broken but fixed in
ba4ead6ead (Stop saving autosuggestions that we can't restore, 2025-01-17).
2025-05-29 16:39:52 +02:00
Johannes Altmanninger
19c3bebdd9 Merge pull request #11506 2025-05-29 16:23:19 +02:00
Johannes Altmanninger
093b468ac1 Merge pull request #11502 2025-05-29 16:06:24 +02:00
Johannes Altmanninger
88bbf5f3ac Merge pull request #11497 2025-05-29 16:06:11 +02:00
Daniel Rainer
ec8fa7485c Improve docs for string join 2025-05-28 17:09:13 +02:00
Daniel Rainer
c2e2237e7c Add a test which fails on sphinx warning/failure 2025-05-28 15:32:13 +02:00
Daniel Rainer
98df97d317 Add CI check for outdated translations 2025-05-27 16:48:33 +02:00
Daniel Rainer
7ca57894cc Update translations via script
No actual translations are added.
2025-05-27 16:48:20 +02:00
Johannes Altmanninger
c7391d1026 Fix some invalid assertions parsing keys
For example the terminal sending « CSI 55296 ; 5 u » would crash fish.
2025-05-27 14:33:09 +02:00
Johannes Altmanninger
1963b0830d Merge pull request #11517 2025-05-27 13:15:34 +02:00
Johannes Altmanninger
74ce965f32 Merge pull request #11522 2025-05-27 13:15:34 +02:00
Johannes Altmanninger
27420aaf8b Merge pull request #11528 2025-05-27 13:15:34 +02:00
Johannes Altmanninger
52cdb7fd62 functions/history: error out immediately if "builtin read" failed
Didn't test all of them..

Closes #11532
2025-05-27 13:15:33 +02:00
exploide
18c4debbc0 __fish_complete_man: cope with gzipped man pages 2025-05-25 11:48:28 +02:00
Johannes Altmanninger
8617964d4d Fix uvar file mtime force-update (Rust port regression)
When two fish processes rewrite the uvar file concurrent, they rely on the
uvar file's mtime (queried after taking a lock, if locking is supported) to
tell us whether their view of the uvar file is still up-to-date.  If it is,
they proceed to move it into place atomically via rename().

Since the observable mtime only updates on every OS clock tick, we call
futimens() manually to force-update that, to make sure that -- unless both
fish conincide on the same *nanosecond* -- other fish will notice that the
file changed.

Unfortunately, commit 77aeb6a2a8 (Port execution, 2023-10-08) accidentally
made us call futimens() only if clock_gettime() failed, instead of when
it succeeded. This means that we need to wait for the next clock tick to
observe a change in mtime.
Any resulting false negatives might have caused us to drop universal variable updates.

Reported in https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2098948362

See #10300
2025-05-23 08:49:41 +02:00
wcbing
0d99859add completions/apt & apt-get: Let autoremove and autopurge take packages
- add complete for apt-get's autopurge
- continue #7095, add complete for apt/apt-get's autoremove and autopurge
2025-05-21 12:11:24 +08:00
nicole
0b8e0b8835 Add more completions to aptitude 2025-05-20 16:39:38 -03:00
Johannes Altmanninger
3867163193 Fixup history file EINTR loop to actually loop
Fixes d84e68dd4f (Retry history file flock() on EINTR, 2025-05-20).
2025-05-20 17:17:12 +02:00
Johannes Altmanninger
4d84e68dd4 Retry history file flock() on EINTR
When locking the uvar file, we retry whenever flock() fails with EINTR
(e.g. due to ctrl-c).

But not when locking the history file.  This seems wrong; all other libc
functions in the "history_file" code path do retry.

Fix that. In future we should extract a function.

Note that there are other inconsistencies; flock_uvar_file() does not
shy away from remote file systems and does not respect ABANDONED_LOCKING.
This means that empirically probably neither are necessary; let's make things
consistent in future.

See https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2095096200
Might help #10300
2025-05-20 15:31:33 +02:00
Johannes Altmanninger
285a810814 Revert "Temporarily enable history_file debug category by default"
Commit f906a949cf (Temporarily enable history_file debug category by default,
2024-10-09) enabled the "history_file" debug category by default to gather
more data.

Judging from
https://github.com/fish-shell/fish-shell/issues/10300#issuecomment-2876718382
the logs didn't help, or were at least not visible when logging to stderr
(due to reboot).

Let's disable "history_file" logs again to remove potential
noise if the file system is read-only, disk is full etc., see
https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2094781120

See #10300
2025-05-20 15:31:33 +02:00
Johannes Altmanninger
541a069a91 CI: fix detection of path to llvm-symbolizer
clang --version here outputs "clang version 19.1.7"
but it looks like that changed on GHA's Ubuntu runner:

	++ clang --version
	++ awk 'NR==1 { split($NF, version, "."); print version[1] }'
	+ llvm_version='(1ubuntu1)'

which leads to

	  The CHECK on line 7 wants:
	    abbr -a -- cuckoo somevalue # imported from a universal variable, see `help abbr`

	  but there was no remaining output to match.

	  additional output on stderr:1:111:
	    =================================================================
	    ==4680==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7bc287a5d402 at pc 0x55e597fa96b6 bp 0x7ffd2bc00700 sp 0x7ffd2bbffea8
	    READ of size 18 at 0x7bc287a5d402 thread T0
	    ==4680==WARNING: invalid path to external symbolizer!
	    ==4680==WARNING: Failed to use and restart external symbolizer!

Fix that, assuming that "clang --version" always matches the latest symbolizer
that is installed.  While at it, leave a "set -x" (which should be the
default for CI), and install llvm explicitly.
2025-05-20 14:28:38 +02:00
Johannes Altmanninger
e8864ef441 Fix stack-use-after-scope
I missed this in 7c2c7f5874 (Use uninit instead of zeroed, 2025-05-19).
See #11515
2025-05-20 14:18:04 +02:00
Johannes Altmanninger
2f708a7c0b Fix unused import 2025-05-20 12:49:25 +02:00
Johannes Altmanninger
b7a73710e2 Merge pull request #11515 2025-05-20 12:49:04 +02:00
Johannes Altmanninger
7a54ed66fb Merge pull request #11514 2025-05-20 12:39:04 +02:00
Johannes Altmanninger
99f4c09ed3 Merge pull request #11513 2025-05-20 12:39:04 +02:00
Johannes Altmanninger
e26b585ce5 builtin status: remove spurious newline from current-command (Rust port regression)
WHen "status current-command" is called outside a function it always returns
"fish". An extra newline crept in, fix that.

Fixes 77aeb6a2a8 (Port execution, 2023-10-08).
Fixes #11503
2025-05-20 12:32:22 +02:00
王宇逸
7c2c7f5874 Use uninit instead of zeroed 2025-05-19 20:54:12 +08:00
Yuyi Wang
7b3a2900e9 Refactor *NullTerminatedArray
* Remove `strlen_safe` & `null_terminated_array_length` and use the provided method of `OwningNullTerminatedArray`.
* Remove unneeded traits and make `NullTerminatedArray` private.
2025-05-19 17:24:24 +08:00
Yuyi Wang
7a79366f91 Use CStr instead of strlen to improve readability 2025-05-19 16:47:09 +08:00
Yuyi Wang
223b98f2ff Fix build.rs to support cross-compiling to cygwin (#11512)
2719ae4 adds a special cfg for cygwin to avoid annoying warnings. As cygwin target is usually cross-compiled, cfg! is not enough to detect the correct target. This PR uses CARGO_CFG_TARGET_OS env var instead.
2025-05-19 10:27:04 +02:00
Yuyi Wang
01560bf195 Remove libc sem completely on non-linux (#11511)
As it's only used on Linux, we can cfg it out completely on other platforms. It also enables test_topic_monitor_torture on NetBSD & Cygwin.
2025-05-19 10:26:47 +02:00
Daniel Rainer
7fe34ea401 Move and rename messages template file
There is no reason to have this file clutter the repo root.
Move it into the `po` directory, and give it a more descriptive name.

Inspired by this discussion:
https://github.com/fish-shell/fish-shell/pull/11463#discussion_r2083453275

I use `template.po` instead of `message.po-template` to be more compatible with
automatic filetype detection. (e.g. vim/nvim detect the former as a po file, but
the latter as a conf file)
2025-05-18 21:31:00 -07:00
Johannes Altmanninger
36f035b52c Merge pull request #11501 2025-05-16 07:36:03 +02:00
Johannes Altmanninger
0e8edab872 Fix typo 2025-05-16 07:35:43 +02:00
Johannes Altmanninger
448d630d0c Merge pull request #11500 2025-05-16 07:35:34 +02:00
Johannes Altmanninger
38fb2cfd6d Merge pull request #11499 2025-05-16 07:32:45 +02:00
Johannes Altmanninger
d68f8bdd3b Include sys/statvfs.h for the definition of ST_LOCAL (Rust port regression)
See https://man.netbsd.org/statvfs.5.
According to https://github.com/NetBSD/src/blob/trunk/sys/sys/statvfs.h#L135,
NetBSD has "#define ST_LOCAL MNT_LOCAL".  So this commit likely makes no
difference on existing systems.

While at it
- comment include statements
- remove a code clone

See #11486
2025-05-16 07:31:26 +02:00
Johannes Altmanninger
80bafd5a22 Merge pull request #11486 2025-05-16 07:12:47 +02:00
Daniel Rainer
ae8c5eaab7 Fix rst formatting issues 2025-05-16 00:30:34 +02:00
Daniel Rainer
329d190fbf Update translation docs
This is done in accordance with the recent changes to our translation pipeline.
2025-05-15 22:35:05 +02:00
Daniel Rainer
e5fa047412 Mark format strings in po files
This allows msgfmt to detect issues with translations of format strings.
The detection used here is very simple. It just checks if a string contains '%',
and if it does, the entry in the po file is preceded by '#, c-format'.
Any entries with this marker are checked by msgfmt in our tests, so if an issue
arises, we will notice before it is merged.
2025-05-15 22:09:57 +02:00
Daniel Rainer
cb31887941 Do not hardcode xgettext output path
Instead output on stdout, which lets the caller decide what to do with it.
2025-05-13 21:18:39 +02:00
Johannes Altmanninger
04fd697ac9 CONTRIBUTING: update docs on how to create a new translation 2025-05-13 00:29:05 +02:00
Johannes Altmanninger
2558d13361 Merge pull request #11488 2025-05-13 00:21:49 +02:00
Daniel Rainer
02ccf25443 Prettify profiling for multi-line commands
The old version just prints the entire command being profiled as-is.
If such a command consists of more than one line, these lines do not have any
padding, and thus visually interfere with the timings.

This commit adds padding, such that all lines but the first one have padding
prepended, such that the original line content starts at the column in which the
first line starts.

This does not work perfectly for subcommands (in the profiling sense,
where the command starts with (regex) '-+>' instead of just '>').
In such cases, even if the command string is indented in the source, the command
will not start with whitespace. However, subsequent lines are not trimmed, so
the might be indented farther than they should be relative to the first line of
the command.
2025-05-13 00:11:33 +02:00
Johannes Altmanninger
a88acb9715 Merge pull request #11487 2025-05-13 00:01:11 +02:00
Johannes Altmanninger
8d3ad0c3c3 Merge pull request #11485 2025-05-13 00:01:11 +02:00
Johannes Altmanninger
660f52ee4f Merge pull request #11463 2025-05-13 00:01:11 +02:00
Johannes Altmanninger
594b8730d8 completions/git: fix regression causing wrong remote-branch completions
Fixes 54971621de (completions/git: show url as description for remote
completion, 2025-04-13).
Fixes #11482
2025-05-13 00:01:11 +02:00
Johannes Altmanninger
107e4d11de Fix Vi mode glitch when replacing at last character
Another regression from d51f669647 (Vi mode: avoid placing cursor beyond last
character, 2024-02-14) "Unfortunately Vi mode sometimes needs to temporarily
select past end". So do the replace_one mode bindings which were forgotten.

Fix this.

This surfaces a tricky problem: when we use something like

	bind '' self-insert some-command

When key event "x" matches this generic binding, we insert both "self-insert"
and "some-command" at the front of the queue, and do *not* consume "x",
since the binding is empty.

Since there is a command (that might call "exit"), we insert a check-exit
event too, after "self-insert some-command" but _before_ "x".

The check-exit event makes "self-insert" do nothing. I don't think there's a
good reason for this; self-insert can only be triggered by a key event that
maps to self-insert; so there must always be a real key available for it to
consume. A "commandline -f self-insert" is a nop. Skip check-exit here.

Fixes #11484
2025-05-13 00:01:11 +02:00
Johannes Altmanninger
50500ec5b9 Fix typo causing wrong cursor position after Vi mode paste
Regressed in d51f669647 (Vi mode: avoid placing cursor beyond last character,
2024-02-14).
2025-05-12 22:57:20 +02:00
Daniel Rainer
3ccce609f0 Add script for updating translations
The purpose of this script is to simplify the translation-related workflow for
both developers and translators. It runs the xgettext, msgmerge, msgfmt pipeline
(or only parts of it, depending on the arguments), either for all languages, or
for one specific one.

Developers can use the script with the `--no-mo` flag to update the PO files for
all languages after changes to the Rust/fish sources, to keep the translations
up to date. Ideally, this would run automatically for all changes, such that
translations are always up to date, but for now, it would already be an
improvement to run this script before releasing a new version of fish.

Translators can use the script in the same way as developers, to get up to date
PO files. To see their translations in action, the script can be called with
`--only-mo`, which takes the current version of the PO files and generates MO
files from them, which get placed in a location which fish (built with `cargo
build`) can detect.
Translators might also find it useful to specify the language they want to work
on as a non-option argument. This argument should be the path to the po file
they want to work on. Specifying non-existing files to work on a new language is
allowed, but the files must be in the po directory and follow the naming
convention.
2025-05-12 22:49:30 +02:00
Alan Somers
bd26d4b61b Fix use of deprecated symbols in Nix 2025-05-12 13:28:56 -06:00
Alan Somers
7f4998ad9b Fix remote filesystem detection on FreeBSD
Need an extra include to get the definition of MNT_LOCAL

Fixes #11483
2025-05-12 13:18:21 -06:00
Daniel Rainer
122f39de66 Replace loop by pipeline
This simplifies the logic a bit and performs a better.

Performance improvements for extract_fish_script_messages (time in
microseconds):
- explicit regex: from 128241 to 83471 (speedup 1.5)
- implicit regex: from 682203 to 463635 (speedup 1.5)
2025-05-12 20:54:32 +02:00
Daniel Rainer
1df8fbff67 Replace long list by file
The replaces the `strs` list by a corresponding file, which eliminates the need
for looping over the list.

Use sed to transform strings into gettext po format entries.

Format the file with fish_indent and use more expressive variable name for the
file cargo expand writes to.

Performance improvements (in microseconds):
- sort+format rust strings: from 21750 to 11096 (speedup 2.0)
2025-05-12 20:35:41 +02:00
Daniel Rainer
ff5ff50183 Speed up constant string extraction
The fish builtin string functions are significantly slower than grep + sed.
The final replacement of \' to ' also does not make any sense here, because
single quotes appear unescaped in Rust strings.

Performance improvement: from 404880 to 44843 (speedup 9.0)

Profiling details (from separate runs):
Time (μs)   Sum (μs)  Command
       174     404880 > set -a strs (string match -rv 'BUILD_VERSION:|PACKAGE_NAME' <$tmpfile |
             string match -rg 'const [A-Z_]*: &str = "(.*)"' | string replace -a "\'" "'")
    404706     404706 -> string match -rv 'BUILD_VERSION:|PACKAGE_NAME' <$tmpfile |
             string match -rg 'const [A-Z_]*: &str = "(.*)"' | string replace -a "\'" "'"

       202      44843 > set -a strs (grep -Ev 'BUILD_VERSION:|PACKAGE_NAME' <$tmpfile |
             grep -E 'const [A-Z_]*: &str = "(.*)"' |
             sed -E -e 's/^.*const [A-Z_]*: &str = "(.*)".*$/\1/' -e "s_\\\'_'_g")
      4952      44641 -> grep -Ev 'BUILD_VERSION:|PACKAGE_NAME' <$tmpfile |
             grep -E 'const [A-Z_]*: &str = "(.*)"' |
             sed -E -e 's/^.*const [A-Z_]*: &str = "(.*)".*$/\1/' -e "s_\\\'_'_g"
     28716      28716 --> command grep --color=auto $argv
     10973      10973 --> command grep --color=auto $argv
2025-05-12 20:11:05 +02:00
Daniel Rainer
c0d93e4740 Do not use huge fish list
Using a file is significantly faster.

Profiling overview (times in microseconds):
- cargo expand: from 4959320 to 4503409 (speedup 1.1)
- gettext call pipeline: from 436996 to 13536 (speedup 32.3)
- static string pipeline: from 477429 to 404880 (speedup 1.18)
2025-05-12 18:12:37 +02:00
Lucas Melo
3cbb5e384b Shorten and format completions for protontricks, protontricks-launch 2025-05-12 08:36:07 -03:00
Lucas Melo
90b35335ee Add completions for protontricks 2025-05-12 08:24:26 -03:00
Daniel Rainer
55752729d6 Fix escaping in translation 2025-05-12 00:51:07 +02:00
Johannes Altmanninger
41dfb5147f Fix typo in set_color test 2025-05-11 22:55:48 +02:00
Johannes Altmanninger
156fa8081c Underline styles for double/dotted/dashed
My phone uses dotted underline to indicate errors; that seems nice, a bit
less aggressive than curly.  Unfortunately dotted underlines are not as well
supported in terminal emulators; sometimes they are barely visible.  So it's
unlikely that we want to use --underline=dotted for an important theme.
Add double and dashed too I guess, even though I don't have a concrete
use case..
2025-05-11 22:18:06 +02:00
Johannes Altmanninger
3081d0157b Share alt-{b,f} with Vi mode, to work around Terminal.app/Ghostty more
Commit f4503af037 (Make alt-{b,f} move in directory history if commandline is
empty, 2025-01-06) had the intentional side effect of making alt-{left,right}
(move in directory history) work in Terminal.app and Ghostty without other,
less reliable workarounds.
That commit says "that [workaround] alone should not be the reason for
this change."; maybe this was wrong.

Extend the workaround to Vi mode.  The intention here is to provide
alt-{left,right} in Vi mode.  This also adds alt-{b,f} which is odd but
mostly harmless (?) because those don't do anything else in Vi mode.
It might be confusing when studying "bind" output but that one already has
almost 400 lines for Vi mode.

Closes #11479
2025-05-11 22:05:00 +02:00
Johannes Altmanninger
13e4736113 completions/commandline: don't offer deprecated option 2025-05-11 22:00:43 +02:00
Johannes Altmanninger
80e30ac756 Always treat brace at command start as compound statement
For backwards compatibility, fish does not treat "{echo,hello}" as a compound
statement but as brace expansion (effectively "echo hello").  We interpret
"{X...}" as compound statement only if X is whitespace or ';' (which is an
interesting solution).

A brace expansion at the very start of a command 
is usually pointless (space separation is shorter).
The exception are cases where the command name and the first few arguments
share a suffix.

	$ {,1,2,3,4}echo
	1echo 2echo 3echo 4echo

Not sure if anyone uses anything like that.  Perhaps we want to trade
compatibility for simplicity. I don't have a strong opinion on this.

Always parse the opening brace as first character of a command token as
compound statement.
Brace expansion can still be used with a trick like: «''{echo,foo}»

Closes #11477
2025-05-11 22:00:43 +02:00
Daniel Rainer
a86a4dfabf Remove source locations from translations
Source locations (file name and line number) where a string originates is not
required by gettext tooling. It can help translators to identify context,
but the value of this is reduced by our lack of context support, meaning that
all occurrences of a string will receive the same translation.
Translators can use `rg` or similar tools to find the source locations.
For further details see this thread:
https://github.com/fish-shell/fish-shell/pull/11463#discussion_r2079378627

The main advantage is that updates to the PO files are now only necessary when
the source strings change, which greatly reduces the diff noise.

A secondary benefit is that the string extraction logic is simplified.
We can now directly extract the strings from fish scripts,
and several issues are fixed alongside, mostly related to quoting.
The regex for extracting implicit messages from fish scripts has been tweaked to
ignore commented-out lines, and properly support lines starting with `and`/`or`.
2025-05-11 21:10:03 +02:00
Daniel Rainer
22bc8e12c9 Fix xgettext implicit regex
The old regex has the problem that it does not handle lines containing any
non-space characters in front of ` complete` (or ` function`), which results in
`string replace` leaving this part in the resulting string.
For example,
`and complete -d "foo"`
would turn into
`andN_ foo`
if passed to
`string replace --regex $regex 'N_ $1'` (where `$regex` is the `$implicit_regex`) variable.
Another issue are commented-out lines.
2025-05-11 21:10:03 +02:00
Peter Ammon
6c23c6f29b Add myself as SECURITY contact and reformat 2025-05-11 11:48:03 -07:00
Josef Andersson
39fd959eea Add initial security policy
Signed-off-by: Josef Andersson <janderssonse@proton.me>
2025-05-11 11:45:15 -07:00
Johannes Altmanninger
cc2ca60baa commandline.rst: deprecate --tokens-raw option
This was added without a use case.  Now there is a use case (#11084) that
needs it to include all tokens which the sister option "--tokens-expanded"
should not do.  The inconsistency is probably not worth it, given that this
"--tokens-raw" use case can be served by a future "read -zal --tokenize-raw".
2025-05-11 12:46:08 +02:00
Johannes Altmanninger
83f74f9332 builtin commandline: fix "-x" spuriously including redirection targets
completions frequently use

	argparse ... -- (commandline -xpc)

The "commandline -xpc" output
contains only string tokens.

A syntactically-valid process ("-p") consistes of only string tokens
and redirection tokens.  We skip all non-string tokens, but we do include
redirection targets, which are always strings.  This is weird, and confuses
completion scripts such as the one above.  Leave out redirection targets too.

Part of #11084
2025-05-11 12:46:08 +02:00
Johannes Altmanninger
58af4fa34c builtin commandline: rename tokenization mode 2025-05-11 12:46:08 +02:00
Daniel Rainer
f23501dbdc Add locale directory to config log 2025-05-11 09:27:35 +02:00
DaiLu Cao
035cd369c2 Supplement Chinese translation
Squashed commit of the following:

commit 23163d40bed2d97c72050990cf15db3944ce2ff0
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Thu Apr 24 10:11:04 2025 +0800

    Manually review up to line 1055 and modify all Chinese colons ':' to English ':' to prevent potential unknown errors.

commit dca5fb8182b94bffab5034dc5626b2b98d026b6f
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Thu Apr 17 10:50:13 2025 +0800

    Manually proofread up to 340 lines

commit 4b2d91c1138f3c8dec15b68aeb0510f02e15a776
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Thu Apr 17 09:50:21 2025 +0800

    use msgfmt check and fix all error

commit e2470d81c01ab7bf46d3d6ffd0291a05d4b38e13
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Wed Apr 16 11:10:54 2025 +0800

    Fix translation error converting '\\n' to '\\ n' error

commit 7ff970d06ce950aee35e1fb0ec70338f7bd42c1d
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Wed Apr 16 10:53:38 2025 +0800

    Fix make error, local cargo test completed

commit 018dfa225530a85486903ef58d47f4c358956b0b
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Fri Apr 11 16:46:36 2025 +0800

    modification of make errors

commit cbebd506a500aecc0669dce7f08422fcfed5615f
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Fri Apr 11 15:45:01 2025 +0800

    The second modification of make errors are all symbol problems

commit f75c3f7a2a84ffaea4eb642532b5a24da1c9154f
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Fri Apr 11 15:27:01 2025 +0800

    Re-add Chinese translation, try to solve the problem of make failing

commit 58551be20d261e3466a9e4ede290675f633e94a3
Author: DaiLu Cao <caodailu@foxmail.com>
Date:   Fri Apr 11 15:06:01 2025 +0800

    Supplement Chinese translation
2025-05-08 19:17:46 -07:00
Cuichen Li
3bef4863cf Revert "Work around $PATH issues under WSL (#10506)"
This reverts commit 3374692b91.
2025-05-08 18:35:56 -07:00
Daniel Rainer
2d58cfe4cb Remove line numbers from translation strings
This greatly reduces the number of changes necessary to the PO files when the
Rust/fish source files are updated. (Changes to the line number can be applied
automatically, but this adds a lot of noise to the git history.)

Due to the way we have been extracting Rust strings, differentiation between
the same source string in different contexts has not been possible regardless
of the change.

It seems that duplicate msgid entries are not permitted in PO files, so since we
do not use context to distinguish the strings we extract, there is no way to
have context-/location-dependent translations, so we might as well reduce the
git noise by eliminating line numbers.

Including source locations helps translators with understanding context.
Because we do not distinguish between contexts for a given source string,
this is of limited utility, but keeping file names at least allows to open the
relevant files and search them for the string. This might also be helpful to
identify translations which do not make sense in all context in which they are
used. (Although without adding context support, the only remedy would be to
remove the translation altogether, as far as I can tell.)

For extraction from Rust, additional issues are fixed:
- File name extraction from the grep results now works properly. Previously,
  lines not starting with whitespace resulted in missing or corrupted matches.
  (missing if the source line contains no colon followed by a whitespace,
  corrupted if it does, then the match included the part of the line in front of
  the colon, instead of just the location)
- Only a single source location per string was supported (`head -n1`). The new
  approach using sed does not have this limitation.
2025-05-08 18:15:56 +02:00
David Adam
df591a2e0f fish.spec/Debian packaging: drop man dependency in favour of groff 2025-05-08 22:16:33 +08:00
Johannes Altmanninger
ecefce2ea8 Fix "help printf" on --features=embed-data builds 2025-05-08 11:11:15 +02:00
Peter Ammon
786239d280 Changelog fix for #11465 2025-05-07 18:28:25 -07:00
Carl Andersson
7a668fb17e Unset SYSTEMD_COLORS for systemd completion
Fixes an issue where systemctl and other systemd commands completions are prefixed by ANSI color escape codes
2025-05-07 18:23:51 -07:00
Johannes Altmanninger
bf2f7ee6c0 Respect feature flags in fish_key_reader, fix display of "?" key
Commit daa692a20b (Remove unnecessary escaping for # and ~ inside key name
tokens, 2025-04-01) stopped escaping ? in fish_key_reader output.  This is
generally correct but not if the "qmark-noglob" feature flag is turned off.
Add that back, to be safe.

While at it, pass an environment variable more explicitly in a test.
2025-05-07 17:19:51 +02:00
Johannes Altmanninger
2f762e2da1 completions/cargo: re-use __fish_cargo
Technically this is in the autogenerated part, but I'm not sure how I can
re-generate it with today's cargo.
2025-05-07 17:17:09 +02:00
Benjamin VERGNAUD
11d8b83838 completions/cargo: enforce color off
Signed-off-by: Benjamin VERGNAUD <ben@bvergnaud.fr>
2025-05-06 15:39:39 +02:00
Yuyi Wang
c2eaef7273 Update nix to 0.30.1 (#11458)
After nix updated to 0.30, all functions related to file descriptor accepts impl AsFd, e.g., BorrowedFd. This PR is a minimal update. It tries to use impl AsFd as long as possible, but uses BorrowedFd in some places. Yes it introduces unsafe, but doesn't introduce new unsafe code.
2025-05-06 10:52:54 +02:00
Yuyi Wang
2f278f4bfa Update errno to 0.3.11 2025-05-06 10:44:18 +08:00
Ethan Fredsti
1e61e6492d fixed typo mentioned in issue #11454
I found the same typo mentioned in issue #11454 in this file and proposed the suggested change.
2025-05-04 19:52:06 -07:00
Peter Ammon
c993fd022c Rework fish AST implementation
This merges a large set of changes to the fish AST, with the intention of
making the code simpler.

There's no expected user-visible changes here, except for some minor
changes in the output of `fish_indent --dump-parse-tree`.

Ast parsing is about 50% faster measured via
`cargo +nightly bench  --features=benchmark bench_ast_construction`
and also uses less memory due to some size optimization.

The biggest change is removing the `Type` notion from `Node`. Previously
each Node had an integer type identified with it, like Type::Argument. This
was a relic from C++: types were natural in C++ and we could use LLVM-style
RTTI to identify Nodes, leveraging the fact that C++ has inheritance and so
Type could be at the same location in each Node.

This proved quite awkward in Rust which does not have inheritance. So
instead we switch to a new notion, Kind:

    pub enum Kind<'a> {
        Redirection(&'a Redirection),
        Token(&'a dyn Token),
        Keyword(&'a dyn Keyword),
        VariableAssignment(&'a VariableAssignment),
                ...

and a `&dyn Node` can now return its Kind. Basically leveraging Rust's enum
types.

Interesting lesson about the optimal way to construct ASTs in both
languages.
2025-05-04 19:45:36 -07:00
Peter Ammon
fe10f65587 ast: Box redirections in ArgumentOrRedirection
Redirections are bigger and less common.

Reduces ast size of __fish_complete_gpg.fish by ~28 KB.
2025-05-04 19:38:08 -07:00
Peter Ammon
b98c5ee897 ast: remove NodeSubTraits
This can be implemented directly in Node.
2025-05-04 19:37:25 -07:00
Peter Ammon
9ccff5ad5d ast: Clean up implement_acceptor_for_branch macro
We no longer need the field types to be passed to the macro.
2025-05-04 18:59:13 -07:00
Peter Ammon
55f70cbb6d ast: Clean up more macros
Factor some logic out of macros into a trait, to reduce the macro
complexity.
2025-05-04 18:59:13 -07:00
Peter Ammon
b7005e8378 ast: clean up NodeVisitorMut
This eliminates a bunch of the different functions from NodeVisitorMut.

It also removes the runtime polymorphism - now it's a generic instead of
using &dyn. The reason is that there's only one implementation of
NodeVisitorMut so there's no size savings from polymorphism.
2025-05-04 18:59:13 -07:00
Peter Ammon
1f79d48a48 ast: further macro cleanup 2025-05-04 18:59:13 -07:00
Peter Ammon
e9036774cb ast: simplify visitor_accept_field macro
This is a relic from when we used to support visiting in reverse order; we can
simplify this.
2025-05-04 18:59:13 -07:00
Peter Ammon
2cd185a4f1 ast: Eliminate ConcreteNode trait
Fold this into Node
2025-05-04 18:59:13 -07:00
Peter Ammon
bb92d82c3b ast: remove types 2025-05-04 18:59:13 -07:00
Peter Ammon
f9ba834788 ast: further migration from type to kind 2025-05-04 18:59:13 -07:00
Peter Ammon
d23b8af60d ast: More migration from type to kind 2025-05-04 18:59:13 -07:00
Peter Ammon
82eacb6d50 ast: Switch from type to kind in is_same_node 2025-05-04 18:59:13 -07:00
Peter Ammon
c62b09d5d1 ast: Switch from some types to kinds
Preparing to remove types entirely
2025-05-04 18:59:13 -07:00
Peter Ammon
ccfe949514 ast: make Ast generic
We can parse two different things via Ast:

1. A regular job list
2. A freestanding argument list, as used in `complete --arguments ...`

This second case is specific to one use.

Prior to this commit, we parsed the Ast and then "forgot" what we parsed,
storing a &dyn Node. Then we had to cast it to the right type, and assert,
and etc.

Make Ast generic over the Node type it parsed, and default the Node type to
JobList. This simplifies call sites.
2025-05-04 18:59:13 -07:00
Peter Ammon
ccc75d08f3 ast: remove all of the as_foo functions from Node
Kind has subsumed these.
2025-05-04 18:59:05 -07:00
Peter Ammon
dfac66082a ast: adopt Kind in yet more places 2025-05-04 18:59:05 -07:00
Peter Ammon
9ae01ae00d ast: adopt Kind in more places 2025-05-04 18:59:05 -07:00
Peter Ammon
51784b090d ast: adopt Kind in parse_util_detect_errors_in_ast 2025-05-04 18:59:05 -07:00
Peter Ammon
8115982485 ast: adopt Kind in highlighting 2025-05-04 18:59:05 -07:00
Peter Ammon
d88a656e9e ast: further adoption of Kind 2025-05-04 18:59:05 -07:00
Peter Ammon
d6ee4ec698 ast: Clean up BlockStatementHeader
Make this a real Node.
2025-05-04 18:59:05 -07:00
Peter Ammon
dbae271fe7 ast: remove StatementVariant
Statement is the new StatementVariant.
2025-05-04 18:59:05 -07:00
Peter Ammon
a4ec30f298 ast: Remove StatementVariant::None
We can do without this.
2025-05-04 18:59:05 -07:00
Peter Ammon
ee9cf33689 ast: Remove Node::category
This is now unused.
2025-05-04 18:59:05 -07:00
Peter Ammon
11b6bf31c0 ast: Minor cleanup of source ranges 2025-05-04 18:59:05 -07:00
Peter Ammon
4f0e11383e ast: Remove as_mut_foo() functions
Kinds have replaced these.
2025-05-04 18:59:05 -07:00
Peter Ammon
bf78309f79 ast: adopt Kinds in more places 2025-05-04 18:59:05 -07:00
Peter Ammon
01bd854f25 ast: introduce Kind and cast
This begins the process of replacing the underlying Node "type" notion with
Kind. A Kind is an Enum of all of the possible node types, except with
Token and Keyword collapsed into one.

The idea is, rather than this:

    if node.type() == Type::Argument {
	    let arg = node.as_argument().unwrap();
		...
	}

we can instead do this:

    if let Kind::Argument(arg) = node.kind() {
	    // we already have arg
	}

There is also a cast() function:

    let arg: Option<Argument> = node.cast()

which may be convenient in some places.

The big thing we lose is the ability to talk about a Node's type without
actually having a Node. But this turns out to not be an issue in practice.

Future commits will begin adopting Kind.
2025-05-04 18:59:05 -07:00
Peter Ammon
0348389195 ast: Remove as_mut_leaf
This was unused.
2025-05-04 18:28:25 -07:00
Peter Ammon
e05ecd6c7d ast: clean up lists
Make working with lists more natural
2025-05-04 18:28:25 -07:00
Peter Ammon
325232bec1 ast: remove the ability to traverse in reverse
Prior to this commit, each Node in the ast could accept a visitor and visit
children either in order or in reverse order. This reverse feature added a lot
of complexity and the only client is Traversal.

Switch Traversal to reverse the nodes itself and remove the reverse bool
elsewhere, leading to some code simplifications.
2025-05-04 17:09:00 -07:00
Peter Ammon
b78d168050 ast: eliminate ArgumentOrRedirectionVariant
Just use ArgumentOrRedirection directly. Continued simplification.
2025-05-04 17:09:00 -07:00
Peter Ammon
31edcf029b ast: factor out as_node
Shrink another macro.
2025-05-04 17:09:00 -07:00
Peter Ammon
27dc4b3c8a ast: Blanket implementation of NodeMut
Continue to shrink the implement_node! macro.

No functional changes expected.
2025-05-04 17:09:00 -07:00
Peter Ammon
77a4f38a13 ast: derive Category from Type
In the fish AST, each node falls into one of three "categories":

    1. A branch: contains child nodes
    2. A leaf: no child nodes, contains a source range
    3. A list: a sequence of child nodes and nothing more

Prior to this commit the category was explicit in the code for each Node type;
make it instead derived from the node's type. This continues to shrink our
macros.

No functional change expected.
2025-05-04 17:09:00 -07:00
Peter Ammon
e9d396615b ast: push try_source_range into default Node implementation
Minor refactoring, reducing macro size.
2025-05-04 17:09:00 -07:00
Peter Ammon
79ec558d08 ast: remove Default implementation
This doesn't make much conceptual sense, and isn't required.

Do some other miscellaneous cleanup.
2025-05-04 17:09:00 -07:00
Peter Ammon
719a5d2909 ast: remove stale parent pointer comment
It no longer applies.
2025-05-04 17:08:59 -07:00
Peter Ammon
93962c82df ast: store &dyn Node and not &dyn NodeMut
Minor simplifications.
2025-05-04 17:08:59 -07:00
Johannes Altmanninger
111922b60f Fix export test on macOS GHA runner
This system sets something like
$MANPATH: originally inherited as |/Applications/Xcode_15.4.app/...|
2025-05-04 18:19:42 +02:00
Johannes Altmanninger
cb92a5530f functions/export: fix for path variables
Commit f38646593c (Allow `export` to set colon-separated `PATH`, `CDPATH`
and `MANPATH`., 2017-02-10)
did something very weird for «export PATH=foo».
It essentially does

	set -gx PATH (string replace -- "$PATH" (string join ":" -- $PATH) foo)

which makes no sense.  It should set PATH to "foo", no need to involve the
existing value of $PATH.

Additionally, the string split / string join dance is unnecessary.  Nowadays,
builtin set already handles path variables as is needed here, so get rid of
this special case.

Fixes #11434
2025-05-04 18:06:18 +02:00
Johannes Altmanninger
dd4c04e2ff Fix empty soft-wrapped line not being removed before execution
Commit 7acc2b7 added an empty line to our screen representation if we are
wrapped. This regressed the fix for #6826.  In the attached test case, there is
a spurious empty line after the first one.  Adjust the fix to remove it again.

Patch-by: kerty <g.kabakov@inbox.ru>
https://github.com/fish-shell/fish-shell/pull/11153#issuecomment-2800087389
2025-05-04 12:50:12 +02:00
Johannes Altmanninger
6fec5ab320 completions/wpctl: fix when "settings" subcommand is not available
The error is printed to stdout, see
https://github.com/fish-shell/fish-shell/pull/11438#discussion_r2072455009
2025-05-04 12:06:01 +02:00
Johannes Altmanninger
ada9aff63e Merge pull request #11453 2025-05-04 12:01:06 +02:00
Johannes Altmanninger
1d63c1f188 Merge pull request #11399 2025-05-04 11:58:05 +02:00
Johannes Altmanninger
a12298152f Merge pull request #11448 2025-05-04 11:57:18 +02:00
Bergbok
83b10c3919 Rephrase set_color tutorial docs
Closes #11446
2025-05-04 11:56:14 +02:00
Johannes Altmanninger
4a3fc5211f Document workaround for making tab focus search field
Closes #11450
Closes #11449
2025-05-04 11:56:14 +02:00
239
9f80e1f225 completions/keybase: update to 6.4.0
Closes #11428
2025-05-04 11:56:14 +02:00
fabiojb
9a8d578142 completion(winetricks): redirect winetricks list-all sderr to /dev/null 2025-05-03 18:25:17 -03:00
Daniel Rainer
09eae92888 Make printf unicode-aware
Specifically, the width and precision format specifiers are interpreted as
referring to the width of the grapheme clusters rather than the byte count of
the string. Note that grapheme clusters can differ in width.

If a precision is specified for a string, meaning its "maximum number of
characters", we consider this to limit the width displayed.
If there is a grapheme cluster whose width is greater than 1,
it might not be possible to get precisely the desired width.
In such cases, this last grapheme cluster is excluded from the output.

Note that the definitions used here are not consistent with the `string length`
builtin at the moment, but this has already been the case.
2025-05-03 22:53:27 +02:00
Daniel Rainer
af6c3eb69f Ensure that strings do not get wrapped in po files 2025-05-03 16:07:20 +02:00
Daniel Rainer
dd5864ce13 Add quotes around gettext string
This should prevent occurrences of the search string from being found in other
locations (e.g. in a comment).

The whole approach of string extraction from Rust sources is sketchy,
but this at least prevents producing garbage when the content of a string
appears somewhere else unquoted.
2025-05-03 16:07:20 +02:00
Daniel Rainer
d31dc9ffd8 Fix fish script translation file generation
The previous version generates files which do not preserve the line number from
the original fish script file, resulting in translation not working.

The new approach is quite ugly, and might have some issues,
but at least it seems to work in some cases.
2025-05-03 16:07:03 +02:00
Daniel Rainer
d5e80d43d9 Extract function for gettext extraction
Extracting explicit and implicit messages works essentially the same way, which
is also reflected in the code being identical, except for the regex.

Extract the duplicated code into a function.
2025-05-03 16:03:03 +02:00
Johannes Altmanninger
0d59e89374 completions/wpctl: silence stderr
In case the command is missing, I guess
See https://github.com/fish-shell/fish-shell/pull/11438
2025-05-03 14:15:33 +02:00
Johannes Altmanninger
8b1f72c54b completions/tmutil: namespace 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
54a5ade57d Merge pull request #11394 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
7c25d6a1ba Merge pull request #11443 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
a5a5dc46e4 Merge pull request #11438 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
1687b3fe7a Merge pull request #11377 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
f3ddf793a3 Merge pull request #11381 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
647ae7da8c Merge pull request #11411 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
0950cd1598 Merge pull request #11422 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
a1b1bff97b Merge pull request #11441 2025-05-03 14:15:33 +02:00
Johannes Altmanninger
a95be351fb Merge pull request #11447 2025-05-03 14:15:33 +02:00
Axlefublr
91b9bbf651 fix single backticks 2025-05-03 19:26:07 +08:00
Johannes Altmanninger
c14e8c1939 Fix assertion error in set_color
This doesn't hold for e.g. TERM=linux-m fish -c 'set_color red'
2025-05-03 12:56:45 +02:00
Daniel Rainer
7e4c3b9fa7 Use workspace config in packages
- Apply lint config to entire workspace

- Inherit workspace config for fish-printf

- Allow stdlib printing in fish-printf tests

The current problem which is addressed by this is that warnings about C-String
literals are generated by clippy for code in fish-printf. These literals are not
available with the current MSRV 1.70, but previously the MSRV setting was not
inherited by fish-printf, causing the warning to appear.
2025-05-02 22:31:39 +02:00
Fabian Boehm
8048e38ea4 docs: Actually document commandline --input
This is a useful option and has been a thing for years.
2025-05-02 20:55:36 +02:00
Fabian Boehm
8a5a547d88 builtins/commandline: Correct error message 2025-05-02 20:54:29 +02:00
Johannes Altmanninger
48704dc612 Fix regression causing crash indenting commandline with "$()"
Commit b00899179f (Don't indent multi-line quoted strings; do indent inside
(), 2024-04-28) changed how we compute indents for string tokens with command
substitutions:

	echo "begin
	not indented
	end $(
	begin
	    indented
	end)"(
	begin
	    indented
	end
	)

For the leading quoted part of the string, we compute indentation only for
the first character (the opening quote), see 4c43819d32 (Fix crash indenting
quoted suffix after command substitution, 2024-09-28).

The command substitutions, we do indent as usual.

To implement the above, we need to separate quoted from non-quoted
parts. This logic crashes when indent_string_part() is wrongly passed
is_double_quoted=true.

This is because, given the string "$()"$(), parse_util_locate_cmdsub calls
quote_end() at index 4 (the second quote). This is wrong because that function
should only be called at opening quotes; this is a closing quote. The opening
quote is virtual here. Hack around this.

Fixes #11444
2025-05-02 08:31:15 +02:00
Johannes Altmanninger
8abab0e2cc Explicit type for "$()" hack in parse_util_locate_cmdsub 2025-05-02 08:31:15 +02:00
Johannes Altmanninger
bd178c8ba8 Remove code clone in parse_util_locate_cmdsub 2025-05-02 08:31:15 +02:00
Johannes Altmanninger
cb719cd418 Remove dead code
Introduced in 149594f974 (Initial revision, 2005-09-20).
2025-05-02 08:31:15 +02:00
Johannes Altmanninger
1ff8f983c4 Remove obsolete Vi mode delete key workaround
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$n20_uqiMqatEQcPG79Ca0c2_YvHBHTr-yCVXTEuze_Y

commit f5fac096c0 (Don't move cursor in delete-char, 2017-04-19) fixed the
behavior of Vi mode keys "delete" and "x" when the cursor is at the end of
the buffer, and commit d51f669647 (Vi mode: avoid placing cursor beyond
last character, 2024-02-14) generalized this fix.

This means that the delete-specific fix is no longer necessary. Remove it.

Note that if the cursor is at end of a line but not the last line, the
behavior of "delete" in Vi mode is still wrong.  It should stay on the line.
2025-05-02 06:05:31 +02:00
Johannes Altmanninger
e3517f69b3 Simplify check for bare builtin invocation 2025-05-02 06:05:31 +02:00
Fabian Boehm
f7bde1354d Only count it as a naked invocation at the end of the "file"
This is a weird confusion between the "end" and "terminate" token
types.

"end" is the end of the "line" - a newline or ";".

"terminate" is the end of the "file" - like pressing newline
interactively or having the file end.

So this would count things like `if` and `switch` as a "help"
invocation even if followed by a newline, e.g.

```fish
if; echo foo
```

and

```fish
switch
case foo
```

The result of that was that a naked "if" in a script file isn't an
error, but doesn't start a block either, so if you complete the block
it would count the "end" as superfluous, which sends you on a bit of a
hunt to figure out where the block start is missing.
2025-05-01 14:57:30 +02:00
Axlefublr
1d69226c58 preciser wording for builtin crossmode alt+p binding 2025-05-01 13:58:18 +08:00
Daniel Rainer
d5e71bc46e Fix diff_profiles.fish
This script was broken by the changes to profiling output in
9d904e1113.

The new version works with both the old and new profiling output, even when
mixed. The script output has been adjusted to match the new profiling style
better.

This also adds basic error handling for situations where the script is invoked
incorrectly and makes the file executable.
2025-04-30 19:41:45 +02:00
fabiojb
0d5ab2514c wpctl: add description for settings command options 2025-04-30 11:18:12 -03:00
David Adam
bf0a30b9a8 CHANGELOG: work on 4.1 2025-04-30 14:15:58 +08:00
fabiojb
b54042e512 wpctl: add completion for settings option 2025-04-29 17:11:01 -03:00
Anton Bilous
b7b1753716 Mention replace mode in fish_mode_prompt docs 2025-04-24 16:26:45 +03:00
Ilia Gogotchuri
c0f5fcb089 Update tofu.fish 2025-04-22 14:17:52 +04:00
Sam Doran
b9f2275349 Refine when file completions are offered and add a missing short arg 2025-04-19 01:59:47 -04:00
Sam Doran
0b97fa7114 Evaluate completion arguments when called
This makes the destinations update dynamically when they are added/removed.
Unquote the echo statement so that it is correctly paresd by the -a options.
2025-04-19 01:17:58 -04:00
Sam Doran
1a2958d42b No need to reset ID
The values are only echoed if ID matches, so it will always be correct.
2025-04-19 00:59:30 -04:00
Sam Doran
3e8308f6eb Argument not description 2025-04-19 00:54:18 -04:00
Sam Doran
ff987f5f76 Do not use test for evaluating string match
Also add `--` to ensure parameters don't get mixed up with the line itself.
2025-04-19 00:52:31 -04:00
Sam Doran
a6fdb41940 Update completion for tmutil
- Reorganize completions and options so they are easier to read.
- Add destination UUIDs to completetions as well as descriptions
- Add a few missing sub commands
2025-04-16 11:59:24 -04:00
kpbaks
54971621de completions/git: show url as description for remote completion 2025-04-16 09:56:45 +02:00
exploide
b6c5f3dc38 completions: improved ip completions
added completions for ip tuntap
standardize help completion
2025-04-12 16:26:15 +02:00
267 changed files with 553202 additions and 742340 deletions

View File

@@ -26,7 +26,7 @@ linux_task:
- lscpu || true
- (cat /proc/meminfo | grep MemTotal) || true
- mkdir build && cd build
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=6 ..
- FISH_TEST_MAX_CONCURRENCY=6 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
- ninja -j 6 fish
- ninja fish_run_tests
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
@@ -45,7 +45,7 @@ linux_arm_task:
- lscpu || true
- (cat /proc/meminfo | grep MemTotal) || true
- mkdir build && cd build
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=6 ..
- FISH_TEST_MAX_CONCURRENCY=6 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
- ninja -j 6 fish
- file ./fish
- ninja fish_run_tests
@@ -54,17 +54,11 @@ linux_arm_task:
freebsd_task:
matrix:
# - name: FreeBSD 14
# freebsd_instance:
# image_family: freebsd-14-0-snap
- name: FreeBSD 13
- name: FreeBSD 14
freebsd_instance:
image: freebsd-13-2-release-amd64
# - name: FreeBSD 12.3
# freebsd_instance:
# image: freebsd-12-3-release-amd64
image: freebsd-14-3-release-amd64-ufs
tests_script:
- pkg install -y cmake-core devel/pcre2 devel/ninja misc/py-pexpect git-lite terminfo-db
- pkg install -y cmake-core devel/pcre2 devel/ninja lang/rust misc/py-pexpect git-lite
# libclang.so is a required build dependency for rust-c++ ffi bridge
- pkg install -y llvm
# BSDs have the following behavior: root may open or access files even if
@@ -77,15 +71,7 @@ freebsd_task:
- mkdir build && cd build
- chown -R fish-user ..
- sudo -u fish-user -s whoami
# FreeBSD's pkg currently has rust 1.66.0 while we need rust 1.70.0+. Use rustup to install
# the latest, but note that it only installs rust per-user.
- sudo -u fish-user -s fetch -qo - https://sh.rustup.rs > rustup.sh
- sudo -u fish-user -s sh ./rustup.sh -y --profile=minimal
# `sudo -s ...` does not invoke a login shell so we need a workaround to make sure the
# rustup environment is configured for subsequent `sudo -s ...` commands.
# For some reason, this doesn't do the job:
# - sudo -u fish-user sh -c 'echo source \$HOME/.cargo/env >> $HOME/.cshrc'
- sudo -u fish-user -s cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=1 ..
- sudo -u fish-user sh -c '. $HOME/.cargo/env; ninja -j 6 fish'
- sudo -u fish-user sh -c '. $HOME/.cargo/env; ninja fish_run_tests'
- sudo -u fish-user -s FISH_TEST_MAX_CONCURRENCY=1 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
- sudo -u fish-user -s ninja -j 6 fish
- sudo -u fish-user -s ninja fish_run_tests
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'

View File

@@ -15,8 +15,8 @@ indent_style = tab
[*.{md,rst}]
trim_trailing_whitespace = false
[*.{sh,ac}]
indent_size = 2
[*.sh]
indent_size = 4
[Dockerfile]
indent_size = 2

View File

@@ -0,0 +1,22 @@
name: Oldest Supported Rust Toolchain
on:
workflow_call:
inputs:
targets:
description: Comma-separated list of target triples to install for this toolchain
required: false
components:
description: Comma-separated list of components to be additionally installed
required: false
permissions:
contents: read
runs:
using: "composite"
steps:
- uses: dtolnay/rust-toolchain@1.70
with:
targets: ${{ inputs.targets }}
components: ${{ inputs.components}}

View File

@@ -0,0 +1,22 @@
name: Stable Rust Toolchain
on:
workflow_call:
inputs:
targets:
description: Comma-separated list of target triples to install for this toolchain
required: false
components:
description: Comma-separated list of components to be additionally installed
required: false
permissions:
contents: read
runs:
using: "composite"
steps:
- uses: dtolnay/rust-toolchain@1.88
with:
targets: ${{ inputs.targets }}
components: ${{ inputs.components }}

View File

@@ -9,12 +9,12 @@ jobs:
environment: macos-codesign
steps:
- uses: actions/checkout@v4
- name: Install Rust 1.73.0
uses: dtolnay/rust-toolchain@1.73.0
- name: Install Rust
uses: ./.github/actions/rust-toolchain@oldest-supported
with:
targets: x86_64-apple-darwin
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@stable
uses: ./.github/actions/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: build-and-codesign

View File

@@ -3,7 +3,7 @@ name: make fish_run_tests
on: [push, pull_request]
env:
CTEST_PARALLEL_LEVEL: "4"
FISH_TEST_MAX_CONCURRENCY: "4"
CMAKE_BUILD_PARALLEL_LEVEL: "4"
permissions:
@@ -16,10 +16,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.70
- uses: ./.github/actions/rust-toolchain@oldest-supported
- name: Install deps
run: |
sudo apt install gettext libpcre2-dev python3-pexpect tmux
sudo apt install gettext libpcre2-dev python3-pexpect python3-sphinx tmux
# Generate a locale that uses a comma as decimal separator.
sudo locale-gen fr_FR.UTF-8
- name: cmake
@@ -32,6 +32,14 @@ jobs:
- name: make fish_run_tests
run: |
make -C build VERBOSE=1 fish_run_tests
- name: translation updates
run: |
# Generate PO files. This should not result it a change in the repo if all translations are
# up to date.
# Ensure that fish is available as an executable.
PATH="$PWD/build:$PATH" build_tools/update_translations.fish --no-mo
# Show diff output. Fail if there is any.
git --no-pager diff --exit-code || { echo 'There are uncommitted changes after regenerating the gettext PO files. Make sure to update them via `build_tools/update_translations.fish --no-mo` after changing source files.'; exit 1; }
ubuntu-32bit-static-pcre2:
@@ -39,7 +47,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.70
- uses: ./.github/actions/rust-toolchain@oldest-supported
with:
targets: "i586-unknown-linux-gnu" # rust-toolchain wants this comma-separated
- name: Install deps
@@ -82,13 +90,14 @@ jobs:
- name: Install deps
run: |
sudo apt install gettext libpcre2-dev python3-pexpect tmux
sudo apt install llvm # for llvm-symbolizer
- name: cmake
env:
CC: clang
run: |
mkdir build && cd build
# Rust's ASAN requires the build system to explicitly pass a --target triple. We read that
# value from CMake variable Rust_CARGO_TARGET (shared with corrosion).
# value from CMake variable Rust_CARGO_TARGET.
cmake .. -DASAN=1 -DRust_CARGO_TARGET=x86_64-unknown-linux-gnu -DCMAKE_BUILD_TYPE=Debug
- name: make
run: |
@@ -104,8 +113,8 @@ jobs:
# UPDATE: this can cause spurious leak reports for __cxa_thread_atexit_impl() under glibc.
LSAN_OPTIONS: verbosity=0:log_threads=0:use_tls=1:print_suppressions=0
run: |
llvm_version=$(clang --version | awk 'NR==1 { split($NF, version, "."); print version[1] }')
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-$llvm_version
set -x
export ASAN_SYMBOLIZER_PATH=$(command -v /usr/bin/llvm-symbolizer* | sort -n | head -1)
export LSAN_OPTIONS="$LSAN_OPTIONS:suppressions=$PWD/build_tools/lsan_suppressions.txt"
make -C build VERBOSE=1 fish_run_tests
@@ -119,7 +128,7 @@ jobs:
#
# steps:
# - uses: actions/checkout@v4
# - uses: dtolnay/rust-toolchain@1.70
# - uses: ./.github/actions/rust-toolchain@oldest-supported
# - name: Install deps
# run: |
# sudo apt install gettext libpcre2-dev python3-pexpect tmux
@@ -147,7 +156,7 @@ jobs:
CARGO_NET_GIT_FETCH_WITH_CLI: true
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.70
- uses: ./.github/actions/rust-toolchain@oldest-supported
- name: Install deps
run: |
# --break-system-packages because homebrew has now declared itself "externally managed".

View File

@@ -8,34 +8,48 @@ permissions:
jobs:
rustfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: ./.github/actions/rust-toolchain@stable
with:
components: rustfmt
- name: cargo fmt
run: cargo fmt --check --all
run: cargo fmt --check
clippy:
clippy-stable:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: ./.github/actions/rust-toolchain@stable
with:
components: clippy
- name: Install deps
run: |
sudo apt install gettext libpcre2-dev
- name: cmake
run: |
cmake -B build
sudo apt install gettext
- name: cargo clippy
# This used to have --deny=warnings, but that turns rust release day
# into automatic CI failure day, so we don't do that.
run: cargo clippy --workspace --all-targets
run: cargo clippy --workspace --all-targets -- --deny=warnings
# Disabling for now because it also checks "advisories",
# making CI fail for reasons unrelated to the patch
# cargo-deny:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - uses: EmbarkStudios/cargo-deny-action@v1
clippy-msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/rust-toolchain@oldest-supported
with:
components: clippy
- name: Install deps
run: |
sudo apt install gettext
- name: cargo clippy
run: cargo clippy --workspace --all-targets -- --deny=warnings
rustdoc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/rust-toolchain@stable
- name: cargo doc
run: |
RUSTDOCFLAGS='-D warnings' cargo doc --workspace
- name: cargo doctest
run: |
cargo test --doc --workspace

View File

@@ -7,10 +7,6 @@ on:
# - cron: "14 13 * * *"
workflow_dispatch:
env:
CTEST_PARALLEL_LEVEL: "1"
CMAKE_BUILD_PARALLEL_LEVEL: "4"
jobs:
staticbuilds-linux:
@@ -20,7 +16,7 @@ jobs:
contents: read
steps:
- uses: dtolnay/rust-toolchain@1.70
- uses: ./.github/actions/rust-toolchain@oldest-supported
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -36,7 +32,7 @@ jobs:
cargo build --release --target x86_64-unknown-linux-musl
- name: Test
run: |
test -e tests/test_driver.py && tests/test_driver.py -f /tmp target/x86_64-unknown-linux-musl/release/
tests/test_driver.py target/x86_64-unknown-linux-musl/release/
- name: Compress
run: |
tar -cazf fish-static-x86_64-$(git describe).tar.xz -C target/x86_64-unknown-linux-musl/release/ fish
@@ -55,7 +51,7 @@ jobs:
contents: read
steps:
- uses: dtolnay/rust-toolchain@1.70
- uses: ./.github/actions/rust-toolchain@oldest-supported
- uses: actions/checkout@v4
with:
fetch-depth: 0

3
.gitignore vendored
View File

@@ -38,7 +38,7 @@ Desktop.ini
Thumbs.db
ehthumbs.db
messages.pot
*.mo
.directory
.fuse_hidden*
@@ -77,6 +77,7 @@ __pycache__
/share/__fish_build_paths.fish
/share/pkgconfig
/tests/*.tmp.*
/tests/.last-check-all-files
# xcode
## Build generated

View File

@@ -1,6 +1,8 @@
fish 4.1.0 (released ???)
=========================
.. ignore for 4.1: 10929 10940 10948 10955 10965 10975 10989 10990 10998 11028 11052 11055 11069 11071 11079 11092 11098 11104 11106 11110 11140 11146 11148 11150 11214 11218 11259 11288 11299 11328 11350 11373 11395 11417 11419
Notable improvements and fixes
------------------------------
- Compound commands (``begin; echo 1; echo 2; end``) can now be now be abbreviated using braces (``{ echo1; echo 2 }``), like in other shells.
@@ -19,7 +21,7 @@ Notable improvements and fixes
Deprecations and removed features
---------------------------------
- Tokens like ``{ echo, echo }`` in command position are no longer interpreted as brace expansion but as compound command.
- Tokens like ``{echo,echo}`` or ``{ echo, echo }`` in command position are no longer interpreted as brace expansion but as compound command.
- Terminfo-style key names (``bind -k``) are no longer supported. They had been superseded by the native notation since 4.0,
and currently they would map back to information from terminfo, which does not match what terminals would send with the kitty keyboard protocol (:issue:`11342`).
- fish no longer reads the terminfo database, so its behavior is no longer affected by the :envvar:`TERM` environment variable (:issue:`11344`).
@@ -48,6 +50,7 @@ Interactive improvements
- Left mouse click (as requested by `click_events <terminal-compatibility.html#click-events>`__) can now select pager items (:issue:`10932`).
- Instead of flashing all the text to the left of the cursor, fish now flashes the matched token during history token search, the completed token during completion (:issue:`11050`), the autosuggestion when deleting it, and the full command line in all other cases.
- Pasted commands are now stripped of any ``$`` prefix.
- The :kbd:`alt-s` binding will now also use ``run0`` if available.
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,13 +64,16 @@ New or improved bindings
this is only enabled by default if the terminal advertises support for the ``indn`` capability via XTGETTCAP.
- Bindings using shift with non-ASCII letters (such as :kbd:`ctrl-shift-ä`) are now supported.
If there is any modifier other than shift, this is the recommended notation (as opposed to :kbd:`ctrl-Ä`).
- Vi mode has learned :kbd:`ctrl-a` (increment) and :kbd:`ctrl-x` (decrement) (:issue:`11570`).
Completions
^^^^^^^^^^^
- ``git`` completions now show the remote url as a description when completing remotes.
- ``systemctl`` completions no longer print escape codes if ``SYSTEMD_COLORS`` is set (:issue:`11465`).
Improved terminal support
^^^^^^^^^^^^^^^^^^^^^^^^^
- Support for curly underlines in `fish_color_*` variables and :doc:`set_color <cmds/set_color>` (:issue:`10957`).
- Support for double, curly, dotted and dashed underlines in `fish_color_*` variables and :doc:`set_color <cmds/set_color>` (:issue:`10957`).
- Underlines can now be colored independent of text (:issue:`7619`).
- New documentation page `Terminal Compatibility <terminal-compatibility.html>`_ (also accessible via ``man fish-terminal-compatibility``) lists required and optional terminal control sequences used by fish.

View File

@@ -219,12 +219,10 @@ Or you can run them on a fish, without involving cmake::
cargo build
cargo test # for the unit tests
tests/test_driver.py --cachedir=/tmp target/debug # for the script and interactive tests
tests/test_driver.py target/debug # for the script and interactive tests
Here, the first argument to test_driver.py refers to a directory with ``fish``, ``fish_indent`` and ``fish_key_reader`` in it.
In this example we're in the root of the git repo and have run ``cargo build`` without ``--release``, so it's a debug build.
The ``--cachedir /tmp`` argument means it will keep the fish_test_helper binary in /tmp instead of recompiling it for every test.
This saves some time, but isn't strictly necessary.
Git hooks
---------
@@ -286,37 +284,62 @@ Contributing Translations
Fish uses the GNU gettext library to translate messages from English to
other languages.
Creating and updating translations requires the Gettext tools, including
``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
Translation sources are
stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
two letter ISO 639-1 language code of the target language (eg ``de`` for
German).
two letter ISO 639-1 language code of the target language (e.g. ``de`` for
German). A region specifier can also be used (e.g. ``pt_BR`` for Brazilian Portuguese).
To create a new translation:
Adding translations for a new language
--------------------------------------
* generate a ``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from
the source tree
* copy ``messages.pot`` to ``po/LANG.po``
Creating new translations requires the Gettext tools.
More specifically, you will need ``msguniq`` and ``msgmerge`` for creating translations for a new
language.
To create a new translation, run::
To update a translation:
build_tools/update_translations.fish po/LANG.po
* generate a ``messages.pot`` file by running
``build_tools/fish_xgettext.fish`` from the source tree
By default, this also creates ``mo`` files, which contain the information from the ``po`` files in a
binary format.
Fish uses these files for translating at runtime.
They are not tracked in version control, but they can help translators check if their translations
show up correctly.
If you build fish locally (``cargo build``), and then run the resulting binary,
it will make use of the ``mo`` files generated by the script.
Use the ``LANG`` environment variable to tell fish which language to use, e.g.::
* update the existing translation by running
``msgmerge --update --no-fuzzy-matching po/LANG.po messages.pot``
LANG=pt_BR.utf8 target/debug/fish
The ``--no-fuzzy-matching`` is important as we have had terrible experiences with gettext's "fuzzy" translations in the past.
If you do not care about the ``mo`` files you can pass the ``--no-mo`` flag to the
``update_translations.fish`` script.
Modifying existing translations
-------------------------------
If you want to work on translations for a language which already has a corresponding ``po`` file, it
is sufficient to edit this file. No other changes are necessary.
To see your translations in action you can run::
build_tools/update_translations.fish --only-mo po/LANG.po
to update the binary ``mo`` used by fish. Check the information for adding new languages for a
description on how you can get fish to use these files.
Running this script requires a fish executable and the gettext ``msgfmt`` tool.
Editing PO files
----------------
Many tools are available for editing translation files, including
command-line and graphical user interface programs. For simple use, you can just use your text editor.
command-line and graphical user interface programs. For simple use, you can use your text editor.
Open up the po file, for example ``po/sv.po``, and you'll see something like::
msgid "%ls: No suitable job\n"
msgstr ""
msgstr ""
The ``msgid`` here is the "name" of the string to translate, typically the english string to translate. The second line (``msgstr``) is where your translation goes.
The ``msgid`` here is the "name" of the string to translate, typically the English string to translate.
The second line (``msgstr``) is where your translation goes.
For example::
@@ -329,11 +352,17 @@ Also any escaped characters, like that ``\n`` newline at the end, should be kept
Our tests run ``msgfmt --check-format /path/to/file``, so they would catch mismatched placeholders - otherwise fish would crash at runtime when the string is about to be used.
Be cautious about blindly updating an existing translation file. Trivial
changes to an existing message (eg changing the punctuation) will cause
existing translations to be removed, since the tools do literal string
matching. Therefore, in general, you need to carefully review any
recommended deletions.
Be cautious about blindly updating an existing translation file.
``msgid`` strings should never be updated manually, only by running the appropriate script.
Modifications to strings in source files
----------------------------------------
If a string changes in the sources, the old translations will no longer work.
They will be preserved in the ``po`` files, but commented-out (starting with ``#~``).
If you add/remove/change a translatable strings in a source file,
run ``build_tools/update_translations.fish`` to propagate this to all translation files (``po/*.po``).
This is only relevant for developers modifying the source files of fish or fish scripts.
Setting Code Up For Translations
--------------------------------

42
Cargo.lock generated
View File

@@ -89,9 +89,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.10"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
"windows-sys",
@@ -104,6 +104,7 @@ dependencies = [
"bitflags",
"cc",
"errno",
"fish-gettext-extraction",
"fish-printf",
"libc",
"lru",
@@ -121,11 +122,20 @@ dependencies = [
"widestring",
]
[[package]]
name = "fish-gettext-extraction"
version = "0.0.1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "fish-printf"
version = "0.2.1"
dependencies = [
"libc",
"unicode-segmentation",
"unicode-width",
"widestring",
]
@@ -173,9 +183,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.169"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "lock_api"
@@ -216,9 +226,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nix"
version = "0.29.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags",
"cfg-if",
@@ -346,18 +356,18 @@ checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
[[package]]
name = "proc-macro2"
version = "1.0.92"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
@@ -546,6 +556,18 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-width"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
[[package]]
name = "unix_path"
version = "1.0.1"

View File

@@ -1,11 +1,12 @@
[workspace]
resolver = "2"
members = ["printf"]
members = ["printf", "gettext-extraction"]
[workspace.package]
# To build revisions that use Corrosion (those before 2024-01), use CMake 3.19, Rustc 1.78 and Rustup 1.27.
rust-version = "1.70"
edition = "2021"
repository = "https://github.com/fish-shell/fish-shell"
[profile.release]
overflow-checks = true
@@ -24,7 +25,6 @@ default-run = "fish"
# see doc_src/license.rst for details
# don't forget to update COPYING and debian/copyright too
license = "GPL-2.0-only AND LGPL-2.0-or-later AND MIT AND PSF-2.0"
repository = "https://github.com/fish-shell/fish-shell"
homepage = "https://fishshell.com"
readme = "README.rst"
@@ -40,7 +40,7 @@ libc = "0.2"
# disabling default features uses the stdlib instead, but it doubles the time to rewrite the history
# files as of 22 April 2024.
lru = "0.13.0"
nix = { version = "0.29.0", default-features = false, features = [
nix = { version = "0.30.1", default-features = false, features = [
"event",
"inotify",
"resource",
@@ -49,6 +49,7 @@ nix = { version = "0.29.0", default-features = false, features = [
num-traits = "0.2.19"
once_cell = "1.19.0"
fish-printf = { path = "./printf", features = ["widestring"] }
fish-gettext-extraction = { path = "./gettext-extraction" }
# Don't use the "getrandom" feature as it requires "getentropy" which was not
# available on macOS < 10.12. We can enable "getrandom" when we raise the
@@ -99,7 +100,7 @@ embed-data = ["dep:rust-embed"]
asan = []
tsan = []
[lints]
[workspace.lints]
rust.non_camel_case_types = "allow"
rust.non_upper_case_globals = "allow"
rust.unknown_lints = "allow"
@@ -113,3 +114,6 @@ clippy.needless_lifetimes = "allow"
# In the future, they might change to flag other methods of printing.
clippy.print_stdout = "deny"
clippy.print_stderr = "deny"
[lints]
workspace = true

35
SECURITY.md Normal file
View File

@@ -0,0 +1,35 @@
# Security Reporting
If you wish to report a security vulnerability privately, we appreciate your diligence. Please follow the guidelines below to submit your report.
## Reporting
To report a security vulnerability, please provide the following information:
1. **PROJECT**
- Include the URL of the project repository - Example: <https://github.com/fish-shell/fish-shell>
2. **PUBLIC**
- Indicate whether this vulnerability has already been publicly discussed or disclosed.
- If so, provide relevant links.
3. **DESCRIPTION**
- Provide a detailed description of the security vulnerability.
- Include as much information as possible to help us understand and address the issue.
Send this information, along with any additional relevant details, to <rf@fishshell.com>.
## Confidentiality
We kindly ask you to keep the report confidential until a public announcement is made.
## Notes
- Vulnerabilities will be handled on a best-effort basis.
- You may request an advance copy of the patched release, but we cannot guarantee early access before the public release.
- You will be notified via email simultaneously with the public announcement.
- We will respond within a few weeks to confirm whether your report has been accepted or rejected.
Thank you for helping to improve the security of our project!

View File

@@ -3,7 +3,16 @@
use rsconf::{LinkType, Target};
use std::env;
use std::error::Error;
use std::path::Path;
use std::path::{Path, PathBuf};
fn canonicalize<P: AsRef<Path>>(path: P) -> PathBuf {
std::fs::canonicalize(path).unwrap()
}
fn canonicalize_str<P: AsRef<Path>>(path: P) -> String {
canonicalize(path).to_str().unwrap().to_owned()
}
const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR");
fn main() {
setup_paths();
@@ -11,23 +20,19 @@ fn main() {
// Add our default to enable tools that don't go through CMake, like "cargo test" and the
// language server.
let cargo_target_dir: PathBuf = option_env!("CARGO_TARGET_DIR")
.map(canonicalize)
.unwrap_or(canonicalize(MANIFEST_DIR).join("target"));
// FISH_BUILD_DIR is set by CMake, if we are using it.
// OUT_DIR is set by Cargo when the build script is running (not compiling)
let default_build_dir = env::var("OUT_DIR").unwrap();
let build_dir = option_env!("FISH_BUILD_DIR").unwrap_or(&default_build_dir);
let build_dir = std::fs::canonicalize(build_dir).unwrap();
let build_dir = build_dir.to_str().unwrap();
rsconf::set_env_value("FISH_BUILD_DIR", build_dir);
rsconf::set_env_value(
"FISH_BUILD_DIR",
option_env!("FISH_BUILD_DIR").unwrap_or(cargo_target_dir.to_str().unwrap()),
);
// We need to canonicalize (i.e. realpath) the manifest dir because we want to be able to
// compare it directly as a string at runtime.
rsconf::set_env_value(
"CARGO_MANIFEST_DIR",
std::fs::canonicalize(env!("CARGO_MANIFEST_DIR"))
.unwrap()
.as_path()
.to_str()
.unwrap(),
);
rsconf::set_env_value("CARGO_MANIFEST_DIR", &canonicalize_str(MANIFEST_DIR));
// Some build info
rsconf::set_env_value("BUILD_TARGET_TRIPLE", &env::var("TARGET").unwrap());
@@ -41,8 +46,7 @@ fn main() {
std::env::set_var("FISH_BUILD_VERSION", version);
let cman = std::fs::canonicalize(env!("CARGO_MANIFEST_DIR")).unwrap();
let targetman = cman.as_path().join("target").join("man");
let targetman = cargo_target_dir.join("fish-man");
#[cfg(feature = "embed-data")]
#[cfg(not(clippy))]
@@ -63,10 +67,9 @@ fn main() {
#[cfg(not(debug_assertions))]
rsconf::rebuild_if_paths_changed(&["doc_src", "share"]);
cc::Build::new()
.file("src/libc.c")
.include(build_dir)
.compile("flibc.a");
rsconf::rebuild_if_env_changed("FISH_GETTEXT_EXTRACTION_FILE");
cc::Build::new().file("src/libc.c").compile("flibc.a");
let mut build = cc::Build::new();
// Add to the default library search path
@@ -143,9 +146,9 @@ fn detect_apple(_: &Target) -> Result<bool, Box<dyn Error>> {
Ok(cfg!(any(target_os = "ios", target_os = "macos")))
}
#[allow(unexpected_cfgs)]
fn detect_cygwin(_: &Target) -> Result<bool, Box<dyn Error>> {
Ok(cfg!(target_os = "cygwin"))
// Cygwin target is usually cross-compiled.
Ok(std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "cygwin")
}
/// Detect if we're being compiled for a BSD-derived OS, allowing targeting code conditionally with
@@ -252,8 +255,6 @@ fn has_small_stack(_: &Target) -> Result<bool, Box<dyn Error>> {
}
fn setup_paths() {
#[cfg(unix)]
use std::path::PathBuf;
#[cfg(windows)]
use unix_path::{Path, PathBuf};
@@ -324,7 +325,7 @@ fn get_version(src_dir: &Path) -> String {
let path = src_dir.join("version");
if let Ok(strver) = read_to_string(path) {
return strver.to_string();
return strver;
}
let args = &["describe", "--always", "--dirty=-dirty"];
@@ -351,8 +352,8 @@ fn get_version(src_dir: &Path) -> String {
// or because it refused (safe.directory applies to `git describe`!)
// So we read the SHA ourselves.
fn get_git_hash() -> Result<String, Box<dyn std::error::Error>> {
let gitdir = Path::new(env!("CARGO_MANIFEST_DIR")).join(".git");
let jjdir = Path::new(env!("CARGO_MANIFEST_DIR")).join(".jj");
let gitdir = Path::new(MANIFEST_DIR).join(".git");
let jjdir = Path::new(MANIFEST_DIR).join(".jj");
let commit_id = if gitdir.exists() {
// .git/HEAD contains ref: refs/heads/branch
let headpath = gitdir.join("HEAD");
@@ -397,10 +398,7 @@ fn build_man(build_dir: &Path) {
use std::process::Command;
let mandir = build_dir;
let sec1dir = mandir.join("man1");
let docsrc_path = std::fs::canonicalize(env!("CARGO_MANIFEST_DIR"))
.unwrap()
.as_path()
.join("doc_src");
let docsrc_path = canonicalize(MANIFEST_DIR).join("doc_src");
let docsrc = docsrc_path.to_str().unwrap();
let args = &[
"-j",
@@ -450,10 +448,7 @@ fn build_man(build_dir: &Path) {
);
}
Ok(out) => {
if out.success() {
// Success!
return;
} else {
if !out.success() {
panic!("sphinx-build failed to build the man pages.");
}
}

54
build_tools/check.sh Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
{
set -ex
lint=true
if [ "$FISH_CHECK_LINT" = false ]; then
lint=false
fi
cargo_args=$FISH_CHECK_CARGO_ARGS
target_triple=$FISH_CHECK_TARGET_TRIPLE
if [ -n "$target_triple" ]; then
cargo_args="$cargo_args --target=$FISH_CHECK_TARGET_TRIPLE"
fi
cargo() {
subcmd=$1
shift
# shellcheck disable=2086
command cargo "$subcmd" $cargo_args "$@"
}
cleanup () {
if [ -n "$template_file" ] && [ -e "$template_file" ]; then
rm "$template_file"
fi
}
trap cleanup EXIT INT TERM HUP
if $lint; then
export RUSTFLAGS="--deny=warnings ${RUSTFLAGS}"
export RUSTDOCFLAGS="--deny=warnings ${RUSTDOCFLAGS}"
fi
repo_root="$(dirname "$0")/.."
build_dir="${CARGO_TARGET_DIR:-$repo_root/target}/${target_triple}/debug"
template_file=$(mktemp)
FISH_GETTEXT_EXTRACTION_FILE=$template_file cargo build --workspace --all-targets
if $lint; then
PATH="$build_dir:$PATH" "$repo_root/build_tools/style.fish" --all --check
cargo clippy --workspace --all-targets
fi
cargo test --no-default-features --workspace --all-targets
cargo test --doc --workspace
if $lint; then
cargo doc --workspace
fi
FISH_GETTEXT_EXTRACTION_FILE=$template_file "$repo_root/tests/test_driver.py" "$build_dir"
exit
}

15
build_tools/diff_profiles.fish Normal file → Executable file
View File

@@ -5,6 +5,13 @@
#
# Usage: ./diff_profiles.fish profile1.log profile2.log > profile_diff.log
if test (count $argv) -ne 2
echo "Incorrect number of arguments."
echo "Usage: "(status filename)" profile1.log profile2.log"
exit 1
end
set -l profile1 (cat $argv[1])
set -l profile2 (cat $argv[2])
@@ -15,13 +22,13 @@ while set -l next_line_no (math $line_no + 1) && set -q profile1[$next_line_no]
set -l line1 $profile1[$line_no]
set -l line2 $profile2[$line_no]
if not string match -qr '^\d+\t\d+' $line1
if not string match -qr '^\s*\d+\s+\d+' $line1
echo $line1
continue
end
set -l results1 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line1)
set -l results2 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line2)
set -l results1 (string match -r '^\s*(\d+)\s+(\d+)\s+(.*)' $line1)
set -l results2 (string match -r '^\s*(\d+)\s+(\d+)\s+(.*)' $line2)
# times from both files
set -l time1 $results1[2..3]
@@ -42,5 +49,5 @@ while set -l next_line_no (math $line_no + 1) && set -q profile1[$next_line_no]
set diff[1] (math $time1[1] - $time2[1])
set diff[2] (math $time1[2] - $time2[2])
echo $diff[1] $diff[2] $remainder1
printf '%10d %10d %s\n' $diff[1] $diff[2] $remainder1
end

View File

@@ -1,68 +1,87 @@
#!/usr/bin/env fish
#
# Tool to generate messages.pot
# Tool to generate gettext messages template file.
# Writes to stdout.
# Intended to be called from `update_translations.fish`.
# Create temporary directory for these operations. OS X `mktemp` is somewhat restricted, so this block
# works around that - based on share/functions/funced.fish.
set -q TMPDIR
or set -l TMPDIR /tmp
set -l tmpdir (mktemp -d $TMPDIR/fish.XXXXXX)
or exit 1
argparse use-existing-template= -- $argv
or exit $status
# This is a gigantic crime.
# xgettext still does not support rust *at all*, so we use cargo-expand to get all our wgettext invocations.
set -l expanded (cargo expand --lib; for f in fish{,_indent,_key_reader}; cargo expand --bin $f; end)
begin
# Write header. This is required by msguniq.
# Note that this results in the file being overwritten.
# This is desired behavior, to get rid of the results of prior invocations
# of this script.
begin
echo 'msgid ""'
echo 'msgstr ""'
echo '"Content-Type: text/plain; charset=UTF-8\n"'
echo ""
end
# Extract any gettext call
set -l strs (printf '%s\n' $expanded | grep -A1 wgettext_static_str |
grep 'widestring::internals::core::primitive::str =' |
string match -rg '"(.*)"' | string match -rv '^%ls$|^$' |
# escaping difference between gettext and cargo-expand: single-quotes
string replace -a "\'" "'" | sort -u)
set -g repo_root (status dirname)/..
# Extract any constants
set -a strs (string match -rv 'BUILD_VERSION:|PACKAGE_NAME' -- $expanded |
string match -rg 'const [A-Z_]*: &str = "(.*)"' | string replace -a "\'" "'")
set -l rust_extraction_file
if set -l --query _flag_use_existing_template
set rust_extraction_file $_flag_use_existing_template
else
set rust_extraction_file (mktemp)
# We need to build to ensure that the proc macro for extracting strings runs.
FISH_GETTEXT_EXTRACTION_FILE=$rust_extraction_file cargo check
or exit 1
end
# We construct messages.pot ourselves instead of forcing this into msgmerge or whatever.
# The escaping so far works out okay.
for str in $strs
# grep -P needed for string escape to be compatible (PCRE-style),
# -H gives the filename, -n the line number.
# If you want to run this on non-GNU grep: Don't.
echo "#:" (grep -PHn -r -- (string escape --style=regex -- $str) src/ |
head -n1 | string replace -r ':\s.*' '')
echo "msgid \"$str\""
echo 'msgstr ""'
end >messages.pot
# Get rid of duplicates and sort.
msguniq --no-wrap --strict --sort-output $rust_extraction_file
or exit 1
# This regex handles descriptions for `complete` and `function` statements. These messages are not
# particularly important to translate. Hence the "implicit" label.
set -l implicit_regex '(?:^| +)(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
if not set -l --query _flag_use_existing_template
rm $rust_extraction_file
end
# This regex handles explicit requests to translate a message. These are more important to translate
# than messages which should be implicitly translated.
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
function extract_fish_script_messages --argument-names regex
mkdir -p $tmpdir/implicit/share/completions $tmpdir/implicit/share/functions
mkdir -p $tmpdir/explicit/share/completions $tmpdir/explicit/share/functions
# Using xgettext causes more trouble than it helps.
# This is due to handling of escaping in fish differing from formats xgettext understands
# (e.g. POSIX shell strings).
# We work around this issue by manually writing the file content.
for f in share/config.fish share/completions/*.fish share/functions/*.fish
# Extract explicit attempts to translate a message. That is, those that are of the form
# `(_ "message")`.
string replace --filter --regex $explicit_regex '$1' <$f | string unescape \
| string replace --all '"' '\\"' | string replace -r '(.*)' 'N_ "$1"' >$tmpdir/explicit/$f
# Steps:
# 1. We extract strings to be translated from the relevant files and drop the rest. This step
# depends on the regex matching the entire line, and the first capture group matching the
# string.
# 2. We unescape. This gets rid of some escaping necessary in fish strings.
# 3. The resulting strings are sorted alphabetically. This step is optional. Not sorting would
# result in strings from the same file appearing together. Removing duplicates is also
# optional, since msguniq takes care of that later on as well.
# 4. Single backslashes are replaced by double backslashes. This results in the backslashes
# being interpreted as literal backslashes by gettext tooling.
# 5. Double quotes are escaped, such that they are not interpreted as the start or end of
# a msgid.
# 6. We transform the string into the format expected in a PO file.
cat $share_dir/config.fish $share_dir/completions/*.fish $share_dir/functions/*.fish |
string replace --filter --regex $regex '$1' |
string unescape |
sort -u |
sed -E -e 's_\\\\_\\\\\\\\_g' -e 's_"_\\\\"_g' -e 's_^(.*)$_msgid "\1"\nmsgstr ""\n_'
end
# Handle `complete` / `function` description messages. The `| fish` is subtle. It basically
# avoids the need to use `source` with a command substitution that could affect the current
# shell.
string replace --filter --regex $implicit_regex '$1' <$f | string unescape \
| string replace --all '"' '\\"' | string replace -r '(.*)' 'N_ "$1"' >$tmpdir/implicit/$f
end
set -g share_dir $repo_root/share
xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot $tmpdir/{ex,im}plicit/share/*/*.fish
# This regex handles explicit requests to translate a message. These are more important to translate
# than messages which should be implicitly translated.
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
extract_fish_script_messages $explicit_regex
# Remove the tmpdir from the location to avoid churn
sed -i 's_^#: /.*/share/_#: share/_' messages.pot
rm -r $tmpdir
# This regex handles descriptions for `complete` and `function` statements. These messages are not
# particularly important to translate. Hence the "implicit" label.
set -l implicit_regex '^(?:\s|and |or )*(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
extract_fish_script_messages $implicit_regex
end |
# At this point, all extracted strings have been written to stdout,
# starting with the ones taken from the Rust sources,
# followed by strings explicitly marked for translation in fish scripts,
# and finally the strings from fish scripts which get translated implicitly.
# Because we do not eliminate duplicates across these categories,
# we do it here, since other gettext tools expect no duplicates.
msguniq --no-wrap

View File

@@ -3,18 +3,18 @@
# Script to produce an OS X installer .pkg and .app(.zip)
usage() {
echo "Build macOS packages, optionally signing and notarizing them."
echo "Usage: $0 options"
echo "Options:"
echo " -s Enables code signing"
echo " -f <APP_KEY.p12> Path to .p12 file for application signing"
echo " -i <INSTALLER_KEY.p12> Path to .p12 file for installer signing"
echo " -p <PASSWORD> Password for the .p12 files (necessary to access the certificates)"
echo " -e <entitlements file> (Optional) Path to an entitlements XML file"
echo " -n Enables notarization. This will fail if code signing is not also enabled."
echo " -j <API_KEY.JSON> Path to JSON file generated with \`rcodesign encode-app-store-connect-api-key\` (required for notarization)"
echo
exit 1
echo "Build macOS packages, optionally signing and notarizing them."
echo "Usage: $0 options"
echo "Options:"
echo " -s Enables code signing"
echo " -f <APP_KEY.p12> Path to .p12 file for application signing"
echo " -i <INSTALLER_KEY.p12> Path to .p12 file for installer signing"
echo " -p <PASSWORD> Password for the .p12 files (necessary to access the certificates)"
echo " -e <entitlements file> (Optional) Path to an entitlements XML file"
echo " -n Enables notarization. This will fail if code signing is not also enabled."
echo " -j <API_KEY.JSON> Path to JSON file generated with \`rcodesign encode-app-store-connect-api-key\` (required for notarization)"
echo
exit 1
}
set -x
@@ -30,35 +30,35 @@ X86_64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=10.9'
# The first supported version of macOS on arm64 is 10.15, so any Rust is fine for arm64.
# We wish to support back to 10.9 on x86-64; the last version of Rust to support that is
# version 1.73.0.
RUST_VERSION_X86_64=1.73.0
RUST_VERSION_X86_64=1.70.0
while getopts "sf:i:p:e:nj:" opt; do
case $opt in
s) SIGN=1;;
f) P12_APP_FILE=$(realpath "$OPTARG");;
i) P12_INSTALL_FILE=$(realpath "$OPTARG");;
p) P12_PASSWORD="$OPTARG";;
e) ENTITLEMENTS_FILE=$(realpath "$OPTARG");;
n) NOTARIZE=1;;
j) API_KEY_FILE=$(realpath "$OPTARG");;
\?) usage;;
esac
case $opt in
s) SIGN=1;;
f) P12_APP_FILE=$(realpath "$OPTARG");;
i) P12_INSTALL_FILE=$(realpath "$OPTARG");;
p) P12_PASSWORD="$OPTARG";;
e) ENTITLEMENTS_FILE=$(realpath "$OPTARG");;
n) NOTARIZE=1;;
j) API_KEY_FILE=$(realpath "$OPTARG");;
\?) usage;;
esac
done
if [ -n "$SIGN" ] && { [ -z "$P12_APP_FILE" ] || [ -z "$P12_INSTALL_FILE" ] || [ -z "$P12_PASSWORD" ]; }; then
usage
usage
fi
if [ -n "$NOTARIZE" ] && [ -z "$API_KEY_FILE" ]; then
usage
usage
fi
VERSION=$(git describe --always --dirty 2>/dev/null)
if test -z "$VERSION" ; then
echo "Could not get version from git"
if test -f version; then
VERSION=$(cat version)
fi
echo "Could not get version from git"
if test -f version; then
VERSION=$(cat version)
fi
fi
echo "Version is $VERSION"
@@ -76,7 +76,7 @@ mkdir -p "$PKGDIR/build_x86_64" "$PKGDIR/build_arm64" "$PKGDIR/root" "$PKGDIR/in
# and will probably not be built universal, so the package will fail to validate/run on other systems.
# Note CMAKE_OSX_ARCHITECTURES is still relevant for the Mac app.
{ cd "$PKGDIR/build_arm64" \
&& cmake \
&& cmake \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
-DWITH_GETTEXT=OFF \
@@ -91,7 +91,7 @@ mkdir -p "$PKGDIR/build_x86_64" "$PKGDIR/build_arm64" "$PKGDIR/root" "$PKGDIR/in
# Build for x86-64 but do not install; instead we will make some fat binaries inside the root.
# Set RUST_VERSION_X86_64 to the last version of Rust that supports macOS 10.9.
{ cd "$PKGDIR/build_x86_64" \
&& cmake \
&& cmake \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
-DWITH_GETTEXT=OFF \
@@ -99,7 +99,7 @@ mkdir -p "$PKGDIR/build_x86_64" "$PKGDIR/build_arm64" "$PKGDIR/root" "$PKGDIR/in
-DRust_CARGO_TARGET=x86_64-apple-darwin \
-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
-DFISH_USE_SYSTEM_PCRE2=OFF "$SRC_DIR" \
&& env $X86_64_DEPLOY_TARGET make VERBOSE=1 -j 12; }
&& env $X86_64_DEPLOY_TARGET make VERBOSE=1 -j 12; }
# Fatten them up.
for FILE in "$PKGDIR"/root/usr/local/bin/*; do

View File

@@ -18,22 +18,22 @@ set -e
BUILD_TOOL="make"
BUILD_GENERATOR="Unix Makefiles"
if command -v ninja >/dev/null; then
BUILD_TOOL="ninja"
BUILD_GENERATOR="Ninja"
BUILD_TOOL="ninja"
BUILD_GENERATOR="Ninja"
fi
# We need GNU tar as that supports the --mtime and --transform options
TAR=notfound
for try in tar gtar gnutar; do
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
TAR=$try
break
fi
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
TAR=$try
break
fi
done
if [ "$TAR" = "notfound" ]; then
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
exit 1
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
exit 1
fi
# Get the current directory, which we'll use for symlinks
@@ -63,7 +63,7 @@ cmake -G "$BUILD_GENERATOR" -DCMAKE_BUILD_TYPE=Debug "$wd"
$BUILD_TOOL doc
TAR_APPEND="$TAR --append --file=$path --mtime=now --owner=0 --group=0 \
--mode=g+w,a+rX --transform s/^/$prefix\//"
--mode=g+w,a+rX --transform s/^/$prefix\//"
$TAR_APPEND --no-recursion user_doc
$TAR_APPEND user_doc/html user_doc/man
$TAR_APPEND version

View File

@@ -11,15 +11,15 @@ set -e
# We need GNU tar as that supports the --mtime and --transform options
TAR=notfound
for try in tar gtar gnutar; do
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
TAR=$try
break
fi
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
TAR=$try
break
fi
done
if [ "$TAR" = "notfound" ]; then
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
exit 1
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
exit 1
fi
# Get the current directory, which we'll use for telling Cargo where to find the sources

View File

@@ -1,38 +1,53 @@
#!/usr/bin/env fish
#
# This runs C++ files and fish scripts (*.fish) through their respective code
# formatting programs.
# This runs Python files, fish scripts (*.fish), and Rust files
# through their respective code formatting programs.
#
# `--all`: Format all eligible files instead of the ones specified as arguments.
# `--check`: Instead of reformatting, fail if a file is not formatted correctly.
# `--force`: Proceed without asking if uncommitted changes are detected.
# Only relevant if `--all` is specified but `--check` is not specified.
set -l fish_files
set -l python_files
set -l rust_files
set -l all no
if test "$argv[1]" = --all
argparse all check force -- $argv
or exit $status
if set -l -q _flag_all
set all yes
set -e argv[1]
if set -q argv[1]
echo "Unexpected arguments: '$argv'"
exit 1
end
end
if set -q argv[1]
echo "Unexpected arguments: '$argv'"
exit 1
end
set -l repo_root (status dirname)/..
if test $all = yes
set -l files (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//')
if set -q files[1]
echo
echo 'You have uncommitted changes. Are you sure you want to restyle?'
read -P 'y/N? ' -n1 -l ans
if not string match -qi y -- $ans
exit 1
if not set -l -q _flag_force; and not set -l -q _flag_check
# Potential for false positives: Not all fish files are formatted, see the `fish_files`
# definition below.
set -l relevant_uncommitted_changes (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//' | grep -E '.*\.(fish|py|rs)$')
if set -q relevant_uncommitted_changes[1]
for changed_file in $relevant_uncommitted_changes
echo $changed_file
end
echo
echo 'You have uncommitted changes (listed above). Are you sure you want to restyle?'
read -P 'y/N? ' -n1 -l ans
if not string match -qi y -- $ans
exit 1
end
end
end
set fish_files share/**.fish
set fish_files $repo_root/{benchmarks,build_tools,etc,share}/**.fish
set python_files {doc_src,share,tests}/**.py
set rust_files fish-rust/src/**.rs
else
# Extract just the fish files.
# Format the files specified as arguments.
set -l files $argv
set fish_files (string match -r '^.*\.fish$' -- $files)
set python_files (string match -r '^.*\.py$' -- $files)
set rust_files (string match -r '^.*\.rs$' -- $files)
@@ -40,37 +55,70 @@ end
set -l red (set_color red)
set -l green (set_color green)
set -l blue (set_color blue)
set -l yellow (set_color yellow)
set -l normal (set_color normal)
# Run the fish reformatter if we have any fish files.
if set -q fish_files[1]
if not type -q fish_indent
make fish_indent
set PATH . $PATH
echo
echo $yellow'Could not find `fish_indent` in `$PATH`.'$normal
exit 127
end
echo === Running "$green"fish_indent"$normal"
fish_indent -w -- $fish_files
if set -l -q _flag_check
if not fish_indent --check -- $fish_files
echo $red"Fish files are not formatted correctly."$normal
exit 1
end
else
fish_indent -w -- $fish_files
end
end
if set -q python_files[1]
if not type -q black
echo
echo Please install "`black`" to style python
echo
echo $yellow'Please install `black` to style python'$normal
exit 127
end
echo === Running "$green"black"$normal"
if set -l -q _flag_check
if not black --check $python_files
echo $red"Python files are not formatted correctly."$normal
exit 1
end
else
echo === Running "$blue"black"$normal"
black $python_files
end
end
if set -q rust_files[1]
if not type -q rustfmt
echo
echo Please install "`rustfmt`" to style rust
echo
if not cargo fmt --version >/dev/null
echo
echo $yellow'Please install "rustfmt" to style Rust, e.g. via:'
echo "rustup component add rustfmt"$normal
exit 127
end
echo === Running "$green"rustfmt"$normal"
if set -l -q _flag_check
if set -l -q _flag_all
if not cargo fmt --check
echo $red"Rust files are not formatted correctly."$normal
exit 1
end
else
echo === Running "$blue"rustfmt"$normal"
rustfmt $rust_files
if set -q rust_files[1]
if not rustfmt --check --files-with-diff $rust_files
echo $red"Rust files are not formatted correctly."
exit 1
end
end
end
else
if set -l -q _flag_all
cargo fmt
else
if set -q rust_files[1]
rustfmt $rust_files
end
end
end

View File

@@ -0,0 +1,145 @@
#!/usr/bin/env fish
# Updates the files used for gettext translations.
# By default, the whole xgettext, msgmerge, msgfmt pipeline runs,
# which extracts the messages from the source files into $template_file,
# updates the PO files for each language from that
# (changed line numbers, added messages, removed messages),
# and finally generates a machine-readable MO file for each language,
# which is stored in share/locale/$LANG/LC_MESSAGES/fish.mo (relative to the repo root).
#
# Use cases:
# For developers:
# - Run with args `--no-mo` to update all PO files after making changes to Rust/fish
# sources.
# For translators:
# - Run with `--no-mo` first, to ensure that the strings you are translating are up to date.
# - Specify the language you want to work on as an argument, which must be a file in the po/
# directory. You can specify a language which does not have translations yet by specifying the
# name of a file which does not yet exist. Make sure to follow the naming convention.
# For testing:
# - Specify `--dry-run` to see if any updates to the PO files would by applied by this script.
# If this flag is specified, the script will exit with an error if there are outstanding
# changes, and will display the diff. Do not specify other flags if `--dry-run` is specified.
#
# Specify `--use-existing-template=FILE` to prevent running cargo for extracting an up-to-date
# version of the localized strings. This flag is intended for testing setups which make it
# inconvenient to run cargo here, but run it in an earlier step to ensure up-to-date values.
# This argument is passed on to the `fish_xgettext.fish` script and has no other uses.
# `FILE` must be the path to a gettext template file generated from our compilation process.
# It can be obtained by running:
# set -l FILE (mktemp)
# FISH_GETTEXT_EXTRACTION_FILE=$FILE cargo check
# The sort utility is locale-sensitive.
# Ensure that sorting output is consistent by setting LC_ALL here.
set -gx LC_ALL C.UTF-8
set -l build_tools (status dirname)
set -g tmpdir
set -l po_dir $build_tools/../po
set -l extract
set -l po
set -l mo
argparse --exclusive 'no-mo,only-mo,dry-run' no-mo only-mo dry-run use-existing-template= -- $argv
or exit $status
if test -z $argv[1]
# Update everything if not specified otherwise.
set -g po_files $po_dir/*.po
else
set -l po_dir_id (stat --format='%d:%i' -- $po_dir)
for arg in $argv
set -l arg_dir_id (stat --format='%d:%i' -- (dirname $arg))
if test $po_dir_id != $arg_dir_id
echo "Argument $arg is not a file in the directory $(realpath $po_dir)."
echo "Non-option arguments must specify paths to files in this directory."
echo ""
echo "If you want to add a new language to the translations not the following:"
echo "The filename must identify a language, with a two letter ISO 639-1 language code of the target language (e.g. 'pt' for Portuguese), and use the file extension '.po'."
echo "Optionally, you can specify a regional variant (e.g. 'pt_BR')."
echo "So valid filenames are of the shape 'll.po' or 'll_CC.po'."
exit 1
end
if not basename $arg | grep -qE '^[a-z]{2}(_[A-Z]{2})?\.po$'
echo "Filename does not match the expected format ('ll.po' or 'll_CC.po')."
exit 1
end
end
set -g po_files $argv
end
if set -l --query _flag_no_mo
set -l --erase mo
end
if set -l --query _flag_only_mo
set -l --erase extract
set -l --erase po
end
set -g template_file (mktemp)
# Protect from externally set $tmpdir leaking into this script.
set -g tmpdir
function cleanup_exit
set -l exit_status $status
rm $template_file
if set -g --query tmpdir[1]
rm -r $tmpdir
end
exit $exit_status
end
if set -l --query extract
set -l xgettext_args
if set -l --query _flag_use_existing_template
set xgettext_args --use-existing-template=$_flag_use_existing_template
end
$build_tools/fish_xgettext.fish $xgettext_args >$template_file
or cleanup_exit
end
if set -l --query _flag_dry_run
# On a dry run, we do not modify po/ but write to a temporary directory instead and check if
# there is a difference between po/ and the tmpdir after re-generating the PO files.
set -g tmpdir (mktemp -d)
# On a dry-run, we do not update the MO files.
set -l --erase mo
# Ensure tmpdir has the same initial state as the po dir.
cp -r $po_dir/* $tmpdir
end
for po_file in $po_files
if set --query tmpdir[1]
set po_file $tmpdir/(basename $po_file)
end
if set -l --query po
if test -e $po_file
msgmerge --no-wrap --update --no-fuzzy-matching --backup=none --quiet $po_file $template_file
and msgattrib --no-wrap --no-obsolete -o $po_file $po_file
or cleanup_exit
else
cp $template_file $po_file
end
end
if set -l --query mo
set -l locale_dir $build_tools/../share/locale
set -l out_dir $locale_dir/(basename $po_file .po)/LC_MESSAGES
mkdir -p $out_dir
msgfmt --check-format --output-file=$out_dir/fish.mo $po_file
end
end
if set -g --query tmpdir[1]
diff -ur $po_dir $tmpdir
or cleanup_exit
end
cleanup_exit

View File

@@ -1,92 +1,33 @@
# This adds ctest support to the project
enable_testing()
# By default, ctest runs tests serially
# Support CTEST_PARALLEL_LEVEL as an environment variable in addition to a CMake variable
if(NOT CTEST_PARALLEL_LEVEL)
set(CTEST_PARALLEL_LEVEL $ENV{CTEST_PARALLEL_LEVEL})
if(NOT CTEST_PARALLEL_LEVEL)
include(ProcessorCount)
ProcessorCount(CORES)
math(EXPR halfcores "${CORES} / 2")
set(CTEST_PARALLEL_LEVEL ${halfcores})
endif()
endif()
# Put in a tests folder to reduce the top level targets in IDEs.
set(CMAKE_FOLDER tests)
# We will use 125 as a reserved exit code to indicate that a test has been skipped, i.e. it did not
# pass but it should not be considered a failed test run, either.
set(SKIP_RETURN_CODE 125)
# Even though we are using CMake's ctest for testing, we still define our own `make fish_run_tests` target
# rather than use its default for many reasons:
# * CMake doesn't run tests in-proc or even add each tests as an individual node in the ninja
# dependency tree, instead it just bundles all tests into a target called `test` that always just
# shells out to `ctest`, so there are no build-related benefits to not doing that ourselves.
# * CMake devs insist that it is appropriate for `make fish_run_tests` to never depend on `make all`, i.e.
# running `make fish_run_tests` does not require any of the binaries to be built before testing.
# * It is not possible to set top-level CTest options/settings such as CTEST_PARALLEL_LEVEL from
# within the CMake configuration file.
# * The only way to have a test depend on a binary is to add a fake test with a name like
# "build_fish" that executes CMake recursively to build the `fish` target.
# * Circling back to the point about individual tests not being actual Makefile targets, CMake does
# not offer any way to execute a named test via the `make`/`ninja`/whatever interface; the only
# way to manually invoke test `foo` is to to manually run `ctest` and specify a regex matching
# `foo` as an argument, e.g. `ctest -R ^foo$`... which is really crazy.
# The top-level test target is "fish_run_tests".
add_custom_target(fish_run_tests
COMMAND env CTEST_PARALLEL_LEVEL=${CTEST_PARALLEL_LEVEL} FISH_FORCE_COLOR=1
${CMAKE_CTEST_COMMAND} --force-new-ctest-process # --verbose
--output-on-failure --progress
DEPENDS fish fish_indent fish_key_reader fish_test_helper
USES_TERMINAL
)
# CMake being CMake, you can't just add a DEPENDS argument to add_test to make it depend on any of
# your binaries actually being built before `make fish_run_tests` is executed (requiring `make all` first),
# and the only dependency a test can have is on another test. So we make building fish
# prerequisites to our entire top-level `test` target.
function(add_test_target NAME)
string(REPLACE "/" "-" NAME ${NAME})
add_custom_target("test_${NAME}" COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R "^${NAME}$$"
DEPENDS fish fish_indent fish_key_reader fish_test_helper USES_TERMINAL)
endfunction()
add_executable(fish_test_helper tests/fish_test_helper.c)
FILE(GLOB FISH_CHECKS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/checks/*.fish)
foreach(CHECK ${FISH_CHECKS})
get_filename_component(CHECK_NAME ${CHECK} NAME)
get_filename_component(CHECK ${CHECK} NAME_WE)
add_test(NAME ${CHECK_NAME}
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py --cachedir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
checks/${CHECK}.fish
add_custom_target(
test_${CHECK_NAME}
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${CMAKE_CURRENT_BINARY_DIR}
checks/${CHECK_NAME}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
DEPENDS fish fish_indent fish_key_reader fish_test_helper
USES_TERMINAL
)
set_tests_properties(${CHECK_NAME} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
set_tests_properties(${CHECK_NAME} PROPERTIES ENVIRONMENT FISH_FORCE_COLOR=1)
add_test_target("${CHECK_NAME}")
endforeach(CHECK)
FILE(GLOB PEXPECTS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/pexpects/*.py)
foreach(PEXPECT ${PEXPECTS})
get_filename_component(PEXPECT ${PEXPECT} NAME)
add_test(NAME ${PEXPECT}
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py --cachedir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
add_custom_target(
test_${PEXPECT}
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${CMAKE_CURRENT_BINARY_DIR}
pexpects/${PEXPECT}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
DEPENDS fish fish_indent fish_key_reader fish_test_helper
USES_TERMINAL
)
set_tests_properties(${PEXPECT} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
set_tests_properties(${PEXPECT} PROPERTIES ENVIRONMENT FISH_FORCE_COLOR=1)
add_test_target("${PEXPECT}")
endforeach(PEXPECT)
set(cargo_test_flags)
# Rust stuff.
set(cargo_test_flags)
if(DEFINED ASAN)
# Rust w/ -Zsanitizer=address requires explicitly specifying the --target triple or else linker
# errors pertaining to asan symbols will ensue.
@@ -107,10 +48,17 @@ if(DEFINED Rust_CARGO_TARGET)
list(APPEND cargo_test_flags "--lib")
endif()
add_test(
NAME "cargo-test"
COMMAND env ${VARS_FOR_CARGO} cargo test --no-default-features ${CARGO_FLAGS} --workspace --target-dir ${rust_target_dir} ${cargo_test_flags}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
set(max_concurrency_flag)
if(DEFINED ENV{FISH_TEST_MAX_CONCURRENCY})
list(APPEND max_concurrency_flag "--max-concurrency" $ENV{FISH_TEST_MAX_CONCURRENCY})
endif()
# The top-level test target is "fish_run_tests".
add_custom_target(fish_run_tests
# TODO: This should be replaced with a unified solution, possibly build_tools/check.sh.
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${max_concurrency_flag} ${CMAKE_CURRENT_BINARY_DIR}
COMMAND env ${VARS_FOR_CARGO} cargo test --no-default-features ${CARGO_FLAGS} --workspace --target-dir ${rust_target_dir} ${cargo_test_flags}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
DEPENDS fish fish_indent fish_key_reader fish_test_helper
USES_TERMINAL
)
set_tests_properties("cargo-test" PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
add_test_target("cargo-test")

1
debian/control vendored
View File

@@ -27,7 +27,6 @@ Depends: bsdextrautils | bsdmainutils,
gettext-base,
# for nroff and preconv
groff-base,
man-db,
# for terminal definitions
ncurses-base,
# for kill

View File

@@ -425,6 +425,24 @@ Launch ``git diff`` and repaint the commandline afterwards when :kbd:`ctrl-g` is
bind ctrl-g 'git diff' repaint
Swap :kbd:`tab` and :kbd:`shift-tab`, making tab focus the search field.
But if the search field is already active, keep the behavior (:kbd:`tab` cycles forward, :kbd:`shift-tab` backward).::
bind tab '
if commandline --search-field >/dev/null
commandline -f complete
else
commandline -f complete-and-search
end
'
bind shift-tab '
if commandline --search-field >/dev/null
commandline -f complete-and-search
else
commandline -f complete
end
'
.. _cmd-bind-termlimits:
Terminal Limitations

View File

@@ -74,6 +74,9 @@ The following options change what part of the commandline is printed or updated:
**--search-field**
Use the pager search field instead of the command line. Returns false if the search field is not shown.
**--input=INPUT**
Operate on this string instead of the commandline. Useful for using options like **--tokens-expanded**.
The following options change the way ``commandline`` prints the current commandline buffer:
**-c** or **--cut-at-cursor**
@@ -87,10 +90,7 @@ The following options change the way ``commandline`` prints the current commandl
Perform argument expansion on the selection and print one argument per line.
Command substitutions are not expanded but forwarded as-is.
**--tokens-raw**
Print arguments in the selection as they appear on the command line, one per line.
**-o** or **tokenize**
**-o**, **tokenize**, **--tokens-raw**
Deprecated; do not use.
If ``commandline`` is called during a call to complete a given string using ``complete -C STRING``, ``commandline`` will consider the specified string to be the current contents of the command line.

View File

@@ -8,7 +8,7 @@ Synopsis
.. synopsis::
fish_git_prompt
fish_git_prompt [FORMAT]
::
@@ -24,6 +24,8 @@ The ``fish_git_prompt`` function displays information about the current git repo
`Git <https://git-scm.com>`_ must be installed.
It is possible to modify the output format by passing an argument. The default value is ``" (%s)"``.
There are numerous customization options, which can be controlled with git options or fish variables. git options, where available, take precedence over the fish variable with the same function. git options can be set on a per-repository or global basis. git options can be set with the ``git config`` command, while fish variables can be set as usual with the :doc:`set <set>` command.
Boolean options (those which enable or disable something) understand "1", "yes" or "true" to mean true and every other value to mean false.

View File

@@ -22,7 +22,7 @@ Description
The ``fish_mode_prompt`` function outputs the mode indicator for use in vi mode.
The default ``fish_mode_prompt`` function will output indicators about the current vi editor mode displayed to the left of the regular prompt. Define your own function to customize the appearance of the mode indicator. The ``$fish_bind_mode variable`` can be used to determine the current mode. It will be one of ``default``, ``insert``, ``replace_one``, or ``visual``.
The default ``fish_mode_prompt`` function will output indicators about the current vi editor mode displayed to the left of the regular prompt. Define your own function to customize the appearance of the mode indicator. The ``$fish_bind_mode variable`` can be used to determine the current mode. It will be one of ``default``, ``insert``, ``replace_one``, ``replace``, or ``visual``.
You can also define an empty ``fish_mode_prompt`` function to remove the vi mode indicators::
@@ -51,6 +51,9 @@ Example
case replace_one
set_color --bold green
echo 'R'
case replace
set_color --bold bryellow
echo 'R'
case visual
set_color --bold brmagenta
echo 'V'

View File

@@ -13,7 +13,7 @@ Synopsis
path extension GENERAL_OPTIONS [PATH ...]
path filter GENERAL_OPTIONS [-v | --invert]
[-d] [-f] [-l] [-r] [-w] [-x]
[(-t | --type) TYPE] [(-p | --perm) PERMISSION] [PATH ...]
[(-t | --type) TYPE] [(-p | --perm) PERMISSION] [--all] [PATH ...]
path is GENERAL_OPTIONS [(-v | --invert)] [(-t | --type) TYPE]
[-d] [-f] [-l] [-r] [-w] [-x]
[(-p | --perm) PERMISSION] [PATH ...]
@@ -22,7 +22,7 @@ Synopsis
path resolve GENERAL_OPTIONS [PATH ...]
path change-extension GENERAL_OPTIONS EXTENSION [PATH ...]
path sort GENERAL_OPTIONS [-r | --reverse]
[-u | --unique] [--key=basename|dirname|path] [PATH ...]
[-u | --unique] [--key=(basename | dirname | path)] [PATH ...]
GENERAL_OPTIONS
[-z | --null-in] [-Z | --null-out] [-q | --quiet]
@@ -148,7 +148,7 @@ Examples
> echo $path$extension
# reconstructs the original path again.
./foo.mp4
.. _cmd-path-filter:
"filter" subcommand
@@ -158,7 +158,7 @@ Examples
path filter [-z | --null-in] [-Z | --null-out] [-q | --quiet] \
[-d] [-f] [-l] [-r] [-w] [-x] \
[-v | --invert] [(-t | --type) TYPE] [(-p | --perm) PERMISSION] [PATH ...]
[-v | --invert] [(-t | --type) TYPE] [(-p | --perm) PERMISSION] [--all] [PATH ...]
``path filter`` returns all of the given paths that match the given checks. In all cases, the paths need to exist, nonexistent paths are always filtered.
@@ -180,6 +180,10 @@ When a path starts with ``-``, ``path filter`` will prepend ``./`` to avoid it b
It returns 0 if at least one path passed the filter.
With ``--all``, return status 0 (true) if all paths pass the filter, and status 1 (false) if any path fails. This is equivalent to ``not path filter -v``. It produces no output, only a status.
When ``--all`` combined with ``--invert``, it returns status 0 (true) if all paths fail the filter and status 1 (false) if any path passes.
``path is`` is shorthand for ``path filter -q``, i.e. just checking without producing output, see :ref:`The is subcommand <cmd-path-is>`.
Examples
@@ -211,6 +215,9 @@ Examples
>_ path filter -fx $PATH/*
# Prints all possible commands - the first entry of each name is what fish would execute!
>_ path filter --all /usr/bin /usr/argagagji
# This returns 1 (false) because not all paths pass the filter.
.. _cmd-path-is:
"is" subcommand

View File

@@ -57,7 +57,7 @@ The following options are available:
Sets reverse mode.
**-u** or **--underline**, or **-uSTYLE** or **--underline=STYLE**
Set the underline mode; supported styles are **single** (default) and **curly**.
Set the underline mode; supported styles are **single** (default), **double**, **curly**, **dotted** and **dashed**.
**-h** or **--help**
Displays help about using this command.

View File

@@ -8,8 +8,8 @@ Synopsis
.. synopsis::
string join [-q | --quiet] SEP [STRING ...]
string join0 [-q | --quiet] [STRING ...]
string join [-q | --quiet] [-n | --no-empty] [--] SEP [STRING ...]
string join0 [-q | --quiet] [-n | --no-empty] [--] [STRING ...]
.. END SYNOPSIS
@@ -18,11 +18,28 @@ Description
.. BEGIN DESCRIPTION
``string join`` joins its *STRING* arguments into a single string separated by *SEP*, which can be an empty string. Exit status: 0 if at least one join was performed, or 1 otherwise. If ``-n`` or ``--no-empty`` is specified, empty strings are excluded from consideration (e.g. ``string join -n + a b "" c`` would expand to ``a+b+c`` not ``a+b++c``).
Joins its *STRING* arguments into a single string separated by *SEP* (for ``string join``) or by the
zero byte (NUL) (for ``string join0``).
Exit status: 0 if at least one join was performed, or 1 otherwise.
``string join0`` joins its *STRING* arguments into a single string separated by the zero byte (NUL), and adds a trailing NUL. This is most useful in conjunction with tools that accept NUL-delimited input, such as ``sort -z``. Exit status: 0 if at least one join was performed, or 1 otherwise.
**-n**, **--no-empty**
Exclude empty strings from consideration (e.g. ``string join -n + a b "" c`` would expand to ``a+b+c`` not ``a+b++c``).
Because Unix uses NUL as the string terminator, passing the output of ``string join0`` as an *argument* to a command (via a :ref:`command substitution <expand-command-substitution>`) won't actually work. Fish will pass the correct bytes along, but the command won't be able to tell where the argument ends. This is a limitation of Unix' argument passing.
**-q**, **--quiet**
Do not print the strings, only set the exit status as described above.
**WARNING**:
Insert a ``--`` before positional arguments to prevent them from being interpreted as flags.
Otherwise, any strings starting with ``-`` will be treated as flag arguments, meaning they will most likely result in the command failing.
This is also true if you specify a variable which expands to such a string instead of a literal string.
If you don't need to append flag arguments at the end of the command,
just always use ``--`` to avoid unwelcome surprises.
``string join0`` adds a trailing NUL. This is most useful in conjunction with tools that accept NUL-delimited input, such as ``sort -z``.
Because Unix uses NUL as the string terminator, passing the output of ``string join0`` as an *argument* to a command (via a :ref:`command substitution <expand-command-substitution>`) won't actually work.
Fish will pass the correct bytes along, but the command won't be able to tell where the argument ends.
This is a limitation of Unix' argument passing.
.. END DESCRIPTION
@@ -43,4 +60,14 @@ Examples
>_ string join '' a b c
abc
>_ set -l markdown_list '- first' '- second' '- third'
# Strings with leading hyphens (also in variable expansions) are interpreted as flag arguments by default.
>_ string join \n $markdown_list
string join: - first: unknown option
# Use '--' to prevent this.
>_ string join -- \n $markdown_list
- first
- second
- third
.. END EXAMPLES

View File

@@ -11,7 +11,7 @@ Synopsis
string collect [-a | --allow-empty] [-N | --no-trim-newlines] [STRING ...]
string escape [-n | --no-quoted] [--style=] [STRING ...]
string join [-q | --quiet] [-n | --no-empty] SEP [STRING ...]
string join0 [-q | --quiet] [STRING ...]
string join0 [-q | --quiet] [-n | --no-empty] [STRING ...]
string length [-q | --quiet] [STRING ...]
string lower [-q | --quiet] [STRING ...]
string match [-a | --all] [-e | --entire] [-i | --ignore-case]
@@ -27,7 +27,7 @@ Synopsis
[-r | --regex] [-q | --quiet] PATTERN REPLACE [STRING ...]
string shorten [(-c | --char) CHARS] [(-m | --max) INTEGER]
[-N | --no-newline] [-l | --left] [-q | --quiet] [STRING ...]
string split [(-f | --fields) FIELDS] [(-m | --max) MAX] [-n | --no-empty]
string split [(-f | --fields) FIELDS] [(-m | --max) MAX] [-n | --no-empty]
[-q | --quiet] [-r | --right] SEP [STRING ...]
string split0 [(-f | --fields) FIELDS] [(-m | --max) MAX] [-n | --no-empty]
[-q | --quiet] [-r | --right] [STRING ...]

View File

@@ -354,7 +354,7 @@ Some bindings are common across Emacs and vi mode, because they aren't text edit
- :kbd:`alt-o` opens the file at the cursor in a pager. If the cursor is in command position and the command is a script, it will instead open that script in your editor. The editor is chosen from the first available of the ``$VISUAL`` or ``$EDITOR`` variables.
- :kbd:`alt-p` adds the string ``&| less;`` to the end of the job under the cursor. The result is that the output of the command will be paged.
- :kbd:`alt-p` adds the string ``&| less;`` to the end of the job under the cursor. The result is that the output of the command will be paged. If you set the ``PAGER`` variable, its value is used instead of ``less``.
- :kbd:`alt-w` prints a short description of the command under the cursor.
@@ -362,7 +362,7 @@ Some bindings are common across Emacs and vi mode, because they aren't text edit
- :kbd:`alt-v` Same as :kbd:`alt-e`.
- :kbd:`alt-s` Prepends ``sudo`` to the current commandline. If the commandline is empty, prepend ``sudo`` to the last commandline.
- :kbd:`alt-s` Prepends ``sudo`` to the current commandline. If the commandline is empty, prepend ``sudo`` to the last commandline. If ``sudo`` is not installed, various similar commands are tried: ``doas``, ``please``, and ``run0``.
- :kbd:`ctrl-space` Inserts a space without expanding an :ref:`abbreviation <abbreviations>`. For vi mode, this only applies to insert-mode.
@@ -507,7 +507,13 @@ Command mode is also known as normal mode.
- :kbd:`backspace` moves the cursor left.
- :kbd:`g` / :kbd:`G` moves the cursor to the beginning/end of the commandline, respectively.
- :kbd:`g,g` / :kbd:`G` moves the cursor to the beginning/end of the commandline, respectively.
- :kbd:`~` toggles the case (upper/lower) of the character and moves to the next character.
- :kbd:`g,u` lowercases to the end of the word.
- :kbd:`g,U` uppercases to the end of the word.
- :kbd:`:,q` exits fish.
@@ -551,6 +557,10 @@ Visual mode
- :kbd:`~` toggles the case (upper/lower) on the selection, and enters :ref:`command mode <vi-mode-command>`.
- :kbd:`g,u` lowercases the selection, and enters :ref:`command mode <vi-mode-command>`.
- :kbd:`g,U` uppercases the selection, and enters :ref:`command mode <vi-mode-command>`.
- :kbd:`",*,y` copies the selection to the clipboard, and enters :ref:`command mode <vi-mode-command>`.
.. _custom-binds:

View File

@@ -917,6 +917,12 @@ If there is nothing between a brace and a comma or two commas, it's interpreted
To use a "," as an element, :ref:`quote <quotes>` or :ref:`escape <escapes>` it.
The very first character of a command token is never interpreted as expanding brace, because it's the beginning of a :ref:`compound statement <cmd-begin>`::
> {echo hello, && echo world}
hello,
world
.. _cartesian-product:
Combining lists

View File

@@ -120,10 +120,22 @@ Optional Commands
- smul
- Enter underline mode.
-
* - ``\e[4:2m``
- Su
- Enter double underline mode.
- kitty
* - ``\e[4:3m``
- Su
- Enter curly underline mode.
- kitty
* - ``\e[4:4m``
- Su
- Enter dotted underline mode.
- kitty
* - ``\e[4:5m``
- Su
- Enter dashed underline mode.
- kitty
* - ``\e[7m``
- rev
- Enter reverse video mode (swap foreground and background colors).

View File

@@ -115,7 +115,7 @@ These colors, and many more, can be changed by running ``fish_config``, or by mo
For example, if you want to disable (almost) all coloring::
fish_config theme choose none
fish_config theme choose None
This picks the "none" theme. To see all themes::
@@ -631,12 +631,12 @@ You can define your own prompt from the command line:
Then, if you are happy with it, you can save it to disk by typing ``funcsave fish_prompt``. This saves the prompt in ``~/.config/fish/functions/fish_prompt.fish``. (Or, if you want, you can create that file manually from the start.)
Multiple lines are OK. Colors can be set via :doc:`set_color <cmds/set_color>`, passing it named ANSI colors, or hex RGB values::
Multiple lines are OK. Colors can be set via :doc:`set_color <cmds/set_color>` by passing it named ANSI colors, or hex RGB values::
function fish_prompt
set_color purple
date "+%m/%d/%y"
set_color F00
set_color FF0000
echo (pwd) '>' (set_color normal)
end

View File

@@ -1,19 +1,17 @@
FROM alpine:3.19
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN apk add --no-cache \
bash \
cargo \
cmake \
g++ \
gettext-dev \
git \
libintl \
musl-dev \
ninja \
pcre2-dev \
py3-pexpect \
python3 \
@@ -40,4 +38,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -8,17 +8,13 @@ RUN cd /etc/yum.repos.d/ && \
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
# install powertools to get ninja-build
RUN dnf -y install dnf-plugins-core \
&& dnf config-manager --set-enabled powertools \
&& yum install --assumeyes epel-release \
&& yum install --assumeyes \
cargo \
cmake \
diffutils \
gcc-c++ \
git \
ninja-build \
python3 \
python3-pexpect \
openssl \
@@ -39,4 +35,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -5,22 +5,34 @@ set -e
# This script is copied into the root directory of our Docker tests.
# It is the entry point for running Docker-based tests.
cd ~/fish-build
echo build_tools/check.sh >>~/.bash_history
cd /fish-source
git config --global --add safe.directory /fish-source
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug /fish-source "$@"
export CARGO_TARGET_DIR="$HOME"/fish-build
interactive_shell() {
echo
echo "+ export=CARGO_TARGET_DIR=$CARGO_TARGET_DIR"
echo
bash -i
}
# Spawn a shell if FISH_RUN_SHELL_BEFORE_TESTS is set.
if test -n "$FISH_RUN_SHELL_BEFORE_TESTS"
then
bash -i
interactive_shell
fi
(set +e; ninja && ninja fish_run_tests)
set +e
build_tools/check.sh
RES=$?
set -e
# Drop the user into a shell if FISH_RUN_SHELL_AFTER_TESTS is set.
if test -n "$FISH_RUN_SHELL_AFTER_TESTS"; then
bash -i
interactive_shell
fi
exit $RES

View File

@@ -4,8 +4,9 @@ usage() {
cat << EOF
Usage: $(basename "$0") [--shell-before] [--shell-after] DOCKERFILE
Options:
--shell-before Before the tests start, run a bash shell
--shell-after After the tests end, run a bash shell
--shell-before Before the tests start, run a bash shell
--shell-after After the tests end, run a bash shell
--lint, --no-lint Enable/disable linting and failure on warnings
EOF
exit 1
}
@@ -29,6 +30,12 @@ while [ $# -gt 1 ]; do
--shell-after)
DOCKER_EXTRA_ARGS="$DOCKER_EXTRA_ARGS --env FISH_RUN_SHELL_AFTER_TESTS=1"
;;
--lint)
DOCKER_EXTRA_ARGS="$DOCKER_EXTRA_ARGS --env FISH_CHECK_LINT=true"
;;
--no-lint)
DOCKER_EXTRA_ARGS="$DOCKER_EXTRA_ARGS --env FISH_CHECK_LINT=false"
;;
*)
usage
;;

View File

@@ -2,11 +2,9 @@ FROM fedora:latest
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
RUN dnf install --assumeyes \
cmake \
diffutils \
gcc-c++ \
git-core \
ninja-build \
pcre2-devel \
python3 \
python3-pip \
@@ -28,4 +26,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -1,20 +1,17 @@
FROM ubuntu:20.04
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV CFLAGS="-m32"
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install \
build-essential \
cmake \
g++-multilib \
gettext \
git \
locales \
ninja-build \
pkg-config \
python3 \
python3-pexpect \
@@ -38,6 +35,13 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rustup.sh \
COPY fish_run_tests.sh /
ENV \
CFLAGS=-m32 \
PCRE2_SYS_STATIC=1 \
FISH_CHECK_TARGET_TRIPLE=i686-unknown-linux-gnu
ENV FISH_CHECK_LINT=false
CMD . ~/.cargo/env \
&& rustup target add i686-unknown-linux-gnu \
&& /fish_run_tests.sh -DFISH_USE_SYSTEM_PCRE2=OFF -DRust_CARGO_TARGET=i686-unknown-linux-gnu
&& rustup target add ${FISH_CHECK_TARGET_TRIPLE} \
&& /fish_run_tests.sh

View File

@@ -1,21 +1,19 @@
FROM arm64v8/ubuntu:focal
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install \
build-essential \
cargo \
cmake \
clang \
gettext \
git \
libpcre2-dev \
locales \
ninja-build \
python3 \
python3-pexpect \
rustc \
@@ -36,4 +34,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -1,19 +1,17 @@
FROM ubuntu:20.04
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install \
build-essential \
cargo \
cmake \
gettext \
git \
locales \
ninja-build \
pkg-config \
python3 \
python3-pexpect \
@@ -35,4 +33,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -1,22 +1,20 @@
FROM arm32v7/ubuntu:jammy
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install \
build-essential \
cargo \
cmake \
file \
g++ \
gettext \
git \
libpcre2-dev \
locales \
ninja-build \
pkg-config \
python3 \
python3-pexpect \
@@ -38,4 +36,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -1,19 +1,17 @@
FROM ubuntu:jammy
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN apt-get update \
&& apt-get -y install \
build-essential \
cmake \
clang \
gettext \
git \
libpcre2-dev \
locales \
ninja-build \
python3 \
python3-pexpect \
sudo \
@@ -42,12 +40,17 @@ COPY fish_run_tests.sh /
ENV \
RUSTFLAGS=-Zsanitizer=address \
RUSTDOCFLAGS=-Zsanitizer=address \
FISH_CHECK_CARGO_ARGS='-Zbuild-std --features=tsan' \
FISH_CHECK_TARGET_TRIPLE=x86_64-unknown-linux-gnu \
FISH_CI_SAN=1 \
FISH_TEST_MAX_CONCURRENCY=4 \
CC=clang \
CXX=clang++ \
ASAN_OPTIONS=check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1 \
LSAN_OPTIONS=verbosity=0:log_threads=0:use_tls=1:print_suppressions=0:suppressions=/fish-source/build_tools/lsan_suppressions.txt \
FISH_CI_SAN=1
LSAN_OPTIONS=verbosity=0:log_threads=0:use_tls=1:print_suppressions=0:suppressions=/fish-source/build_tools/lsan_suppressions.txt
ENV FISH_CHECK_LINT=false
CMD . ~/.cargo/env \
&& ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-$(cat /.llvm-version) \
/fish_run_tests.sh -DASAN=1 -DRust_CARGO_TARGET=x86_64-unknown-linux-gnu
&& ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-$(cat /.llvm-version) \
&& /fish_run_tests.sh

View File

@@ -1,19 +1,17 @@
FROM ubuntu:jammy
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN apt-get update \
&& apt-get -y install \
build-essential \
cmake \
clang \
gettext \
git \
libpcre2-dev \
locales \
ninja-build \
python3 \
python3-pexpect \
sudo \
@@ -39,7 +37,11 @@ COPY fish_run_tests.sh /
ENV \
RUSTFLAGS=-Zsanitizer=thread \
RUSTDOCFLAGS=-Zsanitizer=thread \
FISH_CI_SAN=1
FISH_CHECK_CARGO_ARGS='-Zbuild-std --features=tsan' \
FISH_CHECK_TARGET_TRIPLE=x86_64-unknown-linux-gnu \
FISH_CI_SAN=1 \
FISH_TEST_MAX_CONCURRENCY=4
CMD . ~/.cargo/env \
&& /fish_run_tests.sh -DTSAN=1 -DRust_CARGO_TARGET=x86_64-unknown-linux-gnu
ENV FISH_CHECK_LINT=false
CMD . ~/.cargo/env && /fish_run_tests.sh

View File

@@ -1,20 +1,18 @@
FROM ubuntu:jammy
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN apt-get update \
&& apt-get -y install \
build-essential \
cargo \
cmake \
clang \
gettext \
git \
libpcre2-dev \
locales \
ninja-build \
python3 \
python3-pexpect \
rustc \
@@ -35,4 +33,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -1,18 +1,16 @@
FROM ubuntu:noble
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN apt-get update \
&& apt-get -y install \
build-essential \
cmake \
gettext \
git \
libpcre2-dev \
locales \
ninja-build \
python3 \
python3-pexpect \
tmux \
@@ -36,5 +34,7 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rustup.sh \
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD . ~/.cargo/env \
&& /fish_run_tests.sh

View File

@@ -1,16 +1,14 @@
FROM opensuse/tumbleweed:latest
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
RUN zypper --non-interactive install \
bash \
cmake \
diffutils \
gcc-c++ \
git-core \
ninja \
pcre2-devel \
python311 \
python311-pip \
@@ -35,4 +33,6 @@ WORKDIR /home/fishuser
COPY fish_run_tests.sh /
ENV FISH_CHECK_LINT=false
CMD /fish_run_tests.sh

View File

@@ -31,13 +31,12 @@ BuildRequires: glibc-langpack-en
BuildRequires: python3 procps
%if 0%{?suse_version}
Requires: terminfo-base
Requires: terminfo-base groff
%else
Requires: ncurses-base
Requires: ncurses-base groff-base
%endif
Requires: file
Requires: python3
Requires: man
Requires: procps
# Although the build scripts mangle the version number to be RPM compatible

View File

@@ -0,0 +1,16 @@
[package]
name = "fish-gettext-extraction"
edition.workspace = true
rust-version.workspace = true
version = "0.0.1"
repository.workspace = true
description = "proc-macro for extracting strings for gettext translation"
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1.0"
[lints]
workspace = true

View File

@@ -0,0 +1,67 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use std::{ffi::OsString, fs::OpenOptions, io::Write};
fn append_po_entry_to_file(message: &TokenStream, file_name: &OsString) {
let mut file = OpenOptions::new()
.create(true)
.append(true)
.open(file_name)
.unwrap_or_else(|e| panic!("Could not open file {file_name:?}: {e}"));
let message_string = message.to_string();
if message_string.contains('\n') {
panic!("Gettext strings may not contain unescaped newlines. Unescaped newline found in '{message_string}'")
}
// Crude check for format strings. This might result in false positives.
let format_string_annotation = if message_string.contains('%') {
"#, c-format\n"
} else {
""
};
let po_entry = format!("{format_string_annotation}msgid {message_string}\nmsgstr \"\"\n\n");
file.write_all(po_entry.as_bytes()).unwrap();
}
/// The `message` is passed through unmodified.
/// If `FISH_GETTEXT_EXTRACTION_FILE` is defined in the environment,
/// this file is used to write the message,
/// so that it can then be used for generating gettext PO files.
/// The `message` must be a string literal.
///
/// # Panics
///
/// This macro panics if the `FISH_GETTEXT_EXTRACTION_FILE` variable is set and `message` has an
/// unexpected format.
/// Note that for example `concat!(...)` cannot be passed to this macro, because expansion works
/// outside in, meaning this macro would still see the `concat!` macro invocation, instead of a
/// string literal.
#[proc_macro]
pub fn gettext_extract(message: TokenStream) -> TokenStream {
if let Some(file_path) = std::env::var_os("FISH_GETTEXT_EXTRACTION_FILE") {
let pm2_message = proc_macro2::TokenStream::from(message.clone());
let mut token_trees = pm2_message.into_iter();
let first_token = token_trees
.next()
.expect("gettext_extract got empty token stream. Expected one token.");
if token_trees.next().is_some() {
panic!("Invalid number of tokens passed to gettext_extract. Expected one token, but got more.")
}
if let proc_macro2::TokenTree::Group(group) = first_token {
let mut group_tokens = group.stream().into_iter();
let first_group_token = group_tokens
.next()
.expect("gettext_extract expected one group token but got none.");
if group_tokens.next().is_some() {
panic!("Invalid number of tokens in group passed to gettext_extract. Expected one token, but got more.")
}
if let proc_macro2::TokenTree::Literal(_) = first_group_token {
append_po_entry_to_file(&message, &file_path);
} else {
panic!("Expected literal in gettext_extract, but got: {first_group_token:?}");
}
} else {
panic!("Expected group in gettext_extract, but got: {first_token:?}");
}
}
message
}

182145
po/de.po

File diff suppressed because it is too large Load Diff

183530
po/en.po

File diff suppressed because it is too large Load Diff

187555
po/fr.po

File diff suppressed because it is too large Load Diff

181344
po/pl.po

File diff suppressed because it is too large Load Diff

182216
po/pt_BR.po

File diff suppressed because it is too large Load Diff

183220
po/sv.po

File diff suppressed because it is too large Load Diff

181520
po/zh_CN.po

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,17 @@
[package]
name = "fish-printf"
edition = "2021"
edition.workspace = true
rust-version.workspace = true
version = "0.2.1"
repository = "https://github.com/fish-shell/fish-shell"
repository.workspace = true
description = "printf implementation, based on musl"
license = "MIT"
[dependencies]
libc = "0.2.155"
widestring = { version = "1.0.2", optional = true }
unicode-segmentation = "1.12.0"
unicode-width = "0.2.0"
[lints]
workspace = true

1
printf/clippy.toml Normal file
View File

@@ -0,0 +1 @@
allow-print-in-tests = true

View File

@@ -279,6 +279,7 @@ fn format_a(mut y: f64, params: FormatParams<'_, impl Write>) -> Result<usize, E
// Compute the number of hex digits in the mantissa after the decimal.
// -1 for leading 1 bit (we are to the range [1, 2)), then divide by 4, rounding up.
#[allow(unknown_lints)] // for old clippy
#[allow(clippy::manual_div_ceil)]
const MANTISSA_HEX_DIGITS: usize = (MANTISSA_BITS - 1 + 3) / 4;
if had_prec && prec < MANTISSA_HEX_DIGITS {
@@ -495,7 +496,7 @@ fn format_mantissa_e(
let digit = if d < decimal.len_i32() { decimal[d] } else { 0 };
let min_width = if d > 0 { DIGIT_WIDTH } else { 1 };
buf.clear();
write!(buf, "{:0width$}", digit, width = min_width)?;
write!(buf, "{digit:0min_width$}")?;
let mut s = buf.as_str();
if d == 0 {
// First digit. Emit it, and likely also a decimal point.

View File

@@ -71,7 +71,7 @@ macro_rules! sprintf {
/// - `args`: Iterator over the arguments to format.
///
/// # Returns
/// A `Result` which is `Ok` containing the number of characters written on success, or an `Error`.
/// A `Result` which is `Ok` containing the width of the string written on success, or an `Error`.
///
/// # Example
///

View File

@@ -5,6 +5,8 @@
use std::fmt::{self, Write};
use std::mem;
use std::result::Result;
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
#[cfg(feature = "widestring")]
use widestring::Utf32Str as wstr;
@@ -382,7 +384,7 @@ pub fn sprintf_locale(
}
// Read field width. We do not support $.
let width = if s.at(0) == Some('*') {
let desired_width = if s.at(0) == Some('*') {
let arg_width = args.next().ok_or(Error::MissingArg)?.as_sint()?;
s.advance_by(1);
if arg_width < 0 {
@@ -397,7 +399,7 @@ pub fn sprintf_locale(
};
// Optionally read precision. We do not support $.
let mut prec: Option<usize> = if s.at(0) == Some('.') && s.at(1) == Some('*') {
let mut desired_precision: Option<usize> = if s.at(0) == Some('.') && s.at(1) == Some('*') {
// "A negative precision is treated as though it were missing."
// Here we assume the precision is always signed.
s.advance_by(2);
@@ -410,7 +412,7 @@ pub fn sprintf_locale(
None
};
// Disallow precisions larger than i32::MAX, in keeping with C.
if prec.unwrap_or(0) > i32::MAX as usize {
if desired_precision.unwrap_or(0) > i32::MAX as usize {
return Err(Error::Overflow);
}
@@ -429,7 +431,7 @@ pub fn sprintf_locale(
// "If a precision is given with a numeric conversion (d, i, o, u, i, x, and X),
// the 0 flag is ignored." p is included here.
let spec_is_numeric = matches!(conv_spec, CS::d | CS::u | CS::o | CS::p | CS::x | CS::X);
if spec_is_numeric && prec.is_some() {
if spec_is_numeric && desired_precision.is_some() {
flags.zero_pad = false;
}
@@ -443,17 +445,26 @@ pub fn sprintf_locale(
CS::e | CS::f | CS::g | CS::a | CS::E | CS::F | CS::G | CS::A => {
// Floating point types handle output on their own.
let float = arg.as_float()?;
let len = format_float(f, float, width, prec, flags, locale, conv_spec, buf)?;
let len = format_float(
f,
float,
desired_width,
desired_precision,
flags,
locale,
conv_spec,
buf,
)?;
out_len = out_len.checked_add(len).ok_or(Error::Overflow)?;
continue 'main;
}
CS::p => {
const PTR_HEX_DIGITS: usize = 2 * mem::size_of::<*const u8>();
prec = prec.map(|p| p.max(PTR_HEX_DIGITS));
desired_precision = desired_precision.map(|p| p.max(PTR_HEX_DIGITS));
let uint = arg.as_uint()?;
if uint != 0 {
prefix = "0x";
write!(buf, "{:x}", uint)?;
write!(buf, "{uint:x}")?;
}
buf
}
@@ -467,9 +478,9 @@ pub fn sprintf_locale(
prefix = if lower { "0x" } else { "0X" };
}
if lower {
write!(buf, "{:x}", uint)?;
write!(buf, "{uint:x}")?;
} else {
write!(buf, "{:X}", uint)?;
write!(buf, "{uint:X}")?;
}
}
buf
@@ -477,17 +488,17 @@ pub fn sprintf_locale(
CS::o => {
let uint = arg.as_uint()?;
if uint != 0 {
write!(buf, "{:o}", uint)?;
write!(buf, "{uint:o}")?;
}
if flags.alt_form && prec.unwrap_or(0) <= buf.len() + 1 {
prec = Some(buf.len() + 1);
if flags.alt_form && desired_precision.unwrap_or(0) <= buf.len() + 1 {
desired_precision = Some(buf.len() + 1);
}
buf
}
CS::u => {
let uint = arg.as_uint()?;
if uint != 0 {
write!(buf, "{}", uint)?;
write!(buf, "{uint}")?;
}
buf
}
@@ -514,10 +525,38 @@ pub fn sprintf_locale(
CS::s => {
// also 'S'
let s = arg.as_str(buf)?;
let p = prec.unwrap_or(s.len()).min(s.len());
prec = Some(p);
flags.zero_pad = false;
&s[..p]
match desired_precision {
Some(precision) => {
// from man printf(3)
// "the maximum number of characters to be printed from a string"
// We interpret this to mean the maximum width when printed, as defined by
// Unicode grapheme cluster width.
let mut byte_len = 0;
let mut width = 0;
let mut graphemes = s.graphemes(true);
// Iteratively add single grapheme clusters as long as the fit within the
// width limited by precision.
while width < precision {
match graphemes.next() {
Some(grapheme) => {
let grapheme_width = grapheme.width();
if width + grapheme_width <= precision {
byte_len += grapheme.len();
width += grapheme_width;
} else {
break;
}
}
None => break,
}
}
let p = precision.min(width);
desired_precision = Some(p);
&s[..byte_len]
}
None => s,
}
}
};
// Numeric output should be empty iff the value is 0.
@@ -528,23 +567,26 @@ pub fn sprintf_locale(
// Decide if we want to apply thousands grouping to the body, and compute its size.
// Note we have already errored out if grouped is set and this is non-numeric.
let wants_grouping = flags.grouped && locale.thousands_sep.is_some();
let body_len = match wants_grouping {
let body_width = match wants_grouping {
// We assume that text representing numbers is ASCII, so len == width.
true => body.len() + locale.separator_count(body.len()),
false => body.len(),
false => body.width(),
};
// Resolve the precision.
// In the case of a non-numeric conversion, update the precision to at least the
// length of the string.
let prec = if !spec_is_numeric {
prec.unwrap_or(body_len)
let desired_precision = if !spec_is_numeric {
desired_precision.unwrap_or(body_width)
} else {
prec.unwrap_or(1).max(body_len)
desired_precision.unwrap_or(1).max(body_width)
};
let prefix_len = prefix.len();
let unpadded_width = prefix_len.checked_add(prec).ok_or(Error::Overflow)?;
let width = width.max(unpadded_width);
let prefix_width = prefix.width();
let unpadded_width = prefix_width
.checked_add(desired_precision)
.ok_or(Error::Overflow)?;
let width = desired_width.max(unpadded_width);
// Pad on the left with spaces to the desired width?
if !flags.left_adj && !flags.zero_pad {
@@ -560,7 +602,8 @@ pub fn sprintf_locale(
}
// Pad on the left to the given precision?
pad(f, '0', prec, body_len)?;
// TODO: why pad with 0 here?
pad(f, '0', desired_precision, body_width)?;
// Output the actual value, perhaps with grouping.
if wants_grouping {

View File

@@ -13,6 +13,7 @@ macro_rules! sprintf_check {
$(,)? // optional trailing comma
) => {
{
use unicode_width::UnicodeWidthStr;
let mut target = String::new();
let mut args = [$($arg.to_arg()),*];
let len = $crate::printf_c_locale(
@@ -20,7 +21,7 @@ macro_rules! sprintf_check {
$fmt.as_ref() as &str,
&mut args,
).expect("printf failed");
assert!(len == target.len(), "Wrong length returned: {} vs {}", len, target.len());
assert_eq!(len, target.width(), "Wrong length returned");
target
}
};
@@ -735,6 +736,18 @@ fn test_huge_precision_g() {
sprintf_err!("%.2147483648g", f => Error::Overflow);
}
#[test]
fn test_non_ascii() {
assert_fmt!("%3s", "ö" => " ö");
assert_fmt!("%3s", "🇺🇳" => " 🇺🇳");
assert_fmt!("%.3s", "🇺🇳🇺🇳" => "🇺🇳");
assert_fmt!("%.3s", "a🇺🇳" => "a🇺🇳");
assert_fmt!("%.3s", "aa🇺🇳" => "aa");
assert_fmt!("%3.3s", "aa🇺🇳" => " aa");
assert_fmt!("%.1s", "𒈙a" => "𒈙");
assert_fmt!("%3.3s", "👨‍👨‍👧‍👧" => " 👨‍👨‍👧‍👧");
}
#[test]
fn test_errors() {
use Error::*;
@@ -877,7 +890,7 @@ fn test_exhaustive(rust_fmt: &str, c_fmt: *const c_char) {
// "There's only 4 billion floats so test them all."
// This tests a format string expected to be of the form "%.*g" or "%.*e".
// That is, it takes a precision and a double.
println!("Testing {}", rust_fmt);
println!("Testing {rust_fmt}");
let mut rust_str = String::with_capacity(128);
let mut c_storage = [0u8; 128];
let c_storage_ptr = c_storage.as_mut_ptr() as *mut c_char;

View File

@@ -195,6 +195,7 @@ complete -n '__fish_seen_subcommand_from sideload' -c adb -k -xa '(__fish_comple
complete -n '__fish_seen_subcommand_from reconnect' -c adb -x -a device -d 'Kick current connection from device side and make it reconnect.'
# commands that accept listing device files
complete -n '__fish_seen_subcommand_from exec-out' -c adb -f -a "(__fish_adb_list_files)" -d 'File on device'
complete -n '__fish_seen_subcommand_from shell' -c adb -f -a "(__fish_adb_list_files)" -d 'File on device'
complete -n '__fish_seen_subcommand_from pull' -c adb -F -a "(__fish_adb_list_files)" -d 'File on device'
complete -n '__fish_seen_subcommand_from push' -c adb -ka "(__fish_adb_list_files)" -d 'File on device'

View File

@@ -2,7 +2,7 @@
function __fish_apt_no_subcommand -d 'Test if apt has yet to be given the subcommand'
for i in (commandline -xpc)
if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove purge source build-dep check clean autoclean changelog
if contains -- $i update upgrade dselect-upgrade dist-upgrade install remove purge autoremove autopurge source build-dep check clean autoclean changelog
return 1
end
end
@@ -11,7 +11,7 @@ end
function __fish_apt_use_package -d 'Test if apt command should have packages as potential completion'
for i in (commandline -xpc)
if contains -- $i contains install remove purge build-dep changelog
if contains -- $i contains install remove purge autoremove autopurge build-dep changelog
return 0
end
end
@@ -34,7 +34,8 @@ complete -f -n __fish_apt_no_subcommand -c apt-get -a build-dep -d 'Install/remo
complete -f -n __fish_apt_no_subcommand -c apt-get -a check -d 'Update cache and check dependencies'
complete -f -n __fish_apt_no_subcommand -c apt-get -a clean -d 'Clean local caches and packages'
complete -f -n __fish_apt_no_subcommand -c apt-get -a autoclean -d 'Clean packages no longer be downloaded'
complete -f -n __fish_apt_no_subcommand -c apt-get -a autoremove -d 'Remove automatically installed packages'
complete -f -n __fish_apt_no_subcommand -c apt-get -a autoremove -d 'Remove packages no longer needed as dependencies'
complete -f -n __fish_apt_no_subcommand -c apt-get -a autopurge -d 'Remove packages no longer needed as dependencies and delete their config files'
complete -c apt-get -l no-install-recommends -d 'Do not install recommended packages'
complete -c apt-get -l no-install-suggests -d 'Do not install suggested packages'
complete -c apt-get -s d -l download-only -d 'Download Only'

View File

@@ -6,8 +6,8 @@ if [ "$(uname -s)" = Darwin -a "$(command -s apt)" = /usr/bin/apt ]
exit 1
end
set -l all_subcmds update upgrade full-upgrade search list install show remove edit-sources purge changelog autoremove depends rdepends
set -l pkg_subcmds install upgrade full-upgrade show search purge changelog policy depends rdepends autoremove
set -l all_subcmds update upgrade full-upgrade search list install show remove edit-sources purge changelog autoremove autopurge depends rdepends
set -l pkg_subcmds install upgrade full-upgrade show search purge changelog policy depends rdepends autoremove autopurge
set -l installed_pkg_subcmds remove
set -l handle_file_pkg_subcmds install
@@ -114,7 +114,7 @@ __fish_apt_subcommand changelog -r -d 'Download and display package changelog'
# Autoremove
__fish_apt_subcommand autoremove -d 'Remove packages no longer needed as dependencies'
# Autoremove
# Autopurge
__fish_apt_subcommand autopurge -d 'Remove packages no longer needed as dependencies and delete their config files'
# Clean

View File

@@ -11,7 +11,7 @@ end
function __fish_apt_use_package -d 'Test if aptitude command should have packages as potential completion'
for i in (commandline -xpc)
if contains -- $i changelog full-upgrade download forbid-version hold install keep-all markauto purge reinstall remove show unhold unmarkauto
if contains -- $i changelog full-upgrade download forbid-version hold install keep-all markauto purge reinstall remove show showrc unhold unmarkauto why why-not versions
return 0
end
end
@@ -38,15 +38,19 @@ complete -f -n __fish_apt_no_subcommand -c aptitude -a markauto -d 'Mark package
complete -f -n __fish_apt_no_subcommand -c aptitude -a purge -d 'Remove and delete all associated configuration and data files'
complete -f -n __fish_apt_no_subcommand -c aptitude -a reinstall -d 'Reinstall the packages'
complete -f -n __fish_apt_no_subcommand -c aptitude -a remove -d 'Remove the packages'
complete -f -n __fish_apt_no_subcommand -c aptitude -a showsrc -d 'Display detailed information about the source packages (apt wrapper)'
complete -f -n __fish_apt_no_subcommand -c aptitude -a show -d 'Display detailed information about the packages'
complete -f -n __fish_apt_no_subcommand -c aptitude -a unhold -d 'Consider the packages by future upgrade commands'
complete -f -n __fish_apt_no_subcommand -c aptitude -a unmarkauto -d 'Mark packages as manually installed'
complete -f -n __fish_apt_no_subcommand -c aptitude -a search -d 'Search for packages matching one of the patterns'
complete -f -n __fish_apt_no_subcommand -c aptitude -a help -d 'Display brief summary of the available commands and options'
complete -f -n __fish_apt_no_subcommand -c aptitude -a why -d 'Explain why a particular package should be installed'
complete -f -n __fish_apt_no_subcommand -c aptitude -a why-not -d 'Explain why a particular package cannot be installed'
complete -f -n __fish_apt_no_subcommand -c aptitude -a versions -d 'Displays the versions of specified packages'
complete -c aptitude -s D -l show-deps -d 'Show explanations of automatic installations and removals'
complete -c aptitude -s d -l download-only -d 'Download Only'
complete -c aptitude -s f -l fix-broken -d 'Correct broken dependencies'
complete -c aptitude -s d -l download-only -d 'Download only'
complete -c aptitude -s f -l fix-broken -d 'Aggressively try to fix broken packages'
complete -c aptitude -l purge-unused -d 'Purge packages that are not required by any installed package'
complete -c aptitude -s P -l prompt -d 'Always display a prompt'
complete -c aptitude -s R -l without-recommends -d 'Do not treat recommendations as dependencies'
@@ -60,6 +64,7 @@ complete -c aptitude -l version -d 'Display the version of aptitude and compile
complete -c aptitude -l visual-preview -d 'Start up the visual interface and display its preview screen'
complete -c aptitude -s y -l assume-yes -d 'Assume the answer yes for all question prompts'
complete -c aptitude -s Z -d 'Show how much disk space will be used or freed'
complete -c aptitude -s u -d 'Download new package lists on startup (terminal interface only)'
complete -r -c aptitude -s F -l display-format -d 'Specify the format to be used by the search command'
complete -r -c aptitude -s t -l target-release -d 'Set the release from which packages should be installed'
complete -r -c aptitude -s O -l sort -d 'Specify the order for the output from the search command'

View File

@@ -1,20 +1,25 @@
# Tab completion for cargo (https://github.com/rust-lang/cargo).
## --- WRITTEN MANUALLY ---
set -l __fish_cargo_subcommands (cargo --list 2>&1 | string replace -rf '^\s+([^\s]+)\s*(.*)' '$1\t$2' | string escape)
function __fish_cargo
cargo --color=never $argv
end
set -l __fish_cargo_subcommands (__fish_cargo --list 2>&1 | string replace -rf '^\s+([^\s]+)\s*(.*)' '$1\t$2' | string escape)
complete -c cargo -f -c cargo -n __fish_use_subcommand -a "$__fish_cargo_subcommands"
complete -c cargo -x -c cargo -n '__fish_seen_subcommand_from help' -a "$__fish_cargo_subcommands"
for x in bench b build c check rustc t test
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l bench -a "(cargo bench --bench 2>&1 | string replace -rf '^\s+' '')"
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l bench -a "(__fish_cargo bench --bench 2>&1 | string replace -rf '^\s+' '')"
complete -c cargo -n "__fish_seen_subcommand_from $x" -l lib -d 'Only this package\'s library'
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l test -a "(cargo test --test 2>&1 | string replace -rf '^\s+' '')"
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l test -a "(__fish_cargo test --test 2>&1 | string replace -rf '^\s+' '')"
end
for x in bench b build c check r run rustc t test
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l bin -a "(cargo run --bin 2>&1 | string replace -rf '^\s+' '')"
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l example -a "(cargo run --example 2>&1 | string replace -rf '^\s+' '')"
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l bin -a "(__fish_cargo run --bin 2>&1 | string replace -rf '^\s+' '')"
complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l example -a "(__fish_cargo run --example 2>&1 | string replace -rf '^\s+' '')"
end
# If using rustup, get the list of installed targets from there. Otherwise print all targets.
@@ -38,18 +43,18 @@ end
function __fish_cargo_features
if command -q jq
cargo read-manifest | jq -r '.features | keys | .[]' | __fish_concat_completions
__fish_cargo read-manifest | jq -r '.features | keys | .[]' | __fish_concat_completions
else if set -l python (__fish_anypython)
cargo read-manifest | command $python -Sc "import sys, json"\n"print(*json.load(sys.stdin)['features'].keys(), sep='\n')" | __fish_concat_completions
__fish_cargo read-manifest | command $python -Sc "import sys, json"\n"print(*json.load(sys.stdin)['features'].keys(), sep='\n')" | __fish_concat_completions
end
end
function __fish_cargo_packages
if command -q jq
cargo metadata --no-deps --format-version 1 | jq -r '.packages | .[] | .name' | __fish_concat_completions
__fish_cargo metadata --no-deps --format-version 1 | jq -r '.packages | .[] | .name' | __fish_concat_completions
else if set -l python (__fish_anypython)
cargo metadata --no-deps --format-version 1 |
command $python -Sc "import sys, json"\n"print(*[x['name'] for x in json.load(sys.stdin)['packages']], sep='\n')"
__fish_cargo metadata --no-deps --format-version 1 |
command $python -Sc "import sys, json"\n"print(*[x['name'] for x in json.load(sys.stdin)['packages']], sep='\n')"
end
end
complete -c cargo -n '__fish_seen_subcommand_from run test build debug check clippy' -s p -l package \
@@ -60,7 +65,7 @@ complete -c cargo -n '__fish_seen_subcommand_from run test build debug check cli
complete -c cargo -n __fish_use_subcommand -l explain -d 'Run `rustc --explain CODE`'
complete -c cargo -n __fish_use_subcommand -l color -d 'Coloring: auto, always, never'
complete -c cargo -n __fish_use_subcommand -l config -d 'Override a configuration value (unstable)'
complete -c cargo -n __fish_use_subcommand -s Z -d 'Unstable (nightly-only) flags to Cargo, see \'cargo -Z help\' for details' -xa '(cargo -Z help | string replace -rf \'^\s*-Z (\S+)\s+(.*)\' \'$1\t$2\')'
complete -c cargo -n __fish_use_subcommand -s Z -d 'Unstable (nightly-only) flags to Cargo, see \'cargo -Z help\' for details' -xa '(__fish_cargo -Z help | string replace -rf \'^\s*-Z (\S+)\s+(.*)\' \'$1\t$2\')'
complete -c cargo -n __fish_use_subcommand -s V -l version -d 'Print version info and exit'
complete -c cargo -n __fish_use_subcommand -l list -d 'List installed commands'
complete -c cargo -n __fish_use_subcommand -s v -l verbose -d 'Use verbose output (-vv very verbose/build.rs output)'
@@ -718,7 +723,7 @@ complete -c cargo -n "__fish_seen_subcommand_from tree" -s v -l verbose -d 'Use
complete -c cargo -n "__fish_seen_subcommand_from tree" -l frozen -d 'Require Cargo.lock and cache are up to date'
complete -c cargo -n "__fish_seen_subcommand_from tree" -l locked -d 'Require Cargo.lock is up to date'
complete -c cargo -n "__fish_seen_subcommand_from tree" -l offline -d 'Run without accessing the network'
complete -c cargo -n "__fish_seen_subcommand_from uninstall" -fa '(cargo install --list | string replace -rf "(\S+) (.*):" \'$1\t$2\')'
complete -c cargo -n "__fish_seen_subcommand_from uninstall" -fa '(__fish_cargo install --list | string replace -rf "(\S+) (.*):" \'$1\t$2\')'
complete -c cargo -n "__fish_seen_subcommand_from uninstall" -s p -l package -d 'Package to uninstall'
complete -c cargo -n "__fish_seen_subcommand_from uninstall" -l bin -d 'Only uninstall the binary NAME'
complete -c cargo -n "__fish_seen_subcommand_from uninstall" -l root -d 'Directory to uninstall packages from'
@@ -841,8 +846,8 @@ if command -q cargo-asm
# Warning: this will build the project and can take time! We make sure to only call it if it's not a switch so completions
# for --foo will always be fast.
if command -q timeout
complete -c cargo -n "__fish_seen_subcommand_from asm; and not __fish_is_switch" -xa "(timeout 1 cargo asm)"
complete -c cargo -n "__fish_seen_subcommand_from asm; and not __fish_is_switch" -xa "(timeout 1 __fish_cargo asm)"
else
complete -c cargo -n "__fish_seen_subcommand_from asm; and not __fish_is_switch" -xa "(cargo asm)"
complete -c cargo -n "__fish_seen_subcommand_from asm; and not __fish_is_switch" -xa "(__fish_cargo asm)"
end
end

View File

@@ -0,0 +1 @@
cilium completion fish 2>/dev/null | source

102
share/completions/cjpm.fish Normal file
View File

@@ -0,0 +1,102 @@
# cjpm.fish - Fish completion script for Cangjie Package Manager
# Global options
complete -c cjpm -l help -s h -d "Help for cjpm"
complete -c cjpm -l version -s v -d "Version for cjpm"
# Subcommands
complete -c cjpm -n __fish_use_subcommand -f -a init -d "Init a new cangjie module"
complete -c cjpm -n __fish_use_subcommand -f -a check -d "Check the dependencies"
complete -c cjpm -n __fish_use_subcommand -f -a update -d "Update cjpm.lock"
complete -c cjpm -n __fish_use_subcommand -f -a tree -d "Display the package dependencies in the source code"
complete -c cjpm -n __fish_use_subcommand -f -a build -d "Compile the current module"
complete -c cjpm -n __fish_use_subcommand -f -a run -d "Compile and run an executable product"
complete -c cjpm -n __fish_use_subcommand -f -a test -d "Unittest a local package or module"
complete -c cjpm -n __fish_use_subcommand -f -a bench -d "Run benchmarks in a local package or module"
complete -c cjpm -n __fish_use_subcommand -f -a clean -d "Clean up the target directory"
complete -c cjpm -n __fish_use_subcommand -f -a install -d "Install a cangjie binary"
complete -c cjpm -n __fish_use_subcommand -f -a uninstall -d "Uninstall a cangjie binary"
# 'init' subcommand options
complete -c cjpm -n "__fish_seen_subcommand_from init" -f -l help -s h -d "Help for init"
complete -c cjpm -n "__fish_seen_subcommand_from init" -f -l workspace -d "Initialize a workspace's default configuration file"
complete -c cjpm -n "__fish_seen_subcommand_from init" -f -l name -d "Specify root package name (default: current directory)" -r
complete -c cjpm -n "__fish_seen_subcommand_from init" -l path -d "Specify path to create the module (default: current directory)" -r
complete -c cjpm -n "__fish_seen_subcommand_from init" -f -l type -d "Define output type of current module" -r -f -a "executable static dynamic"
# 'run' subcommand options
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -l name -d "Name of the executable product to run (default: main)" -r
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -l build-args -d "Arguments to pass to the build process" -r
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -l skip-build -d "Skip compile, only run the executable product"
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -l run-args -d "Arguments to pass to the executable product" -r
complete -c cjpm -n "__fish_seen_subcommand_from run" -l target-dir -d "Specify target directory" -r
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -s g -d "Enable debug version"
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -s h -l help -d "Help for run"
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -s V -l verbose -d "Enable verbose"
complete -c cjpm -n "__fish_seen_subcommand_from run" -f -l skip-script -d "Disable script 'build.cj'"
# 'install' subcommand options
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -s h -l help -d "Help for install"
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -s V -l verbose -d "Enable verbose"
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -s m -l member -d "Specify a member module of the workspace" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -s g -d "Enable install debug version target"
complete -c cjpm -n "__fish_seen_subcommand_from install" -l path -d "Specify path of source module (default: current path)" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -l root -d "Specify path of installed binary" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l git -d "Specify URL of installed git module" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l branch -d "Specify branch of installed git module" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l tag -d "Specify tag of installed git module" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l commit -d "Specify commit ID of installed git module" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -s j -l jobs -d "Number of jobs to spawn in parallel" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l cfg -d "Enable the customized option 'cfg'"
complete -c cjpm -n "__fish_seen_subcommand_from install" -l target-dir -d "Specify target directory" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l name -d "Specify product name to install (default: all)" -r
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l skip-build -d "Install binary in target directory without building"
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l list -d "List all installed modules and their versions"
complete -c cjpm -n "__fish_seen_subcommand_from install" -f -l skip-script -d "Disable script 'build.cj'"
# 'build' subcommand options
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s h -l help -d "Help for build"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s i -l incremental -d "Enable incremental compilation"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s j -l jobs -d "Number of jobs to spawn in parallel" -r
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s V -l verbose -d "Enable verbose"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s g -d "Enable compile debug version target"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -l coverage -d "Enable coverage"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -l cfg -d "Enable the customized option 'cfg'"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s m -l member -d "Specify a member module of the workspace" -r
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -l target -d "Generate code for the given target platform" -r
complete -c cjpm -n "__fish_seen_subcommand_from build" -l target-dir -d "Specify target directory" -r
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s o -l output -d "Specify product name when compiling an executable file" -r
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -s l -l lint -d "Enable cjlint code check"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -l mock -d "Enable support of mocking classes in tests"
complete -c cjpm -n "__fish_seen_subcommand_from build" -f -l skip-script -d "Disable script 'build.cj'"
# 'test' subcommand options
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -s h -l help -d "Help for test"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -s j -l jobs -d "Number of jobs to spawn in parallel" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -s V -l verbose -d "Enable verbose"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -s g -d "Enable compile debug version tests"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -s i -l incremental -d "Enable incremental compilation"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l no-run -d "Compile, but don't run tests"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l skip-build -d "Skip compile, only run tests"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l coverage -d "Enable coverage"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l cfg -d "Enable the customized option 'cfg'"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l module -d "Specify modules to test (default: current module)" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -s m -l member -d "Specify a member module of the workspace" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l target -d "Unittest for the given target platform" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -l target-dir -d "Specify target directory" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l dry-run -d "Print tests without execution"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l filter -d "Enable filter test" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l include-tags -d "Run tests with specified tags" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l exclude-tags -d "Run tests without specified tags" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l no-color -d "Enable colorless result output"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l random-seed -d "Enable random seed" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l timeout-each -d "Specify default timeout for test cases" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l parallel -d "Number of workers running tests" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l show-all-output -d "Show output for all test cases"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l no-capture-output -d "Disable test output capturing"
complete -c cjpm -n "__fish_seen_subcommand_from test" -l report-path -d "Specify path to directory of report" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l report-format -d "Specify format of report" -r
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l skip-script -d "Disable script 'build.cj'"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l no-progress -d "Disable progress report"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l progress-brief -d "Display brief progress report"
complete -c cjpm -n "__fish_seen_subcommand_from test" -f -l progress-entries-limit -d "Limit number of entries shown in progress report"

View File

@@ -49,10 +49,10 @@ function __fish_clj_tools -V bb_helper
bb -e "$bb_helper" tools
end
complete -c clj -s X -x -r -k -a "(__fish_complete_list : __fish_clj_aliases)" -d "Use concatenated aliases to modify classpath or supply exec fn/args"
complete -c clj -s A -x -r -k -a "(__fish_complete_list : __fish_clj_aliases)" -d "Use concatenated aliases to modify classpath"
complete -c clj -s M -x -r -k -a "(__fish_complete_list : __fish_clj_aliases)" -d "Use concatenated aliases to modify classpath or supply main opts"
complete -c clj -s T -x -r -k -a "(__fish_complete_list : __fish_clj_tools)" -d "Invoke tool by name or via aliases ala -X"
complete -c clj -s X -x -r -k -a "(__fish_stripprefix='^-\w*X' __fish_complete_list : __fish_clj_aliases)" -d "Use concatenated aliases to modify classpath or supply exec fn/args"
complete -c clj -s A -x -r -k -a "(__fish_stripprefix='^-\w*A' __fish_complete_list : __fish_clj_aliases)" -d "Use concatenated aliases to modify classpath"
complete -c clj -s M -x -r -k -a "(__fish_stripprefix='^-\w*M' __fish_complete_list : __fish_clj_aliases)" -d "Use concatenated aliases to modify classpath or supply main opts"
complete -c clj -s T -x -r -k -a "(__fish_stripprefix='^-\w*T' __fish_complete_list : __fish_clj_tools)" -d "Invoke tool by name or via aliases ala -X"
complete -c clj -f -o Sdeps -r -d "Deps data to use as the last deps file to be merged"
complete -c clj -f -o Spath -d "Compute classpath and echo to stdout only"

View File

@@ -13,7 +13,6 @@ complete -c commandline -s b -l current-buffer -d "Select entire command line (d
complete -c commandline -s c -l cut-at-cursor -d "Only return that part of the command line before the cursor"
complete -c commandline -s f -l function -d "Inject readline functions to reader"
complete -c commandline -s x -l tokens-expanded -d "Print a list of expanded tokens"
complete -c commandline -l tokens-raw -d "Print a list of raw tokens"
complete -c commandline -s I -l input -d "Specify command to operate on"
complete -c commandline -s C -l cursor -d "Set/get cursor position, not buffer contents"

View File

@@ -0,0 +1,45 @@
# fish completion for Perl's cpan
function __fish_cpan_list_installed_modules
# Following IRC's #fish suggestion to use </dev/null as cpan might go interactive
cpan -l </dev/null | while read -l line
# Filter out unrelated messages or notifications
if string match -qr -- '^\w.*\t\w.*$' $line
string replace -r -- '\t.*' '' $line |
string escape --style=script
end
end
end
complete -c cpan -s a -d "Creates a CPAN.pm autobundle with CPAN::Shell->autobundle"
complete -c cpan -s A -d "Show primary maintainer for specified module" -xa "(__fish_cpan_list_installed_modules)"
complete -c cpan -s c -d "Runs a `make clean` in the specified modules directories"
complete -c cpan -s C -d "Show the Changes files for specified module" -a "(__fish_cpan_list_installed_modules)"
complete -c cpan -s D -d "Show module details" -a "(__fish_cpan_list_installed_modules)"
complete -c cpan -s f -d "Force the specified action"
complete -c cpan -s F -d "Turn off CPAN.pm's attempts to lock anything"
complete -c cpan -s g -d "Download latest distribution of module to current directory" -a "(__fish_cpan_list_installed_modules)"
# complete -c cpan -s G -d "UNIMPLEMENTED"
complete -c cpan -s h -d "Print a help message and exit"
complete -c cpan -s i -d "Install specified module"
complete -c cpan -s I -d "Load 'local::lib' (think like '-I' for loading lib paths)"
complete -c cpan -s j -d "Load file with CPAN configuration data"
complete -c cpan -s J -d "Dump the configuration in the same format that CPAN.pm uses"
complete -c cpan -s l -d "list all installed modules with their versions"
complete -c cpan -s L -d "List the modules by the specified authors"
complete -c cpan -s m -d "Make the specified modules"
complete -c cpan -s M -d "Comma-separated list of mirrors to use for this run" -x
#complete -c cpan -s n -d "Do a dry run, but dont actually install anything. (unimplemented)"
complete -c cpan -s O -d "Show the out-of-date modules"
complete -c cpan -s p -d "Ping the configured mirrors and print a report"
complete -c cpan -s P -d "Find and the best mirrors available"
complete -c cpan -s r -d "Recompiles dynamically loaded modules with CPAN::Shell->recompile"
complete -c cpan -s s -d "Drop in the CPAN.pm shell"
complete -c cpan -s t -d "Run a `make test` on the specified modules"
complete -c cpan -s T -d "Do not test modules. Simply install them"
complete -c cpan -s u -d "Upgrade all installed modules"
complete -c cpan -s v -d "Print the script version and CPAN.pm version then exit"
complete -c cpan -s V -d "Print detailed information about the cpan client"
# complete -c cpan -s w -d "UNIMPLEMENTED"
complete -c cpan -s x -d "Find close matches to named module. Requires Text::Levenshtein or others"
complete -c cpan -s X -d "Dump all the namespaces to standard output"

View File

@@ -85,7 +85,7 @@ complete -c equery -n '__fish_seen_subcommand_from f files' -s s -l timestamp -d
complete -c equery -n '__fish_seen_subcommand_from f files' -s t -l type -d "Include file type in output"
complete -c equery -n '__fish_seen_subcommand_from f files' -l tree -d "Display results in a tree"
complete -c equery -n '__fish_seen_subcommand_from f files' -s f -l filter -d "Filter output by file type" \
-xa "(__fish_complete_list , __fish_equery_files_filter_args)"
-xa "(__fish_stripprefix='^(--filter=|-\w*f)' __fish_complete_list , __fish_equery_files_filter_args)"
# has + hasuse
complete -c equery -n '__fish_seen_subcommand_from a has h hasuse' -s I -l exclude-installed -d "Exclude installed pkgs from search path"

View File

@@ -1,5 +1,6 @@
complete -c fish_indent -s h -l help -d 'Display help and exit'
complete -c fish_indent -s v -l version -d 'Display version and exit'
complete -c fish_indent -s c -l check -d 'Do not indent, only return 0 if the code is already indented as fish_indent would'
complete -c fish_indent -s i -l no-indent -d 'Do not indent output, only reformat into one job per line'
complete -c fish_indent -l only-indent -d 'Do not reformat, only indent lines'
complete -c fish_indent -l only-unindent -d 'Do not reformat, only unindent lines'

View File

@@ -58,29 +58,12 @@ function __fish_flatpak
flatpak $argv | string replace -rf '^([^A-Z].*?)(?: +|\t)(.*?)\s*$' '$1\t$2'
end
function __fish_print_flatpak_packages
set -l xdg_cache_home (__fish_make_cache_dir)
or return
set -l cache_file $xdg_cache_home/flatpak
if test -f $cache_file
cat $cache_file
set -l age (path mtime -R -- $cache_file)
set -l max_age 250
if test $age -lt $max_age
return
end
end
__fish_cache_put $cache_file
__fish_flatpak remote-ls --columns=application,name >$cache_file &
return 0
end
complete -f -c flatpak -n "__fish_seen_subcommand_from run" -a "(__fish_flatpak list --app --columns=application,name)"
complete -f -c flatpak -n "__fish_seen_subcommand_from info uninstall" -a "(__fish_flatpak list --columns=application,name)"
complete -f -c flatpak -n "__fish_seen_subcommand_from enter kill" -a "(__fish_flatpak ps --columns=instance,application)"
complete -f -c flatpak -n "__fish_seen_subcommand_from remote-info remote-ls remote-modify remote-delete" -a "(__fish_flatpak remotes --columns=name,title)"
complete -c flatpak -n '__fish_seen_subcommand_from install' -xa "(__fish_print_flatpak_packages)"
complete -c flatpak -n '__fish_seen_subcommand_from install' -xa "(__fish_cached -t 250 -- '__fish_flatpak remote-ls --columns=application,name')"
# Plenty of the other stuff is too free-form to complete (e.g. remote-add).
complete -f -c flatpak -s h -l help

View File

@@ -52,8 +52,8 @@ end
function __fish_git_branches
# This is much faster than using `git branch` and avoids dealing with localized "detached HEAD" messages.
# We intentionally only sort local branches by recency. See discussion in #9248.
__fish_git for-each-ref --format='%(refname:strip=2)%09Local Branch' --sort=-committerdate refs/heads/ 2>/dev/null
__fish_git for-each-ref --format='%(refname:strip=2)%09Remote Branch' refs/remotes/ 2>/dev/null
__fish_git_local_branches
__fish_git_remote_branches
end
function __fish_git_submodules
@@ -65,6 +65,10 @@ function __fish_git_local_branches
__fish_git for-each-ref --format='%(refname:strip=2)%09Local Branch' --sort=-committerdate refs/heads/ 2>/dev/null
end
function __fish_git_remote_branches
__fish_git for-each-ref --format='%(refname:strip=2)%09Remote Branch' refs/remotes/ 2>/dev/null
end
function __fish_git_unique_remote_branches
# `git checkout` accepts remote branches without the remote part
# if they are unambiguous.
@@ -72,7 +76,7 @@ function __fish_git_unique_remote_branches
# `git checkout frobulate` is equivalent to `git checkout -b frobulate --track alice/frobulate`.
__fish_git for-each-ref --format="%(refname:strip=3)" \
--sort="refname:strip=3" \
"refs/remotes/*/$match*" "refs/remotes/*/*/**" 2>/dev/null | uniq -u
refs/remotes/ 2>/dev/null | uniq -u
end
function __fish_git_tags
@@ -82,13 +86,20 @@ end
function __fish_git_heads
set -l gitdir (__fish_git rev-parse --git-dir 2>/dev/null)
or return # No git dir, no need to even test.
for head in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD
for head in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD REVERT_HEAD \
CHERRY_PICK_HEAD BISECT_HEAD AUTO_MERGE
if test -f $gitdir/$head
echo $head
end
end
end
function __fish_git_remote_heads
# Example of output parsed:
# "remote.upstream.url git@github.com:fish-shell/fish-shell.git" -> "upstream\tgit@github.com:fish-shell/fish-shell.git"
__fish_git for-each-ref --format="%(refname:strip=2)" 'refs/remotes/*/HEAD' | path dirname
end
function __fish_git_refs
__fish_git_branches
__fish_git_tags
@@ -96,7 +107,27 @@ function __fish_git_refs
end
function __fish_git_remotes
__fish_git remote 2>/dev/null
# Example of output parsed:
# "remote.upstream.url git@github.com:fish-shell/fish-shell.git" -> "upstream\tgit@github.com:fish-shell/fish-shell.git"
__fish_git config --get-regexp 'remote\.[a-z]+\.url' | string replace -rf 'remote\.(.*)\.url (.*)' '$1\t$2'
end
set -g __fish_git_recent_commits_arg
set -g __fish_git_unqualified_unique_remote_branches false
set -g __fish_git_filter_non_pushable ''
function __fish_git_add_revision_completion
set -l c complete -f -c git $argv -n 'not contains -- -- (commandline -xpc)' -ka
# The following dynamic, order-preserved (-k) completions will be shown in reverse order (see #9221)
$c "(__fish_git_recent_commits $__fish_git_recent_commits_arg $__fish_git_filter_non_pushable)"
$c "(__fish_git_tags)" -d Tag
$c "(__fish_git_remote_heads $__fish_git_filter_non_pushable)" -d 'Remote alias'
$c "(__fish_git_heads $__fish_git_filter_non_pushable)" -d Head
$c "(__fish_git_remote_branches $__fish_git_filter_non_pushable)"
if $__fish_git_unqualified_unique_remote_branches
$c "(__fish_git_unique_remote_branches $__fish_git_filter_non_pushable)" -d 'Unique Remote Branch'
end
$c "(__fish_git_local_branches)" -d 'Local Branch'
end
function __fish_git_files
@@ -647,6 +678,7 @@ function __fish_git_aliased_command
end
end
set -g __fish_git_aliases
git config -z --get-regexp 'alias\..*' | while read -lz alias cmdline
set -l command (__fish_git_aliased_command $cmdline)
string match -q --regex '\w+' -- $command; or continue
@@ -772,7 +804,8 @@ function __fish_git_custom_commands
# if any of these completion results match the name of the builtin git commands,
# but it's simpler just to blacklist these names. They're unlikely to change,
# and the failure mode is we accidentally complete a plumbing command.
for name in (string replace -r "^.*/git-([^/]*)" '$1' $PATH/git-*)
set -l git_subcommands $PATH/git-*
for name in (string replace -r "^.*/git-([^/]*)" '$1' $git_subcommands)
switch $name
case cvsserver receive-pack shell upload-archive upload-pack
# skip these
@@ -784,7 +817,7 @@ end
# Suggest branches for the specified remote - returns 1 if no known remote is specified
function __fish_git_branch_for_remote
set -l remotes (__fish_git_remotes)
set -l remotes (__fish_git remote 2>/dev/null)
set -l remote
set -l cmd (commandline -xpc)
for r in $remotes
@@ -1034,7 +1067,7 @@ complete -f -c git -n '__fish_git_using_command fetch' -l shallow-since -d 'Deep
complete -f -c git -n '__fish_git_using_command fetch' -l shallow-exclude -d 'Deepen history of shallow clone, excluding rev'
complete -f -c git -n '__fish_git_using_command fetch' -l unshallow -d 'Convert to a complete repository'
complete -f -c git -n '__fish_git_using_command fetch' -l refetch -d 'Re-fetch without negotiating common commits'
complete -f -c git -n '__fish_git_using_command fetch' -l negotiation-tip -d 'Only report commits reachable from these tips' -kxa '(__fish_git_commits; __fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command fetch' -l negotiation-tip -d 'Only report commits reachable from these tips' -x
complete -f -c git -n '__fish_git_using_command fetch' -l negotiate-only -d "Don't fetch, only show commits in common with the server"
complete -f -c git -n '__fish_git_using_command fetch' -l filter -ra '(__fish_git_filters)' -d 'Request a subset of objects from server'
@@ -1087,10 +1120,8 @@ complete -f -c git -n "__fish_git_using_command remote" -n "__fish_seen_subcomma
### show
complete -f -c git -n __fish_git_needs_command -a show -d 'Show the last commit of a branch'
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_tags)' -d Tag
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_commits)'
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_complete_stashes)'
__fish_git_add_revision_completion -n '__fish_git_using_command show'
complete -f -c git -n __fish_git_needs_rev_files -n 'not contains -- -- (commandline -xpc)' -xa '(__fish_git_complete_rev_files)'
complete -F -c git -n '__fish_git_using_command show' -n 'contains -- -- (commandline -xpc)'
complete -f -c git -n '__fish_git_using_command show' -l format -d 'Pretty-print the contents of the commit logs in a given format' -a '(__fish_git_show_opt format)'
@@ -1179,13 +1210,12 @@ complete -c git -n '__fish_git_using_command am' -l show-current-patch -a 'diff
### checkout
complete -F -c git -n '__fish_git_using_command checkout' -n 'contains -- -- (commandline -xpc)'
complete -f -c git -n __fish_git_needs_command -a checkout -d 'Checkout and switch to a branch'
begin
set -lx __fish_git_recent_commits_arg --all
set -lx __fish_git_unqualified_unique_remote_branches true
__fish_git_add_revision_completion -n '__fish_git_using_command checkout'
end
# The following dynamic, order-preserved (-k) completions will be shown in reverse order (see #9221)
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_recent_commits --all)'
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_tags)' -d Tag
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_heads)' -d Head
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_unique_remote_branches)' -d 'Unique Remote Branch'
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_branches)'
# In the presence of changed files, `git checkout ...` assumes highest likelihood is intent to restore so this comes last (aka shown first).
complete -f -c git -n '__fish_git_using_command checkout' -ka '(__fish_git_files modified deleted modified-staged-deleted)'
@@ -1354,6 +1384,35 @@ complete -f -c git -n '__fish_git_using_command clone' -s b -l branch -d 'Use a
complete -f -c git -n '__fish_git_using_command clone' -l depth -d 'Truncate the history to a specified number of revisions'
complete -f -c git -n '__fish_git_using_command clone' -l recursive -d 'Initialize all submodules within the cloned repository'
complete -f -c git -n '__fish_git_using_command clone' -l filter -ra '(__fish_git_filters)' -d 'Partial clone by requesting a subset of objects from server'
complete -f -c git -n '__fish_git_using_command clone' -l single-branch -d 'Clone only the history leading to the tip of a single branch'
complete -f -c git -n '__fish_git_using_command clone' -l no-single-branch -d 'Clone histories near the tips of all branches'
complete -f -c git -n '__fish_git_using_command clone' -s l -l local -d 'Bypass transport mechanism for local repositories'
complete -f -c git -n '__fish_git_using_command clone' -l no-local -d 'Use Git transport for local paths'
complete -f -c git -n '__fish_git_using_command clone' -s s -l shared -d 'Setup .git/objects/info/alternates to share objects'
complete -f -c git -n '__fish_git_using_command clone' -l dissociate -d 'Stop borrowing objects from reference repositories after clone'
complete -f -c git -n '__fish_git_using_command clone' -l progress -d 'Force progress status'
complete -f -c git -n '__fish_git_using_command clone' -l server-option -d 'Transmit string to the server when using protocol version 2'
complete -f -c git -n '__fish_git_using_command clone' -l no-reject-shallow -d 'Do not fail if the source repository is a shallow repository'
complete -f -c git -n '__fish_git_using_command clone' -l reject-shallow -d 'Fail if the source repository is a shallow repository'
complete -f -c git -n '__fish_git_using_command clone' -l sparse -d 'Employ a sparse-checkout'
complete -f -c git -n '__fish_git_using_command clone' -l also-filter-submodules -d 'Apply partial clone filter to submodules'
complete -f -c git -n '__fish_git_using_command clone' -l revision -r -d 'Fetch history leading to the given revision'
complete -f -c git -n '__fish_git_using_command clone' -s u -l upload-pack -r -d 'Specify a non-default path for the command on the other end'
complete -f -c git -n '__fish_git_using_command clone' -l template -r -d 'Specify the directory from which templates will be used'
complete -f -c git -n '__fish_git_using_command clone' -s c -l config -r -d 'Set a configuration variable in the new repository'
complete -f -c git -n '__fish_git_using_command clone' -l shallow-since -r -d 'Create a shallow clone with a history after the specified time'
complete -f -c git -n '__fish_git_using_command clone' -l shallow-exclude -r -d 'Create a shallow clone excluding commits from a specified ref'
complete -f -c git -n '__fish_git_using_command clone' -l no-tags -d 'Do not clone tags'
complete -f -c git -n '__fish_git_using_command clone' -l tags -d 'Clone tags'
complete -f -c git -n '__fish_git_using_command clone' -l recurse-submodules -r -d 'Initialize and clone submodules'
complete -f -c git -n '__fish_git_using_command clone' -l shallow-submodules -d 'Clone submodules with a depth of 1'
complete -f -c git -n '__fish_git_using_command clone' -l no-shallow-submodules -d 'Do not clone submodules shallowly'
complete -f -c git -n '__fish_git_using_command clone' -l remote-submodules -d 'Use submodule remote-tracking branch to update'
complete -f -c git -n '__fish_git_using_command clone' -l no-remote-submodules -d 'Do not use submodule remote-tracking branch to update'
complete -f -c git -n '__fish_git_using_command clone' -l separate-git-dir -r -d 'Place the cloned repository in a specified directory'
complete -f -c git -n '__fish_git_using_command clone' -l ref-format -f -a "files reftable" -d 'Specify the ref storage format'
complete -f -c git -n '__fish_git_using_command clone' -s j -l jobs -r -d 'Number of submodules fetched at the same time'
complete -f -c git -n '__fish_git_using_command clone' -l bundle-uri -r -d 'Fetch a bundle from the given URI'
### commit
complete -c git -n __fish_git_needs_command -a commit -d 'Record changes to the repository'
@@ -1422,9 +1481,7 @@ complete -x -c git -n '__fish_git_using_command daemon' -l access-hook -d 'Hook
### describe
complete -c git -n __fish_git_needs_command -a describe -d 'Give an object a human readable name'
complete -f -c git -n '__fish_git_using_command describe' -ka '(__fish_git_tags)' -d Tag
complete -f -c git -n '__fish_git_using_command describe' -ka '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command describe' -ka '(__fish_git_heads)' -d Head
__fish_git_add_revision_completion -n '__fish_git_using_command describe'
complete -f -c git -n '__fish_git_using_command describe' -l dirty -d 'Describe the state of the working tree, append dirty if there are local changes'
complete -f -c git -n '__fish_git_using_command describe' -l broken -d 'Describe the state of the working tree, append -broken instead of erroring'
complete -f -c git -n '__fish_git_using_command describe' -l all -d 'Use all tags, not just annotated'
@@ -1444,7 +1501,10 @@ complete -f -c git -n '__fish_git_using_command describe' -l first-parent -d 'Fo
complete -c git -n __fish_git_needs_command -a diff -d 'Show changes between commits and working tree'
complete -c git -n '__fish_git_using_command diff' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_ranges)'
complete -c git -n '__fish_git_using_command diff' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_complete_stashes)'
complete -c git -n '__fish_git_using_command diff' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_recent_commits --all)'
begin
set -lx __fish_git_recent_commits_arg --all
__fish_git_add_revision_completion -n '__fish_git_using_command diff'
end
complete -c git -n '__fish_git_using_command diff' -l cached -d 'Show diff of changes in the index'
complete -c git -n '__fish_git_using_command diff' -l staged -d 'Show diff of changes in the index'
complete -c git -n '__fish_git_using_command diff' -l no-index -d 'Compare two paths on the filesystem'
@@ -1775,7 +1835,7 @@ complete -f -c git -n '__fish_git_using_command maintenance' -l schedule -d 'Run
### merge
complete -f -c git -n __fish_git_needs_command -a merge -d 'Join multiple development histories'
complete -f -c git -n '__fish_git_using_command merge' -ka '(__fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command merge'
complete -f -c git -n '__fish_git_using_command merge' -l commit -d "Autocommit the merge"
complete -f -c git -n '__fish_git_using_command merge' -l no-commit -d "Don't autocommit the merge"
complete -f -c git -n '__fish_git_using_command merge' -s e -l edit -d 'Edit auto-generated merge message'
@@ -1811,7 +1871,7 @@ complete -f -c git -n '__fish_git_using_command merge' -l no-autostash -d 'Do no
### merge-base
complete -f -c git -n __fish_git_needs_command -a merge-base -d 'Find a common ancestor for a merge'
complete -f -c git -n '__fish_git_using_command merge-base' -ka '(__fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command merge-base'
complete -f -c git -n '__fish_git_using_command merge-base' -s a -l all -d 'Output all merge bases for the commits, instead of just one'
complete -f -c git -n '__fish_git_using_command merge-base' -l octopus -d 'Compute the best common ancestors of all supplied commits'
complete -f -c git -n '__fish_git_using_command merge-base' -l independent -d 'Print a minimal subset of the supplied commits with the same ancestors'
@@ -1929,9 +1989,10 @@ complete -f -c git -n '__fish_git_using_command range-diff' -l no-dual-color -d
### push
complete -f -c git -n __fish_git_needs_command -a push -d 'Push changes elsewhere'
complete -f -c git -n '__fish_git_using_command push' -n 'not __fish_git_branch_for_remote' -a '(__fish_git_remotes)' -d 'Remote alias'
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -ka '(__fish_git_tags)' -d Tag
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -ka '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -ka '(__fish_git_heads)'
begin
set -lx __fish_git_filter_non_pushable '| string replace -r "(\t.*)?\$" ":\$1"'
__fish_git_add_revision_completion -n '__fish_git_using_command push' -n __fish_git_branch_for_remote
end
# The "refspec" here is an optional "+" to signify a force-push
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -n 'string match -q "+*" -- (commandline -ct)' -ka '+(__fish_git_branches | string replace -r \t".*" "")' -d 'Force-push branch'
# git push REMOTE :BRANCH deletes BRANCH on remote REMOTE
@@ -1958,16 +2019,13 @@ complete -f -c git -n '__fish_git_using_command push' -l progress -d 'Force prog
### rebase
complete -f -c git -n __fish_git_needs_command -a rebase -d 'Reapply commit sequence on a new base'
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_remotes)' -d 'Remote alias'
complete -f -c git -n '__fish_git_using_command rebase' -ka '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_heads)' -d Head
complete -f -c git -n '__fish_git_using_command rebase' -ka '(__fish_git_tags)' -d Tag -k
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_recent_commits)' -k
__fish_git_add_revision_completion -n '__fish_git_using_command rebase'
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l continue -d 'Restart the rebasing process'
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l abort -d 'Abort the rebase operation'
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l edit-todo -d 'Edit the todo list'
complete -f -c git -n '__fish_git_using_command rebase' -l keep-empty -d "Keep the commits that don't change anything"
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l skip -d 'Restart the rebasing process by skipping the current patch'
complete -f -c git -n '__fish_git_using_command rebase' -l keep-empty -d "Keep the commits that don't change anything"
complete -f -c git -n '__fish_git_using_command rebase' -l keep-base -d 'Keep the base commit as-is'
complete -f -c git -n '__fish_git_using_command rebase' -s m -l merge -d 'Use merging strategies to rebase'
complete -f -c git -n '__fish_git_using_command rebase' -s q -l quiet -d 'Be quiet'
complete -f -c git -n '__fish_git_using_command rebase' -s v -l verbose -d 'Be verbose'
@@ -1987,7 +2045,7 @@ complete -f -c git -n '__fish_git_using_command rebase' -l no-autosquash -d 'No
complete -f -c git -n '__fish_git_using_command rebase' -l autostash -d 'Before starting rebase, stash local changes, and apply stash when done'
complete -f -c git -n '__fish_git_using_command rebase' -l no-autostash -d 'Do not stash local changes before starting rebase'
complete -f -c git -n '__fish_git_using_command rebase' -l no-ff -d 'No fast-forward'
complete -f -c git -n '__fish_git_using_command rebase' -l onto -d 'Rebase current branch onto given upstream or newbase' -ka '(__fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command rebase' -l onto -d 'Rebase current branch onto given upstream or newbase' -r
complete -f -c git -n '__fish_git_using_command rebase' -l update-refs -d 'Update any branches that point to commits being rebased'
complete -f -c git -n '__fish_git_using_command rebase' -l no-update-refs -d 'Don\'t update any branches that point to commits being rebased'
# This actually takes script for $SHELL, but completing that is... complicated.
@@ -2006,7 +2064,7 @@ complete -c git -n __fish_git_needs_command -a reset -d 'Reset current HEAD to t
complete -f -c git -n '__fish_git_using_command reset' -l hard -d 'Reset the index and the working tree'
complete -f -c git -n '__fish_git_using_command reset' -l soft -d 'Reset head without touching the index or the working tree'
complete -f -c git -n '__fish_git_using_command reset' -l mixed -d 'The default: reset the index but not the working tree'
complete -c git -n '__fish_git_using_command reset' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command reset'
# reset can either undo changes to versioned modified files,
# or remove files from the staging area.
# Deleted files seem to need a "--" separator.
@@ -2038,7 +2096,10 @@ complete -f -c git -n '__fish_git_using_command switch' -ka '(__fish_git_unique_
complete -f -c git -n '__fish_git_using_command switch' -ka '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command switch' -s c -l create -d 'Create a new branch'
complete -f -c git -n '__fish_git_using_command switch' -s C -l force-create -d 'Force create a new branch'
complete -f -c git -n '__fish_git_using_command switch' -s d -l detach -rka '(__fish_git_recent_commits --all)'
begin
set -lx __fish_git_recent_commits_arg --all
__fish_git_add_revision_completion -n '__fish_git_using_command switch' -s d -l detach -r
end
complete -f -c git -n '__fish_git_using_command switch' -s d -l detach -d 'Switch to a commit for inspection and discardable experiment' -rka '(__fish_git_refs)'
complete -f -c git -n '__fish_git_using_command switch' -l guess -d 'Guess branch name from remote branch (default)'
complete -f -c git -n '__fish_git_using_command switch' -l no-guess -d 'Do not guess branch name from remote branch'
@@ -2063,9 +2124,7 @@ complete -f -c git -n __fish_git_needs_command -a rev-list -d 'List commits in c
### rev-parse
complete -f -c git -n __fish_git_needs_command -a rev-parse -d 'Parse revision names or give repo information'
complete -f -c git -n '__fish_git_using_command rev-parse' -ka '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command rev-parse' -a '(__fish_git_heads)' -d Head
complete -c git -n '__fish_git_using_command rev-parse' -ka '(__fish_git_tags)' -d Tag
__fish_git_add_revision_completion -n '__fish_git_using_command rev-parse'
complete -c git -n '__fish_git_using_command rev-parse' -l abbrev-ref -d 'Output non-ambiguous short object names'
### revert
@@ -2115,7 +2174,7 @@ complete -f -c git -n '__fish_git_using_command stripspace' -s c -l comment-line
### tag
complete -f -c git -n __fish_git_needs_command -a tag -d 'Create, list, delete or verify a tag object signed with GPG'
complete -f -c git -n '__fish_git_using_command tag' -n '__fish_not_contain_opt -s d' -n '__fish_not_contain_opt -s v' -n 'test (count (commandline -xpc | string match -r -v \'^-\')) -eq 3' -ka '(__fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command tag' -n '__fish_not_contain_opt -s d' -n '__fish_not_contain_opt -s v' -n 'test (count (commandline -xpc | string match -r -v \'^-\')) -eq 3'
complete -f -c git -n '__fish_git_using_command tag' -s a -l annotate -d 'Make an unsigned, annotated tag object'
complete -f -c git -n '__fish_git_using_command tag' -s s -l sign -d 'Make a GPG-signed tag'
complete -f -c git -n '__fish_git_using_command tag' -s d -l delete -d 'Remove a tag'
@@ -2176,11 +2235,10 @@ complete -f -c git -n "__fish_git_using_command worktree" -n "not __fish_seen_su
complete -f -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add move remove' -s f -l force -d 'Override safeguards'
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add'
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_branches)'
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_heads)' -d Head
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_tags)' -d Tag
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_unique_remote_branches)' -d 'Unique Remote Branch'
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_local_branches)'
begin
set -lx __fish_git_unqualified_unique_remote_branches true
__fish_git_add_revision_completion -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add'
end
complete -x -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -s b -d 'Create a new branch'
complete -x -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -s B -d 'Create a new branch even if it already exists'
complete -f -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -l detach -d 'Detach HEAD in the new working tree'
@@ -2216,11 +2274,7 @@ complete -f -c git -n '__fish_git_using_command stash' -n __fish_git_stash_not_u
complete -f -c git -n '__fish_git_using_command stash' -n __fish_git_stash_not_using_subcommand -a branch -d 'Create a new branch from a stash'
complete -f -c git -n '__fish_git_using_command stash' -n __fish_git_stash_not_using_subcommand -a push -d 'Create a new stash with given files'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command apply' -ka '(__fish_git_complete_stashes)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command branch' -ka '(__fish_git_complete_stashes)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command drop' -ka '(__fish_git_complete_stashes)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command pop' -ka '(__fish_git_complete_stashes)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command show' -ka '(__fish_git_complete_stashes)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command apply branch drop pop show' -ka '(__fish_git_complete_stashes)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command push' -a '(__fish_git_files modified deleted modified-staged-deleted)'
complete -f -c git -n '__fish_git_using_command stash' -n '__fish_git_stash_using_command push' -s a -l all -d 'Stash ignored and untracked files'
@@ -2237,7 +2291,7 @@ complete -f -c git -n __fish_git_needs_command -a config -d 'Set and read git co
### format-patch
complete -f -c git -n __fish_git_needs_command -a format-patch -d 'Generate patch series to send upstream'
complete -f -c git -n '__fish_git_using_command format-patch' -ka '(__fish_git_branches)'
__fish_git_add_revision_completion -n '__fish_git_using_command format-patch'
complete -c git -n '__fish_git_using_command format-patch' -s o -l output-directory -xa '(__fish_complete_directories)'
complete -f -c git -n '__fish_git_using_command format-patch' -s p -l no-stat -d "Generate plain patches without diffstat"
complete -f -c git -n '__fish_git_using_command format-patch' -s s -l no-patch -d "Suppress diff output"
@@ -2589,7 +2643,8 @@ end
# source git-* commands' autocompletion file if exists
set -l __fish_git_custom_commands_completion
for file in (path filter -xZ $PATH/git-* | path basename)
set -l git_subcommands $PATH/git-*
for file in (path filter -xZ $git_subcommands | path basename)
# Already seen this command earlier in $PATH.
contains -- $file $__fish_git_custom_commands_completion
and continue
@@ -2599,3 +2654,8 @@ for file in (path filter -xZ $PATH/git-* | path basename)
complete -c git -f -n "__fish_git_using_command $cmd" -a "(__fish_git_complete_custom_command $cmd)"
set -a __fish_git_custom_commands_completion $file
end
functions --erase __fish_git_add_revision_completion
set -eg __fish_git_recent_commits_arg
set -eg __fish_git_unqualified_unique_remote_branches
set -eg __fish_git_filter_non_pushable

View File

@@ -4,5 +4,5 @@ complete -c gpasswd -s d -l delete -d 'Remove user from group' -xa '(__fish_comp
complete -c gpasswd -s h -l help -d 'Print help'
complete -c gpasswd -s r -l remove-password -d 'Remove the GROUP\'s password'
complete -c gpasswd -s R -l restrict -d 'Restrict access to GROUP to its members'
complete -c gpasswd -s M -l members -d 'Set the list of members of GROUP' -xa '(__fish_complete_list , __fish_complete_users)'
complete -c gpasswd -s A -l administrators -d 'set the list of administrators for GROUP' -xa '(__fish_complete_list , __fish_complete_users)'
complete -c gpasswd -s M -l members -d 'Set the list of members of GROUP' -xa "(__fish_stripprefix='^(--members=|-\w*M)' __fish_complete_list , __fish_complete_users)"
complete -c gpasswd -s A -l administrators -d 'set the list of administrators for GROUP' -xa "(__fish_stripprefix='^(--administrators=|-\w*A)' __fish_complete_list , __fish_complete_users)"

View File

@@ -36,7 +36,7 @@ complete -c $command -s x -x \
-n $compile_condition
complete -c $command -s W -l warning \
-a '(__fish_complete_list , __fish_guild__complete_warnings)' \
-a "(__fish_stripprefix='^(--warning=|-\w*W)' __fish_complete_list , __fish_guild__complete_warnings)" \
-d 'Specify the warning level for a compilation' \
-n $compile_condition

View File

@@ -85,7 +85,7 @@ complete -c $command -o ds \
-d 'Treat the last -s option as if it occurred at this point'
complete -c $command -l use-srfi \
-a '(__fish_complete_list , __fish_guile__complete_srfis)' \
-a "(__fish_stripprefix='^--use-srfi=' __fish_complete_list , __fish_guile__complete_srfis)" \
-d 'Specify the SRFI modules to load'
for standard in 6 7

View File

@@ -1,5 +1,5 @@
complete -c gzip -s c -l stdout -d "Compress to stdout"
complete -c gzip -s d -l decompress -k -x -a "(__fish_complete_suffix .gz .tgz)"
complete -c gzip -s d -l decompress -d Decompress -k -x -a "(__fish_complete_suffix .gz .tgz)"
complete -c gzip -s f -l force -d Overwrite
complete -c gzip -s h -l help -d "Display help and exit"

View File

@@ -58,7 +58,7 @@ complete -c hashcat -l restore -d "Restore session from --session"
complete -c hashcat -l restore-disable -d "Do not write restore file"
complete -c hashcat -l restore-file-path -rF -d "Specific path to restore file"
complete -c hashcat -s o -l outfile -rF -d "Define outfile for recovered hash"
complete -c hashcat -l outfile-format -xa "(__fish_complete_list , __fish_hashcat_outfile_formats)" -d "Outfile formats to use"
complete -c hashcat -l outfile-format -xa "(__fish_stripprefix='^--outfile-format=' __fish_complete_list , __fish_hashcat_outfile_formats)" -d "Outfile formats to use"
complete -c hashcat -l outfile-autohex-disable -d "Disable the use of \$HEX[] in output plains"
complete -c hashcat -l outfile-check-timer -x -d "Sets seconds between outfile checks"
complete -c hashcat -l wordlist-autohex-disable -d "Disable the conversion of \$HEX[] from the wordlist"
@@ -106,7 +106,7 @@ complete -c hashcat -l backend-ignore-metal -d "Do not try to open Metal interfa
complete -c hashcat -l backend-ignore-opencl -d "Do not try to open OpenCL interface on startup"
complete -c hashcat -s I -l backend-info -d "Show info about detected backend API devices"
complete -c hashcat -s d -l backend-devices -x -d "Backend devices to use"
complete -c hashcat -s D -l opencl-device-types -xa "(__fish_complete_list , __fish_hashcat_device_types)" -d "OpenCL device-types to use"
complete -c hashcat -s D -l opencl-device-types -xa "(__fish_stripprefix='^(--opencl-device-types=|-\w*D)' __fish_complete_list , __fish_hashcat_device_types)" -d "OpenCL device-types to use"
complete -c hashcat -s O -l optimized-kernel-enable -d "Enable optimized kernels (limits password length)"
complete -c hashcat -s M -l multiply-accel-disable -d "Disable multiply kernel-accel with processor count"
complete -c hashcat -s w -l workload-profile -d "Enable a specific workload profile" -xa "

View File

@@ -0,0 +1 @@
hubble completion fish 2>/dev/null | source

View File

@@ -260,10 +260,12 @@ function __fish_complete_ip
case address
# We're still _on_ the second word, which is the subcommand
if not set -q cmd[3]
printf '%s\t%s\n' add "Add new protocol address" \
printf '%s\t%s\n' \
add "Add new protocol address" \
delete "Delete protocol address" \
show "Look at protocol addresses" \
flush "Flush protocol addresses"
flush "Flush protocol addresses" \
help "Display help"
else
switch $cmd[2]
# Change and replace are undocumented (apart from mentions in the BNF)
@@ -339,7 +341,8 @@ function __fish_complete_ip
end
case link
if not set -q cmd[3]
printf '%s\t%s\n' add "Add virtual link" \
printf '%s\t%s\n' \
add "Add virtual link" \
delete "Delete virtual link" \
set "Change device attributes" \
show "Display device attributes" \
@@ -430,18 +433,20 @@ function __fish_complete_ip
end
case show
case help
__fish_ip_types
end
end
case neighbour
if not set -q cmd[3]
printf '%s\t%s\n' help "Show help" \
printf '%s\t%s\n' \
add "Add new neighbour entry" \
delete "Delete neighbour entry" \
change "Change neighbour entry" \
replace "Add or change neighbour entry" \
show "List neighbour entries" \
flush "Flush neighbour entries" \
get "Lookup neighbour entry"
get "Lookup neighbour entry" \
help "Display help"
else
switch $cmd[2]
case add del delete change replace
@@ -505,7 +510,8 @@ function __fish_complete_ip
get "Get a single route" \
save "Save routing table to stdout" \
showdump "Show saved routing table from stdin" \
restore "Restore routing table from stdin"
restore "Restore routing table from stdin" \
help "Display help"
else
# TODO: switch on $cmd[2] and complete subcommand specific arguments
# for now just complete most useful arguments for the last token
@@ -524,7 +530,8 @@ function __fish_complete_ip
flush "Flush rules" \
show "List rules" \
save "Save rules to stdout" \
restore "Restore rules from stdin"
restore "Restore rules from stdin" \
help "Display help"
else
# TODO: switch on $cmd[2] and complete subcommand specific arguments
# for now just complete most useful arguments for the last token
@@ -579,6 +586,27 @@ function __fish_complete_ip
end
end
end
case tuntap
if not set -q cmd[3]
printf '%s\t%s\n' \
add "Add a new tun or tap device" \
del "Delete a tun or tap device" \
show "Show tun and tap devices" \
help "Display help"
else
switch $cmd[-2]
case dev
__fish_ip_device
case mode
printf '%s\n' tun tap
case user
__fish_complete_users
case group
__fish_complete_groups
case '*'
printf '%s\n' dev mode user group one_queue pi vnet_hdr multi_queue name
end
end
end
end

View File

@@ -9,7 +9,7 @@ function __fish_john_formats --description "Print JohnTheRipper hash formats"
end
complete -c john -l help -d "print usage summary"
complete -c john -l single -fa "(__fish_complete_list , __fish_john_rules)" -d "single crack mode"
complete -c john -l single -fa "(__fish_stripprefix='^--single=' __fish_complete_list , __fish_john_rules)" -d "single crack mode"
complete -c john -l single-seed -rf -d "add static seed word(s) for all salts in single mode"
complete -c john -l single-wordlist -rF -d "short wordlist with static seed words/morphemes"
complete -c john -l single-user-seed -rF -d "wordlist with seeds per username"
@@ -35,8 +35,8 @@ complete -c john -l prince-case-permute -d "permute case of first letter"
complete -c john -l prince-mmap -d "memory-map infile"
complete -c john -l prince-keyspace -d "just show total keyspace that would be produced"
complete -c john -l encoding -l input-encoding -fa "$__fish_john_encodings" -d "input encoding"
complete -c john -l rules -fa "(__fish_complete_list , __fish_john_rules)" -d "enable word mangling rules"
complete -c john -l rules-stack -fa "(__fish_complete_list , __fish_john_rules)" -d "stacked rules"
complete -c john -l rules -fa "(__fish_stripprefix='^--rules=' __fish_complete_list , __fish_john_rules)" -d "enable word mangling rules"
complete -c john -l rules-stack -fa "(__fish_stripprefix='^--rules-stack=' __fish_complete_list , __fish_john_rules)" -d "stacked rules"
complete -c john -l rules-skip-nop -d "skip any NOP rules"
complete -c john -l incremental -fa "(john --list=inc-modes 2>/dev/null)" -d "incremental mode"
complete -c john -l incremental-charcount -rf -d "override CharCount for incremental mode"
@@ -97,4 +97,4 @@ complete -c john -l internal-codepage -fa "$__fish_john_encodings" -d "codepage
complete -c john -l target-encoding -fa "$__fish_john_encodings" -d "output encoding"
complete -c john -l tune -fa "auto report N" -d "tuning options"
complete -c john -l force-tty -d "set up terminal for reading keystrokes"
complete -c john -l format -fa "(__fish_complete_list , __fish_john_formats)" -d "force hash type"
complete -c john -l format -fa "(__fish_stripprefix='^--format=' __fish_complete_list , __fish_john_formats)" -d "force hash type"

View File

@@ -30,6 +30,7 @@ complete -c journalctl -f -l version -d 'Prints a short version string and exits
complete -c journalctl -f -l no-pager -d 'Do not pipe output into a pager'
complete -c journalctl -f -s a -l all -d 'Show all fields in full'
complete -c journalctl -f -s f -l follow -d 'Show live tail of entries'
complete -c journalctl -f -s e -l pager-end -d 'Skip to the end of the journal'
complete -c journalctl -f -s n -l lines -d 'Controls the number of journal lines'
complete -c journalctl -f -l no-tail -d 'Show all lines, even in follow mode'
complete -c journalctl -f -s o -l output -d 'Controls the formatting' -xa '(printf %s\t\n (command journalctl --output=help))'

View File

@@ -0,0 +1 @@
k9s completion fish 2>/dev/null | source

View File

@@ -1,4 +1,4 @@
#Keybase 5.6.1
# Keybase 6.4.0
function __fish_keybase_line_ends_with
set -l line (commandline -pxc | string match -v -r '^-')
@@ -9,123 +9,132 @@ function __fish_keybase_line_ends_with
end
end
#variables
# variables
set -l ends __fish_keybase_line_ends_with
set -l seen __fish_seen_subcommand_from
#L1
set -l keybase account blocks bot chat config ctl currency decrypt deprovision device encrypt follow fs git h help id kvstore list-followers list-following log login logout oneshot paperkey passphrase pgp ping prove rekey selfprovision service sign signup sigs status team track unfollow untrack update verify version wallet whoami
#L2
set -l keybase_account contact-settings delete email h help lockdown recover-username upload-avatar
set -l keybase_blocks h help list-users list-teams
# 1
set -l keybase account apicall audit base62 blocks bot btc ca chat config ctl currency db decrypt deprovision device dir dismiss dismiss-category dump-keyfamily dump-push-notifications encrypt fnmr follow fs git h help home id interesting-people kvstore list-followers list-following log login logout network-stats oneshot paperkey passphrase pgp ping pprof prove push rekey riit script selfprovision service sign signup sigs status team track unfollow unlock untrack upak update upload-avatar verify version wallet web-auth-token whoami wot
# 2
set -l keybase_account contact-settings delete email h help lockdown phonenumber recover-username reset-cancel upload-avatar
set -l keybase_audit box h help
set -l keybase_base62 decode encode h help
set -l keybase_blocks h help list-teams list-users
set -l keybase_bot h help signup token
set -l keybase_chat add-bot-member add-to-channel api api-listen bot-member-settings clear-commands conv-info create-channel default-channels delete-channel delete-history download edit-bot-member featured-bots h help hide join-channel leave-channel list list-channels list-members list-unread ls lsur min-writer-role mute notification-settings read readd-member remove-bot-member rename-channel report retention-policy search search-bots search-regexp send upload
set -l keybase_chat add-bot-member add-to-channel api api-listen archive archive-delete archive-list archive-pause archive-resume bot-member-settings clear-commands conv-info create-channel default-channels delete-channel delete-history download edit-bot-member emoji-add emoji-addalias emoji-list emoji-remove featured-bots forward-message h help hide join-channel leave-channel list list-channels list-members list-unread ls lsur mark-as-read min-writer-role mute notification-settings read readd-member remove-bot-member remove-from-channel rename-channel report retention-policy search search-bots search-regexp send upload
set -l keybase_config get h help info set
set -l keybase_ctl app-exit autostart h help init log-rotate redirector reload restart start stop wait watchdog watchdog2
set -l keybase_ctl app-exit autostart h help init log-rotate redirector reload restart start stop wait wants-systemd watchdog watchdog2
set -l keybase_currency add h help
set -l keybase_db clean delete get h help keys-with-prefix nuke put
set -l keybase_device add h help list remove
set -l keybase_fs clear-conflicts cp debug finish-resolving-conflicts get-status h help history kill ln ls mkdir mv ps quota read recover reset rm set-debug-level stat sync uploads write
set -l keybase_git create delete gc h help lfs-config list settings
set -l keybase_fs archive cancel-uploads clear-conflicts cp debug finish-resolving-conflicts get-status h help history index-progress kill ln ls mkdir mv ps quota read recover reset reset-index rm search set-debug-level stat sync uploads write
set -l keybase_git archive create delete gc h help lfs-config list settings
set -l keybase_help advanced gpg keyring tor
set -l keybase_kvstore api h help
set -l keybase_log h help send
set -l keybase_log h help profile send
set -l keybase_passphrase change check h help recover remember set
set -l keybase_pgp decrypt drop encrypt export gen h help import list pull pull-private purge push-private select sign update verify
set -l keybase_pprof cpu h heap help trace
set -l keybase_rekey h help paper status
set -l keybase_sigs h help list revoke
set -l keybase_team accept-invite add-member add-members-bulk api bot-settings create delete edit-member h help ignore-request leave list-members list-memberships list-requests remove-member rename request-access search settings show-tree
set -l keybase_team accept-invite add-member add-members-bulk api bot-settings create delete edit-member ftl generate-invite-token generate-invitelink h help ignore-request leave list-members list-memberships list-requests profile-load remove-member rename request-access search settings show-tree
set -l keybase_update check check-in-use notify
set -l keybase_wallet accounts add-trustline api asset-search balances cancel cancel-request change-trustline-limit delete-trustline detail details export get-inflation get-started h help history import list lookup merge popular-assets reclaim rename request send send-path-payment set-currency set-inflation set-primary sign
#L3
set -l keybase_wallet accounts balances detail details export h help list
set -l keybase_wot accept h help list reject vouch
# 3
set -l keybase_account_email add delete edit h help list send-verification-email set-primary set-visibility
set -l keybase_account_phonenumber add delete edit h help list set-visibility verify
set -l keybase_bot_token create delete h help list
set -l keybase_fs_archive cancel check check dismiss h help start status
set -l keybase_fs_debug deobfuscate dump h help obfuscate
set -l keybase_fs_sync disable enable h help show
#...
#global options
complete -c keybase -f -n "$ends keybase" -l api-dump-unsafe
complete -c keybase -f -n "$ends keybase" -l api-timeout
complete -c keybase -f -n "$ends keybase" -l api-uri-path-prefix
complete -c keybase -f -n "$ends keybase" -l app-start-mode
complete -c keybase -f -n "$ends keybase" -l auto-fork
complete -c keybase -f -n "$ends keybase" -l bg-identifier-disabled
complete -c keybase -f -n "$ends keybase" -l chat-db
complete -c keybase -f -n "$ends keybase" -l code-signing-kids
complete -c keybase -f -n "$ends keybase" -l config-file -s c
complete -c keybase -f -n "$ends keybase" -l db
complete -c keybase -f -n "$ends keybase" -l debug -s d
complete -c keybase -f -n "$ends keybase" -l debug-journeycard
complete -c keybase -f -n "$ends keybase" -l disable-bg-conv-loader
complete -c keybase -f -n "$ends keybase" -l disable-cert-pinning
complete -c keybase -f -n "$ends keybase" -l disable-merkle-auditor
complete -c keybase -f -n "$ends keybase" -l disable-search-indexer
complete -c keybase -f -n "$ends keybase" -l disable-team-auditor
complete -c keybase -f -n "$ends keybase" -l disable-team-box-auditor
complete -c keybase -f -n "$ends keybase" -l display-raw-untrusted-output
complete -c keybase -f -n "$ends keybase" -l ek-log-file
complete -c keybase -f -n "$ends keybase" -l enable-bot-lite-mode
complete -c keybase -f -n "$ends keybase" -l extra-net-logging
complete -c keybase -f -n "$ends keybase" -l features
complete -c keybase -f -n "$ends keybase" -l force-linux-keyring
complete -c keybase -f -n "$ends keybase" -l generate-bash-completion
complete -c keybase -f -n "$ends keybase" -l gpg
complete -c keybase -f -n "$ends keybase" -l gpg-options
complete -c keybase -f -n "$ends keybase" -l gpgdir
complete -c keybase -f -n "$ends keybase" -l gui-config-file
complete -c keybase -f -n "$ends keybase" -l help -s h
complete -c keybase -f -n "$ends keybase" -l home -s H
complete -c keybase -f -n "$ends keybase" -l leveldb-num-files
complete -c keybase -f -n "$ends keybase" -l local-rpc-debug-unsafe
complete -c keybase -f -n "$ends keybase" -l log-file
complete -c keybase -f -n "$ends keybase" -l log-format
complete -c keybase -f -n "$ends keybase" -l log-prefix
complete -c keybase -f -n "$ends keybase" -l merkle-kids
complete -c keybase -f -n "$ends keybase" -l no-auto-fork -s F
complete -c keybase -f -n "$ends keybase" -l no-debug
complete -c keybase -f -n "$ends keybase" -l paramproof-kit
complete -c keybase -f -n "$ends keybase" -l pgpdir
complete -c keybase -f -n "$ends keybase" -l pid-file
complete -c keybase -f -n "$ends keybase" -l pinentry
complete -c keybase -f -n "$ends keybase" -l proof-cache-size
complete -c keybase -f -n "$ends keybase" -l prove-bypass
complete -c keybase -f -n "$ends keybase" -l proxy
complete -c keybase -f -n "$ends keybase" -l proxy-type
complete -c keybase -f -n "$ends keybase" -l push-disabled
complete -c keybase -f -n "$ends keybase" -l push-save-interval
complete -c keybase -f -n "$ends keybase" -l push-server-uri
complete -c keybase -f -n "$ends keybase" -l pvl-kit
complete -c keybase -f -n "$ends keybase" -l read-deleted-sigchain
complete -c keybase -f -n "$ends keybase" -l remember-passphrase
complete -c keybase -f -n "$ends keybase" -l run-mode
complete -c keybase -f -n "$ends keybase" -l scraper-timeout
complete -c keybase -f -n "$ends keybase" -l secret-keyring
complete -c keybase -f -n "$ends keybase" -l server -s s
complete -c keybase -f -n "$ends keybase" -l session-file
complete -c keybase -f -n "$ends keybase" -l slow-gregor-conn
complete -c keybase -f -n "$ends keybase" -l socket-file
complete -c keybase -f -n "$ends keybase" -l standalone
complete -c keybase -f -n "$ends keybase" -l timers
complete -c keybase -f -n "$ends keybase" -l tor-hidden-address
complete -c keybase -f -n "$ends keybase" -l tor-mode
complete -c keybase -f -n "$ends keybase" -l tor-proxy
complete -c keybase -f -n "$ends keybase" -l updater-config-file
complete -c keybase -f -n "$ends keybase" -l use-default-log-file
complete -c keybase -f -n "$ends keybase" -l use-root-config-file
complete -c keybase -f -n "$ends keybase" -l user-cache-size
complete -c keybase -f -n "$ends keybase" -l vdebug
complete -c keybase -f -n "$ends keybase" -l version -s v
# global options
complete -c keybase -f -n "$ends keybase" -l api-dump-unsafe -d "Dump API call internals (may leak secrets)"
complete -c keybase -f -n "$ends keybase" -l api-timeout -d "Set the HTTP timeout for API calls to the keybase API server"
complete -c keybase -f -n "$ends keybase" -l api-uri-path-prefix -d "Specify an alternate API URI path prefix"
complete -c keybase -f -n "$ends keybase" -l app-start-mode -d "Specify 'service' to auto-start UI app, or anything else to disable"
complete -c keybase -f -n "$ends keybase" -l auto-fork -d "Enable auto-fork of background service"
complete -c keybase -f -n "$ends keybase" -l bg-identifier-disabled -d "Supply to disable the BG identifier loop"
complete -c keybase -f -n "$ends keybase" -l chat-db -d "Specify an alternate local Chat DB location"
complete -c keybase -f -n "$ends keybase" -l code-signing-kids -d "Set of code signing key IDs (colon-separated)"
complete -c keybase -f -n "$ends keybase" -l config-file -s c -d "Specify an (alternate) master config file"
complete -c keybase -f -n "$ends keybase" -l db -d "Specify an alternate local DB location"
complete -c keybase -f -n "$ends keybase" -l debug -s d -d "Enable debugging mode"
complete -c keybase -f -n "$ends keybase" -l debug-journeycard -d "Enable experimental journey cards"
complete -c keybase -f -n "$ends keybase" -l disable-bg-conv-loader -d "Disable background conversation loading"
complete -c keybase -f -n "$ends keybase" -l disable-cert-pinning -d "WARNING: Do not use unless necessary!"
complete -c keybase -f -n "$ends keybase" -l disable-merkle-auditor -d "Disable background probabilistic merkle audit"
complete -c keybase -f -n "$ends keybase" -l disable-search-indexer -d "Disable chat search background indexer"
complete -c keybase -f -n "$ends keybase" -l disable-team-auditor -d "Disable auditing of teams"
complete -c keybase -f -n "$ends keybase" -l disable-team-box-auditor -d "Disable box auditing of teams"
complete -c keybase -f -n "$ends keybase" -l display-raw-untrusted-output -d "Display output from users without escaping terminal codes"
complete -c keybase -f -n "$ends keybase" -l ek-log-file -d "Specify a log file for the keybase ephemeral key log"
complete -c keybase -f -n "$ends keybase" -l enable-bot-lite-mode -d "Enable bot lite mode. Disables non-critical background services"
complete -c keybase -f -n "$ends keybase" -l extra-net-logging -d "Do additional debug logging during network requests"
complete -c keybase -f -n "$ends keybase" -l features -d "Specify experimental feature flags"
complete -c keybase -f -n "$ends keybase" -l force-linux-keyring -d "Require the use of the OS keyring"
complete -c keybase -f -n "$ends keybase" -l generate-bash-completion -d ""
complete -c keybase -f -n "$ends keybase" -l gpg -d "Path to GPG client (optional for exporting keys)"
complete -c keybase -f -n "$ends keybase" -l gpg-options -d "Options to use when calling GPG"
complete -c keybase -f -n "$ends keybase" -l gpgdir -d "Specify a PGP directory (default is ~/.gnupg)"
complete -c keybase -f -n "$ends keybase" -l gui-config-file -d "Specify a path to the GUI config file"
complete -c keybase -f -n "$ends keybase" -l help -s h -d "Show help"
complete -c keybase -f -n "$ends keybase" -l home -s H -d "Specify an (alternate) home directory"
complete -c keybase -f -n "$ends keybase" -l leveldb-num-files -d "Specify the max number of files LevelDB may open"
complete -c keybase -f -n "$ends keybase" -l local-rpc-debug-unsafe -d "Use to debug local RPC (may leak secrets)"
complete -c keybase -f -n "$ends keybase" -l log-file -d "Specify a log file for the keybase service"
complete -c keybase -f -n "$ends keybase" -l log-format -d "Log format (default, plain, file, fancy)"
complete -c keybase -f -n "$ends keybase" -l log-prefix -d "Specify a prefix for a unique log file name"
complete -c keybase -f -n "$ends keybase" -l merkle-kids -d "Set of admissible Merkle Tree fingerprints (colon-separated)"
complete -c keybase -f -n "$ends keybase" -l no-auto-fork -s F -d "Disable auto-fork of background service"
complete -c keybase -f -n "$ends keybase" -l no-debug -d "Suppress debugging mode; takes precedence over --debug"
complete -c keybase -f -n "$ends keybase" -l paramproof-kit -d "Specify an alternate local parameterized proof kit file location"
complete -c keybase -f -n "$ends keybase" -l pgpdir -d "Specify a PGP directory (default is ~/.gnupg)"
complete -c keybase -f -n "$ends keybase" -l pid-file -d "Location of the keybased pid-file (to ensure only one running daemon)"
complete -c keybase -f -n "$ends keybase" -l pinentry -d "Specify a path to find a pinentry program"
complete -c keybase -f -n "$ends keybase" -l proof-cache-size -d "Number of proof entries to cache"
complete -c keybase -f -n "$ends keybase" -l prove-bypass -d "Prove even disabled proof services"
complete -c keybase -f -n "$ends keybase" -l proxy -d "Specify a proxy to ship all Web requests over"
complete -c keybase -f -n "$ends keybase" -l proxy-type -d "Set the proxy type; One of: socks,http_connect"
complete -c keybase -f -n "$ends keybase" -l push-disabled -d "Disable push server connection (which is on by default)"
complete -c keybase -f -n "$ends keybase" -l push-save-interval -d "Set the interval between saves of the push cache (in seconds)"
complete -c keybase -f -n "$ends keybase" -l push-server-uri -d "Specify a URI for contacting the Keybase push server"
complete -c keybase -f -n "$ends keybase" -l pvl-kit -d "Specify an alternate local PVL kit file location"
complete -c keybase -f -n "$ends keybase" -l read-deleted-sigchain -d "Allow admins to read deleted sigchains for debugging"
complete -c keybase -f -n "$ends keybase" -l remember-passphrase -d "Remember keybase passphrase"
complete -c keybase -f -n "$ends keybase" -l run-mode -d "Run mode (devel, staging, prod)"
complete -c keybase -f -n "$ends keybase" -l scraper-timeout -d "Set the HTTP timeout for external proof scrapers"
complete -c keybase -f -n "$ends keybase" -l secret-keyring -d "Location of the Keybase secret-keyring (P3SKB-encoded)"
complete -c keybase -f -n "$ends keybase" -l server -s s -d "Specify server API"
complete -c keybase -f -n "$ends keybase" -l session-file -d "Specify an alternate session data file"
complete -c keybase -f -n "$ends keybase" -l slow-gregor-conn -d "Slow responses from gregor for testing"
complete -c keybase -f -n "$ends keybase" -l socket-file -d "Location of the keybased socket-file"
complete -c keybase -f -n "$ends keybase" -l standalone -d "Use the client without any daemon support"
complete -c keybase -f -n "$ends keybase" -l timers -d "Specify 'a' for API; 'r' for RPCs; and 'x' for eXternal API calls"
complete -c keybase -f -n "$ends keybase" -l tor-hidden-address -d "Set TOR address of keybase server"
complete -c keybase -f -n "$ends keybase" -l tor-mode -d "Set TOR mode to be 'leaky', 'none', or 'strict'"
complete -c keybase -f -n "$ends keybase" -l tor-proxy -d "Set TOR proxy; when Tor mode is on; defaults to localhost:9050"
complete -c keybase -f -n "$ends keybase" -l updater-config-file -d "Specify a path to the updater config file"
complete -c keybase -f -n "$ends keybase" -l use-default-log-file -d "Log to the default log file in $XDG_CACHE_HOME, or ~/.cache if unset"
complete -c keybase -f -n "$ends keybase" -l use-root-config-file -d "Use the default root config on Linux only"
complete -c keybase -f -n "$ends keybase" -l user-cache-size -d "Number of User entries to cache"
complete -c keybase -f -n "$ends keybase" -l vdebug -d "Verbose debugging; takes a comma-joined list of levels and tags"
complete -c keybase -f -n "$ends keybase" -l version -s v -d "Print the version"
#commands
#L1
# commands
# 1
complete -c keybase -f -n "not $ends keybase"
complete -c keybase -f -n "$ends keybase" -a "$keybase"
#L2
# 2
complete -c keybase -f -n "$ends keybase account" -a "$keybase_account"
complete -c keybase -f -n "$ends keybase audit" -a "$keybase_audit"
complete -c keybase -f -n "$ends keybase base62" -a "$keybase_base62"
complete -c keybase -f -n "$ends keybase blocks" -a "$keybase_blocks"
complete -c keybase -f -n "$ends keybase bot" -a "$keybase_bot"
complete -c keybase -f -n "$ends keybase chat" -a "$keybase_chat"
complete -c keybase -f -n "$ends keybase config" -a "$keybase_config"
complete -c keybase -f -n "$ends keybase ctl" -a "$keybase_ctl"
complete -c keybase -f -n "$ends keybase currency" -a "$keybase_currency"
complete -c keybase -f -n "$ends keybase db" -a "$keybase_db"
complete -c keybase -f -n "$ends keybase device" -a "$keybase_device"
complete -c keybase -f -n "$ends keybase fs" -a "$keybase_fs"
complete -c keybase -f -n "$ends keybase git" -a "$keybase_git"
@@ -135,19 +144,22 @@ complete -c keybase -f -n "$ends keybase kvstore" -a "$keybase_kvstore"
complete -c keybase -f -n "$ends keybase log" -a "$keybase_log"
complete -c keybase -f -n "$ends keybase passphrase" -a "$keybase_passphrase"
complete -c keybase -f -n "$ends keybase pgp" -a "$keybase_pgp"
complete -c keybase -f -n "$ends keybase pprof" -a "$keybase_pprof"
complete -c keybase -f -n "$ends keybase rekey" -a "$keybase_rekey"
complete -c keybase -f -n "$ends keybase sigs" -a "$keybase_sigs"
complete -c keybase -f -n "$ends keybase team" -a "$keybase_team"
complete -c keybase -f -n "$ends keybase update" -a "$keybase_update"
complete -c keybase -f -n "$ends keybase wallet" -a "$keybase_wallet"
#...
#L3
complete -c keybase -f -n "$ends keybase wot" -a "$keybase_wot"
# 3
complete -c keybase -f -n "$ends keybase account email" -a "$keybase_account_email"
complete -c keybase -f -n "$ends keybase account phonenumber" -a "$keybase_account_phonenumber"
complete -c keybase -f -n "$ends keybase bot token" -a "$keybase_bot_token"
complete -c keybase -f -n "$ends keybase fs archive" -a "$keybase_fs_archive"
complete -c keybase -f -n "$ends keybase fs debug" -a "$keybase_fs_debug"
complete -c keybase -f -n "$ends keybase fs sync" -a "$keybase_fs_sync"
#...
#command options
# command options
complete -c keybase -f -n "$ends keybase account upload-avatar" -l skip-chat-message -s s
complete -c keybase -f -n "$ends keybase account upload-avatar" -l team
#...
# ...

View File

@@ -1,24 +1,19 @@
# Light is a program to control backlight controllers under GNU/Linux.
# See: https://github.com/haikarainen/light
function __fish_print_light_controllers
command light -L
end
complete -c light -s h -d 'Print help and exit'
complete -c light -s h -s -H -d 'Print help and exit'
complete -c light -s V -d 'Print version info and exit'
complete -c light -s G -d 'Get value (default)'
complete -c light -s S -x -d 'Set value'
complete -c light -s L -d 'List controllers'
complete -c light -s A -x -d 'Add value'
complete -c light -s U -x -d 'Subtract value'
complete -c light -s L -d 'List controllers'
complete -c light -s I -d 'Restore brightness'
complete -c light -s T -d 'Save brightness'
complete -c light -s S -x -d 'Set value'
complete -c light -s G -d 'Get value (default)'
complete -c light -s N -d 'Set minimum brightness'
complete -c light -s P -d 'Get minimum brightness'
complete -c light -s O -d 'Save brightness'
complete -c light -s b -d 'Brightness (default)'
complete -c light -s m -d 'Maximum brightness'
complete -c light -s c -d 'Minimum cap'
complete -c light -s a -d 'Selects controller automatically (default)'
complete -c light -s s -a '(__fish_print_light_controllers)' -x -d 'Specify controller to use'
complete -c light -s p -d 'Interpret & output values in percent'
complete -c light -s I -d 'Restore brightness after saving'
complete -c light -s r -d 'Interpret & output values in raw mode'
complete -c light -s s -a '(command light -L)' -x -d 'Specify controller to use'
complete -c light -s v -x -d 'Sets the verbosity level' -a '0\tRead\ values 1\tRead\ values\ \&\ errors 2\tRead\ values,\ errors\ \&\ warnings 3\tRead\ values,\ errors,\ warnings\ \&\ notices'

View File

@@ -41,7 +41,7 @@ complete -c losetup -s v -l verbose -d "Verbose mode"
complete -c losetup -s J -l json -d "Use JSON --list output format"
complete -c losetup -s l -l list -d "List info about all or specified"
complete -c losetup -s n -l noheadings -d "Don't print headings for --list output"
complete -c losetup -s O -l output -x -a "(__fish_complete_list , __fish_print_losetup_list_output)" -d "Specify columns to output for --list"
complete -c losetup -s O -l output -x -a "(__fish_stripprefix='^(--output=|-\w*O)' __fish_complete_list , __fish_print_losetup_list_output)" -d "Specify columns to output for --list"
complete -c losetup -l output-all -d "Output all columns"
complete -c losetup -l raw -d "Use raw --list output format"
complete -c losetup -s h -l help -d "Display help"

View File

@@ -25,7 +25,7 @@ complete -c lpadmin -s o -xa printer-is-shared=true -d 'Sets dest to shared/publ
complete -c lpadmin -s o -xa printer-is-shared=false -d 'Sets dest to shared/published or unshared/unpublished'
complete -c lpadmin -s o -d 'Set IPP operation policy associated with dest' -xa "printer-policy=(test -r /etc/cups/cupsd.conf; and string replace -r --filter '<Policy (.*)>' '$1' < /etc/cups/cupsd.conf)"
complete -c lpadmin -s u -xa 'allow:all allow:none (__fish_complete_list , __fish_complete_users allow:)' -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa '(__fish_complete_list , __fish_complete_groups allow: @)' -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa 'deny:all deny:none (__fish_complete_list , __fish_complete_users deny:)' -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa '(__fish_complete_list , __fish_complete_groups deny: @)' -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa "allow:all allow:none (__fish_stripprefix='^-\w*u' __fish_complete_list , __fish_complete_users allow:)" -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa "(__fish_stripprefix='^-\w*u' __fish_complete_list , __fish_complete_groups allow: @)" -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa "deny:all deny:none (__fish_stripprefix='^-\w*u' __fish_complete_list , __fish_complete_users deny:)" -d 'Sets user-level access control on a destination'
complete -c lpadmin -s u -xa "(__fish_stripprefix='^-\w*u' __fish_complete_list , __fish_complete_groups deny: @)" -d 'Sets user-level access control on a destination'

View File

@@ -12,7 +12,7 @@ complete -c lsblk -s h -l help -d "usage information (this)"
complete -c lsblk -s i -l ascii -d "use ascii characters only"
complete -c lsblk -s m -l perms -d "output info about permissions"
complete -c lsblk -s n -l noheadings -d "don't print headings"
complete -c lsblk -s o -l output -d "output columns" -xa '( __fish_complete_list , __fish_print_lsblk_columns )'
complete -c lsblk -s o -l output -d "output columns" -xa "(__fish_stripprefix='^(--output=|-\w*o)' __fish_complete_list , __fish_print_lsblk_columns)"
complete -c lsblk -s P -l pairs -d "use key='value' output format"
complete -c lsblk -s r -l raw -d "use raw output format"
complete -c lsblk -s t -l topology -d "output info about topology"

View File

@@ -11,9 +11,9 @@ i\t"ignore the device cache file"
r\t"read the device cache file"
u\t"read and update the device cache file"'
complete -c lsof -s g -d 'select by group (^ - negates)' -xa '(__fish_complete_list , __fish_complete_groups)'
complete -c lsof -s g -d 'select by group (^ - negates)' -xa "(__fish_stripprefix='^-\w*g' __fish_complete_list , __fish_complete_groups)"
complete -c lsof -s l -d 'Convert UIDs to login names'
complete -c lsof -s p -d 'Select or exclude processes by pid' -xa '(__fish_complete_list , __fish_complete_pids)'
complete -c lsof -s p -d 'Select or exclude processes by pid' -xa "(__fish_stripprefix='^-\w*p' __fish_complete_list , __fish_complete_pids)"
complete -c lsof -s R -d 'Print PPID'
complete -c lsof -s t -d 'Produce terse output (pids only, no header)'
complete -c lsof -s u -d 'select by user (^ - negates)' -xa '(__fish_complete_list , __fish_complete_users)'
complete -c lsof -s u -d 'select by user (^ - negates)' -xa "(__fish_stripprefix='^-\w*u' __fish_complete_list , __fish_complete_users)"

View File

@@ -35,7 +35,7 @@ function __fish_complete_openssl_ciphers
printf "%s\tCipher String\n" $cs
end
end
complete -c ncat -l ssl-ciphers -x -a "(__fish_complete_list : __fish_complete_openssl_ciphers)" -d "Specify SSL ciphersuites"
complete -c ncat -l ssl-ciphers -x -a "(__fish_stripprefix='^--ssl-ciphers=' __fish_complete_list : __fish_complete_openssl_ciphers)" -d "Specify SSL ciphersuites"
complete -c ncat -l ssl-servername -x -a "(__fish_print_hostnames)" -d "Request distinct server name"
complete -c ncat -l ssl-alpn -x -d "Specify ALPN protocol list"

View File

@@ -92,11 +92,11 @@ function __fish_complete_nmap_script
end
echo -e $__fish_nmap_script_completion_cache
end
complete -c nmap -l script -r -a "(__fish_complete_list , __fish_complete_nmap_script)"
complete -c nmap -l script -r -a "(__fish_stripprefix='^--script=' __fish_complete_list , __fish_complete_nmap_script)"
complete -c nmap -l script -r -d 'Runs a script scan'
complete -c nmap -l script-args -d 'provide arguments to NSE scripts'
complete -c nmap -l script-args-file -r -d 'load arguments to NSE scripts from a file'
complete -c nmap -l script-help -r -a "(__fish_complete_list , __fish_complete_nmap_script)"
complete -c nmap -l script-help -r -a "(__fish_stripprefix='^--script-help=' __fish_complete_list , __fish_complete_nmap_script)"
complete -c nmap -l script-help -r -d "Shows help about scripts"
complete -c nmap -l script-trace
complete -c nmap -l script-updatedb

View File

@@ -24,6 +24,7 @@ complete -c objdump -l target -s b -d "Specify target object format" -x -a "elf6
complete -c objdump -l architecture -s m -d "Specify target architecture" -x -a "i386 i386:x86-64 i386:x64-32 i8086 i386:intel i386:x86-64:intel i386:x64-32:intel i386:nacl i386:x86-64:nacl i386:x64-32:nacl iamcu iamcu:intel l1om l1om:intel k1om k1om:intel plugin"
complete -c objdump -l section -s j -d "Only display information for given section" -x
complete -c objdump -l disassembler-options -s M -d "Pass given options on to disassembler" -x
complete -c objdump -l disassembler-color -d "Control disassembler syntax highlighting style" -x -a "off terminal on extended"
complete -c objdump -l endian -x -d "Set format endianness when disassembling" -a "big little"
complete -c objdump -o EB -d "Assume big endian format when disassembling"
complete -c objdump -o EL -d "Assume little endian format when disassembling"

Some files were not shown because too many files have changed in this diff Show More