mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-04-19 14:51:13 -03:00
Compare commits
69 Commits
Integratio
...
4.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1456f9707 | ||
|
|
c88e6827b7 | ||
|
|
bc3e3ae029 | ||
|
|
3191ac13e5 | ||
|
|
4f810809c8 | ||
|
|
d622949d26 | ||
|
|
d95b662542 | ||
|
|
d88d3122c8 | ||
|
|
a7f717c59c | ||
|
|
ba49981f17 | ||
|
|
05ae55b172 | ||
|
|
b5877ebe44 | ||
|
|
f9a03215b8 | ||
|
|
ff0980c4c1 | ||
|
|
1a58d3f08b | ||
|
|
b71027f622 | ||
|
|
84c03c6f26 | ||
|
|
bf455bc316 | ||
|
|
6af0378916 | ||
|
|
de154065fe | ||
|
|
459e9b7847 | ||
|
|
f127323c33 | ||
|
|
3fc245d829 | ||
|
|
542793a534 | ||
|
|
18c231de29 | ||
|
|
8e78857836 | ||
|
|
c7efbf590e | ||
|
|
5771085280 | ||
|
|
76d2419228 | ||
|
|
ffbf957fa3 | ||
|
|
ae3532e9ec | ||
|
|
5cd2ef903a | ||
|
|
67b6afffd4 | ||
|
|
6df88e1a9f | ||
|
|
61884bda36 | ||
|
|
66584dadcc | ||
|
|
5944518e6e | ||
|
|
19502ff9e7 | ||
|
|
e37e1b8f78 | ||
|
|
5d31be1c3e | ||
|
|
7a959723ef | ||
|
|
ad7631093d | ||
|
|
bd8d268255 | ||
|
|
83f29ed09c | ||
|
|
aca6836103 | ||
|
|
c9f1979b05 | ||
|
|
4a35c48ce5 | ||
|
|
f336cf5624 | ||
|
|
1504731d53 | ||
|
|
9dce68fab4 | ||
|
|
815bc054e7 | ||
|
|
b8af4b20c2 | ||
|
|
c06830ccf2 | ||
|
|
f96b9c53ce | ||
|
|
12527d1522 | ||
|
|
46422b6a16 | ||
|
|
97f0809b62 | ||
|
|
d30a2c5240 | ||
|
|
7ee6d91ba0 | ||
|
|
a94c4e96ab | ||
|
|
e767bb623f | ||
|
|
e925eccad2 | ||
|
|
200eeffeee | ||
|
|
0d453039ac | ||
|
|
044afefc5c | ||
|
|
5cce0918a9 | ||
|
|
3a673aff63 | ||
|
|
880aa479bf | ||
|
|
303af078f3 |
18
.github/workflows/main.yml
vendored
18
.github/workflows/main.yml
vendored
@@ -28,10 +28,10 @@ jobs:
|
||||
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- name: make
|
||||
run: |
|
||||
make VERBOSE=1
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
run: |
|
||||
make VERBOSE=1 test
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
ubuntu-32bit-static-pcre2:
|
||||
|
||||
@@ -54,10 +54,10 @@ jobs:
|
||||
cmake -DFISH_USE_SYSTEM_PCRE2=OFF -DRust_CARGO_TARGET=i586-unknown-linux-gnu ..
|
||||
- name: make
|
||||
run: |
|
||||
make VERBOSE=1
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
run: |
|
||||
make VERBOSE=1 test
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
ubuntu-asan:
|
||||
|
||||
@@ -92,7 +92,7 @@ jobs:
|
||||
cmake .. -DASAN=1 -DRust_CARGO_TARGET=x86_64-unknown-linux-gnu -DCMAKE_BUILD_TYPE=Debug
|
||||
- name: make
|
||||
run: |
|
||||
make VERBOSE=1
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
env:
|
||||
FISH_CI_SAN: 1
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
llvm_version=$(clang --version | awk 'NR==1 { split($NF, version, "."); print version[1] }')
|
||||
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-$llvm_version
|
||||
export LSAN_OPTIONS="$LSAN_OPTIONS:suppressions=$PWD/build_tools/lsan_suppressions.txt"
|
||||
make VERBOSE=1 test
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
# Our clang++ tsan builds are not recognizing safe rust patterns (such as the fact that Drop
|
||||
# cannot be called while a thread is using the object in question). Rust has its own way of
|
||||
@@ -135,7 +135,7 @@ jobs:
|
||||
# make
|
||||
# - name: make fish_run_tests
|
||||
# run: |
|
||||
# make fish_run_tests
|
||||
# make -C build fish_run_tests
|
||||
|
||||
macos:
|
||||
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
cmake -DWITH_GETTEXT=NO -DCMAKE_BUILD_TYPE=Debug ..
|
||||
- name: make
|
||||
run: |
|
||||
make VERBOSE=1
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
run: |
|
||||
make VERBOSE=1 test
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
@@ -1,3 +1,52 @@
|
||||
fish 4.0.2 (released April 20, 2025)
|
||||
====================================
|
||||
|
||||
This release of fish fixes a number of issues identified in fish 4.0.1:
|
||||
|
||||
- Completions are quoted, rather than backslash-escaped, only if the completion is unambiguous. Continuing to edit the token is therefore easier (:issue:`11271`). This changes the behavior introduced in 4.0.0 where all completions were quoted.
|
||||
- The warning when the terminfo database can't be found has been downgraded to a log message. fish will act as if the terminal behaves like xterm-256color, which is correct for the vast majority of cases (:issue:`11277`, :issue:`11290`).
|
||||
- Key combinations using the super (Windows/command) key can now (actually) be bound using the :kbd:`super-` prefix (:issue:`11217`). This was listed in the release notes for 4.0.1 but did not work correctly.
|
||||
- :doc:`function <cmds/function>` is stricter about argument parsing, rather than allowing additional parameters to be silently ignored (:issue:`11295`).
|
||||
- Using parentheses in the :doc:`test <cmds/test>` builtin works correctly, following a regression in 4.0.0 where they were not recognized (:issue:`11387`).
|
||||
- :kbd:`delete` in Vi mode when Num Lock is active will work correctly (:issue:`11303`).
|
||||
- Abbreviations cannot alter the command-line contents, preventing a crash (:issue:`11324`).
|
||||
- Improvements to various completions, including new completions for ``wl-randr`` (:issue:`11301`), performance improvements for ``cargo`` completions by avoiding network requests (:issue:`11347`), and other improvements for ``btrfs`` (:issue:`11320`), ``cryptsetup`` (:issue:`11315`), ``git`` (:issue:`11319`, :issue:`11322`, :issue:`11323`), ``jj`` (:issue:`11046`), and ``systemd-analyze`` (:issue:`11314`).
|
||||
- The Mercurial (``hg``) prompt can handle working directories that contain an embedded newline, rather than producing errors (:issue:`11348`).
|
||||
- A number of crashes have been fixed. Triggers include prompts containing backspace characters (:issue:`11280`), history pager search (:issue:`11355`), invalid UTF-8 in :doc:`read <cmds/read>` (:issue:`11383`), and the ``kill-selection`` binding (:issue:`11367`).
|
||||
- A race condition in the test suite has been fixed (:issue:`11254`), and a test for fish versioning relaxed to support downstream distributors' modifications (:issue:`11173`).
|
||||
- Small improvements to the documentation (:issue:`11264`, :issue:`11329`, :issue:`11361`).
|
||||
|
||||
--------------
|
||||
|
||||
fish 4.0.1 (released March 12, 2025)
|
||||
====================================
|
||||
|
||||
This release of fish includes the following improvements compared to fish 4.0.0:
|
||||
|
||||
- Key combinations using the super (Windows/command) key can be bound using the :kbd:`super-` prefix (:issue:`11217`).
|
||||
- Konsole's menu shows the "Open folder with" option again (:issue:`11198`).
|
||||
- ``$fish_color_search_match`` will now only be applied to the foreground color if it has an explicit foreground. For example, this allows setting::
|
||||
set -g fish_color_search_match --reverse
|
||||
- Cursor shape commands (``\e[2 q``) are no longer sent in non-interactive shells or in redirections (:issue:`11255`).
|
||||
- :doc:`status <cmds/status>` gained a ``is-interactive-read`` subcommand, to check whether the script is being called from an interactive :doc:`read <cmds/read>` invocation.
|
||||
- fish's background tasks are now started in a way that avoids an error on macOS Terminal.app (:issue:`11181`).
|
||||
- Using key combinations within qemu should work correctly.
|
||||
- Prompts containing control characters no longer cause incorrect display of command lines (:issue:`11252`).
|
||||
- Cancelling the command-line in Vi mode displays correctly again (:issue:`11261`).
|
||||
- The acidhub prompt properly displays the git branch again (:issue:`11179`).
|
||||
- Completions for ``wine`` correctly include files again (:issue:`11202`).
|
||||
- On macOS, paths from ``/etc/paths`` and ``/etc/manpaths`` containing colons are handled correctly (:issue:`10684`). This functionality was included in the 4.0.0 release notes but was missing from the source code.
|
||||
- The XTerm ``modifyOtherKeys`` keyboard encoding is no longer used under WezTerm, as it does not work correctly in all layouts (:issue:`11204`).
|
||||
- kbd:`option-left` and other similar keys should now work in iTerm versions before 3.5.12; the kitty keyboard protocol is now disabled on these versions (:issue:`11192`).
|
||||
- The kitty keyboard protocol is no longer used under Midnight Commander, as it does not work correctly (:issue:`10640`).
|
||||
- fish now sends the commandline along with the OSC 133 semantic prompt command start sequence. This fixes a test in the kitty terminal (:issue:`11203`).
|
||||
- Git completions for third-party commands like "git-absorb" are completed correctly again (:issue:`11205`).
|
||||
- Completions for ``diskutil`` no longer produce an error (:issue:`11201`).
|
||||
- The output of certain error messages no longer prints newlines to standard output (:issue:`11248`).
|
||||
- A number of crashes have been fixed, including file names longer than 255 bytes (:issue:`11221`), using fish on a btrfs filesystem (:issue:`11219`), history files that do not have the expected format (:issue:`11236`), and pasting into an empty command line (:issue:`11256`).
|
||||
|
||||
--------------
|
||||
|
||||
fish 4.0.0 (released February 27, 2025)
|
||||
=======================================
|
||||
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -112,7 +112,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fish"
|
||||
version = "4.0.0"
|
||||
version = "4.0.2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
|
||||
@@ -16,7 +16,7 @@ debug = true
|
||||
|
||||
[package]
|
||||
name = "fish"
|
||||
version = "4.0.0"
|
||||
version = "4.0.2"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
default-run = "fish"
|
||||
|
||||
@@ -306,18 +306,23 @@ if (Rust_RESOLVE_RUSTUP_TOOLCHAINS)
|
||||
set(_DISCOVERED_TOOLCHAINS_VERSION "")
|
||||
|
||||
foreach(_TOOLCHAIN_RAW ${_TOOLCHAINS_RAW})
|
||||
if (_TOOLCHAIN_RAW MATCHES "([a-zA-Z0-9\\._\\-]+)[ \t\r\n]?(\\(default\\) \\(override\\)|\\(default\\)|\\(override\\))?[ \t\r\n]+(.+)")
|
||||
# We're going to try to parse the output of `rustup toolchain list --verbose`.
|
||||
# We expect output like this:
|
||||
# stable-random-toolchain-junk (parenthesized-random-stuff-like-active-or-default) /path/to/toolchain/blah/more-blah
|
||||
# In the following regex, we capture the toolchain name, any parenthesized stuff, and then the path.
|
||||
message(STATUS "Parsing toolchain: ${_TOOLCHAIN_RAW}")
|
||||
if (_TOOLCHAIN_RAW MATCHES "([^\t ]+)[\t ]*(\\(.*\\))?[\t ]*(.+)")
|
||||
set(_TOOLCHAIN "${CMAKE_MATCH_1}")
|
||||
set(_TOOLCHAIN_TYPE "${CMAKE_MATCH_2}")
|
||||
|
||||
set(_TOOLCHAIN_PATH "${CMAKE_MATCH_3}")
|
||||
set(_TOOLCHAIN_${_TOOLCHAIN}_PATH "${CMAKE_MATCH_3}")
|
||||
|
||||
if (_TOOLCHAIN_TYPE MATCHES ".*\\(default\\).*")
|
||||
if (_TOOLCHAIN_TYPE MATCHES "default")
|
||||
set(_TOOLCHAIN_DEFAULT "${_TOOLCHAIN}")
|
||||
endif()
|
||||
|
||||
if (_TOOLCHAIN_TYPE MATCHES ".*\\(override\\).*")
|
||||
if (_TOOLCHAIN_TYPE MATCHES "override")
|
||||
set(_TOOLCHAIN_OVERRIDE "${_TOOLCHAIN}")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ If both ``KEYS`` and ``COMMAND`` are given, ``bind`` adds (or replaces) a bindin
|
||||
If only ``KEYS`` is given, any existing binding in the given ``MODE`` will be printed.
|
||||
|
||||
``KEYS`` is a comma-separated list of key names.
|
||||
Modifier keys can be specified by prefixing a key name with a combination of ``ctrl-``, ``alt-`` and ``shift-``.
|
||||
Modifier keys can be specified by prefixing a key name with a combination of ``ctrl-``, ``alt-``, ``shift-`` and ``super-`` (i.e. the "windows" or "command" key).
|
||||
For example, pressing :kbd:`w` while holding the Alt modifier is written as ``alt-w``.
|
||||
Key names are case-sensitive; for example ``alt-W`` is the same as ``alt-shift-w``.
|
||||
``ctrl-x,ctrl-e`` would mean pressing :kbd:`ctrl-x` followed by :kbd:`ctrl-e`.
|
||||
@@ -99,6 +99,12 @@ The following options are available:
|
||||
**-s** or **--silent**
|
||||
Silences some of the error messages, including for unknown key names and unbound sequences.
|
||||
|
||||
**-k KEY_NAME** or **--key KEY_NAME**
|
||||
This looks up KEY_NAME in terminfo and binds that sequence instead of a key that fish would decode.
|
||||
To view a list of the terminfo keys fish knows about, use ``bind --key-names`` or ``bind -K``.
|
||||
This is deprecated and provided for compatibility with older fish versions. You should bind the keys directly.
|
||||
Instead of ``bind -k sright`` use ``bind shift-right``, instead of ``bind -k nul`` use ``bind ctrl-space`` and so on.
|
||||
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
|
||||
|
||||
@@ -26,15 +26,12 @@ The first argument to fish_title contains the most recently executed foreground
|
||||
|
||||
This requires that your terminal supports programmable titles and the feature is turned on.
|
||||
|
||||
To disable setting the title, use an empty function (see below).
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
A simple title:
|
||||
|
||||
|
||||
|
||||
::
|
||||
A simple title::
|
||||
|
||||
function fish_title
|
||||
set -q argv[1]; or set argv fish
|
||||
@@ -43,3 +40,7 @@ A simple title:
|
||||
echo (fish_prompt_pwd_dir_length=1 prompt_pwd): $argv;
|
||||
end
|
||||
|
||||
Do not change the title::
|
||||
|
||||
function fish_title
|
||||
end
|
||||
|
||||
@@ -11,6 +11,7 @@ Synopsis
|
||||
status
|
||||
status is-login
|
||||
status is-interactive
|
||||
status is-interactive-read
|
||||
status is-block
|
||||
status is-breakpoint
|
||||
status is-command-substitution
|
||||
@@ -50,6 +51,9 @@ The following operations (subcommands) are available:
|
||||
**is-interactive**, **-i** or **--is-interactive**
|
||||
Returns 0 if fish is interactive - that is, connected to a keyboard.
|
||||
|
||||
**is-interactive-read** or **--is-interactive-read**
|
||||
Returns 0 if fish is running an interactive :doc:`read <read>` builtin which is connected to a keyboard.
|
||||
|
||||
**is-login**, **-l** or **--is-login**
|
||||
Returns 0 if fish is a login shell - that is, if fish should perform login tasks such as setting up :envvar:`PATH`.
|
||||
|
||||
|
||||
@@ -52,13 +52,13 @@ Match Glob Examples
|
||||
|
||||
::
|
||||
|
||||
>_ string match '?' a
|
||||
>_ string match 'a' a
|
||||
a
|
||||
|
||||
>_ string match 'a*b' axxb
|
||||
axxb
|
||||
|
||||
>_ string match -i 'a??B' Axxb
|
||||
>_ string match -i 'a*B' Axxb
|
||||
Axxb
|
||||
|
||||
>_ string match -- '-*' -h foo --version bar
|
||||
@@ -67,7 +67,7 @@ Match Glob Examples
|
||||
-h
|
||||
--version
|
||||
|
||||
>_ echo 'ok?' | string match '*\?'
|
||||
>_ echo 'ok?' | string match '*?'
|
||||
ok?
|
||||
|
||||
# Note that only the second STRING will match here.
|
||||
@@ -79,7 +79,7 @@ Match Glob Examples
|
||||
foo
|
||||
foo2
|
||||
|
||||
>_ string match 'foo?' 'foo1' 'foo' 'foo2'
|
||||
>_ string match 'foo*' 'foo1' 'foo' 'foo2'
|
||||
foo1
|
||||
foo2
|
||||
|
||||
|
||||
@@ -102,33 +102,36 @@ complete -f -c btrfs -n $restore -s S -l symlink -d 'Restore symbolic links'
|
||||
complete -f -c btrfs -n $restore -s v -l verbose -d Verbose
|
||||
complete -f -c btrfs -n $restore -s i -l ignore-errors -d 'Ignore errors'
|
||||
complete -f -c btrfs -n $restore -s o -l overwrite -d Overwrite
|
||||
complete -f -c btrfs -n $restore -s t -d 'Tree location'
|
||||
complete -f -c btrfs -n $restore -s f -d 'Filesystem location'
|
||||
complete -f -c btrfs -n $restore -s u -l super -d 'Super mirror'
|
||||
complete -f -c btrfs -n $restore -s r -l root -d 'Root objectid'
|
||||
complete -f -c btrfs -n $restore -s t -r -d 'Tree location'
|
||||
complete -f -c btrfs -n $restore -s f -r -d 'Filesystem location'
|
||||
complete -f -c btrfs -n $restore -s u -l super -r -d 'Super mirror'
|
||||
complete -f -c btrfs -n $restore -s r -l root -r -d 'Root objectid'
|
||||
complete -f -c btrfs -n $restore -s d -d 'Find dir'
|
||||
complete -f -c btrfs -n $restore -s l -l list-roots -d 'List tree roots'
|
||||
complete -f -c btrfs -n $restore -s D -l dry-run -d 'Only list files that would be recovered'
|
||||
complete -f -c btrfs -n $restore -l path-regex -d 'Restore only filenames matching regex'
|
||||
complete -f -c btrfs -n $restore -l path-regex -r -d 'Restore only filenames matching regex'
|
||||
complete -f -c btrfs -n $restore -s c -d 'Ignore case (--path-regex only)'
|
||||
|
||||
# btrfs send
|
||||
complete -f -c btrfs -n $send -s e -d ''
|
||||
complete -f -c btrfs -n $send -s p -d 'Send an incremental stream from <parent> to <subvol>'
|
||||
complete -f -c btrfs -n $send -s c -d 'Use this snapshot as a clone source for an incremental send'
|
||||
complete -f -c btrfs -n $send -s f -d 'Output is normally written to stdout'
|
||||
complete -f -c btrfs -n $send -s p -r -d 'Send an incremental stream from <parent> to <subvol>'
|
||||
complete -f -c btrfs -n $send -s c -r -d 'Use this snapshot as a clone source for an incremental send'
|
||||
complete -f -c btrfs -n $send -s f -r -d 'Output is normally written to stdout'
|
||||
complete -f -c btrfs -n $send -l no-data -d 'send in NO_FILE_DATA mode'
|
||||
complete -f -c btrfs -n $send -s v -l verbose -d 'Enable verbose output to stderr'
|
||||
complete -f -c btrfs -n $send -s q -l quiet -d 'Suppress all messages, except errors'
|
||||
complete -f -c btrfs -n $send -l proto -a '0 1 2' -r -d 'Use send protocol version'
|
||||
complete -f -c btrfs -n $send -l proto -l compressed-data -d 'Send compressed data directly'
|
||||
|
||||
# btrfs receive
|
||||
complete -f -c btrfs -n $receive -s v -d 'Increase verbosity about performed actions'
|
||||
complete -f -c btrfs -n $receive -s q -l quiet -d 'Suppress all messages, except errors'
|
||||
complete -f -c btrfs -n $receive -s f -d 'Read the stream from FILE instead of stdin'
|
||||
complete -f -c btrfs -n $receive -s f -r -d 'Read the stream from FILE instead of stdin'
|
||||
complete -f -c btrfs -n $receive -s e -d 'Terminate after receiving an <end cmd> marker in the stream'
|
||||
complete -f -c btrfs -n $receive -s C -l chroot -d 'Confine the process to <mount> using chroot'
|
||||
complete -f -c btrfs -n $receive -s E -l max-errors -d 'Terminate when NUMBER errors occur'
|
||||
complete -f -c btrfs -n $receive -s m -d 'The root mount point of the destination filesystem'
|
||||
complete -f -c btrfs -n $receive -s E -l max-errors -r -d 'Terminate when NUMBER errors occur'
|
||||
complete -f -c btrfs -n $receive -s m -r -d 'The root mount point of the destination filesystem'
|
||||
complete -f -c btrfs -n $receive -l force-decompress -r -d 'Always decompress data'
|
||||
complete -f -c btrfs -n $receive -l dump -d 'Dump stream metadata'
|
||||
|
||||
# btrfs help
|
||||
@@ -147,9 +150,11 @@ complete -f -c btrfs -n $subvolume -a show -d 'Show more information about the s
|
||||
complete -f -c btrfs -n $subvolume -a sync -d 'Wait until given subvolume(s) are completely removed from the filesystem.'
|
||||
# btrfs subvolume create
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume create' -s i -d 'Add subvolume to a qgroup (can be given multiple times)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume create' -s p -d 'Create any missing parent directories'
|
||||
# btrfs subvolume delete
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume delete' -s c -l commit-after -d 'Wait for transaction commit at the end of the operation'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume delete' -s C -l commit-each -d 'Wait for transaction commit after deleting each subvolume'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume delete' -s R -l recursive -d 'Delete subvolumes beneath each subvolume recursively'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume delete' -s v -l verbose -d 'Verbose output of operations'
|
||||
# btrfs subvolume list
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s o -d 'Print only subvolumes below specified path'
|
||||
@@ -164,8 +169,8 @@ complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s s -d 'List on
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s r -d 'List readonly subvolumes (including snapshots)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s d -d 'List deleted subvolumes that are not yet cleaned'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s t -d 'Print the result as a table'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s G -d 'Filter the subvolumes by generation'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s C -d 'Filter the subvolumes by ogeneration'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s G -r -d 'Filter the subvolumes by generation'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -s C -r -d 'Filter the subvolumes by ogeneration'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume list' -l sort -d 'List the subvolume in order' -a '{gen,ogen,rootid,path}'
|
||||
# btrfs subvolume snapshot
|
||||
complete -f -c btrfs -n '__btrfs_command_groups subvolume snapshot' -s r -d 'Create a readonly snapshot'
|
||||
@@ -194,6 +199,7 @@ complete -f -c btrfs -n $filesystem -a defragment -d 'Defragment a file or a dir
|
||||
complete -f -c btrfs -n $filesystem -a resize -d 'Resize a filesystem'
|
||||
complete -f -c btrfs -n $filesystem -a label -d 'Get or change the label of a filesystem'
|
||||
complete -f -c btrfs -n $filesystem -a usage -d 'Show detailed information about internal filesystem usage.'
|
||||
complete -f -c btrfs -n $filesystem -a mkswapfile -d 'Create a new swapfile'
|
||||
# btrfs filesystem df
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem df' -s b -l raw -d 'Show raw numbers in bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem df' -s h -l human-readable -d 'Show human friendly numbers, base 1024'
|
||||
@@ -230,9 +236,12 @@ complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s v -d '
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s r -d 'Defragment files recursively'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s c -d 'Compress the file while defragmenting' -ra '{zlib,lzo,zstd}'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s f -d 'Flush data to disk immediately after defragmenting'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s s -d 'Defragment only from NUMBER byte onward'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s l -d 'Defragment only up to LEN bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s t -d 'Target extent SIZE hint'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s s -r -d 'Defragment only from NUMBER byte onward'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s l -r -d 'Defragment only up to LEN bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s t -r -d 'Target extent SIZE hint'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -l step -r -d 'Defragment in steps of SIZE'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem defragment' -s L -l level -r -d 'Specify compression levels'
|
||||
|
||||
# btrfs filesystem usage
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem usage' -s b -l raw -d 'Show raw numbers in bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem usage' -s h -l human-readable -d 'Show human friendly numbers, base 1024'
|
||||
@@ -244,6 +253,11 @@ complete -f -c btrfs -n '__btrfs_command_groups filesystem usage' -s m -l mbytes
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem usage' -s g -l gbytes -d 'Show sizes in GiB, or GB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem usage' -s t -l tbytes -d 'Show sizes in TiB, or TB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem usage' -s T -d 'Show data in tabular format'
|
||||
# btrfs filesystem mkswapfile
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem mkswapfile' -s s -l size -r -d 'Swapfile size'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem mkswapfile' -s U -l uuid -r -d 'UUID for the swapfile'
|
||||
# btrfs filesystem resize
|
||||
complete -f -c btrfs -n '__btrfs_command_groups filesystem resize' -l enqueue -d 'Wait for other exclusive operations'
|
||||
|
||||
# btrfs balance
|
||||
complete -f -c btrfs -n $balance -a start -d 'Balance chunks across the devices'
|
||||
@@ -252,13 +266,23 @@ complete -f -c btrfs -n $balance -a cancel -d 'Cancel running or paused balance'
|
||||
complete -f -c btrfs -n $balance -a resume -d 'Resume interrupted balance'
|
||||
complete -f -c btrfs -n $balance -a status -d 'Show status of running or paused balance'
|
||||
# btrfs balance start
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s d -d 'Act on data chunks with FILTERS'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s m -d 'Act on metadata chunks with FILTERS'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s s -d 'Act on system chunks with FILTERS (only under -f)'
|
||||
function __btrfs_balance_filters
|
||||
set -l profiles raid{0,1{,c3,c4},10,5,6} dup single
|
||||
set -l btrfs_balance_filters \
|
||||
profiles=$profiles\t"Balances only block groups with the given profiles" \
|
||||
convert=$profiles\t"Convert selected block groups to given profile" \
|
||||
usage= devid= vrange= limit= strips= soft
|
||||
set -l prefix (commandline -tc | string replace -r '^-d' -- '' | string match -rg '^(.*?)?[^,]*$' -- $token)
|
||||
printf "%s\n" "$prefix"$btrfs_balance_filters
|
||||
end
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s d -ra '(__btrfs_balance_filters)' -d 'Act on data chunks with FILTERS'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s m -ra '(__btrfs_balance_filters)' -d 'Act on metadata chunks with FILTERS'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s s -ra '(__btrfs_balance_filters)' -d 'Act on system chunks with FILTERS (only under -f)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s v -d 'Be verbose'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -s f -d 'Force a reduction of metadata integrity'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -l full-balance -d 'Do not print warning and do not delay start'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -l background -l bg -d 'Run the balance as a background process'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance start' -l enqueue -d 'Wait for other exclusive operations'
|
||||
# btrfs balance status
|
||||
complete -f -c btrfs -n '__btrfs_command_groups balance status' -s v -d 'Be verbose'
|
||||
|
||||
@@ -279,6 +303,10 @@ complete -f -c btrfs -n '__btrfs_command_groups device scan' -s u -l forget -d '
|
||||
# btrfs device stats
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device stats' -s c -l check -d 'Return non-zero if any stat counter is not zero'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device stats' -s z -l reset -d 'Show current stats and reset values to zero'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device stats' -s T -d "Print stats in a tabular form"
|
||||
# btrfs device remove
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device remove' -l enqueue -d 'Wait for other exclusive operations'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device remove' -l force -d 'Skip the safety timeout for removing multiple devices'
|
||||
# btrfs device usage
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device usage' -s b -l raw -d 'Show raw numbers in bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups device usage' -s h -l human-readable -d 'Show human friendly numbers, base 1024'
|
||||
@@ -295,12 +323,18 @@ complete -f -c btrfs -n $scrub -a start -d 'Start a new scrub. If a scrub is alr
|
||||
complete -f -c btrfs -n $scrub -a cancel -d 'Cancel a running scrub'
|
||||
complete -f -c btrfs -n $scrub -a resume -d 'Resume previously canceled or interrupted scrub'
|
||||
complete -f -c btrfs -n $scrub -a status -d 'Show status of running or finished scrub'
|
||||
complete -f -c btrfs -n $scrub -a limit -d 'Show or set scrub limits on devices of the given filesystem'
|
||||
# btrfs scrub limit
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub limit' -s d -l devid -d 'Select the device by DEVID to apply the limit'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub limit' -s l -l limit -d 'Set the limit of the device'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub limit' -s a -l all -d 'Apply the limit to all devices'
|
||||
# btrfs scrub start
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s B -d 'Do not background'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s d -d 'Stats per device (-B only)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s q -d 'Be quiet'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s r -d 'Read only mode'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s R -d 'Raw print mode, print full data instead of summary'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -l limit -d 'Set the scrub throughput limit'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s c -d 'Set ioprio class (see ionice(1) manpage)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s n -d 'Set ioprio classdata (see ionice(1) manpage)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups scrub start' -s f -d 'Force starting new scrub'
|
||||
@@ -321,6 +355,9 @@ complete -f -c btrfs -n $rescue -a chunk-recover -d 'Recover the chunk tree by s
|
||||
complete -f -c btrfs -n $rescue -a super-recover -d 'Recover bad superblocks from good copies'
|
||||
complete -f -c btrfs -n $rescue -a zero-log -d 'Clear the tree log. Usable if it\'s corrupted and prevents mount.'
|
||||
complete -f -c btrfs -n $rescue -a fix-device-size -d 'Re-align device and super block sizes'
|
||||
complete -f -c btrfs -n $rescue -a clear-ino-cache -d 'Remove leftover items pertaining to the deprecated inode cache feature'
|
||||
complete -f -c btrfs -n $rescue -a clear-space-cache -d 'Completely remove the on-disk data of free space cache of given version'
|
||||
complete -f -c btrfs -n $rescue -a clear-uuid-tree -d 'Clear the UUID tree'
|
||||
# btrfs rescue chunk-recover
|
||||
complete -f -c btrfs -n '__btrfs_command_groups rescue chunk-recover' -s y -d 'Assume an answer of YES to all questions'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups rescue chunk-recover' -s v -d 'Verbose mode'
|
||||
@@ -337,6 +374,8 @@ complete -f -c btrfs -n $inspect_internal -a min-dev-size -d 'Get the minimum si
|
||||
complete -f -c btrfs -n $inspect_internal -a dump-tree -d 'Dump tree structures from a given device'
|
||||
complete -f -c btrfs -n $inspect_internal -a dump-super -d 'Dump superblock from a device in a textual form'
|
||||
complete -f -c btrfs -n $inspect_internal -a tree-stats -d 'Print various stats for trees'
|
||||
complete -f -c btrfs -n $inspect_internal -a list-chunks -d 'Enumerate chunks on all devices'
|
||||
complete -f -c btrfs -n $inspect_internal -a map-swapfile -d 'Find device-specific physical offset of file that can be used for hibernation'
|
||||
# btrfs inspect-internal inode-resolve
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal inode-resolve' -s v -d 'Verbose mode'
|
||||
# btrfs inspect-internal logical-resolve
|
||||
@@ -351,20 +390,50 @@ complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s d
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s r -l roots -d 'Print only short root node info'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s R -l backups -d 'Print short root node info and backup root info'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s u -l uuid -d 'Print only the uuid tree'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s b -l block -d 'Print info from the specified BLOCK only'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s t -l tree -d 'Print only tree with the given ID'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s b -l block -r -d 'Print info from the specified BLOCK only'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -s t -l tree -r -d 'Print only tree with the given ID'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l follow -d 'Use with -b, to show all children tree blocks of <block_num>'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l noscan -d 'Do not scan the devices from the filesystem'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l bfs -d 'Breadth-first traversal of the trees, print nodes, then leaves'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l dfs -d 'Depth-first traversal of the trees'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l hide-names -d 'Print placeholder instead of names'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l csum-headers -d 'Print b-tree node checksums in headers'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-tree' -l csum-items -d 'Print checksums stored in checksum items'
|
||||
|
||||
# btrfs inspect-internal dump-super
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-super' -s f -l full -d 'Print full superblock information, backup roots etc.'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-super' -s a -l all -d 'Print information about all superblocks'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-super' -s s -l super -d 'Specify which SUPER-BLOCK copy to print out' -ra '{0,1,2}'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-super' -s F -l force -d 'Attempt to dump superblocks with bad magic'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal dump-super' -l bytenr -d 'Specify alternate superblock OFFSET'
|
||||
# btrfs inspect-internal logical-resolve
|
||||
complete -f -c btrfs -n '__btrfs_command_groups logical-resolve' -s P -d 'Print inodes instead of resolving paths'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups logical-resolve' -s o -d 'Ignore offsets, find all references to an extent'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups logical-resolve' -s s -r -d 'Set internal buffer size for storing file names'
|
||||
# btrfs inspect-internal tree-stats
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -s b -d 'Show raw numbers in bytes'
|
||||
# btrfs inspect-internal list-chunks
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l sort -ra 'devid pstart lstart usage length' -d 'Sort by a column (ascending)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l raw -d 'Show raw numbers in bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l human-readable -d 'Show human friendly numbers, base 1024'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l iec -d 'Use 1024 as a base (KiB, MiB, GiB, TiB)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l si -d 'Use 1000 as a base (kB, MB, GB, TB)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l kbytes -d 'Show sizes in KiB, or kB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l mbytes -d 'Show sizes in MiB, or MB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l gbytes -d 'Show sizes in GiB, or GB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal list-chunks' -l tbytes -d 'Show sizes in TiB, or TB with --si'
|
||||
# btrfs inspect-internal map-swapfile
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal map-swapfile' -l resume-offset -s r -d 'Print the value suitable as resume offset for /sys/power/resume_offset.'
|
||||
# btrfs inspect-internal tree-stats
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -s t -r -d 'Print stats only for the given treeid'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l raw -s b -d 'Show raw numbers in bytes'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l human-readable -d 'Show human friendly numbers, base 1024'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l iec -d 'Use 1024 as a base (KiB, MiB, GiB, TiB)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l si -d 'Use 1000 as a base (kB, MB, GB, TB)'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l kbytes -d 'Show sizes in KiB, or kB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l mbytes -d 'Show sizes in MiB, or MB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l gbytes -d 'Show sizes in GiB, or GB with --si'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups inspect-internal tree-stats' -l tbytes -d 'Show sizes in TiB, or TB with --si'
|
||||
|
||||
# btrfs property
|
||||
complete -f -c btrfs -n $property -a get -d 'Get a property value of a btrfs object'
|
||||
@@ -381,9 +450,12 @@ complete -f -c btrfs -n '__btrfs_command_groups property list' -s t -d 'List pro
|
||||
complete -f -c btrfs -n $quota -a enable -d 'Enable subvolume quota support for a filesystem.'
|
||||
complete -f -c btrfs -n $quota -a disable -d 'Disable subvolume quota support for a filesystem.'
|
||||
complete -f -c btrfs -n $quota -a rescan -d 'Trash all qgroup numbers and scan the metadata again with the current config.'
|
||||
# btrfs quota enable
|
||||
complete -f -c btrfs -n '__btrfs_command_groups quota enable' -s s -l simple -d 'Use simple quotas'
|
||||
# btrfs quota rescan
|
||||
complete -f -c btrfs -n '__btrfs_command_groups quota rescan' -s s -d 'Show status of a running rescan operation'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups quota rescan' -s w -d 'Wait for rescan operation to finish'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups quota rescan' -s s -l status -d 'Show status of a running rescan operation'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups quota rescan' -s w -l wait -d 'Wait for rescan operation to finish'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups quota rescan' -s W -l wait-norescan -d 'Wait for rescan to finish without starting it'
|
||||
|
||||
# btrfs qgroup
|
||||
complete -f -c btrfs -n $qgroup -a assign -d 'Assign SRC as the child qgroup of DST'
|
||||
@@ -391,6 +463,7 @@ complete -f -c btrfs -n $qgroup -a remove -d 'Remove a child qgroup SRC from DST
|
||||
complete -f -c btrfs -n $qgroup -a create -d 'Create a subvolume quota group.'
|
||||
complete -f -c btrfs -n $qgroup -a destroy -d 'Destroy a quota group.'
|
||||
complete -f -c btrfs -n $qgroup -a show -d 'Show subvolume quota groups.'
|
||||
complete -f -c btrfs -n $qgroup -a clear-stale -d 'Clear all stale qgroups whose subvolume does not exist'
|
||||
complete -f -c btrfs -n $qgroup -a limit -d 'Set the limits a subvolume quota group.'
|
||||
# btrfs qgroup assign
|
||||
complete -f -c btrfs -n '__btrfs_command_groups qgroup assign' -l rescan -d 'Schedule qutoa rescan if needed'
|
||||
@@ -424,5 +497,7 @@ complete -f -c btrfs -n $replace -a cancel -d 'Cancel a running device replace o
|
||||
complete -f -c btrfs -n '__btrfs_command_groups replace start' -s r -d 'Only read from <srcdev> if no other zero-defect mirror exists'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups replace start' -s f -d 'Force using and overwriting <targetdev>'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups replace start' -s B -d 'Do not background'
|
||||
complete -f -c btrfs -n '__btrfs_command_groups replace start' -l enqueue -d "Wait if there's another exclusive operation running"
|
||||
complete -f -c btrfs -n '__btrfs_command_groups replace start' -s K -l nodiscard -d 'Do not perform TRIM on DEVICES'
|
||||
# btrfs replace status
|
||||
complete -f -c btrfs -n '__btrfs_command_groups replace status' -s 1 -d 'Only print once until the replace operation finishes'
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
## --- WRITTEN MANUALLY ---
|
||||
set -l __fish_cargo_subcommands (cargo --list 2>&1 | string replace -rf '^\s+([^\s]+)\s*(.*)' '$1\t$2' | string escape)
|
||||
|
||||
# Append user-installed extensions (e.g. cargo-foo, invokable as `cargo foo`) to the list of subcommands (à la git)
|
||||
set -la __fish_cargo_subcommands (complete -C'cargo-' | string replace -rf '^cargo-(\w+).*' '$1')
|
||||
|
||||
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"
|
||||
|
||||
@@ -53,27 +50,6 @@ end
|
||||
complete -c cargo -n '__fish_seen_subcommand_from run test build debug check' -l package \
|
||||
-xa "(__fish_cargo_packages)"
|
||||
|
||||
# Look up crates.io crates matching the single argument provided to this function
|
||||
function __fish_cargo_search
|
||||
if test (string length -- "$argv[1]") -le 2
|
||||
# Don't waste time searching for strings with too many results to realistically
|
||||
# provide a meaningful completion within our results limit.
|
||||
return
|
||||
end
|
||||
|
||||
# This doesn't do a prefix search, so bump up the limit a tiny bit to try and
|
||||
# get enough results to show something.
|
||||
cargo search --color never --quiet --limit 20 -- $argv[1] 2>/dev/null |
|
||||
# Filter out placeholders and "... and xxx more crates"
|
||||
string match -rvi '^\.\.\.|= "0.0.0"|# .*(reserved|yanked)' |
|
||||
# Remove the version number and map the description
|
||||
string replace -rf '^([^ ]+).*# (.*)' '$1\t$2'
|
||||
end
|
||||
|
||||
# Complete possible crate names by search the crates.io index
|
||||
complete -c cargo -n '__fish_seen_subcommand_from add install' -n '__fish_is_nth_token 2' \
|
||||
-a "(__fish_cargo_search (commandline -ct))"
|
||||
|
||||
## --- AUTO-GENERATED WITH `cargo complete fish` ---
|
||||
# Manually massaged to improve some descriptions
|
||||
complete -c cargo -n __fish_use_subcommand -l explain -d 'Run `rustc --explain CODE`'
|
||||
|
||||
@@ -94,3 +94,6 @@ complete -c cryptsetup -l veracrypt-query-pim -d "Query Personal Iteration Multi
|
||||
complete -c cryptsetup -l verbose -s v -d "Shows more detailed error messages"
|
||||
complete -c cryptsetup -l verify-passphrase -s y -d "Verifies the passphrase by asking for it twice"
|
||||
complete -c cryptsetup -l version -s V -d "Print package version"
|
||||
|
||||
# subcommands
|
||||
complete -c cryptsetup -n "__fish_seen_subcommand_from close status resize" -f -r -a "(path basename /dev/mapper/* | string match -v control)"
|
||||
|
||||
@@ -53,7 +53,7 @@ complete -f -c diskutil -n '__fish_diskutil_using_not_subcommand umountDisk' -a
|
||||
|
||||
# eject
|
||||
complete -f -c diskutil -n __fish_use_subcommand -a eject -d 'Eject a volume or disk'
|
||||
complete -f -c diskutil -n '__fish_diskutil_using_not_subcommand eject' -a '(__fish_diskutil_volumes ; __fish_diskutil_devices)'
|
||||
complete -f -c diskutil -n '__fish_diskutil_using_not_subcommand eject' -a '(__fish_diskutil_mounted_volumes ; __fish_diskutil_devices)'
|
||||
|
||||
# mount
|
||||
complete -f -c diskutil -n __fish_use_subcommand -a mount -d 'Mount a single volume'
|
||||
|
||||
27
share/completions/git-subtree.fish
Normal file
27
share/completions/git-subtree.fish
Normal file
@@ -0,0 +1,27 @@
|
||||
complete -f -c git -a subtree -d 'Manage git subtrees'
|
||||
# Git subtree common completions
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -s q -l quiet -d 'Suppress output'
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -s d -l debug -d 'Debug output'
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -s P -l path -d 'Path to the subtree'
|
||||
|
||||
# Git subtree subcommands
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -a add -d "Add a new subtree to the repository"
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -a merge -d "Merge changes from a subtree into the repository"
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -a split -d "Extract a subtree from the repository"
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -a pull -d "Fetch and integrate changes from a remote subtree"
|
||||
complete -f -c git -n '__fish_git_using_command subtree' -a push -d "Push changes to a remote subtree"
|
||||
|
||||
# Completions for push and split subcommands
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split' -l annotate -d 'Annotate the commit'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split' -s b -l branch -d 'Branch to split'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split' -l ignore-joins -d 'Ignore joins during history reconstruction'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split' -l onto -d 'Specify the commit ID to start history reconstruction'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split' -l rejoin -d 'Merge the synthetic history back into the main project'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split; and __fish_contains_opt rejoin' -l squash -d 'Merge subtree changes as a single commit'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split; and __fish_contains_opt rejoin' -l no-squash -d 'Do not merge subtree changes as a single commit'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from push split; and __fish_contains_opt rejoin' -s m -l message -d 'Use the given message as the commit message for the merge commit'
|
||||
|
||||
# Completion for add and merge subcommands
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from add merge' -l squash -d 'Merge subtree changes as a single commit'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from add merge' -l no-squash -d 'Do not merge subtree changes as a single commit'
|
||||
complete -f -c git -n '__fish_git_using_command subtree; and __fish_seen_subcommand_from add merge' -s m -l message -d 'Use the given message as the commit message for the merge commit'
|
||||
@@ -899,6 +899,15 @@ function __fish_git_is_rebasing
|
||||
test -e (__fish_git rev-parse --absolute-git-dir)/rebase-merge
|
||||
end
|
||||
|
||||
function __fish_git_filters
|
||||
printf "%s\n" \
|
||||
blob:none\t"omits all blobs" \
|
||||
blob:limit=\t"omits blobs by size" \
|
||||
object:type={tag,commit,tree,blob}\t"omit object which are not of the requested type" \
|
||||
sparse:oid=\t"omit blobs not required for a sparse checkout" \
|
||||
tree:\t"omits all blobs and trees"
|
||||
end
|
||||
|
||||
# general options
|
||||
complete git -f -l help -s h -d 'Display manual of a Git command'
|
||||
complete git -f -n __fish_git_needs_command -l version -s v -d 'display git version'
|
||||
@@ -1033,6 +1042,7 @@ complete -f -c git -n '__fish_git_using_command fetch' -l unshallow -d 'Convert
|
||||
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)'
|
||||
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'
|
||||
|
||||
# TODO other options
|
||||
|
||||
@@ -1347,6 +1357,7 @@ complete -f -c git -n '__fish_git_using_command clone' -s o -l origin -d 'Use a
|
||||
complete -f -c git -n '__fish_git_using_command clone' -s b -l branch -d 'Use a specific branch instead of the one used by the cloned repository'
|
||||
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'
|
||||
|
||||
### commit
|
||||
complete -c git -n __fish_git_needs_command -a commit -d 'Record changes to the repository'
|
||||
@@ -1595,6 +1606,7 @@ complete -c git -n '__fish_git_using_command log rev-list' -l bisect
|
||||
complete -c git -n '__fish_git_using_command log rev-list' -l stdin -d 'Read commits from stdin'
|
||||
complete -c git -n '__fish_git_using_command log rev-list' -l cherry-mark -d 'Mark equivalent commits with = and inequivalent with +'
|
||||
complete -c git -n '__fish_git_using_command log rev-list' -l cherry-pick -d 'Omit equivalent commits'
|
||||
complete -f -c git -n '__fish_git_using_command rev-list' -l filter -ra '(__fish_git_filters)' -d 'Omits objects from the list of printed objects'
|
||||
complete -c git -n '__fish_git_using_command log' -l left-only
|
||||
complete -c git -n '__fish_git_using_command log' -l right-only
|
||||
complete -c git -n '__fish_git_using_command log' -l cherry
|
||||
@@ -1798,6 +1810,8 @@ complete -f -c git -n '__fish_git_using_command merge' -l rerere-autoupdate -d '
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l no-rerere-autoupdate -d 'Do not use previous conflict resolutions'
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l abort -d 'Abort the current conflict resolution process'
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l continue -d 'Conclude current conflict resolution process'
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l autostash -d 'Before starting merge, stash local changes, and apply stash when done'
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l no-autostash -d 'Do not stash local changes before starting merge'
|
||||
|
||||
### merge-base
|
||||
complete -f -c git -n __fish_git_needs_command -a merge-base -d 'Find a common ancestor for a merge'
|
||||
@@ -2278,6 +2292,7 @@ complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subco
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from update' -s N -l no-fetch -d "Don't fetch new objects from the remote"
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from update' -l remote -d "Instead of using superproject's SHA-1, use the state of the submodule's remote-tracking branch"
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from update' -l force -d "Discard local changes when switching to a different commit & always run checkout"
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from update' -l filter -ra '(__fish_git_filters)' -d 'Request a subset of objects from server'
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from add' -l force -d "Also add ignored submodule path"
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from deinit' -l force -d "Remove even with local changes"
|
||||
complete -f -c git -n '__fish_git_using_command submodule' -n '__fish_seen_subcommand_from deinit' -l all -d "Remove all submodules"
|
||||
@@ -2569,11 +2584,11 @@ complete -c git -n __fish_git_needs_command -a '(__fish_git_custom_commands)' -d
|
||||
function __fish_git_complete_custom_command -a subcommand
|
||||
set -l cmd (commandline -xpc)
|
||||
set -e cmd[1] # Drop "git".
|
||||
set -lx subcommand_args
|
||||
set -l subcommand_args
|
||||
if argparse -s (__fish_git_global_optspecs) -- $cmd
|
||||
set subcommand_args $argv[2..] # Drop the subcommand.
|
||||
set subcommand_args (string escape -- $argv[2..]) # Drop the subcommand.
|
||||
end
|
||||
complete -C "git-$subcommand \$subcommand_args "(commandline -ct)
|
||||
complete -C "git-$subcommand $subcommand_args "(commandline -ct)
|
||||
end
|
||||
|
||||
# source git-* commands' autocompletion file if exists
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
jj util completion fish | source
|
||||
# The reason for `__this-command-does-not-exist` is that, if dynamic completion
|
||||
# is not implemented, we'd like to get an error reliably. However, the
|
||||
# behavior of `jj` without arguments depends on the value of a config, see
|
||||
# https://jj-vcs.github.io/jj/latest/config/#default-command
|
||||
if set -l completion (COMPLETE=fish jj __this-command-does-not-exist 2>/dev/null)
|
||||
# jj is new enough for dynamic completions to be implemented
|
||||
printf %s\n $completion | source
|
||||
else
|
||||
jj util completion fish | source
|
||||
end
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# Note that when a completion file is sourced a new block scope is created so `set -l` works.
|
||||
set -l __fish_status_all_commands basename current-command current-commandline current-filename current-function current-line-number dirname features filename fish-path function is-block is-breakpoint is-command-substitution is-full-job-control is-interactive is-interactive-job-control is-login is-no-job-control job-control line-number print-stack-trace stack-trace test-feature
|
||||
set -l __fish_status_all_commands \
|
||||
basename \
|
||||
buildinfo \
|
||||
current-command \
|
||||
current-commandline \
|
||||
current-filename \
|
||||
current-function \
|
||||
current-line-number \
|
||||
dirname \
|
||||
features \
|
||||
filename \
|
||||
fish-path \
|
||||
function \
|
||||
is-block \
|
||||
is-breakpoint \
|
||||
is-command-substitution \
|
||||
is-full-job-control \
|
||||
is-interactive \
|
||||
is-interactive-job-control \
|
||||
is-interactive-read \
|
||||
is-login \
|
||||
is-no-job-control \
|
||||
job-control \
|
||||
line-number \
|
||||
print-stack-trace \
|
||||
stack-trace \
|
||||
test-feature
|
||||
|
||||
# These are the recognized flags.
|
||||
complete -c status -s h -l help -d "Display help and exit"
|
||||
@@ -7,6 +33,7 @@ complete -c status -s h -l help -d "Display help and exit"
|
||||
# The "is-something" subcommands.
|
||||
complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-login -d "Test if this is a login shell"
|
||||
complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-interactive -d "Test if this is an interactive shell"
|
||||
complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-interactive-read -d "Test if inside an interactive read builtin"
|
||||
complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-command-substitution -d "Test if a command substitution is currently evaluated"
|
||||
complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-block -d "Test if a code block is currently evaluated"
|
||||
complete -f -c status -n "not __fish_seen_subcommand_from $__fish_status_all_commands" -a is-breakpoint -d "Test if a breakpoint is currently in effect"
|
||||
|
||||
@@ -16,9 +16,18 @@ complete -c systemd-analyze -l to-pattern -d 'dot: show relationships matching r
|
||||
complete -c systemd-analyze -l fuzz -x -d 'critical-chain: also show units which finished timespan earlier than last unit in same level'
|
||||
complete -c systemd-analyze -l man -xa no -d 'Do not invoke man to verify the existence of man pages'
|
||||
complete -c systemd-analyze -l generators -d 'Invoke unit generators'
|
||||
complete -c systemd-analyze -l instance -r -d 'Fallback instance name for template units'
|
||||
complete -c systemd-analyze -l root -xa "(__fish_complete_directories)" -d 'With cat-files, show config files underneath the specified root path'
|
||||
complete -c systemd-analyze -l image -r -d 'With cat-files, show config files inside the specified image path'
|
||||
complete -c systemd-analyze -l image-policy -d 'Disk image dissection policy'
|
||||
complete -c systemd-analyze -l iterations -x -d 'calendar: show number of iterations the calendar expression will elapse next'
|
||||
complete -c systemd-analyze -l base-time -x -d 'calendar: show next iterations relative to the specified point in time'
|
||||
complete -c systemd-analyze -l tldr -d 'cat-config: skip comments, empty lines and section headers'
|
||||
complete -c systemd-analyze -l unit -r -d "condition: evaluate Condition and Assert assignments in unit file"
|
||||
complete -c systemd-analyze -l table -d 'plot: output raw time data in a table'
|
||||
complete -c systemd-analyze -l no-legend -d 'plot: exclude legends/hints'
|
||||
complete -c systemd-analyze -l detailed -d "plot: show activation timestamps details in SVG plot"
|
||||
complete -c systemd-analyze -l scale-svg -r -d "plot: stretch the x-axis of the plot"
|
||||
complete -c systemd-analyze -s H -l host -xa "(__fish_complete_user_at_hosts)" -d 'Execute the operation on a remote host'
|
||||
complete -c systemd-analyze -s M -l machine -xa "(__fish_systemd_machines)" -d 'Execute operation on a VM or container'
|
||||
complete -c systemd-analyze -s h -l help -d 'Print a short help and exit'
|
||||
@@ -34,6 +43,7 @@ complete -c systemd-analyze -n __fish_use_subcommand -a critical-chain -d "Print
|
||||
complete -c systemd-analyze -n "__fish_seen_subcommand_from critical-chain" -a "(__fish_systemd_units)"
|
||||
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a dump -d "Output serialization of server state"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a malloc -d "Output internal memory state of D-Bus service"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a plot -d "Output SVG graphic showing service initialization"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a dot -d "Output dependency graph in dot(1) format"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a unit-paths -d "List all directories from which unit files may be loaded"
|
||||
@@ -41,15 +51,25 @@ complete -c systemd-analyze -n __fish_use_subcommand -a exit-status -d "List exi
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a capability -d "List Linux capabilities along with their numeric IDs"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a condition -d "Evaluate Condition and Assert assignments"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a syscall-filter -d "List system calls contained in the specified system call set"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a filesystems -d "List filesystems"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a calendar -d "Normalize repetitive calendar events and calculate when they elapse next"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a timestamp -d "Parse timestamp and output the normalized form"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a timestamp -d "Parse time span and output the normalized form"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a timespan -d "Parse time span and output the normalized form"
|
||||
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a cat-config -d "Show contents of a config file"
|
||||
complete -c systemd-analyze -n "__fish_seen_subcommand_from cat-config" -F
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a compare-versions -d "Compare two version strings"
|
||||
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a verify -d "Check unit files for correctness"
|
||||
complete -c systemd-analyze -n "__fish_seen_subcommand_from verify" -F
|
||||
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a security -d "Analyze security settings of specified service units"
|
||||
complete -c systemd-analyze -n "__fish_seen_subcommand_from security" -a "(__fish_systemctl_services)"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a inspect-elf -d "Parse and print ELF object packaging metadata"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a fdstore -d "List contents of service unit's file descriptor store"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a image-policy -d "Analyze image policy string"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a has-tpm2 -d "Report TPM2 support"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a pcrs -d "Show known TPM2 PCRs"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a srk -d "Read Storage Root Key from TPM2 device"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a architectures -d "List known CPU architectures"
|
||||
complete -c systemd-analyze -n __fish_use_subcommand -a smbios11 -d "Show SMBIOS Type #11 strings passed to the system"
|
||||
|
||||
@@ -325,7 +325,6 @@ function __fish_wine__complete_winepath_subcommand --argument-names command
|
||||
end
|
||||
|
||||
set -l command wine
|
||||
complete -c $command -f
|
||||
|
||||
complete -c $command -l help -d 'Show help'
|
||||
complete -c $command -l version -d 'Show version'
|
||||
|
||||
58
share/completions/wlr-randr.fish
Normal file
58
share/completions/wlr-randr.fish
Normal file
@@ -0,0 +1,58 @@
|
||||
# `wlr-randr` completions.
|
||||
# See: https://gitlab.freedesktop.org/emersion/wlr-randr
|
||||
|
||||
function __fish_print_wlr-randr_outputs --argument-names exclude
|
||||
if command -q jq
|
||||
wlr-randr --json | jq \
|
||||
--raw-output \
|
||||
--arg exclude "$exclude" \
|
||||
'.[] | select(.name != $exclude) | "\(.name)\t\(.make), \(.model)"'
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_get_wlr-randr-current_output
|
||||
set -l last_output
|
||||
set -l tokens (commandline -xpc)
|
||||
|
||||
while set -q tokens[1]
|
||||
if test "$tokens[1]" = --output
|
||||
set last_output "$tokens[2]"
|
||||
set -e tokens[1]
|
||||
else if string match -qr -- '^--output=' "$tokens[1]"
|
||||
set last_output (string replace -r -- '--output=(.*)' '$1' "$tokens[1]")
|
||||
end
|
||||
|
||||
set -e tokens[1]
|
||||
end
|
||||
|
||||
printf "%s" $last_output
|
||||
end
|
||||
|
||||
function __fish_complete_wlr-randr_modes
|
||||
if command -q jq
|
||||
set -l output (__fish_get_wlr-randr-current_output)
|
||||
|
||||
wlr-randr --json | jq \
|
||||
--raw-output \
|
||||
--arg output "$output" \
|
||||
--arg preferred_str Preferred \
|
||||
--arg empty_str '' \
|
||||
'.[] | select(.name == $output) | .modes[] | "\(.width)x\(.height)\t\(if .preferred then $preferred_str else $empty_str end)"'
|
||||
end
|
||||
end
|
||||
|
||||
complete -c wlr-randr -f
|
||||
complete -c wlr-randr -s h -l help -d 'Show help'
|
||||
complete -c wlr-randr -l json -d 'Print as JSON'
|
||||
complete -c wlr-randr -l dryrun -d 'Dry run'
|
||||
complete -c wlr-randr -l output -x -d Output -a '(__fish_print_wlr-randr_outputs)'
|
||||
complete -c wlr-randr -l on -d 'Turn on'
|
||||
complete -c wlr-randr -l off -d 'Turn off'
|
||||
complete -c wlr-randr -l mode -x -d Mode -a '(__fish_complete_wlr-randr_modes)'
|
||||
complete -c wlr-randr -l pos -r -d Position
|
||||
complete -c wlr-randr -l left-of -x -d 'Relative left position' -a '(__fish_print_wlr-randr_outputs (__fish_get_wlr-randr-current_output))'
|
||||
complete -c wlr-randr -l right-of -x -d 'Relative right position' -a '(__fish_print_wlr-randr_outputs (__fish_get_wlr-randr-current_output))'
|
||||
complete -c wlr-randr -l above -x -d 'Relative top position' -a '(__fish_print_wlr-randr_outputs (__fish_get_wlr-randr-current_output))'
|
||||
complete -c wlr-randr -l below -x -d 'Relative bottom position' -a '(__fish_print_wlr-randr_outputs (__fish_get_wlr-randr-current_output))'
|
||||
complete -c wlr-randr -l transform -x -d Transformation -a 'normal\t 90\t 180\t 270\t flipped\t flipped-90\t flipped-180\t flipped-270\t'
|
||||
complete -c wlr-randr -l scale -x -d Scale
|
||||
@@ -166,13 +166,11 @@ if status --is-login
|
||||
|
||||
# Populate path according to config files
|
||||
for path_file in $argv[2] $argv[3]/*
|
||||
if test -f $path_file
|
||||
while read -l entry
|
||||
if not contains -- $entry $result
|
||||
test -n "$entry"
|
||||
and set -a result $entry
|
||||
end
|
||||
end <$path_file
|
||||
for entry in (string split : <? $path_file)
|
||||
if not contains -- $entry $result
|
||||
test -n "$entry"
|
||||
and set -a result $entry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ if test $status -eq 0 -a (count $sysver) -eq 3
|
||||
|
||||
if test $age -ge $max_age
|
||||
test -d "$dir" || mkdir -m 700 -p $dir
|
||||
/usr/libexec/makewhatis -o "$whatis" (/usr/bin/manpath | string split : | xargs realpath) >/dev/null 2>&1 </dev/null &
|
||||
disown $last_pid
|
||||
/bin/sh -c '( "$@" ) >/dev/null 2>&1 </dev/null &' -- /usr/libexec/makewhatis -o "$whatis" (/usr/bin/manpath | string split : | xargs realpath)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
@@ -99,9 +99,8 @@ end" >$__fish_config_dir/config.fish
|
||||
set -l update_args -B $__fish_data_dir/tools/create_manpage_completions.py --manpath --cleanup-in $__fish_user_data_dir/generated_completions --cleanup-in $__fish_cache_dir/generated_completions
|
||||
if set -l python (__fish_anypython)
|
||||
# Run python directly in the background and swallow all output
|
||||
$python $update_args >/dev/null 2>&1 &
|
||||
# Then disown the job so that it continues to run in case of an early exit (#6269)
|
||||
disown >/dev/null 2>&1
|
||||
# Orphan the job so that it continues to run in case of an early exit (#6269)
|
||||
/bin/sh -c '( "$@" ) >/dev/null 2>&1 &' -- $python $update_args
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -221,7 +220,11 @@ end" >$__fish_config_dir/config.fish
|
||||
|
||||
# Notify terminals when $PWD changes via OSC 7 (issue #906).
|
||||
function __fish_update_cwd_osc --on-variable PWD --description 'Notify terminals when $PWD changes'
|
||||
printf \e\]7\;file://%s%s\a $hostname (string escape --style=url -- $PWD)
|
||||
set -l host $hostname
|
||||
if set -q KONSOLE_VERSION
|
||||
set host ''
|
||||
end
|
||||
printf \e\]7\;file://%s%s\a $host (string escape --style=url -- $PWD)
|
||||
end
|
||||
__fish_update_cwd_osc # Run once because we might have already inherited a PWD from an old tab
|
||||
|
||||
|
||||
@@ -56,9 +56,13 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod
|
||||
|
||||
bind --preset $argv alt-right nextd-or-forward-word
|
||||
bind --preset $argv alt-left prevd-or-backward-word
|
||||
$legacy_bind --preset $argv \e\[1\;9C nextd-or-forward-word # iTerm2 < 3.5.12
|
||||
$legacy_bind --preset $argv \e\[1\;9D prevd-or-backward-word # iTerm2 < 3.5.12
|
||||
|
||||
bind --preset $argv alt-up history-token-search-backward
|
||||
bind --preset $argv alt-down history-token-search-forward
|
||||
$legacy_bind --preset $argv \e\[1\;9A history-token-search-backward # iTerm2 < 3.5.12
|
||||
$legacy_bind --preset $argv \e\[1\;9B history-token-search-forward # iTerm2 < 3.5.12
|
||||
# Bash compatibility
|
||||
# https://github.com/fish-shell/fish-shell/issues/89
|
||||
bind --preset $argv alt-. history-token-search-backward
|
||||
@@ -116,7 +120,7 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod
|
||||
bind --preset $argv alt-enter "commandline -i \n" expand-abbr
|
||||
bind --preset $argv ")" self-insert expand-abbr # Closing a command substitution.
|
||||
bind --preset $argv ctrl-space 'test -n "$(commandline)" && commandline -i " "'
|
||||
bind --preset $argv -k nul 'test -n "$(commandline)" && commandline -i " "'
|
||||
$legacy_bind --preset $argv -k nul 'test -n "$(commandline)" && commandline -i " "'
|
||||
# Shift-space behaves like space because it's easy to mistype.
|
||||
bind --preset $argv shift-space 'commandline -i " "' expand-abbr
|
||||
|
||||
|
||||
@@ -180,8 +180,7 @@ if string match -q Darwin -- (uname) && string match -q /usr/bin/git -- (command
|
||||
else
|
||||
# git is installed, but on the first run it may be very slow as xcrun needs to populate the cache.
|
||||
# Kick it off in the background to populate the cache.
|
||||
/bin/sh -c '/usr/bin/git --version; touch /tmp/__fish_git_ready' &>/dev/null &
|
||||
disown $last_pid &>/dev/null
|
||||
/bin/sh -c '( /usr/bin/git --version; touch /tmp/__fish_git_ready ) >/dev/null 2>&1 &'
|
||||
function __fish_git_prompt_ready
|
||||
path is /tmp/__fish_git_ready || return 1
|
||||
# git is ready, erase the function.
|
||||
|
||||
@@ -7,16 +7,16 @@ function fish_print_hg_root
|
||||
# Find an hg directory above $PWD
|
||||
# without calling `hg root` because that's too slow
|
||||
set -l root
|
||||
set -l dir (pwd -P 2>/dev/null)
|
||||
set -l dir "$(pwd -P 2>/dev/null)"
|
||||
or return 1
|
||||
|
||||
while test $dir != /
|
||||
while not contains -- "$dir" "" / .
|
||||
if test -f $dir'/.hg/dirstate'
|
||||
echo $dir/.hg
|
||||
return 0
|
||||
end
|
||||
# Go up one directory
|
||||
set dir (string replace -r '[^/]*/?$' '' $dir)
|
||||
set dir (path dirname -- $dir)
|
||||
end
|
||||
|
||||
return 1
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
function fish_vi_cursor -d 'Set cursor shape for different vi modes'
|
||||
# if stdin is not a tty, there is effectively no bind mode.
|
||||
if not test -t 0
|
||||
return
|
||||
end
|
||||
|
||||
set -q fish_cursor_unknown
|
||||
or set -g fish_cursor_unknown block
|
||||
|
||||
function __fish_vi_cursor --argument-names varname
|
||||
if not status is-interactive; and not status is-interactive-read
|
||||
return
|
||||
end
|
||||
if not set -q $varname
|
||||
switch $varname
|
||||
case fish_cursor_insert
|
||||
|
||||
@@ -109,18 +109,24 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||
bind -s --preset -M insert ctrl-n accept-autosuggestion
|
||||
|
||||
# Vi/Vim doesn't support these keys in insert mode but that seems silly so we do so anyway.
|
||||
bind -s --preset -M insert -k home beginning-of-line
|
||||
bind -s --preset -M default -k home beginning-of-line
|
||||
bind -s --preset -M insert -k end end-of-line
|
||||
bind -s --preset -M default -k end end-of-line
|
||||
bind -s --preset -M insert home beginning-of-line
|
||||
$legacy_bind -s --preset -M insert -k home beginning-of-line
|
||||
bind -s --preset -M default home beginning-of-line
|
||||
$legacy_bind -s --preset -M default -k home beginning-of-line
|
||||
bind -s --preset -M insert end end-of-line
|
||||
$legacy_bind -s --preset -M insert -k end end-of-line
|
||||
bind -s --preset -M default end end-of-line
|
||||
$legacy_bind -s --preset -M default -k end end-of-line
|
||||
|
||||
# Vi moves the cursor back if, after deleting, it is at EOL.
|
||||
# To emulate that, move forward, then backward, which will be a NOP
|
||||
# if there is something to move forward to.
|
||||
bind -s --preset -M default x delete-char 'set fish_cursor_end_mode exclusive' forward-single-char backward-char 'set fish_cursor_end_mode inclusive'
|
||||
bind -s --preset -M default X backward-delete-char
|
||||
bind -s --preset -M insert -k dc delete-char forward-single-char backward-char
|
||||
bind -s --preset -M default -k dc delete-char 'set fish_cursor_end_mode exclusive' forward-single-char backward-char 'set fish_cursor_end_mode inclusive'
|
||||
bind -s --preset -M insert delete delete-char forward-single-char backward-char
|
||||
$legacy_bind -s --preset -M insert -k dc delete-char forward-single-char backward-char
|
||||
bind -s --preset -M default delete delete-char 'set fish_cursor_end_mode exclusive' forward-single-char backward-char 'set fish_cursor_end_mode inclusive'
|
||||
$legacy_bind -s --preset -M default -k dc delete-char 'set fish_cursor_end_mode exclusive' forward-single-char backward-char 'set fish_cursor_end_mode inclusive'
|
||||
|
||||
# Backspace deletes a char in insert mode, but not in normal/default mode.
|
||||
bind -s --preset -M insert backspace backward-delete-char
|
||||
|
||||
@@ -239,8 +239,7 @@ function help --description 'Show help for the fish shell'
|
||||
# The space before the /c is to prevent msys2 from expanding it to a path
|
||||
$fish_browser " /c" start $page_url
|
||||
else if contains -- $fish_browser[1] $graphical_browsers
|
||||
$fish_browser $page_url &
|
||||
disown $last_pid >/dev/null 2>&1
|
||||
/bin/sh -c '( "$@" ) &' -- $fish_browser $page_url
|
||||
else
|
||||
$fish_browser $page_url
|
||||
end
|
||||
|
||||
@@ -5,18 +5,17 @@ function fish_prompt -d "Write out the prompt"
|
||||
set -l laststatus $status
|
||||
|
||||
set -l git_info
|
||||
if set -l git_branch (command git branch --format=%\(refname:lstrip=2\) 2> /dev/null)
|
||||
if git rev-parse 2>/dev/null
|
||||
set -l git_branch (
|
||||
command git symbolic-ref HEAD 2>/dev/null | string replace 'refs/heads/' ''
|
||||
or command git describe HEAD 2>/dev/null
|
||||
or echo unknown
|
||||
)
|
||||
set git_branch (set_color -o blue)"$git_branch"
|
||||
set -l git_status
|
||||
if test -n "$git_branch"; and not command git diff-index --quiet HEAD --
|
||||
if set -l count (command git rev-list --count --left-right $upstream...HEAD 2>/dev/null)
|
||||
echo $count | read -l ahead behind
|
||||
if test "$ahead" -gt 0
|
||||
set git_status "$git_status"(set_color red)⬆
|
||||
end
|
||||
if test "$behind" -gt 0
|
||||
set git_status "$git_status"(set_color red)⬇
|
||||
end
|
||||
end
|
||||
if git rev-parse --quiet --verify HEAD >/dev/null
|
||||
and not command git diff-index --quiet HEAD --
|
||||
|
||||
for i in (git status --porcelain | string sub -l 2 | sort | uniq)
|
||||
switch $i
|
||||
case "."
|
||||
@@ -35,11 +34,8 @@ function fish_prompt -d "Write out the prompt"
|
||||
end
|
||||
else
|
||||
set git_status (set_color green):
|
||||
if test -z "$git_branch"
|
||||
set git_branch -
|
||||
end
|
||||
end
|
||||
set git_info "(git$git_status"(set_color -o blue)"$git_branch"(set_color white)")"
|
||||
set git_info "(git$git_status$git_branch"(set_color white)")"
|
||||
end
|
||||
|
||||
# Disable PWD shortening by default.
|
||||
|
||||
@@ -55,6 +55,7 @@ enum TokenMode {
|
||||
/// \param buff the original command line buffer
|
||||
/// \param cursor_pos the position of the cursor in the command line
|
||||
fn replace_part(
|
||||
parser: &Parser,
|
||||
range: Range<usize>,
|
||||
insert: &wstr,
|
||||
insert_mode: AppendMode,
|
||||
@@ -86,9 +87,9 @@ fn replace_part(
|
||||
|
||||
out.push_utfstr(&buff[range.end..]);
|
||||
if search_field_mode {
|
||||
commandline_set_search_field(out, Some(out_pos));
|
||||
commandline_set_search_field(parser, out, Some(out_pos));
|
||||
} else {
|
||||
commandline_set_buffer(Some(out), Some(out_pos));
|
||||
commandline_set_buffer(parser, Some(out), Some(out_pos));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +466,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
}
|
||||
line_offset + new_coord
|
||||
};
|
||||
commandline_set_buffer(None, Some(new_pos));
|
||||
commandline_set_buffer(parser, None, Some(new_pos));
|
||||
} else {
|
||||
streams.out.append(sprintf!(
|
||||
"%d\n",
|
||||
@@ -631,7 +632,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
.saturating_add_signed(isize::try_from(new_pos).unwrap()),
|
||||
current_buffer.len(),
|
||||
);
|
||||
commandline_set_buffer(None, Some(new_pos));
|
||||
commandline_set_buffer(parser, None, Some(new_pos));
|
||||
} else {
|
||||
streams
|
||||
.out
|
||||
@@ -652,6 +653,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
);
|
||||
} else if positional_args == 1 {
|
||||
replace_part(
|
||||
parser,
|
||||
range,
|
||||
args[w.wopt_index],
|
||||
append_mode,
|
||||
@@ -662,6 +664,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
} else {
|
||||
let sb = join_strings(&w.argv[w.wopt_index..], '\n');
|
||||
replace_part(
|
||||
parser,
|
||||
range,
|
||||
&sb,
|
||||
append_mode,
|
||||
|
||||
@@ -517,7 +517,8 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
|
||||
next.flags,
|
||||
faux_cmdline,
|
||||
&mut tmp_cursor,
|
||||
false,
|
||||
/*append_only=*/ false,
|
||||
/*is_unique=*/ false,
|
||||
);
|
||||
|
||||
// completion_apply_to_command_line will append a space unless COMPLETE_NO_SPACE
|
||||
|
||||
@@ -92,6 +92,14 @@ fn parse_cmd_opts(
|
||||
// A positional argument we got because we use RETURN_IN_ORDER.
|
||||
let woptarg = w.woptarg.unwrap().to_owned();
|
||||
if handling_named_arguments {
|
||||
if is_read_only(&woptarg) {
|
||||
streams.err.append(wgettext_fmt!(
|
||||
"%ls: variable '%ls' is read-only\n",
|
||||
cmd,
|
||||
woptarg
|
||||
));
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
opts.named_arguments.push(woptarg);
|
||||
} else {
|
||||
streams.err.append(wgettext_fmt!(
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
use crate::env::Environment;
|
||||
use crate::env::READ_BYTE_LIMIT;
|
||||
use crate::env::{EnvVar, EnvVarFlags};
|
||||
use crate::input_common::decode_input_byte;
|
||||
use crate::input_common::terminal_protocols_disable_ifn;
|
||||
use crate::libc::MB_CUR_MAX;
|
||||
use crate::input_common::DecodeState;
|
||||
use crate::nix::isatty;
|
||||
use crate::reader::commandline_set_buffer;
|
||||
use crate::reader::ReaderConfig;
|
||||
@@ -23,7 +24,6 @@
|
||||
use crate::wcstringutil::split_about;
|
||||
use crate::wcstringutil::split_string_tok;
|
||||
use crate::wutil;
|
||||
use crate::wutil::encoding::mbrtowc;
|
||||
use crate::wutil::encoding::zero_mbstate;
|
||||
use crate::wutil::perror;
|
||||
use libc::SEEK_CUR;
|
||||
@@ -234,7 +234,11 @@ fn read_interactive(
|
||||
|
||||
// Keep in-memory history only.
|
||||
reader_push(parser, L!(""), conf);
|
||||
commandline_set_buffer(Some(commandline.to_owned()), None);
|
||||
let _modifiable_commandline = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().readonly_commandline, new_value),
|
||||
false,
|
||||
);
|
||||
commandline_set_buffer(parser, Some(commandline.to_owned()), None);
|
||||
|
||||
let mline = {
|
||||
let _interactive = scoped_push_replacer(
|
||||
@@ -337,70 +341,61 @@ fn read_one_char_at_a_time(
|
||||
split_null: bool,
|
||||
) -> Option<c_int> {
|
||||
let mut exit_res = STATUS_CMD_OK;
|
||||
let mut eof = false;
|
||||
let mut nbytes = 0;
|
||||
|
||||
let mut unconsumed = vec![];
|
||||
|
||||
loop {
|
||||
let mut finished = false;
|
||||
let mut res = '\x00';
|
||||
let mut state = zero_mbstate();
|
||||
|
||||
while !finished {
|
||||
let chars_read = buff.len();
|
||||
let res = loop {
|
||||
let mut b = [0_u8; 1];
|
||||
match read_blocked(fd, &mut b) {
|
||||
Ok(0) | Err(_) => {
|
||||
eof = true;
|
||||
break;
|
||||
break None;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let b = b[0];
|
||||
|
||||
unconsumed.push(b);
|
||||
nbytes += 1;
|
||||
if MB_CUR_MAX() == 1 {
|
||||
res = char::from(b);
|
||||
finished = true;
|
||||
} else {
|
||||
let sz = unsafe {
|
||||
mbrtowc(
|
||||
std::ptr::addr_of_mut!(res).cast(),
|
||||
std::ptr::addr_of!(b).cast(),
|
||||
1,
|
||||
&mut state,
|
||||
)
|
||||
} as isize;
|
||||
if sz == -1 {
|
||||
let mut consumed = 0;
|
||||
match decode_input_byte(buff, &mut state, &unconsumed, &mut consumed) {
|
||||
DecodeState::Incomplete => continue,
|
||||
DecodeState::Complete => {
|
||||
unconsumed.clear();
|
||||
break Some(buff.as_char_slice().last().unwrap());
|
||||
}
|
||||
DecodeState::Error => {
|
||||
state = zero_mbstate();
|
||||
} else if sz != -2 {
|
||||
finished = true;
|
||||
unconsumed.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if nbytes > READ_BYTE_LIMIT.load(Ordering::Relaxed) {
|
||||
// Historical behavior: do not include the codepoint that made us overflow.
|
||||
buff.truncate(chars_read);
|
||||
exit_res = STATUS_READ_TOO_MUCH;
|
||||
break;
|
||||
}
|
||||
if eof {
|
||||
let Some(&res) = res else {
|
||||
// EOF
|
||||
if buff.is_empty() {
|
||||
exit_res = STATUS_CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
};
|
||||
if res == if split_null { '\0' } else { '\n' } {
|
||||
buff.pop();
|
||||
break;
|
||||
}
|
||||
if !split_null && res == '\n' {
|
||||
break;
|
||||
}
|
||||
if split_null && res == '\0' {
|
||||
break;
|
||||
}
|
||||
|
||||
buff.push(res);
|
||||
if nchars > 0 && nchars <= buff.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if buff.is_empty() && eof {
|
||||
exit_res = STATUS_CMD_ERROR;
|
||||
}
|
||||
|
||||
exit_res
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
use crate::proc::{
|
||||
get_job_control_mode, get_login, is_interactive_session, set_job_control_mode, JobControl,
|
||||
};
|
||||
use crate::reader::reader_in_interactive_read;
|
||||
use crate::wutil::{waccess, wbasename, wdirname, wrealpath, Error};
|
||||
use libc::F_OK;
|
||||
use nix::errno::Errno;
|
||||
@@ -50,6 +51,7 @@ enum StatusCmd {
|
||||
STATUS_IS_FULL_JOB_CTRL,
|
||||
STATUS_IS_INTERACTIVE,
|
||||
STATUS_IS_INTERACTIVE_JOB_CTRL,
|
||||
STATUS_IS_INTERACTIVE_READ,
|
||||
STATUS_IS_LOGIN,
|
||||
STATUS_IS_NO_JOB_CTRL,
|
||||
STATUS_LINE_NUMBER,
|
||||
@@ -82,6 +84,7 @@ enum StatusCmd {
|
||||
(STATUS_IS_FULL_JOB_CTRL, "is-full-job-control"),
|
||||
(STATUS_IS_INTERACTIVE, "is-interactive"),
|
||||
(STATUS_IS_INTERACTIVE_JOB_CTRL, "is-interactive-job-control"),
|
||||
(STATUS_IS_INTERACTIVE_READ, "is-interactive-read"),
|
||||
(STATUS_IS_LOGIN, "is-login"),
|
||||
(STATUS_IS_NO_JOB_CTRL, "is-no-job-control"),
|
||||
(STATUS_SET_JOB_CONTROL, "job-control"),
|
||||
@@ -141,6 +144,7 @@ fn default() -> Self {
|
||||
const IS_FULL_JOB_CTRL_SHORT: char = '\x02';
|
||||
const IS_INTERACTIVE_JOB_CTRL_SHORT: char = '\x03';
|
||||
const IS_NO_JOB_CTRL_SHORT: char = '\x04';
|
||||
const IS_INTERACTIVE_READ_SHORT: char = '\x05';
|
||||
|
||||
const SHORT_OPTIONS: &wstr = L!(":L:cbilfnhj:t");
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
@@ -162,6 +166,11 @@ fn default() -> Self {
|
||||
NoArgument,
|
||||
IS_INTERACTIVE_JOB_CTRL_SHORT,
|
||||
),
|
||||
wopt(
|
||||
L!("is-interactive-read"),
|
||||
NoArgument,
|
||||
IS_INTERACTIVE_READ_SHORT,
|
||||
),
|
||||
wopt(L!("is-login"), NoArgument, 'l'),
|
||||
wopt(L!("is-no-job-control"), NoArgument, IS_NO_JOB_CTRL_SHORT),
|
||||
wopt(L!("job-control"), RequiredArgument, 'j'),
|
||||
@@ -271,6 +280,11 @@ fn parse_cmd_opts(
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
IS_INTERACTIVE_READ_SHORT => {
|
||||
if !opts.try_set_status_cmd(STATUS_IS_INTERACTIVE_READ, streams) {
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
IS_NO_JOB_CTRL_SHORT => {
|
||||
if !opts.try_set_status_cmd(STATUS_IS_NO_JOB_CTRL, streams) {
|
||||
return STATUS_CMD_ERROR;
|
||||
@@ -548,6 +562,13 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> O
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
STATUS_IS_INTERACTIVE_READ => {
|
||||
if reader_in_interactive_read() {
|
||||
return STATUS_CMD_OK;
|
||||
} else {
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
STATUS_IS_NO_JOB_CTRL => {
|
||||
if get_job_control_mode() == JobControl::none {
|
||||
return STATUS_CMD_OK;
|
||||
|
||||
@@ -684,10 +684,11 @@ fn parse_4_arg_expression(
|
||||
|
||||
if let Token::UnaryBoolean(token) = first_token {
|
||||
let subject = self.parse_3_arg_expression(start + 1, end)?;
|
||||
let range = start..subject.range().end;
|
||||
UnaryOperator {
|
||||
subject,
|
||||
token,
|
||||
range: start..end,
|
||||
range,
|
||||
}
|
||||
.into_some_box()
|
||||
} else if first_token == Token::ParenOpen {
|
||||
|
||||
@@ -103,6 +103,12 @@ fn test_test() {
|
||||
assert!(run_test_test(1, &["!", "15", "-ge", "10"]));
|
||||
assert!(run_test_test(0, &["!", "!", "15", "-ge", "10"]));
|
||||
|
||||
assert!(run_test_test(0, &[
|
||||
"(", "-d", "/", ")",
|
||||
"-o",
|
||||
"(", "!", "-d", "/", ")",
|
||||
]));
|
||||
|
||||
assert!(run_test_test(0, &["0", "-ne", "1", "-a", "0", "-eq", "0"]));
|
||||
assert!(run_test_test(0, &["0", "-ne", "1", "-a", "-n", "5"]));
|
||||
assert!(run_test_test(0, &["-n", "5", "-a", "10", "-gt", "5"]));
|
||||
|
||||
@@ -554,19 +554,16 @@ fn init_curses(vars: &EnvStack) {
|
||||
if curses::setup(None, |term| apply_term_hacks(vars, term)).is_none() {
|
||||
if is_interactive_session() {
|
||||
let term = vars.get_unless_empty(L!("TERM")).map(|v| v.as_string());
|
||||
// We do not warn for xterm-256color at all, we know that one.
|
||||
if term != Some("xterm-256color".into()) {
|
||||
if let Some(term) = term {
|
||||
FLOG!(
|
||||
warning,
|
||||
wgettext_fmt!("Could not set up terminal for $TERM '%ls'. Falling back to hardcoded xterm-256color values", term)
|
||||
);
|
||||
} else {
|
||||
FLOG!(
|
||||
warning,
|
||||
wgettext!("Could not set up terminal because $TERM is unset. Falling back to hardcoded xterm-256color values")
|
||||
);
|
||||
}
|
||||
if let Some(term) = term {
|
||||
FLOG!(
|
||||
term_support,
|
||||
wgettext_fmt!("Could not set up terminal for $TERM '%ls'. Falling back to hardcoded xterm-256color values", term)
|
||||
);
|
||||
} else {
|
||||
FLOG!(
|
||||
term_support,
|
||||
wgettext!("Could not set up terminal because $TERM is unset. Falling back to hardcoded xterm-256color values")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,9 @@ fn extract_prefix_and_unescape_yaml(line: &[u8]) -> Option<(Cow<[u8]>, Cow<[u8]>
|
||||
fn decode_item_fish_2_0(mut data: &[u8]) -> Option<HistoryItem> {
|
||||
let (advance, line) = read_line(data);
|
||||
let line = trim_start(line);
|
||||
assert!(line.starts_with(b"- cmd"));
|
||||
if !line.starts_with(b"- cmd") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (_key, value) = extract_prefix_and_unescape_yaml(line)?;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
use crate::wutil::encoding::{mbrtowc, mbstate_t, zero_mbstate};
|
||||
use crate::wutil::fish_wcstol;
|
||||
use std::collections::VecDeque;
|
||||
use std::ops::ControlFlow;
|
||||
use std::os::fd::RawFd;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::ptr;
|
||||
@@ -332,7 +331,7 @@ fn readb(in_fd: RawFd, blocking: bool) -> ReadbResult {
|
||||
let select_res = fdset.check_readable(if blocking {
|
||||
FdReadableSet::kNoTimeout
|
||||
} else {
|
||||
0
|
||||
1000
|
||||
});
|
||||
if select_res < 0 {
|
||||
let err = errno::errno().0;
|
||||
@@ -437,6 +436,7 @@ pub fn update_wait_on_sequence_key_ms(vars: &EnvStack) {
|
||||
static IN_ITERM_PRE_CSI_U: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
static IN_JETBRAINS: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
static IN_KITTY: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
static IN_WEZTERM: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
||||
|
||||
pub fn terminal_protocol_hacks() {
|
||||
use std::env::var_os;
|
||||
@@ -457,6 +457,10 @@ pub fn terminal_protocol_hacks() {
|
||||
);
|
||||
IN_KITTY
|
||||
.store(var_os("TERM").is_some_and(|term| term.as_os_str().as_bytes() == b"xterm-kitty"));
|
||||
IN_WEZTERM.store(
|
||||
var_os("TERM_PROGRAM")
|
||||
.is_some_and(|term_program| term_program.as_os_str().as_bytes() == b"WezTerm"),
|
||||
);
|
||||
}
|
||||
|
||||
fn parse_version(version: &wstr) -> Option<(i64, i64, i64)> {
|
||||
@@ -487,12 +491,11 @@ pub fn terminal_protocols_enable_ifn() {
|
||||
|| IN_MIDNIGHT_COMMANDER_PRE_CSI_U.load()
|
||||
{
|
||||
"\x1b[?2004h"
|
||||
} else if IN_ITERM_PRE_CSI_U.load() {
|
||||
concat!("\x1b[?2004h", "\x1b[>4;1m", "\x1b[>5u", "\x1b=",)
|
||||
} else if IN_JETBRAINS.load() {
|
||||
} else if IN_JETBRAINS.load() || IN_ITERM_PRE_CSI_U.load() {
|
||||
// Jetbrains IDE terminals vomit CSI u
|
||||
// iTerm fails to option-modify keys
|
||||
concat!("\x1b[?2004h", "\x1b[>4;1m", "\x1b=",)
|
||||
} else if IN_KITTY.load() {
|
||||
} else if IN_KITTY.load() || IN_WEZTERM.load() {
|
||||
// Kitty spams the log for modifyotherkeys
|
||||
concat!(
|
||||
"\x1b[?2004h", // Bracketed paste
|
||||
@@ -521,11 +524,11 @@ pub(crate) fn terminal_protocols_disable_ifn() {
|
||||
}
|
||||
let sequences = if !feature_test(FeatureFlag::keyboard_protocols) {
|
||||
"\x1b[?2004l"
|
||||
} else if IN_ITERM_PRE_CSI_U.load() {
|
||||
concat!("\x1b[?2004l", "\x1b[>4;0m", "\x1b[<1u", "\x1b>",)
|
||||
} else if IN_JETBRAINS.load() || IN_ITERM_PRE_CSI_U.load() {
|
||||
concat!("\x1b[?2004l", "\x1b[>4;0m", "\x1b>",)
|
||||
} else if IN_JETBRAINS.load() {
|
||||
concat!("\x1b[?2004l", "\x1b[>4;0m", "\x1b>",)
|
||||
} else if IN_KITTY.load() {
|
||||
} else if IN_KITTY.load() || IN_WEZTERM.load() {
|
||||
// Kitty spams the log for modifyotherkeys
|
||||
concat!(
|
||||
"\x1b[?2004l", // Bracketed paste
|
||||
@@ -559,6 +562,7 @@ fn parse_mask(mask: u32) -> Modifiers {
|
||||
ctrl: (mask & 4) != 0,
|
||||
alt: (mask & 2) != 0,
|
||||
shift: (mask & 1) != 0,
|
||||
sup: (mask & 8) != 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,21 +701,25 @@ fn try_readch(&mut self, blocking: bool) -> Option<CharEvent> {
|
||||
_ => 0,
|
||||
});
|
||||
}
|
||||
match self.parse_codepoint(
|
||||
&mut state,
|
||||
&mut key,
|
||||
match decode_input_byte(
|
||||
&mut seq,
|
||||
&buffer,
|
||||
i,
|
||||
&mut state,
|
||||
&buffer[..i + 1],
|
||||
&mut consumed,
|
||||
&mut have_escape_prefix,
|
||||
) {
|
||||
ControlFlow::Continue(codepoint_complete) => {
|
||||
if codepoint_complete && i + 1 == buffer.len() {
|
||||
DecodeState::Incomplete => (),
|
||||
DecodeState::Complete => {
|
||||
if have_escape_prefix && i != 0 {
|
||||
have_escape_prefix = false;
|
||||
let c = seq.as_char_slice().last().unwrap();
|
||||
key = Some(Key::from(alt(*c)));
|
||||
}
|
||||
if i + 1 == buffer.len() {
|
||||
break true;
|
||||
}
|
||||
}
|
||||
ControlFlow::Break(()) => {
|
||||
DecodeState::Error => {
|
||||
self.push_front(CharEvent::from_check_exit());
|
||||
break false;
|
||||
}
|
||||
}
|
||||
@@ -785,73 +793,6 @@ fn parse_escape_sequence(
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_codepoint(
|
||||
&mut self,
|
||||
state: &mut mbstate_t,
|
||||
out_key: &mut Option<Key>,
|
||||
out_seq: &mut WString,
|
||||
buffer: &[u8],
|
||||
i: usize,
|
||||
consumed: &mut usize,
|
||||
have_escape_prefix: &mut bool,
|
||||
) -> ControlFlow<(), bool> {
|
||||
let mut res: char = '\0';
|
||||
let read_byte = buffer[i];
|
||||
if crate::libc::MB_CUR_MAX() == 1 {
|
||||
// single-byte locale, all values are legal
|
||||
// FIXME: this looks wrong, this falsely assumes that
|
||||
// the single-byte locale is compatible with Unicode upper-ASCII.
|
||||
res = read_byte.into();
|
||||
out_seq.push(res);
|
||||
return ControlFlow::Continue(true);
|
||||
}
|
||||
let mut codepoint = u32::from(res);
|
||||
let sz = unsafe {
|
||||
mbrtowc(
|
||||
std::ptr::addr_of_mut!(codepoint).cast(),
|
||||
std::ptr::addr_of!(read_byte).cast(),
|
||||
1,
|
||||
state,
|
||||
)
|
||||
} as isize;
|
||||
match sz {
|
||||
-1 => {
|
||||
FLOG!(reader, "Illegal input");
|
||||
*consumed += 1;
|
||||
self.push_front(CharEvent::from_check_exit());
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
-2 => {
|
||||
// Sequence not yet complete.
|
||||
return ControlFlow::Continue(false);
|
||||
}
|
||||
0 => {
|
||||
// Actual nul char.
|
||||
*consumed += 1;
|
||||
out_seq.push('\0');
|
||||
return ControlFlow::Continue(true);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
if let Some(res) = char::from_u32(codepoint) {
|
||||
// Sequence complete.
|
||||
if !fish_reserved_codepoint(res) {
|
||||
if *have_escape_prefix && i != 0 {
|
||||
*have_escape_prefix = false;
|
||||
*out_key = Some(alt(res));
|
||||
}
|
||||
*consumed += 1;
|
||||
out_seq.push(res);
|
||||
return ControlFlow::Continue(true);
|
||||
}
|
||||
}
|
||||
for &b in &buffer[*consumed..i] {
|
||||
out_seq.push(encode_byte_to_char(b));
|
||||
*consumed += 1;
|
||||
}
|
||||
ControlFlow::Continue(true)
|
||||
}
|
||||
|
||||
fn parse_csi(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
|
||||
let mut next_char = |zelf: &mut Self| zelf.try_readb(buffer).unwrap_or(0xff);
|
||||
// The maximum number of CSI parameters is defined by NPAR, nominally 16.
|
||||
@@ -1321,6 +1262,65 @@ fn has_lookahead(&self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum DecodeState {
|
||||
Incomplete,
|
||||
Complete,
|
||||
Error,
|
||||
}
|
||||
|
||||
pub(crate) fn decode_input_byte(
|
||||
out_seq: &mut WString,
|
||||
state: &mut mbstate_t,
|
||||
buffer: &[u8],
|
||||
consumed: &mut usize,
|
||||
) -> DecodeState {
|
||||
use DecodeState::*;
|
||||
let mut res: char = '\0';
|
||||
let read_byte = *buffer.last().unwrap();
|
||||
if crate::libc::MB_CUR_MAX() == 1 {
|
||||
// single-byte locale, all values are legal
|
||||
// FIXME: this looks wrong, this falsely assumes that
|
||||
// the single-byte locale is compatible with Unicode upper-ASCII.
|
||||
res = read_byte.into();
|
||||
out_seq.push(res);
|
||||
return Complete;
|
||||
}
|
||||
let mut codepoint = u32::from(res);
|
||||
match unsafe {
|
||||
mbrtowc(
|
||||
std::ptr::addr_of_mut!(codepoint).cast(),
|
||||
std::ptr::addr_of!(read_byte).cast(),
|
||||
1,
|
||||
state,
|
||||
)
|
||||
} as isize
|
||||
{
|
||||
-1 => {
|
||||
FLOG!(reader, "Illegal input");
|
||||
*consumed += 1;
|
||||
return Error;
|
||||
}
|
||||
-2 => {
|
||||
// Sequence not yet complete.
|
||||
return Incomplete;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
if let Some(res) = char::from_u32(codepoint) {
|
||||
// Sequence complete.
|
||||
if !fish_reserved_codepoint(res) {
|
||||
*consumed += 1;
|
||||
out_seq.push(res);
|
||||
return Complete;
|
||||
}
|
||||
}
|
||||
for &b in &buffer[*consumed..] {
|
||||
out_seq.push(encode_byte_to_char(b));
|
||||
*consumed += 1;
|
||||
}
|
||||
Complete
|
||||
}
|
||||
|
||||
/// A simple, concrete implementation of InputEventQueuer.
|
||||
pub struct InputEventQueue {
|
||||
data: InputData,
|
||||
|
||||
10
src/key.rs
10
src/key.rs
@@ -54,6 +54,7 @@ pub struct Modifiers {
|
||||
pub ctrl: bool,
|
||||
pub alt: bool,
|
||||
pub shift: bool,
|
||||
pub sup: bool,
|
||||
}
|
||||
|
||||
impl Modifiers {
|
||||
@@ -62,6 +63,7 @@ const fn new() -> Self {
|
||||
ctrl: false,
|
||||
alt: false,
|
||||
shift: false,
|
||||
sup: false,
|
||||
}
|
||||
}
|
||||
pub(crate) const ALT: Self = {
|
||||
@@ -70,10 +72,10 @@ const fn new() -> Self {
|
||||
m
|
||||
};
|
||||
pub(crate) fn is_some(&self) -> bool {
|
||||
self.ctrl || self.alt || self.shift
|
||||
*self != Self::new()
|
||||
}
|
||||
pub(crate) fn is_none(&self) -> bool {
|
||||
!self.is_some()
|
||||
*self == Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +273,7 @@ pub(crate) fn parse_keys(value: &wstr) -> Result<Vec<Key>, WString> {
|
||||
_ if modifier == "ctrl" => modifiers.ctrl = true,
|
||||
_ if modifier == "alt" => modifiers.alt = true,
|
||||
_ if modifier == "shift" => modifiers.shift = true,
|
||||
_ if modifier == "super" => modifiers.sup = true,
|
||||
_ => {
|
||||
return Err(wgettext_fmt!(
|
||||
"unknown modifier '%s' in '%s'",
|
||||
@@ -407,6 +410,9 @@ fn from(key: Key) -> Self {
|
||||
if key.modifiers.ctrl {
|
||||
res.insert_utfstr(0, L!("ctrl-"));
|
||||
}
|
||||
if key.modifiers.sup {
|
||||
res.insert_utfstr(0, L!("super-"));
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Generic output functions.
|
||||
use crate::color::RgbColor;
|
||||
use crate::color::{self, RgbColor};
|
||||
use crate::common::{self, wcs2string_appending};
|
||||
use crate::curses::{self, tparm1, Term};
|
||||
use crate::env::EnvVar;
|
||||
@@ -456,6 +456,35 @@ pub fn stdoutput() -> &'static RefCell<Outputter> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BufferedOuputter<'a>(&'a mut Outputter);
|
||||
|
||||
impl<'a> BufferedOuputter<'a> {
|
||||
pub fn new(outputter: &'a mut Outputter) -> Self {
|
||||
outputter.begin_buffering();
|
||||
Self(outputter)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for BufferedOuputter<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.0.end_buffering();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Write for BufferedOuputter<'a> {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
self.0
|
||||
.write(buf)
|
||||
.expect("Writing to in-memory buffer should never fail");
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
self.0.flush().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a list of RgbColor, pick the "best" one, as determined by the color support. Returns
|
||||
/// RgbColor::NONE if empty.
|
||||
pub fn best_color(candidates: &[RgbColor], support: ColorSupport) -> RgbColor {
|
||||
@@ -493,6 +522,14 @@ pub fn best_color(candidates: &[RgbColor], support: ColorSupport) -> RgbColor {
|
||||
/// In particular, the argument parsing still isn't fully capable.
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
pub fn parse_color(var: &EnvVar, is_background: bool) -> RgbColor {
|
||||
let mut result = parse_color_maybe_none(var, is_background);
|
||||
if result.is_none() {
|
||||
result.typ = color::Type::Normal;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn parse_color_maybe_none(var: &EnvVar, is_background: bool) -> RgbColor {
|
||||
let mut is_bold = false;
|
||||
let mut is_underline = false;
|
||||
let mut is_italics = false;
|
||||
@@ -551,9 +588,6 @@ pub fn parse_color(var: &EnvVar, is_background: bool) -> RgbColor {
|
||||
}
|
||||
|
||||
let mut result = best_color(&candidates, get_color_support());
|
||||
if result.is_none() {
|
||||
result = RgbColor::NORMAL;
|
||||
}
|
||||
result.set_bold(is_bold);
|
||||
result.set_underline(is_underline);
|
||||
result.set_italics(is_italics);
|
||||
|
||||
@@ -276,6 +276,9 @@ pub struct LibraryData {
|
||||
/// Whether we are currently interactive.
|
||||
pub is_interactive: bool,
|
||||
|
||||
/// Whether the command line is closed for modification from fish script.
|
||||
pub readonly_commandline: bool,
|
||||
|
||||
/// Whether to suppress fish_trace output. This occurs in the prompt, event handlers, and key
|
||||
/// bindings.
|
||||
pub suppress_fish_trace: bool,
|
||||
|
||||
@@ -183,7 +183,7 @@ fn maybe_issue_path_warning(
|
||||
)
|
||||
);
|
||||
}
|
||||
printf!("\n");
|
||||
eprintf!("\n");
|
||||
}
|
||||
|
||||
/// Finds the path of an executable named `cmd`, by looking in $PATH taken from `vars`.
|
||||
@@ -707,7 +707,7 @@ fn path_remoteness(path: &wstr) -> DirRemoteness {
|
||||
// these are in varying headers. Simply hard code them.
|
||||
// Note that we treat FUSE filesystems as remote, which means we lock less on such filesystems.
|
||||
// NOTE: The cast is necessary for 32-bit systems because of the 4-byte CIFS_MAGIC_NUMBER
|
||||
match usize::try_from(buf.f_type).unwrap() {
|
||||
match buf.f_type as usize {
|
||||
0x5346414F | // AFS_SUPER_MAGIC - Andrew File System
|
||||
0x6B414653 | // AFS_FS_MAGIC - Kernel AFS and AuriStorFS
|
||||
0x73757245 | // CODA_SUPER_MAGIC - Coda File System
|
||||
|
||||
102
src/reader.rs
102
src/reader.rs
@@ -88,6 +88,8 @@
|
||||
use crate::nix::isatty;
|
||||
use crate::operation_context::{get_bg_context, OperationContext};
|
||||
use crate::output::parse_color;
|
||||
use crate::output::parse_color_maybe_none;
|
||||
use crate::output::BufferedOuputter;
|
||||
use crate::output::Outputter;
|
||||
use crate::pager::{PageRendering, Pager, SelectionMotion};
|
||||
use crate::panic::AT_EXIT;
|
||||
@@ -221,6 +223,13 @@ unsafe impl Sync for ReaderDataStack {}
|
||||
unsafe { &mut *READER_DATA_STACK.0.get() }
|
||||
}
|
||||
|
||||
pub fn reader_in_interactive_read() -> bool {
|
||||
reader_data_stack()
|
||||
.iter()
|
||||
.rev()
|
||||
.any(|reader| reader.conf.exit_on_interrupt)
|
||||
}
|
||||
|
||||
/// Access the top level reader data.
|
||||
pub fn current_data() -> Option<&'static mut ReaderData> {
|
||||
reader_data_stack()
|
||||
@@ -650,8 +659,13 @@ fn read_i(parser: &Parser) -> i32 {
|
||||
data.command_line.clear();
|
||||
data.update_buff_pos(EditableLineTag::Commandline, None);
|
||||
data.command_line_changed(EditableLineTag::Commandline);
|
||||
// OSC 133 End of command
|
||||
data.screen.write_bytes(b"\x1b]133;C\x07");
|
||||
// OSC 133 "Command start"
|
||||
write!(
|
||||
BufferedOuputter::new(&mut Outputter::stdoutput().borrow_mut()),
|
||||
"\x1b]133;C;cmdline_url={}\x07",
|
||||
escape_string(&command, EscapeStringStyle::Url),
|
||||
)
|
||||
.unwrap();
|
||||
event::fire_generic(parser, L!("fish_preexec").to_owned(), vec![command.clone()]);
|
||||
let eval_res = reader_run_command(parser, &command);
|
||||
signal_clear_cancel();
|
||||
@@ -664,11 +678,12 @@ fn read_i(parser: &Parser) -> i32 {
|
||||
parser.libdata_mut().exit_current_script = false;
|
||||
|
||||
// OSC 133 "Command finished"
|
||||
let _ = write!(
|
||||
Outputter::stdoutput().borrow_mut(),
|
||||
write!(
|
||||
BufferedOuputter::new(&mut Outputter::stdoutput().borrow_mut()),
|
||||
"\x1b]133;D;{}\x07",
|
||||
parser.get_last_status()
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
event::fire_generic(parser, L!("fish_postexec").to_owned(), vec![command]);
|
||||
// Allow any pending history items to be returned in the history array.
|
||||
data.history.resolve_pending();
|
||||
@@ -940,6 +955,9 @@ pub fn reader_schedule_prompt_repaint() {
|
||||
}
|
||||
|
||||
pub fn reader_execute_readline_cmd(parser: &Parser, ch: CharEvent) {
|
||||
if parser.libdata().readonly_commandline {
|
||||
return;
|
||||
}
|
||||
if let Some(data) = current_data() {
|
||||
let mut data = Reader { parser, data };
|
||||
let CharEvent::Readline(readline_cmd_evt) = &ch else {
|
||||
@@ -1018,7 +1036,10 @@ pub fn commandline_get_state(sync: bool) -> CommandlineState {
|
||||
|
||||
/// Set the command line text and position. This may be called on a background thread; the reader
|
||||
/// will pick it up when it is done executing.
|
||||
pub fn commandline_set_buffer(text: Option<WString>, cursor_pos: Option<usize>) {
|
||||
pub fn commandline_set_buffer(parser: &Parser, text: Option<WString>, cursor_pos: Option<usize>) {
|
||||
if parser.libdata().readonly_commandline {
|
||||
return;
|
||||
}
|
||||
{
|
||||
let mut state = commandline_state_snapshot();
|
||||
if let Some(text) = text {
|
||||
@@ -1029,7 +1050,10 @@ pub fn commandline_set_buffer(text: Option<WString>, cursor_pos: Option<usize>)
|
||||
current_data().map(|data| data.apply_commandline_state_changes());
|
||||
}
|
||||
|
||||
pub fn commandline_set_search_field(text: WString, cursor_pos: Option<usize>) {
|
||||
pub fn commandline_set_search_field(parser: &Parser, text: WString, cursor_pos: Option<usize>) {
|
||||
if parser.libdata().readonly_commandline {
|
||||
return;
|
||||
}
|
||||
{
|
||||
let mut state = commandline_state_snapshot();
|
||||
assert!(state.search_field.is_some());
|
||||
@@ -1499,8 +1523,15 @@ fn paint_layout(&mut self, reason: &wstr, is_final_rendering: bool) {
|
||||
range.end = colors.len();
|
||||
}
|
||||
|
||||
let explicit_foreground = self
|
||||
.vars()
|
||||
.get_unless_empty(L!("fish_color_search_match"))
|
||||
.is_some_and(|var| !parse_color_maybe_none(&var, false).is_none());
|
||||
|
||||
for color in &mut colors[range] {
|
||||
color.foreground = HighlightRole::search_match;
|
||||
if explicit_foreground {
|
||||
color.foreground = HighlightRole::search_match;
|
||||
}
|
||||
color.background = HighlightRole::search_match;
|
||||
}
|
||||
}
|
||||
@@ -2325,7 +2356,12 @@ fn handle_readline_command(&mut self, c: ReadlineCmd) {
|
||||
if c == rl::CancelCommandline {
|
||||
// Move cursor to the end of the line.
|
||||
let end = self.command_line.len();
|
||||
self.update_buff_pos(EditableLineTag::Commandline, Some(end));
|
||||
{
|
||||
let tmp =
|
||||
std::mem::replace(&mut self.cursor_end_mode, CursorEndMode::Exclusive);
|
||||
self.update_buff_pos(EditableLineTag::Commandline, Some(end));
|
||||
self.cursor_end_mode = tmp;
|
||||
}
|
||||
|
||||
self.autosuggestion.clear();
|
||||
// Repaint also changes the actual cursor position
|
||||
@@ -2570,7 +2606,7 @@ fn handle_readline_command(&mut self, c: ReadlineCmd) {
|
||||
self.data
|
||||
.insert_string(self.active_edit_line_tag(), &yank_str);
|
||||
self.rls_mut().yank_len = yank_str.len();
|
||||
if self.cursor_end_mode == CursorEndMode::Inclusive {
|
||||
if !yank_str.is_empty() && self.cursor_end_mode == CursorEndMode::Inclusive {
|
||||
let (_elt, el) = self.active_edit_line();
|
||||
self.update_buff_pos(self.active_edit_line_tag(), Some(el.position() - 1));
|
||||
}
|
||||
@@ -3669,8 +3705,11 @@ fn clear_pager(&mut self) {
|
||||
|
||||
fn get_selection(&self) -> Option<Range<usize>> {
|
||||
let selection = self.selection?;
|
||||
let start = selection.start;
|
||||
let start = std::cmp::min(selection.start, self.command_line.len());
|
||||
let end = std::cmp::min(selection.stop, self.command_line.len());
|
||||
if start == end {
|
||||
return None;
|
||||
}
|
||||
Some(start..end)
|
||||
}
|
||||
|
||||
@@ -3750,6 +3789,7 @@ fn pager_selection_changed(&mut self) {
|
||||
&self.cycle_command_line,
|
||||
&mut cursor_pos,
|
||||
false,
|
||||
/*is_unique=*/ false, // don't care
|
||||
),
|
||||
};
|
||||
|
||||
@@ -4065,7 +4105,10 @@ fn reader_interactive_init(parser: &Parser) {
|
||||
terminal_protocol_hacks();
|
||||
IN_MIDNIGHT_COMMANDER_PRE_CSI_U.store(
|
||||
parser.vars().get_unless_empty(L!("MC_TMPDIR")).is_some()
|
||||
&& parser.vars().get_unless_empty(L!("__mc_csi_u")).is_none(),
|
||||
&& parser
|
||||
.vars()
|
||||
.get_unless_empty(L!("__mc_kitty_keyboard"))
|
||||
.is_none(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4384,6 +4427,7 @@ fn get_autosuggestion_performer(
|
||||
&search_string,
|
||||
&mut cursor,
|
||||
/*append_only=*/ true,
|
||||
/*is_unique=*/ false,
|
||||
);
|
||||
}
|
||||
result
|
||||
@@ -4790,7 +4834,9 @@ fn fill_history_pager(
|
||||
if search_term != zelf.pager.search_field_line.text() {
|
||||
return; // Stale request.
|
||||
}
|
||||
let history_pager = zelf.history_pager.as_mut().unwrap();
|
||||
let Some(history_pager) = zelf.history_pager.as_mut() else {
|
||||
return; // Pager has been closed.
|
||||
};
|
||||
history_pager.direction = direction;
|
||||
match direction {
|
||||
SearchDirection::Forward => {
|
||||
@@ -4859,6 +4905,10 @@ fn expand_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_interactive, new_value),
|
||||
false,
|
||||
);
|
||||
let _readonly_commandline = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().readonly_commandline, new_value),
|
||||
true,
|
||||
);
|
||||
|
||||
let mut outputs = vec![];
|
||||
let ret = exec_subshell(
|
||||
@@ -5567,6 +5617,7 @@ pub fn completion_apply_to_command_line(
|
||||
command_line: &wstr,
|
||||
inout_cursor_pos: &mut usize,
|
||||
append_only: bool,
|
||||
is_unique: bool,
|
||||
) -> WString {
|
||||
let add_space = !flags.contains(CompleteFlags::NO_SPACE);
|
||||
let do_replace_token = flags.contains(CompleteFlags::REPLACES_TOKEN);
|
||||
@@ -5591,7 +5642,7 @@ pub fn completion_apply_to_command_line(
|
||||
}
|
||||
|
||||
let mut escape_flags = EscapeFlags::empty();
|
||||
if append_only || !add_space {
|
||||
if append_only || !is_unique || !add_space {
|
||||
escape_flags.insert(EscapeFlags::NO_QUOTED);
|
||||
}
|
||||
if no_tilde {
|
||||
@@ -5839,7 +5890,12 @@ fn try_insert(&mut self, c: Completion, tok: &wstr, token_range: Range<usize>) {
|
||||
// If this is a replacement completion, check that we know how to replace it, e.g. that
|
||||
// the token doesn't contain evil operators like {}.
|
||||
if !c.flags.contains(CompleteFlags::REPLACES_TOKEN) || reader_can_replace(tok, c.flags) {
|
||||
self.completion_insert(&c.completion, token_range.end, c.flags);
|
||||
self.completion_insert(
|
||||
&c.completion,
|
||||
token_range.end,
|
||||
c.flags,
|
||||
/*is_unique=*/ true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5975,7 +6031,12 @@ fn handle_completions(&mut self, token_range: Range<usize>) -> bool {
|
||||
if prefix_is_partial_completion {
|
||||
flags |= CompleteFlags::NO_SPACE;
|
||||
}
|
||||
self.completion_insert(&common_prefix, token_range.end, flags);
|
||||
self.completion_insert(
|
||||
&common_prefix,
|
||||
token_range.end,
|
||||
flags,
|
||||
/*is_unique=*/ false,
|
||||
);
|
||||
self.cycle_command_line = self.command_line.text().to_owned();
|
||||
self.cycle_cursor_pos = self.command_line.position();
|
||||
}
|
||||
@@ -6019,7 +6080,13 @@ fn handle_completions(&mut self, token_range: Range<usize>) -> bool {
|
||||
/// \param token_end the position after the token to complete
|
||||
/// \param flags A union of all flags describing the completion to insert. See the completion_t
|
||||
/// struct for more information on possible values.
|
||||
fn completion_insert(&mut self, val: &wstr, token_end: usize, flags: CompleteFlags) {
|
||||
fn completion_insert(
|
||||
&mut self,
|
||||
val: &wstr,
|
||||
token_end: usize,
|
||||
flags: CompleteFlags,
|
||||
is_unique: bool,
|
||||
) {
|
||||
let (elt, el) = self.active_edit_line();
|
||||
|
||||
// Move the cursor to the end of the token.
|
||||
@@ -6035,6 +6102,7 @@ fn completion_insert(&mut self, val: &wstr, token_end: usize, flags: CompleteFla
|
||||
el.text(),
|
||||
&mut cursor,
|
||||
/*append_only=*/ false,
|
||||
is_unique,
|
||||
);
|
||||
self.set_buffer_maintaining_pager(&new_command_line, cursor, false);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
use crate::output::Outputter;
|
||||
use crate::termsize::{termsize_last, Termsize};
|
||||
use crate::wchar::prelude::*;
|
||||
use crate::wcstringutil::string_prefixes_string;
|
||||
use crate::wcstringutil::{fish_wcwidth_visible, string_prefixes_string};
|
||||
use crate::wutil::fstat;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@@ -1636,7 +1636,11 @@ fn measure_run_from(
|
||||
width = next_tab_stop(width);
|
||||
} else {
|
||||
// Ordinary char. Add its width with care to ignore control chars which have width -1.
|
||||
width += wcwidth_rendered_min_0(input.char_at(idx));
|
||||
if let Ok(ww) = usize::try_from(fish_wcwidth_visible(input.char_at(idx))) {
|
||||
width += ww;
|
||||
} else {
|
||||
width = width.saturating_sub(1);
|
||||
}
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
@@ -1682,7 +1686,8 @@ fn truncate_run(
|
||||
curr_width = measure_run_from(run, 0, None, cache);
|
||||
idx = 0;
|
||||
} else {
|
||||
let char_width = wcwidth_rendered_min_0(c);
|
||||
// FIXME: In case of backspace, this would remove the last width.
|
||||
let char_width = usize::try_from(fish_wcwidth_visible(c)).unwrap_or(0);
|
||||
curr_width -= std::cmp::min(curr_width, char_width);
|
||||
run.remove(idx);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,8 @@ macro_rules! unique_completion_applies_as {
|
||||
completions[0].flags,
|
||||
cmdline,
|
||||
&mut cursor,
|
||||
false,
|
||||
/*append_only=*/ false,
|
||||
/*is_unique=*/ true,
|
||||
);
|
||||
assert_eq!(newcmdline, L!($applied), "apply result mismatch");
|
||||
};
|
||||
@@ -224,6 +225,7 @@ macro_rules! unique_completion_applies_as {
|
||||
L!("mv debug debug"),
|
||||
&mut cursor_pos,
|
||||
true,
|
||||
/*is_unique=*/ false,
|
||||
);
|
||||
assert_eq!(newcmdline, L!("mv debug Debug/"));
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ macro_rules! validate {
|
||||
&line,
|
||||
&mut cursor_pos,
|
||||
$append_only,
|
||||
/*is_unique=*/ false,
|
||||
);
|
||||
assert_eq!(result, expected);
|
||||
assert_eq!(cursor_pos, out_cursor_pos);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::sync::MutexGuard;
|
||||
|
||||
use crate::common::{
|
||||
escape_string, str2wcstring, unescape_string, wcs2string, EscapeFlags, EscapeStringStyle,
|
||||
UnescapeStringStyle, ENCODE_DIRECT_BASE, ENCODE_DIRECT_END,
|
||||
@@ -10,21 +12,21 @@
|
||||
|
||||
/// wcs2string is locale-dependent, so ensure we have a multibyte locale
|
||||
/// before using it in a test.
|
||||
fn setlocale() {
|
||||
let _guard = LOCALE_LOCK.lock().unwrap();
|
||||
fn setlocale() -> MutexGuard<'static, ()> {
|
||||
let guard = LOCALE_LOCK.lock().unwrap();
|
||||
|
||||
#[rustfmt::skip]
|
||||
const UTF8_LOCALES: &[&str] = &[
|
||||
"C.UTF-8", "en_US.UTF-8", "en_GB.UTF-8", "de_DE.UTF-8", "C.utf8", "UTF-8",
|
||||
];
|
||||
if crate::libc::MB_CUR_MAX() > 1 {
|
||||
return;
|
||||
return guard;
|
||||
}
|
||||
for locale in UTF8_LOCALES {
|
||||
let locale = std::ffi::CString::new(locale.to_owned()).unwrap();
|
||||
unsafe { libc::setlocale(libc::LC_CTYPE, locale.as_ptr()) };
|
||||
if crate::libc::MB_CUR_MAX() > 1 {
|
||||
return;
|
||||
return guard;
|
||||
}
|
||||
}
|
||||
panic!("No UTF-8 locale found");
|
||||
@@ -100,7 +102,7 @@ fn test_escape_var() {
|
||||
}
|
||||
|
||||
fn escape_test(escape_style: EscapeStringStyle, unescape_style: UnescapeStringStyle) {
|
||||
setlocale();
|
||||
let _locale_guard = setlocale();
|
||||
let seed: u128 = 92348567983274852905629743984572;
|
||||
let mut rng = get_seeded_rng(seed);
|
||||
|
||||
@@ -174,7 +176,7 @@ fn str2hex(input: &[u8]) -> String {
|
||||
/// string comes back through double conversion.
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
setlocale();
|
||||
let _locale_guard = setlocale();
|
||||
let seed = get_rng_seed();
|
||||
let mut rng = get_seeded_rng(seed);
|
||||
let mut origin = Vec::new();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::wopendir;
|
||||
use crate::common::{cstr2wcstring, wcs2zstring};
|
||||
use crate::common::{str2wcstring, wcs2zstring};
|
||||
use crate::wchar::{wstr, WString};
|
||||
use crate::wutil::DevInode;
|
||||
use libc::{
|
||||
@@ -8,11 +8,10 @@
|
||||
S_IFSOCK,
|
||||
};
|
||||
use std::cell::Cell;
|
||||
use std::io::{self};
|
||||
use std::io;
|
||||
use std::os::fd::RawFd;
|
||||
use std::ptr::NonNull;
|
||||
use std::ptr::{addr_of, NonNull};
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
|
||||
/// Types of files that may be in a directory.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@@ -267,19 +266,23 @@ pub fn next(&mut self) -> Option<io::Result<&DirEntry>> {
|
||||
|
||||
// dent.d_name is c_char; pretend it's u8.
|
||||
assert!(std::mem::size_of::<libc::c_char>() == std::mem::size_of::<u8>());
|
||||
let d_name_cchar = &dent.d_name;
|
||||
let d_name = unsafe {
|
||||
slice::from_raw_parts(d_name_cchar.as_ptr() as *const u8, d_name_cchar.len())
|
||||
};
|
||||
|
||||
// Do not rely on `libc::dirent::d_name.len()` as dirent names may exceed
|
||||
// the nominal buffer size; instead use the terminating nul byte.
|
||||
// TODO: This should use &raw from Rust 1.82 on
|
||||
// https://github.com/rust-lang/libc/issues/2669
|
||||
// https://github.com/fish-shell/fish-shell/issues/11221
|
||||
let d_name_ptr = addr_of!((*dent).d_name);
|
||||
let d_name = unsafe { std::ffi::CStr::from_ptr(d_name_ptr.cast()) }.to_bytes();
|
||||
|
||||
// Skip . and ..,
|
||||
// unless we've been told not to.
|
||||
if !self.withdot && (d_name.starts_with(b".\0") || d_name.starts_with(b"..\0")) {
|
||||
if !self.withdot && (d_name == b"." || d_name == b"..") {
|
||||
return self.next();
|
||||
}
|
||||
|
||||
self.entry.reset();
|
||||
self.entry.name = cstr2wcstring(d_name);
|
||||
self.entry.name = str2wcstring(d_name);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
|
||||
{
|
||||
self.entry.inode = dent.d_fileno;
|
||||
|
||||
@@ -10,7 +10,7 @@ complete -c complete_test_alpha3 --no-files -w 'complete_test_alpha2 extra2'
|
||||
complete -C'complete_test_alpha1 arg1 '
|
||||
# CHECK: complete_test_alpha1 arg1
|
||||
complete --escape -C'complete_test_alpha1 arg1 '
|
||||
# CHECK: 'complete_test_alpha1 arg1 '
|
||||
# CHECK: complete_test_alpha1\ arg1\{{ }}
|
||||
complete -C'complete_test_alpha2 arg2 '
|
||||
# CHECK: complete_test_alpha1 extra1 arg2
|
||||
complete -C'complete_test_alpha3 arg3 '
|
||||
|
||||
@@ -183,6 +183,11 @@ function foo --argument-names status; end
|
||||
echo status $status
|
||||
# CHECK: status 2
|
||||
|
||||
function foo --argument-names foo status; end
|
||||
# CHECKERR: {{.*}}function.fish (line {{\d+}}): function: variable 'status' is read-only
|
||||
# CHECKERR: function foo --argument-names foo status; end
|
||||
# CHECKERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
|
||||
|
||||
functions -q foo
|
||||
echo exists $status
|
||||
# CHECK: exists 1
|
||||
|
||||
@@ -40,12 +40,21 @@ echo "echo foo" > git-frobnicate
|
||||
chmod +x git-frobnicate
|
||||
|
||||
complete -c git-frobnicate -xa 'foo bar baz'
|
||||
complete -c git-frobnicate -l onto -xa 'onto1 onto2'
|
||||
|
||||
complete -C'git frobnicate '
|
||||
#CHECK: bar
|
||||
#CHECK: baz
|
||||
#CHECK: foo
|
||||
|
||||
complete -C'git frobnicate --onto '
|
||||
#CHECK: onto1
|
||||
#CHECK: onto2
|
||||
|
||||
complete -C'git frobnicate graft --onto '
|
||||
#CHECK: onto1
|
||||
#CHECK: onto2
|
||||
|
||||
complete -C'git ' | grep '^add'\t
|
||||
# (note: actual tab character in the check here)
|
||||
#CHECK: add Add file contents to the staging area
|
||||
|
||||
@@ -400,3 +400,8 @@ echo foo | read -n -1
|
||||
# CHECKERR: echo foo | read -n -1
|
||||
# CHECKERR: ^
|
||||
# CHECKERR: (Type 'help read' for related documentation)
|
||||
|
||||
printf \xf9\x98\xb1\x83\x8b | read -z out_of_range_codepoint
|
||||
set -S out_of_range_codepoint
|
||||
# CHECK: $out_of_range_codepoint: set in global scope, unexported, with 1 elements
|
||||
# CHECK: $out_of_range_codepoint[1]: |\Xf9\X98\Xb1\X83\X8b|
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#RUN: %fish -v
|
||||
# CHECK: fish, version {{[-.gabcdeflphat0-9]*(irty)?}}
|
||||
# CHECK: fish, version {{[0-9].*}}
|
||||
|
||||
@@ -28,6 +28,21 @@ expect_prompt(increment=False)
|
||||
send("\f")
|
||||
expect_prompt(increment=False)
|
||||
|
||||
# Test that kill-selection after selection is cleared doesn't crash
|
||||
sendline("bind ctrl-space begin-selection")
|
||||
expect_prompt()
|
||||
sendline("bind ctrl-w kill-selection end-selection")
|
||||
expect_prompt()
|
||||
send("echo 123")
|
||||
# Send Ctrl-Space using CSI u encoding
|
||||
send("\x1b[32;5u")
|
||||
# Send Ctrl-C to clear the command line
|
||||
send("\x1b[99;5u")
|
||||
# Send Ctrl-W which used to crash
|
||||
send("\x1b[119;5u")
|
||||
sendline("bind --erase ctrl-space ctrl-w")
|
||||
expect_prompt()
|
||||
|
||||
# Fish should start in default-mode (i.e., emacs) bindings. The default escape
|
||||
# timeout is 30ms.
|
||||
#
|
||||
@@ -345,7 +360,7 @@ send("\x1b")
|
||||
expect_str("foo")
|
||||
send("\x1b[A")
|
||||
expect_str("bind escape 'echo foo'")
|
||||
sendline("")
|
||||
sendline("bind --erase escape")
|
||||
expect_prompt()
|
||||
|
||||
send(" a b c d\x01") # ctrl-a, move back to the beginning of the line
|
||||
@@ -394,6 +409,11 @@ expect_prompt()
|
||||
sendline("commandline -f and")
|
||||
expect_prompt()
|
||||
|
||||
sendline("bind ctrl-g 'sleep 1' history-pager")
|
||||
expect_prompt()
|
||||
send("\x07") # ctrl-g
|
||||
send("\x1b[27u") # escape, to close pager
|
||||
|
||||
# Check that the builtin version of `exit` works
|
||||
# (for obvious reasons this MUST BE LAST)
|
||||
sendline("function myexit; echo exit; exit; end; bind ctrl-z myexit")
|
||||
|
||||
Reference in New Issue
Block a user