mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-30 23:51:15 -03:00
Compare commits
25 Commits
ci-for-mor
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77a9466337 | ||
|
|
2668e281d7 | ||
|
|
5fc7deab16 | ||
|
|
9896a9f02e | ||
|
|
deaa8bf3a9 | ||
|
|
43e3aa4e6b | ||
|
|
8c1a625076 | ||
|
|
0ee41cb55d | ||
|
|
e6db10d1e0 | ||
|
|
391ede475b | ||
|
|
cab89b5dfa | ||
|
|
77357c4e37 | ||
|
|
53b185e102 | ||
|
|
5b992cf273 | ||
|
|
2c17c96e55 | ||
|
|
22cb01d437 | ||
|
|
972528648c | ||
|
|
16532cfaba | ||
|
|
d573dd9f79 | ||
|
|
be58b66c82 | ||
|
|
fa8a2ee265 | ||
|
|
6fd86a6e9b | ||
|
|
becded65d2 | ||
|
|
36a6659390 | ||
|
|
eb8f53c48d |
33
.github/workflows/build_docker_images.yml
vendored
33
.github/workflows/build_docker_images.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: Build Docker test images
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'docker/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: docker-builds
|
||||
|
||||
jobs:
|
||||
docker-build:
|
||||
if: github.repository_owner == 'fish-shell'
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: alpine
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2, build_tools/update-dependencies.sh
|
||||
- run: |
|
||||
printf %s "${{ secrets.GITHUB_TOKEN }}" |
|
||||
docker login ghcr.io --username=${{ github.actor }} --password-stdin
|
||||
docker/push.sh docker/${{ matrix.target }}.Dockerfile
|
||||
50
.github/workflows/test.yml
vendored
50
.github/workflows/test.yml
vendored
@@ -10,56 +10,8 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
alpine:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2, build_tools/update-dependencies.sh
|
||||
- run:
|
||||
docker/docker_run_tests.sh docker/alpine.Dockerfile
|
||||
|
||||
freebsd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2, build_tools/update-dependencies.sh
|
||||
- uses: vmactions/freebsd-vm@21de0c823079bc57bd8fcf25fb60193f36887e3d # v1, build_tools/update-dependencies.sh
|
||||
with:
|
||||
# # See https://github.com/vmactions/.github/wiki/debug%E2%80%90on%E2%80%90error
|
||||
# debug-on-error: true
|
||||
# vnc-password: fish
|
||||
usesh: true
|
||||
run: |
|
||||
pkg update
|
||||
# TODO This should be shared with .github/actions/install-dependencies/action.yml
|
||||
pkg install -y \
|
||||
cmake-core \
|
||||
devel/ninja \
|
||||
devel/pcre2 \
|
||||
gettext \
|
||||
git-lite \
|
||||
lang/rust \
|
||||
misc/py-pexpect \
|
||||
python \
|
||||
sudo \
|
||||
;
|
||||
# BSDs have the following behavior: root may open or access files even if
|
||||
# the mode bits would otherwise disallow it. For example root may open()
|
||||
# a file with write privileges even if the file has mode 400. This breaks
|
||||
# our tests for e.g. cd and path. So create a new unprivileged user to run tests.
|
||||
pw user add -n fish-user -s /bin/csh -d /home/fish-user
|
||||
mkdir -p /home/fish-user
|
||||
chown -R fish-user /home/fish-user
|
||||
mkdir build && cd build
|
||||
chown -R fish-user ..
|
||||
sudo -u fish-user -s whoami
|
||||
sudo -u fish-user -s FISH_TEST_MAX_CONCURRENCY=1 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
|
||||
sudo -u fish-user -s ninja fish
|
||||
sudo -u fish-user -s env CI=1 ninja fish_run_tests
|
||||
|
||||
ubuntu:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, ubuntu-latest-arm64]
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2, build_tools/update-dependencies.sh
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
|
||||
@@ -1,38 +1,52 @@
|
||||
fish ?.?.? (released ???)
|
||||
=========================
|
||||
|
||||
Interactive improvements
|
||||
------------------------
|
||||
- Builtin and function commands can now be colored separately via new variables :envvar:`fish_color_builtin` and :envvar:`fish_color_function` (:issue:`12837`).
|
||||
|
||||
Regression fixes:
|
||||
-----------------
|
||||
- ``abbr --position=anywhere`` completions are no longer offered in argument position, to avoid cluttering the completion pager (:issue:`12838`).
|
||||
|
||||
fish 4.8.0 (released June 24, 2026)
|
||||
===================================
|
||||
|
||||
Notable improvements and fixes
|
||||
------------------------------
|
||||
- Translatable messages defined in Rust source code may now be localized using `Fluent <https://projectfluent.org/>`__ instead of GNU gettext.
|
||||
- Translatable messages defined in Rust source code can and should now be translated using `Fluent <https://projectfluent.org/>`__ instead of GNU gettext.
|
||||
For now, GNU gettext continues to be used for translating messages defined in fish scripts.
|
||||
To make Fluent easy to work with, we have added tooling based on the new `fluent-ftl-tools <https://codeberg.org/danielrainer/fluent-ftl-tools>`__ library.
|
||||
See :ref:`Contributing Translations <localization>` (:issue:`11928`).
|
||||
|
||||
Deprecations and removed features
|
||||
---------------------------------
|
||||
- The ``--command`` and ``--path`` options in :doc:`complete <cmds/complete>` no longer unescape their argument.
|
||||
- Builtin :doc:`complete's <cmds/complete>` ``--command`` and ``--path`` options no longer unescape their argument.
|
||||
|
||||
Interactive improvements
|
||||
------------------------
|
||||
- History search would sometimes forget about commands after those were re-run in concurrent sessions. This has been fixed (:issue:`10300`).
|
||||
- On the first run after upgrading from an older version, fish will try harder to check if the current theme matches a historical default. If it does match, fish won't create ``~/.config/fish/conf.d/fish_frozen_theme.fish`` when upgrading from fish < 4.3.
|
||||
Specifically, on systems where fish version 3.x was installed originally, fish 4.8 will avoid creating that file on upgrade (:issue:`12725`).
|
||||
- ``fish_hg_prompt``, ``fish_git_prompt`` and ``fish_fossil_prompt`` now strip control characters from VCS state read off disk, matching ``prompt_pwd``.
|
||||
- :doc:`bind <cmds/bind>` shows the file where bindings were defined (:issue:`12504`).
|
||||
- Abbreviations with ``--position=anywhere`` can now be completed in argument position, not just in command position (:issue:`12630`).
|
||||
- Path component movement (:kbd:`ctrl-w`) skips escaped characters.
|
||||
- Completions no longer offer repeated short options (:issue:`12821`).
|
||||
- Fixed an issue where control-C might fail to cancel certain functions (:issue:`12802`).
|
||||
- Completion of short option groups will now handle ``--condition`` correctly (:issue:`12821`).
|
||||
- Fixed an issue where :kbd:`ctrl-c` might fail to cancel certain functions (:issue:`12802`).
|
||||
- On the first run after upgrading from an older version, fish will try harder to check if the current theme matches a historical default.
|
||||
If it does match, fish won't create ``~/.config/fish/conf.d/fish_frozen_theme.fish`` when upgrading from fish < 4.3.
|
||||
In particular, on systems where fish version 3.x was installed originally, fish will now avoid creating that file on upgrade (:issue:`12725`).
|
||||
|
||||
Scripting improvements
|
||||
----------------------
|
||||
- ``cd`` supports the ``-L`` and ``-P`` options, like other shells, to allow specifying whether symbolic links (symlinks) are resolved when changing directories (:issue:`7206`).
|
||||
- ``cd`` with a relative path will now retry using the real current directory, if ``$PWD`` has been moved or deleted (:issue:`12700`).
|
||||
- ``cd`` with a relative path will now retry using the real current directory, if ``$PWD`` has been moved (:issue:`12700`).
|
||||
- Nested brace expansions now strip unquoted leading and trailing spaces from entries consistently (:issue:`12794`).
|
||||
- :doc:`bind <cmds/bind>` shows the files where bindings were defined (:issue:`12504`).
|
||||
|
||||
Other improvements
|
||||
------------------
|
||||
- fish no longer creates universal variables by default; specifically, the ``__fish_initialized`` variable is no longer created.
|
||||
- fish no longer creates the ``__fish_initialized`` universal variable on startup.
|
||||
If you don't expect to need to downgrade to earlier versions, you can remove it with ``set --erase __fish_initialized``.
|
||||
This means that fish now only creates universal variables if instructed by the user.
|
||||
|
||||
For distributors and developers
|
||||
-------------------------------
|
||||
@@ -53,7 +67,7 @@ Regression fixes:
|
||||
- (from 4.4.0) Vi mode ``c,W`` key binding wrongly deleted trailing spaces (:issue:`12790`).
|
||||
- (from 4.4.0) Vi mode ``x`` in :doc:`builtin read <cmds/read>` (:issue:`12724`).
|
||||
- (from 4.3.3) Repeated tab would sometimes insert smartcase completions redundantly.
|
||||
- (from 4.3.0) Pressing escape during command input would insert garbage text into the command line (:issue:`12379`).
|
||||
- (from 4.3.0) Pressing escape during command execution could insert garbage text into the command line (:issue:`12379`).
|
||||
|
||||
fish 4.7.1 (released May 08, 2026)
|
||||
==================================
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -334,7 +334,7 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "fish"
|
||||
version = "4.7.1"
|
||||
version = "4.8.0"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"bitflags",
|
||||
|
||||
@@ -106,7 +106,7 @@ debug = true
|
||||
|
||||
[package]
|
||||
name = "fish"
|
||||
version = "4.7.1"
|
||||
version = "4.8.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
default-run = "fish"
|
||||
|
||||
@@ -35,7 +35,6 @@ update_gh_action dessant/lock-threads
|
||||
update_gh_action EmbarkStudios/cargo-deny-action
|
||||
update_gh_action msys2/setup-msys2
|
||||
update_gh_action softprops/action-gh-release
|
||||
update_gh_action vmactions/freebsd-vm
|
||||
|
||||
updatecli "${@:-apply}"
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
fish (4.8.0-1) stable; urgency=medium
|
||||
|
||||
* Release of new version 4.8.0.
|
||||
|
||||
See https://github.com/fish-shell/fish-shell/releases/tag/4.8.0 for details.
|
||||
|
||||
-- Johannes Altmanninger <aclopte@gmail.com> Wed, 24 Jun 2026 11:59:34 +0200
|
||||
|
||||
fish (4.7.1-1) stable; urgency=medium
|
||||
|
||||
* Release of new version 4.7.1.
|
||||
|
||||
@@ -6,7 +6,7 @@ Synopsis
|
||||
|
||||
.. synopsis::
|
||||
|
||||
contains [OPTIONS] KEY [VALUES ...]
|
||||
contains [OPTIONS] [--] KEY [VALUES ...]
|
||||
|
||||
Description
|
||||
-----------
|
||||
@@ -22,7 +22,9 @@ The following options are available:
|
||||
**-h** or **--help**
|
||||
Displays help about using this command.
|
||||
|
||||
Note that ``contains`` interprets all arguments starting with a **-** as an option to ``contains``, until an **--** argument is reached.
|
||||
Options must be passed before *KEY*.
|
||||
All arguments after *KEY* will be considered a value, regardless if they start with a ``-`` or not, including ``--``.
|
||||
If *KEY* itself starts with a ``-``, use a ``--`` argument to separate it from the options.
|
||||
|
||||
See the examples below.
|
||||
|
||||
@@ -62,3 +64,10 @@ While this will check if function ``hasargs`` is being ran with the **-q** optio
|
||||
|
||||
The **--** here stops ``contains`` from treating **-q** to an option to itself.
|
||||
Instead it treats it as a normal string to check.
|
||||
|
||||
::
|
||||
|
||||
contains -i foo -q -- foo
|
||||
|
||||
|
||||
This returns 3, since all arguments after the key are considered a value.
|
||||
|
||||
@@ -129,6 +129,8 @@ Variable Meaning
|
||||
========================================== =====================================================================
|
||||
.. envvar:: fish_color_normal default color
|
||||
.. envvar:: fish_color_command commands like echo
|
||||
.. envvar:: fish_color_builtin builtin commands like cd and set - this falls back on the command color if unset
|
||||
.. envvar:: fish_color_function user-defined functions - this falls back on the command color if unset
|
||||
.. envvar:: fish_color_keyword keywords like if - this falls back on the command color if unset
|
||||
.. envvar:: fish_color_quote quoted text like ``"abc"``
|
||||
.. envvar:: fish_color_redirection IO redirections like >/dev/null
|
||||
@@ -157,6 +159,7 @@ Variable Meaning
|
||||
If a variable isn't set or is empty after subtracting any ``--theme=THEME`` options,
|
||||
fish usually tries ``$fish_color_normal``, except for:
|
||||
|
||||
- ``$fish_color_builtin`` and ``$fish_color_function``, where they try ``$fish_color_command`` first.
|
||||
- ``$fish_color_keyword``, where it tries ``$fish_color_command`` first.
|
||||
- ``$fish_color_option``, where it tries ``$fish_color_param`` first.
|
||||
- For ``$fish_color_valid_path``, if that doesn't have a color, but only modifiers, it adds those to the color that would otherwise be used,
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
# Version set by updatecli.d/docker.yml
|
||||
FROM alpine:3.23
|
||||
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
|
||||
|
||||
ENV LANG=C.UTF-8
|
||||
ENV LC_ALL=C.UTF-8
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
cargo \
|
||||
g++ \
|
||||
gettext-dev \
|
||||
git \
|
||||
libintl \
|
||||
musl-dev \
|
||||
pcre2-dev \
|
||||
py3-pexpect \
|
||||
py3-pip \
|
||||
python3 \
|
||||
rust \
|
||||
sudo \
|
||||
tmux
|
||||
|
||||
RUN addgroup -g 1000 fishuser
|
||||
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--home "/home/fishuser" \
|
||||
--ingroup fishuser \
|
||||
--uid 1000 \
|
||||
fishuser
|
||||
|
||||
RUN mkdir -p /home/fishuser/fish-build \
|
||||
&& mkdir /fish-source \
|
||||
&& chown -R fishuser:fishuser /home/fishuser /fish-source
|
||||
|
||||
USER fishuser
|
||||
WORKDIR /home/fishuser
|
||||
|
||||
COPY fish_run_tests.sh /
|
||||
|
||||
ENV FISH_CHECK_LINT=false
|
||||
|
||||
CMD /fish_run_tests.sh
|
||||
@@ -11,9 +11,15 @@ EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
DOCKER_EXTRA_ARGS=""
|
||||
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
# Exit on failure.
|
||||
set -e
|
||||
|
||||
DOCKER_EXTRA_ARGS=""
|
||||
# Get fish source directory.
|
||||
workspace_root=$(cd "$( dirname "$0" )"/.. >/dev/null && pwd)
|
||||
|
||||
# Parse args.
|
||||
while [ $# -gt 1 ]; do
|
||||
@@ -37,19 +43,19 @@ while [ $# -gt 1 ]; do
|
||||
shift
|
||||
done
|
||||
|
||||
dockerfile=$1
|
||||
test -n "$dockerfile" || usage
|
||||
DOCKERFILE="$1"
|
||||
test -n "$DOCKERFILE" || usage
|
||||
|
||||
workspace_root=$(cd "$( dirname "$0" )"/.. >/dev/null && pwd)
|
||||
|
||||
. "$workspace_root"/docker/lib.sh
|
||||
|
||||
docker_build "$dockerfile"
|
||||
# Construct a docker image.
|
||||
IMG_TAGNAME="ghcr.io/fish-shell/fish-ci/$(basename -s .Dockerfile "$DOCKERFILE"):latest"
|
||||
docker build \
|
||||
-t "$IMG_TAGNAME" \
|
||||
-f "$DOCKERFILE" \
|
||||
"$workspace_root"/docker/context/
|
||||
|
||||
# Run tests in it, allowing them to fail without failing this script.
|
||||
# shellcheck disable=SC2046 # for the isatty snippet
|
||||
# shellcheck disable=SC2086 # $DOCKER_EXTRA_ARGS should have globbing and splitting applied.
|
||||
docker run -i $(isatty 0 && printf %s -t) \
|
||||
docker run -it \
|
||||
--mount type=bind,source="$workspace_root",target=/fish-source,readonly \
|
||||
$DOCKER_EXTRA_ARGS \
|
||||
"$(image_tagname "$dockerfile")"
|
||||
"$IMG_TAGNAME"
|
||||
|
||||
@@ -2,15 +2,17 @@ FROM fedora:latest
|
||||
LABEL org.opencontainers.image.source=https://github.com/fish-shell/fish-shell
|
||||
|
||||
RUN dnf install --assumeyes \
|
||||
cargo \
|
||||
diffutils \
|
||||
gcc-c++ \
|
||||
git-core \
|
||||
openssl \
|
||||
pcre2-devel \
|
||||
procps \
|
||||
python3 \
|
||||
python3-pip \
|
||||
openssl \
|
||||
procps \
|
||||
sudo && \
|
||||
rust \
|
||||
sudo \
|
||||
&& \
|
||||
dnf clean all
|
||||
|
||||
RUN pip3 install pexpect
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Get fish source directory.
|
||||
set -e
|
||||
# shellcheck disable=SC2154
|
||||
test -n "$workspace_root"
|
||||
|
||||
image_tagname() {
|
||||
printf %s "ghcr.io/fish-shell/fish-ci/$(basename -s .Dockerfile "$1"):latest"
|
||||
}
|
||||
|
||||
docker_build() {
|
||||
dockerfile=$1
|
||||
shift
|
||||
tagname=$(image_tagname "$dockerfile")
|
||||
docker pull "$tagname" || true
|
||||
DOCKER_BUILDKIT=1 \
|
||||
docker build \
|
||||
--cache-from "$tagname" \
|
||||
-t "$tagname" \
|
||||
-f "$dockerfile" \
|
||||
"$workspace_root"/docker/context/ \
|
||||
"$@"
|
||||
}
|
||||
@@ -7,7 +7,6 @@ ENV LC_ALL=C.UTF-8
|
||||
RUN zypper --non-interactive install \
|
||||
bash \
|
||||
diffutils \
|
||||
gcc-c++ \
|
||||
git-core \
|
||||
pcre2-devel \
|
||||
python311 \
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage: $(basename "$0") DOCKERFILE
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
dockerfile=$1
|
||||
test -n "$dockerfile" || usage
|
||||
|
||||
workspace_root=$(cd "$( dirname "$0" )"/.. >/dev/null && pwd)
|
||||
. "$workspace_root"/docker/lib.sh
|
||||
|
||||
docker_build "$dockerfile" --cache-to=type=inline
|
||||
docker push "$(image_tagname "$dockerfile")"
|
||||
@@ -61662,6 +61662,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61662,6 +61662,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61791,6 +61791,9 @@ msgstr "Ignorer le pré-traitement des blancs et commentaires"
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61665,6 +61665,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61658,6 +61658,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61663,6 +61663,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61659,6 +61659,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61683,6 +61683,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -61660,6 +61660,9 @@ msgstr ""
|
||||
msgid "Skipping JUnit Tests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips acquiring file locks"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skips autoloader generation"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
# Completions for the dnf command
|
||||
#
|
||||
|
||||
function __dnf_is_dnf5
|
||||
function __fish_dnf_is_dnf5
|
||||
path resolve -- $PATH/dnf | path filter | string match -q -- '*/dnf5'
|
||||
end
|
||||
|
||||
function __dnf_list_installed_packages
|
||||
function __fish_dnf_list_installed_packages
|
||||
dnf repoquery --cacheonly "$cur*" --qf "%{name}\n" --installed </dev/null
|
||||
end
|
||||
|
||||
function __dnf_list_copr_repos
|
||||
function __fish_dnf_list_copr_repos
|
||||
set -l copr_repos (dnf copr list)
|
||||
|
||||
switch $argv[1]
|
||||
@@ -23,7 +23,7 @@ function __dnf_list_copr_repos
|
||||
end
|
||||
end
|
||||
|
||||
function __dnf_list_available_packages
|
||||
function __fish_dnf_list_available_packages
|
||||
set -l tok (commandline -ct | string collect)
|
||||
set -l files (__fish_complete_suffix .rpm)
|
||||
if string match -q -- '*/*' $tok
|
||||
@@ -32,7 +32,7 @@ function __dnf_list_available_packages
|
||||
return
|
||||
end
|
||||
set -l results
|
||||
if __dnf_is_dnf5
|
||||
if __fish_dnf_is_dnf5
|
||||
# dnf5 provides faster completions than repoquery, but does not maintain the
|
||||
# same sqlite db as dnf4
|
||||
set results (dnf --complete=2 dnf install "$tok*")
|
||||
@@ -58,8 +58,8 @@ function __dnf_list_available_packages
|
||||
string join \n $results
|
||||
end
|
||||
|
||||
function __dnf_list_transactions
|
||||
if not __dnf_is_dnf5 && type -q sqlite3
|
||||
function __fish_dnf_list_transactions
|
||||
if not __fish_dnf_is_dnf5 && type -q sqlite3
|
||||
sqlite3 /var/lib/dnf/history.sqlite "SELECT id, cmdline FROM trans" 2>/dev/null | string replace "|" \t
|
||||
end
|
||||
end
|
||||
@@ -69,6 +69,7 @@ set -l dnf_install_cmds install in
|
||||
set -l dnf_remove_cmds remove rm
|
||||
set -l dnf_reinstall_cmds reinstall rei
|
||||
set -l dnf_info_cmds info if
|
||||
set -l dnf_upgrade_cmds upgrade up
|
||||
|
||||
# Alias
|
||||
complete -c dnf -n __fish_use_subcommand -xa alias -d "Manage aliases"
|
||||
@@ -78,7 +79,7 @@ complete -c dnf -n "__fish_seen_subcommand_from alias" -xa delete -d "Delete an
|
||||
|
||||
# Autoremove
|
||||
complete -c dnf -n __fish_use_subcommand -xa autoremove -d "Removes unneeded packages"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from autoremove" -xa "(__dnf_list_installed_packages)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from autoremove" -xa "(__fish_dnf_list_installed_packages)"
|
||||
|
||||
# Check
|
||||
complete -c dnf -n __fish_use_subcommand -xa check -d "Check for problems in packagedb"
|
||||
@@ -110,7 +111,7 @@ complete -c dnf -n "__fish_seen_subcommand_from copr; and not __fish_seen_subcom
|
||||
complete -c dnf -n "__fish_seen_subcommand_from copr; and not __fish_seen_subcommand_from $coprcommands" -l hub -d "Copr hub hostname"
|
||||
|
||||
for i in enable disable remove
|
||||
complete -c dnf -n "__fish_seen_subcommand_from copr; and __fish_seen_subcommand_from $i" -xa "(__dnf_list_copr_repos $i)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from copr; and __fish_seen_subcommand_from $i" -xa "(__fish_dnf_list_copr_repos $i)"
|
||||
end
|
||||
|
||||
# Distro-sync
|
||||
@@ -118,7 +119,7 @@ complete -c dnf -n __fish_use_subcommand -xa distro-sync -d "Synchronizes packag
|
||||
|
||||
# Downgrade
|
||||
complete -c dnf -n __fish_use_subcommand -xa downgrade -d "Downgrades the specified package"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from downgrade" -xa "(__dnf_list_installed_packages)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from downgrade" -xa "(__fish_dnf_list_installed_packages)"
|
||||
|
||||
# Group
|
||||
complete -c dnf -n __fish_use_subcommand -xa group -d "Manage groups"
|
||||
@@ -156,18 +157,18 @@ complete -c dnf -n "__fish_seen_subcommand_from history" -xa undo -d "Undoes the
|
||||
complete -c dnf -n "__fish_seen_subcommand_from history" -xa userinstalled -d "Lists all user installed packages"
|
||||
|
||||
for i in info redo rollback undo
|
||||
complete -c dnf -n "__fish_seen_subcommand_from history; and __fish_seen_subcommand_from $i" -xa "(__dnf_list_transactions)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from history; and __fish_seen_subcommand_from $i" -xa "(__fish_dnf_list_transactions)"
|
||||
end
|
||||
|
||||
# Info
|
||||
complete -c dnf -n __fish_use_subcommand -xa "$dnf_info_cmds" -d "Describes the given package"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from $dnf_info_cmds; and not __fish_seen_subcommand_from history" \
|
||||
-k -xa "(__dnf_list_available_packages)"
|
||||
-k -xa "(__fish_dnf_list_available_packages)"
|
||||
|
||||
# Install
|
||||
complete -c dnf -n __fish_use_subcommand -xa "$dnf_install_cmds" -d "Install package"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from $dnf_install_cmds" \
|
||||
-k -xa "(__dnf_list_available_packages)"
|
||||
-k -xa "(__fish_dnf_list_available_packages)"
|
||||
|
||||
# List
|
||||
complete -c dnf -n __fish_use_subcommand -xa list -d "Lists all packages"
|
||||
@@ -227,12 +228,12 @@ complete -c dnf -n __fish_use_subcommand -xa provides -d "Finds packages providi
|
||||
# Reinstall
|
||||
complete -c dnf -n __fish_use_subcommand -xa "$dnf_reinstall_cmds" -d "Reinstalls a package"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from $dnf_reinstall_cmds" \
|
||||
-xa "(__dnf_list_installed_packages)"
|
||||
-xa "(__fish_dnf_list_installed_packages)"
|
||||
|
||||
# Remove
|
||||
complete -c dnf -n __fish_use_subcommand -xa "$dnf_remove_cmds" -d "Remove packages"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from $dnf_remove_cmds" \
|
||||
-xa "(__dnf_list_installed_packages)"
|
||||
-xa "(__fish_dnf_list_installed_packages)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from remove" -l duplicates -d "Removes older version of duplicated packages"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from remove" -l oldinstallonly -d "Removes old installonly packages"
|
||||
|
||||
@@ -339,29 +340,29 @@ complete -c dnf -n "__fish_seen_subcommand_from updateinfo" -l installed
|
||||
complete -c dnf -n "__fish_seen_subcommand_from updateinfo" -l updates
|
||||
|
||||
# Upgrade
|
||||
complete -c dnf -n __fish_use_subcommand -xa upgrade -d "Updates packages"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from upgrade" -xa "(__dnf_list_installed_packages)"
|
||||
complete -c dnf -n __fish_use_subcommand -xa "$dnf_upgrade_cmds" -d "Updates packages"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from $dnf_upgrade_cmds" -xa "(__fish_dnf_list_installed_packages)"
|
||||
|
||||
# Upgrade-Minimal
|
||||
complete -c dnf -n __fish_use_subcommand -xa upgrade-minimal -d "Updates packages"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from upgrade-minimal" -xa "(__dnf_list_installed_packages)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from upgrade-minimal" -xa "(__fish_dnf_list_installed_packages)"
|
||||
|
||||
# Versionlock
|
||||
if test -f /etc/dnf/plugins/versionlock.conf
|
||||
function __dnf_current_versionlock_list
|
||||
function __fish_dnf_current_versionlock_list
|
||||
dnf versionlock list | grep -v metadata
|
||||
end
|
||||
|
||||
complete -c dnf -n __fish_use_subcommand -xa versionlock -d "DNF versionlock plugin"
|
||||
# - add
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock" -xa add -d "Add a versionlock for all available packages matching the spec"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from add" -xa "(__dnf_list_installed_packages)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from add" -xa "(__fish_dnf_list_installed_packages)"
|
||||
# - exclude
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock" -xa exclude -d "Add an exclude (within versionlock) for the available packages matching the spec"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from exclude" -xa "(__dnf_list_installed_packages)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from exclude" -xa "(__fish_dnf_list_installed_packages)"
|
||||
# - delete
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock" -xa delete -d "Remove any matching versionlock entries"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from delete" -xa "(__dnf_current_versionlock_list)"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from delete" -xa "(__fish_dnf_current_versionlock_list)"
|
||||
# - list
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock" -xa list -d "List the current versionlock entries"
|
||||
complete -c dnf -n "__fish_seen_subcommand_from versionlock; and __fish_seen_subcommand_from list" -xa "(false)"
|
||||
@@ -371,55 +372,54 @@ if test -f /etc/dnf/plugins/versionlock.conf
|
||||
end
|
||||
|
||||
# Options:
|
||||
# Using __fish_no_arguments here so that users are not completely overloaded with
|
||||
# available options when using subcommands (e.g. repoquery) (40 vs 100ish)
|
||||
complete -c dnf -n __fish_no_arguments -s 4 -d "Use IPv4 only"
|
||||
complete -c dnf -n __fish_no_arguments -s 6 -d "Use IPv6 only"
|
||||
complete -c dnf -n __fish_no_arguments -l advisory -l advisories -d "Include packages corresponding to the advisory ID"
|
||||
complete -c dnf -n __fish_no_arguments -l allowerasing -d "Allow erasing of installed packages to resolve dependencies"
|
||||
complete -c dnf -n __fish_no_arguments -l assumeno -d "Answer no for all questions"
|
||||
complete -c dnf -n __fish_no_arguments -s b -l best -d "Try the best available package versions in transactions"
|
||||
complete -c dnf -n __fish_no_arguments -l bugfix -d "Include packages that fix a bugfix issue"
|
||||
complete -c dnf -n __fish_no_arguments -l bz -l bzs -d "Include packages that fix a Bugzilla ID"
|
||||
complete -c dnf -n __fish_no_arguments -s C -l cacheonly -d "Run entirely from system cache"
|
||||
complete -c dnf -n __fish_no_arguments -l color -xa "always never auto" -d "Control whether color is used"
|
||||
complete -c dnf -n __fish_no_arguments -s c -l config -d "Configuration file location"
|
||||
complete -c dnf -n __fish_no_arguments -l cve -l cves -d "Include packages that fix a CVE"
|
||||
complete -c dnf -n __fish_no_arguments -s d -l debuglevel -d "Debugging output level"
|
||||
complete -c dnf -n __fish_no_arguments -l debugsolver -d "Dump dependency solver debugging info"
|
||||
complete -c dnf -n __fish_no_arguments -l disableexcludes -l disableexcludepkgs -d "Disable excludes"
|
||||
complete -c dnf -n __fish_no_arguments -l disable -l set-disabled -d "Disable specified repositories"
|
||||
complete -c dnf -n __fish_no_arguments -l disableplugin -d "Disable the listed plugins specified"
|
||||
complete -c dnf -n __fish_no_arguments -l disablerepo -d "Disable specified repositories"
|
||||
complete -c dnf -n __fish_no_arguments -l downloaddir -l destdir -d "Change downloaded packages to provided directory"
|
||||
complete -c dnf -n __fish_no_arguments -l downloadonly -d "Download packages without performing any transaction"
|
||||
complete -c dnf -n __fish_no_arguments -l enable -l set-enabled -d "Enable specified repositories"
|
||||
complete -c dnf -n __fish_no_arguments -l enableplugin -d "Enable the listed plugins"
|
||||
complete -c dnf -n __fish_no_arguments -l enablerepo -d "Enable additional repositories"
|
||||
complete -c dnf -n __fish_no_arguments -l enhancement -d "Include enhancement relevant packages"
|
||||
complete -c dnf -n __fish_no_arguments -s x -l exclude -d "Exclude packages specified"
|
||||
complete -c dnf -n __fish_no_arguments -l forcearch -d "Force the use of the specified architecture"
|
||||
complete -c dnf -n __fish_no_arguments -s h -l help -l help-i -d "Show the help"
|
||||
complete -c dnf -n __fish_no_arguments -l installroot -d "Specifies an alternative installroot"
|
||||
complete -c dnf -n __fish_no_arguments -l newpackage -d "Include newpackage relevant packages"
|
||||
complete -c dnf -n __fish_no_arguments -l noautoremove -d "Disable autoremove"
|
||||
complete -c dnf -n __fish_no_arguments -l nobest -d "Set best option to False"
|
||||
complete -c dnf -n __fish_no_arguments -l nodocs -d "Do not install documentation"
|
||||
complete -c dnf -n __fish_no_arguments -l nogpgcheck -d "Skip checking GPG signatures on packages"
|
||||
complete -c dnf -n __fish_no_arguments -l noplugins -d "Disable all plugins"
|
||||
complete -c dnf -n __fish_no_arguments -l obsoletes -d "Enables obsoletes processing logic"
|
||||
complete -c dnf -n __fish_no_arguments -s q -l quiet -d "Quiet mode"
|
||||
complete -c dnf -n __fish_no_arguments -s R -l randomwait -d "Maximum command wait time"
|
||||
complete -c dnf -n __fish_no_arguments -l refresh -d "Set metadata as expired before running the command"
|
||||
complete -c dnf -n __fish_no_arguments -l releasever -d "Configure the distribution release"
|
||||
complete -c dnf -n __fish_no_arguments -l repofrompath -d "Specify repository to add to the repositories for this query"
|
||||
complete -c dnf -n __fish_no_arguments -l repo -l repoid -d "Enable just specific repositories by an id or a glob"
|
||||
complete -c dnf -n __fish_no_arguments -l rpmverbosity -d "RPM debug scriptlet output level"
|
||||
complete -c dnf -n __fish_no_arguments -l sec-severity -l secseverity -d "Includes packages that provide a fix for an issue of the specified severity"
|
||||
complete -c dnf -n __fish_no_arguments -l security -d "Includes packages that provide a fix for a security issue"
|
||||
complete -c dnf -n __fish_no_arguments -l setopt -d "Override a configuration option"
|
||||
complete -c dnf -n __fish_no_arguments -l skip-broken -d "Skips broken packages"
|
||||
complete -c dnf -n __fish_no_arguments -l showduplicates -d "Shows duplicate packages"
|
||||
complete -c dnf -n __fish_no_arguments -s v -l verbose -d "Verbose mode"
|
||||
complete -c dnf -n __fish_no_arguments -l version -d "Shows DNF version and exit"
|
||||
complete -c dnf -n __fish_no_arguments -s y -l assumeyes -d "Answer yes for all questions"
|
||||
complete -c dnf -s 4 -d "Use IPv4 only"
|
||||
complete -c dnf -s 6 -d "Use IPv6 only"
|
||||
complete -c dnf -l advisory -l advisories -d "Include packages corresponding to the advisory ID"
|
||||
complete -c dnf -l allowerasing -d "Allow erasing of installed packages to resolve dependencies"
|
||||
complete -c dnf -l assumeno -d "Answer no for all questions"
|
||||
complete -c dnf -s b -l best -d "Try the best available package versions in transactions"
|
||||
complete -c dnf -l bugfix -d "Include packages that fix a bugfix issue"
|
||||
complete -c dnf -l bz -l bzs -d "Include packages that fix a Bugzilla ID"
|
||||
complete -c dnf -s C -l cacheonly -d "Run entirely from system cache"
|
||||
complete -c dnf -l color -xa "always never auto" -d "Control whether color is used"
|
||||
complete -c dnf -s c -l config -d "Configuration file location"
|
||||
complete -c dnf -l cve -l cves -d "Include packages that fix a CVE"
|
||||
complete -c dnf -s d -l debuglevel -d "Debugging output level"
|
||||
complete -c dnf -l debugsolver -d "Dump dependency solver debugging info"
|
||||
complete -c dnf -l disableexcludes -l disableexcludepkgs -d "Disable excludes"
|
||||
complete -c dnf -l disable -l set-disabled -d "Disable specified repositories"
|
||||
complete -c dnf -l disableplugin -d "Disable the listed plugins specified"
|
||||
complete -c dnf -l disablerepo -d "Disable specified repositories"
|
||||
complete -c dnf -l downloaddir -l destdir -d "Change downloaded packages to provided directory"
|
||||
complete -c dnf -l downloadonly -d "Download packages without performing any transaction"
|
||||
complete -c dnf -l enable -l set-enabled -d "Enable specified repositories"
|
||||
complete -c dnf -l enableplugin -d "Enable the listed plugins"
|
||||
complete -c dnf -l enablerepo -d "Enable additional repositories"
|
||||
complete -c dnf -l enhancement -d "Include enhancement relevant packages"
|
||||
complete -c dnf -s x -l exclude -d "Exclude packages specified"
|
||||
complete -c dnf -l forcearch -d "Force the use of the specified architecture"
|
||||
complete -c dnf -s h -l help -l help-i -d "Show the help"
|
||||
complete -c dnf -l installroot -d "Specifies an alternative installroot"
|
||||
complete -c dnf -l newpackage -d "Include newpackage relevant packages"
|
||||
complete -c dnf -l noautoremove -d "Disable autoremove"
|
||||
complete -c dnf -l nobest -d "Set best option to False"
|
||||
complete -c dnf -l nodocs -d "Do not install documentation"
|
||||
complete -c dnf -l nogpgcheck -d "Skip checking GPG signatures on packages"
|
||||
complete -c dnf -l noplugins -d "Disable all plugins"
|
||||
complete -c dnf -l obsoletes -d "Enables obsoletes processing logic"
|
||||
complete -c dnf -s q -l quiet -d "Quiet mode"
|
||||
complete -c dnf -s R -l randomwait -d "Maximum command wait time"
|
||||
complete -c dnf -l refresh -d "Set metadata as expired before running the command"
|
||||
complete -c dnf -l releasever -d "Configure the distribution release"
|
||||
complete -c dnf -l repofrompath -d "Specify repository to add to the repositories for this query"
|
||||
complete -c dnf -l repo -l repoid -d "Enable just specific repositories by an id or a glob"
|
||||
complete -c dnf -l rpmverbosity -d "RPM debug scriptlet output level"
|
||||
complete -c dnf -l sec-severity -l secseverity -d "Includes packages that provide a fix for an issue of the specified severity"
|
||||
complete -c dnf -l security -d "Includes packages that provide a fix for a security issue"
|
||||
complete -c dnf -l setopt -d "Override a configuration option"
|
||||
complete -c dnf -l skip-broken -d "Skips broken packages"
|
||||
complete -c dnf -l showduplicates -d "Shows duplicate packages"
|
||||
complete -c dnf -s v -l verbose -d "Verbose mode"
|
||||
complete -c dnf -l version -d "Shows DNF version and exit"
|
||||
complete -c dnf -s y -l assumeyes -d "Answer yes for all questions"
|
||||
complete -c dnf -s y -l skip-file-locks -d "Skips acquiring file locks"
|
||||
|
||||
@@ -1 +1 @@
|
||||
complete -c firefox-developer-edition -w firefox
|
||||
__fish_complete_firefox firefox-developer-edition
|
||||
|
||||
@@ -1,41 +1 @@
|
||||
# X11 options
|
||||
complete -c firefox -l display -r -d "X display to use"
|
||||
complete -c firefox -l sync -d "Make X calls synchronous"
|
||||
complete -c firefox -l g-fatal-warnings -d "Make all warnings fatal"
|
||||
|
||||
# Firefox options
|
||||
complete -c firefox -s h -l help -d "Print this message"
|
||||
complete -c firefox -s v -l version -d "Print Firefox version"
|
||||
complete -c firefox -l full-version -d "Print Firefox version, build and platform build ids"
|
||||
complete -c firefox -s P -r -d "Start this profile" -fa '(string replace -rf "^Name=(.*)" \'$1\' < ~/.mozilla/firefox/profiles.ini)'
|
||||
complete -c firefox -l profile -r -d "Start with profile at <path>"
|
||||
complete -c firefox -l migration -d "Start with migration wizard"
|
||||
complete -c firefox -l ProfileManager -d "Start with ProfileManager"
|
||||
complete -c firefox -l no-remote -d "Do not accept or send remote commands implies --new-instance"
|
||||
complete -c firefox -l new-instance -d "Open new instance, not a new window in running instance"
|
||||
complete -c firefox -l safe-mode -d "Disables extensions and themes for this session"
|
||||
complete -c firefox -l allow-downgrade -d "Allows downgrading a profile"
|
||||
complete -c firefox -l MOZ_LOG -rf -d "Treated as MOZ_LOG=<modules> environment variable, overrides it"
|
||||
complete -c firefox -l MOZ_LOG_FILE -r -d "Treated as MOZ_LOG_FILE=<file> environment variable, overrides it"
|
||||
complete -c firefox -l headless -d "Run without a GUI"
|
||||
complete -c firefox -l jsdebugger -d "Open the Browser Toolbox"
|
||||
complete -c firefox -l wait-for-jsdebugger -d "Spin event loop until JS debugger connects"
|
||||
complete -c firefox -l start-debugger-server -d "Start the devtools server on a TCP port or Unix domain socket path"
|
||||
complete -c firefox -l browser -d "Open a browser window"
|
||||
complete -c firefox -l new-window -r -d "Open <url> in a new window"
|
||||
complete -c firefox -l new-tab -r -d "Open <url> in a new tab"
|
||||
complete -c firefox -l private-window -r -d "Open <url> in a new private window"
|
||||
complete -c firefox -l preferences -d "Open Preferences dialog"
|
||||
complete -c firefox -l screenshot -d "Save screenshot to <path> or in working directory"
|
||||
complete -c firefox -rf -l window-size -d "Width and optionally height of screenshot"
|
||||
complete -c firefox -l search -r -d "Search <term> with your default search engine"
|
||||
complete -c firefox -l setDefaultBrowser -d "Set this app as the default browser"
|
||||
complete -c firefox -l first-startup -d "Run post-install actions before opening a new window"
|
||||
complete -c firefox -l kiosk -d "Start the browser in kiosk mode"
|
||||
complete -c firefox -l disable-pinch -d "Disable touch-screen and touch-pad pinch gestures"
|
||||
complete -c firefox -l jsconsole -d "Open the Browser Console"
|
||||
complete -c firefox -l devtools -d "Open DevTools on initial load"
|
||||
complete -c firefox -l marionette -d "Enable remote control server"
|
||||
complete -c firefox -f -l remote-debugging-port -d "Start the Firefox Remote Agent"
|
||||
complete -c firefox -f -l remote-allow-hosts -r -d "Values of the Host header to allow for incoming requests"
|
||||
complete -c firefox -f -l remote-allow-origins -r -d "Values of the Origin header to allow for incoming requests"
|
||||
__fish_complete_firefox firefox
|
||||
|
||||
@@ -8,7 +8,7 @@ complete --command fish_opt --short-option h --long-option help --description 'S
|
||||
|
||||
complete --command fish_opt --short-option s --long-option short --no-files --require-parameter --description 'Specify short option'
|
||||
complete --command fish_opt --short-option l --long-option long --no-files --require-parameter --description 'Specify long option'
|
||||
complete --command fish_opt --long-option longonly --description 'Use only long option'
|
||||
complete --command fish_opt --long-option long-only --description 'Use only long option'
|
||||
complete --command fish_opt --short-option o --long-option optional-val -n $CONDITION --description 'Don\'t require value'
|
||||
complete --command fish_opt --short-option r --long-option required-val -n $CONDITION --description 'Require value'
|
||||
complete --command fish_opt --short-option m --long-option multiple-vals --description 'Store all values'
|
||||
|
||||
@@ -77,6 +77,8 @@ function __fish_complete_special_vars
|
||||
fish_user_paths "A list of dirs to prepend to PATH"
|
||||
__fish_complete_special_vars_ifndef fish_color_option 'defaults to $fish_color_param'
|
||||
__fish_complete_special_vars_ifndef fish_color_keyword 'defaults to $fish_color_command'
|
||||
__fish_complete_special_vars_ifndef fish_color_builtin 'defaults to $fish_color_command'
|
||||
__fish_complete_special_vars_ifndef fish_color_function 'defaults to $fish_color_command'
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
44
share/functions/__fish_complete_firefox.fish
Normal file
44
share/functions/__fish_complete_firefox.fish
Normal file
@@ -0,0 +1,44 @@
|
||||
# localization: tier3
|
||||
function __fish_complete_firefox -a firefox
|
||||
# X11 options
|
||||
complete $firefox -l display -r -d "X display to use"
|
||||
complete $firefox -l sync -d "Make X calls synchronous"
|
||||
complete $firefox -l g-fatal-warnings -d "Make all warnings fatal"
|
||||
|
||||
# Firefox options
|
||||
complete $firefox -s h -l help -d "Print this message"
|
||||
complete $firefox -s v -l version -d "Print Firefox version"
|
||||
complete $firefox -l full-version -d "Print Firefox version, build and platform build ids"
|
||||
complete $firefox -s P -r -d "Start this profile" -fa '(string replace -rf "^Name=(.*)" \'$1\' < ~/.mozilla/firefox/profiles.ini)'
|
||||
complete $firefox -l profile -r -d "Start with profile at <path>"
|
||||
complete $firefox -l migration -d "Start with migration wizard"
|
||||
complete $firefox -l ProfileManager -d "Start with ProfileManager"
|
||||
complete $firefox -l no-remote -d "Do not accept or send remote commands implies --new-instance"
|
||||
complete $firefox -l new-instance -d "Open new instance, not a new window in running instance"
|
||||
complete $firefox -l safe-mode -d "Disables extensions and themes for this session"
|
||||
complete $firefox -l allow-downgrade -d "Allows downgrading a profile"
|
||||
complete $firefox -l MOZ_LOG -rf -d "Treated as MOZ_LOG=<modules> environment variable, overrides it"
|
||||
complete $firefox -l MOZ_LOG_FILE -r -d "Treated as MOZ_LOG_FILE=<file> environment variable, overrides it"
|
||||
complete $firefox -l headless -d "Run without a GUI"
|
||||
complete $firefox -l jsdebugger -d "Open the Browser Toolbox"
|
||||
complete $firefox -l wait-for-jsdebugger -d "Spin event loop until JS debugger connects"
|
||||
complete $firefox -l start-debugger-server -d "Start the devtools server on a TCP port or Unix domain socket path"
|
||||
complete $firefox -l browser -d "Open a browser window"
|
||||
complete $firefox -l new-window -r -d "Open <url> in a new window"
|
||||
complete $firefox -l new-tab -r -d "Open <url> in a new tab"
|
||||
complete $firefox -l private-window -r -d "Open <url> in a new private window"
|
||||
complete $firefox -l preferences -d "Open Preferences dialog"
|
||||
complete $firefox -l screenshot -d "Save screenshot to <path> or in working directory"
|
||||
complete $firefox -rf -l window-size -d "Width and optionally height of screenshot"
|
||||
complete $firefox -l search -r -d "Search <term> with your default search engine"
|
||||
complete $firefox -l setDefaultBrowser -d "Set this app as the default browser"
|
||||
complete $firefox -l first-startup -d "Run post-install actions before opening a new window"
|
||||
complete $firefox -l kiosk -d "Start the browser in kiosk mode"
|
||||
complete $firefox -l disable-pinch -d "Disable touch-screen and touch-pad pinch gestures"
|
||||
complete $firefox -l jsconsole -d "Open the Browser Console"
|
||||
complete $firefox -l devtools -d "Open DevTools on initial load"
|
||||
complete $firefox -l marionette -d "Enable remote control server"
|
||||
complete $firefox -f -l remote-debugging-port -d "Start the Firefox Remote Agent"
|
||||
complete $firefox -f -l remote-allow-hosts -r -d "Values of the Host header to allow for incoming requests"
|
||||
complete $firefox -f -l remote-allow-origins -r -d "Values of the Origin header to allow for incoming requests"
|
||||
end
|
||||
@@ -1291,6 +1291,8 @@ fn html_class_name_for_color(spec: HighlightSpec) -> &'static wstr {
|
||||
HighlightRole::Normal => L!("fish_color_normal"),
|
||||
HighlightRole::Error => L!("fish_color_error"),
|
||||
HighlightRole::Command => L!("fish_color_command"),
|
||||
HighlightRole::Builtin => L!("fish_color_builtin"),
|
||||
HighlightRole::Function => L!("fish_color_function"),
|
||||
HighlightRole::StatementTerminator => L!("fish_color_statement_terminator"),
|
||||
HighlightRole::Param => L!("fish_color_param"),
|
||||
HighlightRole::Option => L!("fish_color_option"),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
abbrs::{Position, with_abbrs},
|
||||
abbrs::with_abbrs,
|
||||
ast::unescape_keyword,
|
||||
autoload::{Autoload, AutoloadResult},
|
||||
builtins::{builtin_exists, builtin_get_desc, builtin_get_names},
|
||||
@@ -689,7 +689,7 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
return;
|
||||
}
|
||||
self.complete_cmd(WString::new());
|
||||
self.complete_abbr(L!(""), true);
|
||||
self.complete_abbr(L!(""));
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -744,7 +744,7 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
return;
|
||||
}
|
||||
// Complete command filename.
|
||||
self.complete_abbr(current_token, true);
|
||||
self.complete_abbr(current_token);
|
||||
self.complete_cmd(current_token.to_owned());
|
||||
return;
|
||||
}
|
||||
@@ -784,17 +784,10 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
enum DoFile {
|
||||
No,
|
||||
Yes,
|
||||
Only,
|
||||
}
|
||||
|
||||
let mut do_file = DoFile::No;
|
||||
let mut do_file = false;
|
||||
let mut handle_as_special_cd = false;
|
||||
if in_redirection {
|
||||
do_file = DoFile::Only;
|
||||
do_file = true;
|
||||
} else {
|
||||
// Try completing as an argument.
|
||||
let mut arg_data = CustomArgData::new(&mut var_assignments);
|
||||
@@ -824,15 +817,11 @@ enum DoFile {
|
||||
command_range,
|
||||
&mut arg_data,
|
||||
);
|
||||
do_file = if arg_data.do_file {
|
||||
DoFile::Yes
|
||||
} else {
|
||||
DoFile::No
|
||||
};
|
||||
do_file = arg_data.do_file;
|
||||
|
||||
// If we're autosuggesting, and the token is empty, don't do file suggestions.
|
||||
if is_autosuggest && arg_data.current_argument.is_empty() {
|
||||
do_file = DoFile::No;
|
||||
do_file = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,14 +833,10 @@ enum DoFile {
|
||||
// Maybe apply variable assignments.
|
||||
let block = self.apply_var_assignments(&var_assignments);
|
||||
if !self.ctx.check_cancel() {
|
||||
if do_file != DoFile::Only {
|
||||
self.complete_abbr(current_argument, false);
|
||||
}
|
||||
|
||||
// This function wants the unescaped string.
|
||||
self.complete_param_expand(
|
||||
current_argument,
|
||||
do_file != DoFile::No,
|
||||
do_file,
|
||||
handle_as_special_cd,
|
||||
cur_tok.is_unterminated_brace,
|
||||
);
|
||||
@@ -908,26 +893,17 @@ fn short_option_pos(&mut self, arg: &wstr, options: &[CompleteEntryOpt]) -> Opti
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut seen_short_options = HashSet::new();
|
||||
for (pos, arg_char) in arg.chars().enumerate().skip(1) {
|
||||
let mut matched = None;
|
||||
for o in options {
|
||||
if o.typ == CompleteOptionType::Short
|
||||
let matched = options.iter().find(|o| {
|
||||
o.typ == CompleteOptionType::Short
|
||||
&& o.option.char_at(0) == arg_char
|
||||
&& self.conditions_test(&o.conditions)
|
||||
{
|
||||
matched = Some(o);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(matched) = matched {
|
||||
if matched.result_mode.requires_param {
|
||||
return Some(pos);
|
||||
}
|
||||
if !seen_short_options.insert(arg_char) {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
// The first character after the dash is not a valid option.
|
||||
if pos == 1 {
|
||||
@@ -1196,18 +1172,15 @@ fn complete_cmd(&mut self, str_cmd: WString) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempt to complete a non-regex abbreviation for the given string.
|
||||
fn complete_abbr(&mut self, cmd: &wstr, is_command_position: bool) {
|
||||
/// Attempt to complete an abbreviation for the given string.
|
||||
fn complete_abbr(&mut self, cmd: &wstr) {
|
||||
// Copy the list of names and descriptions so as not to hold the lock across the call to
|
||||
// complete_strings.
|
||||
let mut possible_comp = Vec::new();
|
||||
let mut descs = HashMap::new();
|
||||
with_abbrs(|set| {
|
||||
for abbr in set.list() {
|
||||
if abbr.is_regex() {
|
||||
continue;
|
||||
}
|
||||
if abbr.position == Position::Anywhere || is_command_position {
|
||||
if !abbr.is_regex() {
|
||||
possible_comp.push(Completion::from_completion(abbr.key.clone()));
|
||||
descs.insert(abbr.key.clone(), abbr.replacement.clone());
|
||||
}
|
||||
@@ -2229,8 +2202,10 @@ fn param_match(e: &CompleteEntryOpt, optstr: &wstr) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if a string is an option with an argument, like --color=auto or -I/usr/include.
|
||||
/// Test if a string is an option with an argument, like --color=auto or -std=c++26.
|
||||
/// Short options are handled by the caller.
|
||||
fn param_match2(e: &CompleteEntryOpt, optstr: &wstr) -> Option<usize> {
|
||||
assert!(e.typ != CompleteOptionType::Short);
|
||||
// We may get a complete_entry_opt_t with no options if it's just arguments.
|
||||
if e.option.is_empty() {
|
||||
return None;
|
||||
@@ -2250,7 +2225,6 @@ fn param_match2(e: &CompleteEntryOpt, optstr: &wstr) -> Option<usize> {
|
||||
|
||||
// Short options are like -DNDEBUG. Long options are like --color=auto. So check for an equal
|
||||
// sign for long options.
|
||||
assert!(e.typ != CompleteOptionType::Short);
|
||||
if optstr.char_at(cursor) != '=' {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -22,19 +22,19 @@
|
||||
use libc::PATH_MAX;
|
||||
use nix::unistd::AccessFlags;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
collections::{HashMap, hash_map},
|
||||
os::fd::RawFd,
|
||||
};
|
||||
|
||||
// This is used only internally to this file, and is exposed only for testing.
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct PathFlags {
|
||||
struct PathFlags {
|
||||
// The path must be to a directory.
|
||||
pub require_dir: bool,
|
||||
require_dir: bool,
|
||||
// Expand any leading tilde in the path.
|
||||
pub expand_tilde: bool,
|
||||
expand_tilde: bool,
|
||||
// Normalize directories before resolving, as "cd".
|
||||
pub for_cd: bool,
|
||||
for_cd: bool,
|
||||
}
|
||||
|
||||
// When a file test is OK, we may also return whether this was a file.
|
||||
@@ -48,15 +48,15 @@ pub struct PathFlags {
|
||||
/// The result of a file test.
|
||||
pub type FileTestResult = Result<IsFile, IsErr>;
|
||||
|
||||
pub struct FileTester<'src, 'opctx> {
|
||||
pub struct FileTester<'src, 'wd, 'opctx> {
|
||||
// The working directory, for resolving paths against.
|
||||
working_directory: WString,
|
||||
working_directory: &'wd wstr,
|
||||
// The operation context.
|
||||
pub(super) ctx: &'opctx mut OperationContext<'src>,
|
||||
pub ctx: &'opctx mut OperationContext<'src>,
|
||||
}
|
||||
|
||||
impl<'src, 'opctx> FileTester<'src, 'opctx> {
|
||||
pub fn new(working_directory: WString, ctx: &'opctx mut OperationContext<'src>) -> Self {
|
||||
impl<'src, 'wd, 'opctx> FileTester<'src, 'wd, 'opctx> {
|
||||
pub fn new(working_directory: &'wd wstr, ctx: &'opctx mut OperationContext<'src>) -> Self {
|
||||
Self {
|
||||
working_directory,
|
||||
ctx,
|
||||
@@ -110,7 +110,7 @@ pub fn test_cd_path(&mut self, token: &wstr, is_prefix: bool) -> FileTestResult
|
||||
let valid_path = is_potential_cd_path(
|
||||
¶m,
|
||||
is_prefix,
|
||||
&self.working_directory,
|
||||
self.working_directory,
|
||||
self.ctx,
|
||||
PathFlags {
|
||||
expand_tilde: true,
|
||||
@@ -144,7 +144,7 @@ pub fn test_redirection_target(
|
||||
// Ok, we successfully expanded our target. Now verify that it works with this
|
||||
// redirection. We will probably need it as a path (but not in the case of fd
|
||||
// redirections). Note that the target is now unescaped.
|
||||
let target_path = path_apply_working_directory(&target, &self.working_directory);
|
||||
let target_path = path_apply_working_directory(&target, self.working_directory);
|
||||
match mode {
|
||||
RedirectionMode::Fd => {
|
||||
if target == "-" {
|
||||
@@ -224,10 +224,10 @@ pub fn test_redirection_target(
|
||||
/// cdpath). This does I/O!
|
||||
///
|
||||
/// We expect the path to already be unescaped.
|
||||
pub fn is_potential_path(
|
||||
fn is_potential_path(
|
||||
potential_path_fragment: &wstr,
|
||||
at_cursor: bool,
|
||||
directories: &[WString],
|
||||
directories: &[&wstr],
|
||||
ctx: &OperationContext<'_>,
|
||||
flags: PathFlags,
|
||||
) -> bool {
|
||||
@@ -274,7 +274,8 @@ pub fn is_potential_path(
|
||||
|
||||
// Don't test the same path multiple times, which can happen if the path is absolute and the
|
||||
// CDPATH contains multiple entries.
|
||||
let mut checked_paths = HashSet::new();
|
||||
// TODO This should be a HashSet https://github.com/rust-lang/rust/issues/60896.
|
||||
let mut checked_paths = HashMap::new();
|
||||
|
||||
// Keep a cache of which paths / filesystems are case sensitive.
|
||||
let mut case_sensitivity_cache = CaseSensitivityCache::new();
|
||||
@@ -289,11 +290,17 @@ pub fn is_potential_path(
|
||||
abs_path = normalize_path(&abs_path, /*allow_leading_double_slashes=*/ true);
|
||||
}
|
||||
|
||||
// Skip this if it's empty or we've already checked it.
|
||||
if abs_path.is_empty() || checked_paths.contains(&abs_path) {
|
||||
if abs_path.is_empty() {
|
||||
continue;
|
||||
}
|
||||
checked_paths.insert(abs_path.clone());
|
||||
let abs_path = {
|
||||
use hash_map::Entry::*;
|
||||
match checked_paths.entry(abs_path) {
|
||||
Occupied(_occupied_entry) => continue,
|
||||
Vacant(vacant) => vacant.insert_entry(()),
|
||||
}
|
||||
};
|
||||
let abs_path = abs_path.key();
|
||||
|
||||
// If the user is still typing the argument, we want to highlight it if it's the prefix
|
||||
// of a valid path. This means we need to potentially walk all files in some directory.
|
||||
@@ -302,15 +309,15 @@ pub fn is_potential_path(
|
||||
// 2. If the cursor is not at the argument, it means the user is definitely not typing it,
|
||||
// so we can skip the prefix-match.
|
||||
if must_be_full_dir || !at_cursor {
|
||||
if let Ok(md) = wstat(&abs_path) {
|
||||
if let Ok(md) = wstat(abs_path) {
|
||||
if !at_cursor || md.file_type().is_dir() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We do not end with a slash; it does not have to be a directory.
|
||||
let dir_name = wdirname(&abs_path);
|
||||
let filename_fragment = wbasename(&abs_path);
|
||||
let dir_name = wdirname(abs_path);
|
||||
let filename_fragment = wbasename(abs_path);
|
||||
if dir_name == "/" && filename_fragment == "/" {
|
||||
// cd ///.... No autosuggestion.
|
||||
return true;
|
||||
@@ -351,7 +358,7 @@ pub fn is_potential_path(
|
||||
|
||||
// Given a string, return whether it prefixes a path that we could cd into. Return that path in
|
||||
// out_path. Expects path to be unescaped.
|
||||
pub fn is_potential_cd_path(
|
||||
fn is_potential_cd_path(
|
||||
path: &wstr,
|
||||
at_cursor: bool,
|
||||
working_directory: &wstr,
|
||||
@@ -359,27 +366,36 @@ pub fn is_potential_cd_path(
|
||||
mut flags: PathFlags,
|
||||
) -> bool {
|
||||
let mut directories = vec![];
|
||||
let mut storage = vec![];
|
||||
|
||||
if string_prefixes_string(L!("./"), path) {
|
||||
// Ignore the CDPATH in this case; just use the working directory.
|
||||
directories.push(working_directory.to_owned());
|
||||
directories.push(working_directory);
|
||||
} else {
|
||||
// Get the CDPATH.
|
||||
let cdpath = ctx.vars().get_unless_empty(L!("CDPATH"));
|
||||
let mut pathsv = match cdpath {
|
||||
None => vec![L!(".").to_owned()],
|
||||
Some(cdpath) => cdpath.as_list().to_vec(),
|
||||
};
|
||||
// The current $PWD is always valid.
|
||||
pathsv.push(L!(".").to_owned());
|
||||
|
||||
for mut next_path in pathsv {
|
||||
if next_path.is_empty() {
|
||||
next_path = L!(".").to_owned();
|
||||
}
|
||||
fn add_path(storage: &mut Vec<WString>, working_directory: &wstr, next_path: &wstr) {
|
||||
// Ensure that we use the working directory for relative cdpaths like ".".
|
||||
directories.push(path_apply_working_directory(&next_path, working_directory));
|
||||
storage.push(path_apply_working_directory(next_path, working_directory));
|
||||
}
|
||||
|
||||
// Get the CDPATH.
|
||||
let mut have_curdir = false;
|
||||
if let Some(cdpath) = ctx.vars().get_unless_empty(L!("CDPATH")) {
|
||||
for next_path in cdpath.as_list() {
|
||||
let mut next_path = next_path.as_utfstr();
|
||||
if next_path.is_empty() {
|
||||
next_path = L!(".");
|
||||
}
|
||||
if next_path == L!(".") {
|
||||
have_curdir = true;
|
||||
}
|
||||
add_path(&mut storage, working_directory, next_path);
|
||||
}
|
||||
}
|
||||
// The current $PWD is always valid.
|
||||
if !have_curdir {
|
||||
add_path(&mut storage, working_directory, L!("."));
|
||||
}
|
||||
directories = storage.iter().map(|s| s.as_utfstr()).collect();
|
||||
}
|
||||
|
||||
// Call is_potential_path with all of these directories.
|
||||
@@ -394,7 +410,7 @@ pub fn is_potential_cd_path(
|
||||
/// Returns:
|
||||
/// false: the filesystem is not case insensitive
|
||||
/// true: the file system is case insensitive
|
||||
pub type CaseSensitivityCache = HashMap<WString, bool>;
|
||||
type CaseSensitivityCache = HashMap<WString, bool>;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
fn fs_is_case_insensitive(
|
||||
@@ -414,7 +430,7 @@ fn fs_is_case_insensitive(
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
|
||||
pub fn fs_is_case_insensitive(
|
||||
fn fs_is_case_insensitive(
|
||||
_path: &wstr,
|
||||
_fd: RawFd,
|
||||
_case_sensitivity_cache: &mut CaseSensitivityCache,
|
||||
@@ -453,17 +469,11 @@ fn op_context() -> OperationContext<'static> {
|
||||
OperationContext::empty()
|
||||
}
|
||||
|
||||
fn file_tester<'a>(
|
||||
ctx: &'a mut OperationContext<'static>,
|
||||
tempdir: &TempDir,
|
||||
) -> FileTester<'static, 'a> {
|
||||
FileTester::new(osstr2wcstring(tempdir.path()), ctx)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ispath() {
|
||||
let (tempdir, ctx) = (temp_dir(), &mut op_context());
|
||||
let tester = file_tester(ctx, &tempdir);
|
||||
let wd = osstr2wcstring(tempdir.path());
|
||||
let tester = FileTester::new(&wd, ctx);
|
||||
|
||||
let file_path = filepath(&tempdir, "file.txt");
|
||||
File::create(file_path).unwrap();
|
||||
@@ -512,7 +522,8 @@ fn test_ispath() {
|
||||
#[test]
|
||||
fn test_iscdpath() {
|
||||
let (tempdir, ctx) = (temp_dir(), &mut op_context());
|
||||
let mut tester = file_tester(ctx, &tempdir);
|
||||
let wd = osstr2wcstring(tempdir.path());
|
||||
let mut tester = FileTester::new(&wd, ctx);
|
||||
|
||||
// Note cd (unlike file paths) should report IsErr for invalid cd paths,
|
||||
// rather than IsFile(false).
|
||||
@@ -543,7 +554,8 @@ fn test_iscdpath() {
|
||||
fn test_redirections() {
|
||||
// Note we use is_ok and is_err since we don't care about the IsFile part.
|
||||
let (tempdir, ctx) = (temp_dir(), &mut op_context());
|
||||
let mut tester = file_tester(ctx, &tempdir);
|
||||
let wd = osstr2wcstring(tempdir.path());
|
||||
let mut tester = FileTester::new(&wd, ctx);
|
||||
let file_path = filepath(&tempdir, "file.txt");
|
||||
File::create(&file_path).unwrap();
|
||||
|
||||
@@ -738,8 +750,8 @@ fn test_is_potential_path() {
|
||||
std::fs::write("test/is_potential_path_test/aardvark", []).unwrap();
|
||||
std::fs::write("test/is_potential_path_test/gamma", []).unwrap();
|
||||
|
||||
let wd = L!("test/is_potential_path_test/").to_owned();
|
||||
let wds = [L!(".").to_owned(), wd];
|
||||
let wd = L!("test/is_potential_path_test/");
|
||||
let wds = [L!("."), wd];
|
||||
|
||||
let vars = EnvStack::new();
|
||||
let ctx = OperationContext::background(&vars, EXPANSION_LIMIT_DEFAULT);
|
||||
|
||||
@@ -101,7 +101,7 @@ pub fn highlight_shell<'src, 'ctx>(
|
||||
cursor: Option<usize>,
|
||||
) {
|
||||
let working_directory = ctx.vars().get_pwd_slash();
|
||||
let mut highlighter = Highlighter::new(buff, cursor, ctx, working_directory, io_ok);
|
||||
let mut highlighter = Highlighter::new(buff, cursor, ctx, &working_directory, io_ok);
|
||||
*color = highlighter.highlight();
|
||||
}
|
||||
|
||||
@@ -228,12 +228,21 @@ pub(crate) fn parse_text_face_for_highlight(var: &EnvVar) -> Option<TextFace> {
|
||||
})
|
||||
}
|
||||
|
||||
fn command_is_valid(
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
enum CommandKind {
|
||||
Builtin,
|
||||
Function,
|
||||
Plain,
|
||||
}
|
||||
|
||||
fn command_kind(
|
||||
cmd: &wstr,
|
||||
decoration: StatementDecoration,
|
||||
working_directory: &wstr,
|
||||
vars: &dyn Environment,
|
||||
) -> bool {
|
||||
) -> Option<CommandKind> {
|
||||
use CommandKind::*;
|
||||
|
||||
// Determine which types we check, based on the decoration.
|
||||
let mut builtin_ok = true;
|
||||
let mut function_ok = true;
|
||||
@@ -257,36 +266,32 @@ fn command_is_valid(
|
||||
implicit_cd_ok = false;
|
||||
}
|
||||
|
||||
// Check them.
|
||||
let mut is_valid = false;
|
||||
|
||||
// Builtins
|
||||
if !is_valid && builtin_ok {
|
||||
is_valid = builtin_exists(cmd);
|
||||
if builtin_ok && builtin_exists(cmd) {
|
||||
return Some(Builtin);
|
||||
}
|
||||
|
||||
// Functions
|
||||
if !is_valid && function_ok {
|
||||
is_valid = function::exists_no_autoload(cmd);
|
||||
if function_ok && function::exists_no_autoload(cmd) {
|
||||
return Some(Function);
|
||||
}
|
||||
|
||||
// Abbreviations
|
||||
if !is_valid && abbreviation_ok {
|
||||
is_valid = with_abbrs(|set| set.has_match(cmd, abbrs::Position::Command, L!("")));
|
||||
if abbreviation_ok && with_abbrs(|set| set.has_match(cmd, abbrs::Position::Command, L!(""))) {
|
||||
return Some(Plain);
|
||||
}
|
||||
|
||||
// Regular commands
|
||||
if !is_valid && command_ok {
|
||||
is_valid = path_get_path(cmd, vars).is_some();
|
||||
if command_ok && path_get_path(cmd, vars).is_some() {
|
||||
return Some(Plain);
|
||||
}
|
||||
|
||||
// Implicit cd
|
||||
if !is_valid && implicit_cd_ok {
|
||||
is_valid = path_as_implicit_cd(cmd, working_directory, vars).is_some();
|
||||
if implicit_cd_ok && path_as_implicit_cd(cmd, working_directory, vars).is_some() {
|
||||
return Some(Plain);
|
||||
}
|
||||
|
||||
// Return what we got.
|
||||
is_valid
|
||||
None
|
||||
}
|
||||
|
||||
fn has_expand_reserved(s: &wstr) -> bool {
|
||||
@@ -480,7 +485,9 @@ fn color_string_internal(buffstr: &wstr, base_color: HighlightSpec, colors: &mut
|
||||
[
|
||||
HighlightSpec::with_fg(HighlightRole::Param),
|
||||
HighlightSpec::with_fg(HighlightRole::Option),
|
||||
HighlightSpec::with_fg(HighlightRole::Command)
|
||||
HighlightSpec::with_fg(HighlightRole::Command),
|
||||
HighlightSpec::with_fg(HighlightRole::Builtin),
|
||||
HighlightSpec::with_fg(HighlightRole::Function),
|
||||
]
|
||||
.contains(&base_color),
|
||||
"Unexpected base color"
|
||||
@@ -695,7 +702,7 @@ enum Mode {
|
||||
pub type ColorArray = Vec<HighlightSpec>;
|
||||
|
||||
/// Syntax highlighter helper.
|
||||
struct Highlighter<'src, 'ctx> {
|
||||
struct Highlighter<'src, 'wd, 'ctx> {
|
||||
// The string we're highlighting. Note this is a reference member variable (to avoid copying)!
|
||||
buff: &'src wstr,
|
||||
// The position of the cursor within the string.
|
||||
@@ -703,9 +710,9 @@ struct Highlighter<'src, 'ctx> {
|
||||
// Whether it's OK to do I/O.
|
||||
io_ok: bool,
|
||||
// Working directory.
|
||||
working_directory: WString,
|
||||
working_directory: &'wd wstr,
|
||||
// Our component for testing strings for being potential file paths.
|
||||
file_tester: FileTester<'src, 'ctx>,
|
||||
file_tester: FileTester<'src, 'wd, 'ctx>,
|
||||
// The resulting colors.
|
||||
color_array: ColorArray,
|
||||
// A stack of variables that the current commandline probably defines. We mark redirections
|
||||
@@ -714,15 +721,15 @@ struct Highlighter<'src, 'ctx> {
|
||||
done: bool,
|
||||
}
|
||||
|
||||
impl<'src, 'ctx> Highlighter<'src, 'ctx> {
|
||||
impl<'src, 'wd, 'ctx> Highlighter<'src, 'wd, 'ctx> {
|
||||
pub fn new(
|
||||
buff: &'src wstr,
|
||||
cursor: Option<usize>,
|
||||
ctx: &'ctx mut OperationContext<'src>,
|
||||
working_directory: WString,
|
||||
working_directory: &'wd wstr,
|
||||
can_do_io: bool,
|
||||
) -> Self {
|
||||
let file_tester = FileTester::new(working_directory.clone(), ctx);
|
||||
let file_tester = FileTester::new(working_directory, ctx);
|
||||
Self {
|
||||
buff,
|
||||
cursor,
|
||||
@@ -801,13 +808,19 @@ fn io_still_ok(&self) -> bool {
|
||||
}
|
||||
|
||||
// Color a command.
|
||||
fn color_command(&mut self, node: &ast::String_) {
|
||||
fn color_command(&mut self, node: &ast::String_, cmd_kind: CommandKind) {
|
||||
let source_range = node.source_range();
|
||||
let cmd_str = self.get_source(source_range);
|
||||
|
||||
let role = match cmd_kind {
|
||||
CommandKind::Builtin => HighlightRole::Builtin,
|
||||
CommandKind::Function => HighlightRole::Function,
|
||||
CommandKind::Plain => HighlightRole::Command,
|
||||
};
|
||||
|
||||
color_string_internal(
|
||||
cmd_str,
|
||||
HighlightSpec::with_fg(HighlightRole::Command),
|
||||
HighlightSpec::with_fg(role),
|
||||
&mut self.color_array[source_range.as_usize()],
|
||||
);
|
||||
}
|
||||
@@ -861,7 +874,7 @@ fn color_as_argument(&mut self, node: &dyn ast::Node, options_allowed: bool /* =
|
||||
cmdsub_contents,
|
||||
arg_cursor,
|
||||
self.file_tester.ctx,
|
||||
self.working_directory.clone(),
|
||||
self.working_directory,
|
||||
self.io_still_ok(),
|
||||
);
|
||||
let subcolors = cmdsub_highlighter.highlight();
|
||||
@@ -1049,12 +1062,12 @@ fn visit_decorated_statement(&mut self, stmt: &DecoratedStatement) {
|
||||
let cmd = stmt.command.source(self.buff);
|
||||
|
||||
let mut expanded_cmd = WString::new();
|
||||
let mut is_valid_cmd = false;
|
||||
let mut cmd_kind = None;
|
||||
if !self.io_still_ok() {
|
||||
// We cannot check if the command is invalid, so just assume it's valid.
|
||||
is_valid_cmd = true;
|
||||
cmd_kind = Some(CommandKind::Plain);
|
||||
} else if variable_assignment_equals_pos(cmd).is_some() {
|
||||
is_valid_cmd = true;
|
||||
cmd_kind = Some(CommandKind::Plain);
|
||||
} else {
|
||||
// Check to see if the command is valid.
|
||||
// Try expanding it. If we cannot, it's an error.
|
||||
@@ -1063,10 +1076,10 @@ fn visit_decorated_statement(&mut self, stmt: &DecoratedStatement) {
|
||||
{
|
||||
expanded_cmd = expanded;
|
||||
if !has_expand_reserved(&expanded_cmd) {
|
||||
is_valid_cmd = command_is_valid(
|
||||
cmd_kind = command_kind(
|
||||
&expanded_cmd,
|
||||
stmt.decoration(),
|
||||
&self.working_directory,
|
||||
self.working_directory,
|
||||
self.file_tester.ctx.vars(),
|
||||
);
|
||||
}
|
||||
@@ -1074,8 +1087,8 @@ fn visit_decorated_statement(&mut self, stmt: &DecoratedStatement) {
|
||||
}
|
||||
|
||||
// Color our statement.
|
||||
if is_valid_cmd {
|
||||
self.color_command(&stmt.command);
|
||||
if let Some(cmd_kind) = cmd_kind {
|
||||
self.color_command(&stmt.command, cmd_kind);
|
||||
} else {
|
||||
self.color_node(&stmt.command, HighlightSpec::with_fg(HighlightRole::Error));
|
||||
}
|
||||
@@ -1161,7 +1174,7 @@ fn contains_pending_variable(pending_variables: &[&wstr], haystack: &wstr) -> bo
|
||||
false
|
||||
}
|
||||
|
||||
impl<'src, 'ctx, 'a> NodeVisitor<'a> for Highlighter<'src, 'ctx> {
|
||||
impl<'src, 'wd, 'ctx, 'a> NodeVisitor<'a> for Highlighter<'src, 'wd, 'ctx> {
|
||||
fn visit(&mut self, node: &'a dyn Node) {
|
||||
if let Some(keyword) = node.as_keyword() {
|
||||
return self.visit_keyword(keyword);
|
||||
@@ -1206,6 +1219,8 @@ fn get_highlight_var_name(role: HighlightRole) -> &'static wstr {
|
||||
HighlightRole::Normal => L!("fish_color_normal"),
|
||||
HighlightRole::Error => L!("fish_color_error"),
|
||||
HighlightRole::Command => L!("fish_color_command"),
|
||||
HighlightRole::Builtin => L!("fish_color_builtin"),
|
||||
HighlightRole::Function => L!("fish_color_function"),
|
||||
HighlightRole::Keyword => L!("fish_color_keyword"),
|
||||
HighlightRole::StatementTerminator => L!("fish_color_end"),
|
||||
HighlightRole::Param => L!("fish_color_param"),
|
||||
@@ -1256,7 +1271,9 @@ fn get_fallback(role: HighlightRole) -> HighlightRole {
|
||||
| HighlightRole::PagerPrefix
|
||||
| HighlightRole::PagerCompletion
|
||||
| HighlightRole::PagerDescription => HighlightRole::Normal,
|
||||
HighlightRole::Keyword => HighlightRole::Command,
|
||||
HighlightRole::Builtin | HighlightRole::Function | HighlightRole::Keyword => {
|
||||
HighlightRole::Command
|
||||
}
|
||||
HighlightRole::Option => HighlightRole::Param,
|
||||
HighlightRole::PagerSecondaryBackground => HighlightRole::PagerBackground,
|
||||
HighlightRole::PagerSecondaryPrefix | HighlightRole::PagerSelectedPrefix => {
|
||||
@@ -1279,8 +1296,10 @@ fn get_fallback(role: HighlightRole) -> HighlightRole {
|
||||
pub enum HighlightRole {
|
||||
#[default]
|
||||
Normal, // normal text
|
||||
Error, // error
|
||||
Command, // command
|
||||
Error, // error
|
||||
Command, // command
|
||||
Builtin, // builtin command
|
||||
Function, // user-defined function
|
||||
Keyword,
|
||||
StatementTerminator, // process separator
|
||||
Param, // command parameter (argument)
|
||||
@@ -1451,7 +1470,7 @@ macro_rules! validate {
|
||||
});
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("./foo", param_valid_path),
|
||||
("&", fg(HighlightRole::StatementTerminator)),
|
||||
);
|
||||
@@ -1465,11 +1484,11 @@ macro_rules! validate {
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("foo&bar", fg(HighlightRole::Param)),
|
||||
("foo", fg(HighlightRole::Param), ns),
|
||||
("&", fg(HighlightRole::StatementTerminator)),
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("&>", fg(HighlightRole::Redirection)),
|
||||
);
|
||||
|
||||
@@ -1477,7 +1496,7 @@ macro_rules! validate {
|
||||
("if command", fg(HighlightRole::Keyword)),
|
||||
("ls", fg(HighlightRole::Command)),
|
||||
("; ", fg(HighlightRole::StatementTerminator)),
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("abc", fg(HighlightRole::Param)),
|
||||
("; ", fg(HighlightRole::StatementTerminator)),
|
||||
("/bin/definitely_not_a_command", fg(HighlightRole::Error)),
|
||||
@@ -1487,52 +1506,52 @@ macro_rules! validate {
|
||||
|
||||
validate!(
|
||||
("if", fg(HighlightRole::Keyword)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("else", fg(HighlightRole::Keyword)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("end", fg(HighlightRole::Keyword)),
|
||||
);
|
||||
|
||||
// Verify that cd shows errors for non-directories.
|
||||
validate!(
|
||||
("cd", fg(HighlightRole::Command)),
|
||||
("cd", fg(HighlightRole::Builtin)),
|
||||
("dir", param_valid_path),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("cd", fg(HighlightRole::Command)),
|
||||
("cd", fg(HighlightRole::Builtin)),
|
||||
("foo", fg(HighlightRole::Error)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("cd", fg(HighlightRole::Command)),
|
||||
("cd", fg(HighlightRole::Builtin)),
|
||||
("--help", fg(HighlightRole::Option)),
|
||||
("-h", fg(HighlightRole::Option)),
|
||||
("definitely_not_a_directory", fg(HighlightRole::Error)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("cd", fg(HighlightRole::Command)),
|
||||
("cd", fg(HighlightRole::Builtin)),
|
||||
("--logical", fg(HighlightRole::Option)),
|
||||
("still_definitely_not_a_directory", fg(HighlightRole::Error)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("cd", fg(HighlightRole::Command)),
|
||||
("cd", fg(HighlightRole::Builtin)),
|
||||
("dir-in-cdpath", param_valid_path),
|
||||
);
|
||||
|
||||
// Command substitutions.
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("param1", fg(HighlightRole::Param)),
|
||||
("-l", fg(HighlightRole::Option)),
|
||||
("--", fg(HighlightRole::Option)),
|
||||
("-l", fg(HighlightRole::Param)),
|
||||
("(", fg(HighlightRole::Operat)),
|
||||
("ls", fg(HighlightRole::Command)),
|
||||
("ls", fg(HighlightRole::Function)),
|
||||
("-l", fg(HighlightRole::Option)),
|
||||
("--", fg(HighlightRole::Option)),
|
||||
("-l", fg(HighlightRole::Param)),
|
||||
@@ -1542,33 +1561,33 @@ macro_rules! validate {
|
||||
("cat", fg(HighlightRole::Command)),
|
||||
);
|
||||
validate!(
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
("$(", fg(HighlightRole::Operat)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
(")", fg(HighlightRole::Operat)),
|
||||
);
|
||||
validate!(
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
("\"before", fg(HighlightRole::Quote)),
|
||||
("$(", fg(HighlightRole::Operat)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
("param1", fg(HighlightRole::Param)),
|
||||
(")", fg(HighlightRole::Operat)),
|
||||
("after\"", fg(HighlightRole::Quote)),
|
||||
("param2", fg(HighlightRole::Param)),
|
||||
);
|
||||
validate!(
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
("\"", fg(HighlightRole::Error)),
|
||||
("unclosed quote", fg(HighlightRole::Quote)),
|
||||
("$(", fg(HighlightRole::Operat)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
(")", fg(HighlightRole::Operat)),
|
||||
);
|
||||
|
||||
// Redirections substitutions.
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("param1", fg(HighlightRole::Param)),
|
||||
// Input redirection.
|
||||
("<", fg(HighlightRole::Redirection)),
|
||||
@@ -1596,7 +1615,7 @@ macro_rules! validate {
|
||||
// Output redirection containing a command substitution.
|
||||
("4>", fg(HighlightRole::Redirection)),
|
||||
("(", fg(HighlightRole::Operat)),
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("test/somewhere", fg(HighlightRole::Param)),
|
||||
(")", fg(HighlightRole::Operat)),
|
||||
// Just another param.
|
||||
@@ -1604,7 +1623,7 @@ macro_rules! validate {
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
(">", fg(HighlightRole::Redirection)),
|
||||
("-no-such-file", fg(HighlightRole::Redirection)),
|
||||
(">", fg(HighlightRole::Redirection)),
|
||||
@@ -1618,7 +1637,7 @@ macro_rules! validate {
|
||||
("set-by-for-1", fg(HighlightRole::Param)),
|
||||
("set-by-for-2", fg(HighlightRole::Param)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
(">", fg(HighlightRole::Redirection)),
|
||||
("$x", fg(HighlightRole::Redirection)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
@@ -1626,11 +1645,11 @@ macro_rules! validate {
|
||||
);
|
||||
|
||||
validate!(
|
||||
("set", fg(HighlightRole::Command)),
|
||||
("set", fg(HighlightRole::Builtin)),
|
||||
("x", fg(HighlightRole::Param)),
|
||||
("set-by-set", fg(HighlightRole::Param)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
(">", fg(HighlightRole::Redirection)),
|
||||
("$x", fg(HighlightRole::Redirection)),
|
||||
("2>", fg(HighlightRole::Redirection)),
|
||||
@@ -1643,7 +1662,7 @@ macro_rules! validate {
|
||||
("x", fg(HighlightRole::Param), ns),
|
||||
("=", fg(HighlightRole::Operat), ns),
|
||||
("set-by-variable-override", fg(HighlightRole::Param), ns),
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
(">", fg(HighlightRole::Redirection)),
|
||||
("$x", fg(HighlightRole::Redirection)),
|
||||
);
|
||||
@@ -1656,21 +1675,21 @@ macro_rules! validate {
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("'", fg(HighlightRole::Error)),
|
||||
("single_quote", fg(HighlightRole::Quote)),
|
||||
("$stuff", fg(HighlightRole::Quote)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("\"", fg(HighlightRole::Error)),
|
||||
("double_quote", fg(HighlightRole::Quote)),
|
||||
("$stuff", fg(HighlightRole::Operat)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("$foo", fg(HighlightRole::Operat)),
|
||||
("\"", fg(HighlightRole::Quote)),
|
||||
("$bar", fg(HighlightRole::Operat)),
|
||||
@@ -1690,7 +1709,7 @@ macro_rules! validate {
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("$$foo[", fg(HighlightRole::Operat)),
|
||||
("1", fg(HighlightRole::Param)),
|
||||
("][", fg(HighlightRole::Operat)),
|
||||
@@ -1717,34 +1736,34 @@ macro_rules! validate {
|
||||
|
||||
validate!(
|
||||
("if", fg(HighlightRole::Keyword)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
("&&", fg(HighlightRole::Operat)),
|
||||
("false", fg(HighlightRole::Command)),
|
||||
("false", fg(HighlightRole::Builtin)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("or", fg(HighlightRole::Operat)),
|
||||
("false", fg(HighlightRole::Command)),
|
||||
("false", fg(HighlightRole::Builtin)),
|
||||
("||", fg(HighlightRole::Operat)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("and", fg(HighlightRole::Operat)),
|
||||
("not", fg(HighlightRole::Operat)),
|
||||
("!", fg(HighlightRole::Operat)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
(";", fg(HighlightRole::StatementTerminator)),
|
||||
("end", fg(HighlightRole::Keyword)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("%self", fg(HighlightRole::Operat)),
|
||||
("not%self", fg(HighlightRole::Param)),
|
||||
("self%not", fg(HighlightRole::Param)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("false", fg(HighlightRole::Command)),
|
||||
("false", fg(HighlightRole::Builtin)),
|
||||
("&|", fg(HighlightRole::StatementTerminator)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
@@ -1756,25 +1775,25 @@ macro_rules! validate {
|
||||
("VAL1", fg(HighlightRole::Param), ns),
|
||||
("VAR", fg(HighlightRole::Param)),
|
||||
("=", fg(HighlightRole::Operat), ns),
|
||||
("false", fg(HighlightRole::Command)),
|
||||
("false", fg(HighlightRole::Builtin)),
|
||||
("|&", fg(HighlightRole::StatementTerminator)),
|
||||
("true", fg(HighlightRole::Command)),
|
||||
("true", fg(HighlightRole::Builtin)),
|
||||
("stuff", fg(HighlightRole::Param)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)), // (
|
||||
("echo", fg(HighlightRole::Builtin)), // (
|
||||
(")", fg(HighlightRole::Error)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("stuff", fg(HighlightRole::Param)),
|
||||
("# comment", fg(HighlightRole::Comment)),
|
||||
);
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("--", fg(HighlightRole::Option)),
|
||||
("-s", fg(HighlightRole::Param)),
|
||||
);
|
||||
@@ -1793,7 +1812,7 @@ macro_rules! validate {
|
||||
|
||||
// Highlighting works across escaped line breaks (#8444).
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("$FISH_\\\n", fg(HighlightRole::Operat)),
|
||||
("VERSION", fg(HighlightRole::Operat), ns),
|
||||
);
|
||||
@@ -1824,15 +1843,15 @@ macro_rules! validate {
|
||||
validate!(("\"$EMPTY_VARIABLE\"", fg(HighlightRole::Error)));
|
||||
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("\\UFDFD", fg(HighlightRole::Escape)),
|
||||
);
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("\\U10FFFF", fg(HighlightRole::Escape)),
|
||||
);
|
||||
validate!(
|
||||
("echo", fg(HighlightRole::Command)),
|
||||
("echo", fg(HighlightRole::Builtin)),
|
||||
("\\U110000", fg(HighlightRole::Error)),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
mod file_tester;
|
||||
#[allow(clippy::module_inception)]
|
||||
mod highlight;
|
||||
pub use file_tester::is_potential_path;
|
||||
pub use highlight::*;
|
||||
|
||||
@@ -1331,8 +1331,8 @@ pub fn detect_errors_in_argument(
|
||||
if src.len() == 2
|
||||
&& src[0] == '\\'
|
||||
&& (src[1] == 'c'
|
||||
|| src[1].to_lowercase().eq(['u'])
|
||||
|| src[1].to_lowercase().eq(['x']))
|
||||
|| src[1].eq_ignore_ascii_case(&'u')
|
||||
|| src[1].eq_ignore_ascii_case(&'x'))
|
||||
{
|
||||
append_syntax_error!(
|
||||
out_errors,
|
||||
|
||||
@@ -535,7 +535,7 @@ fn try_transfer(jg: &JobGroup) -> bool {
|
||||
flogf!(
|
||||
warning,
|
||||
"Could not send job %d ('%s') with pgid %d to foreground",
|
||||
jg.job_id.to_wstring(),
|
||||
jg.job_id,
|
||||
jg.command,
|
||||
pgid
|
||||
);
|
||||
|
||||
@@ -229,6 +229,8 @@ contains -i string a b c d; or echo nothing
|
||||
#CHECK: nothing
|
||||
contains -i -- string a b c string d
|
||||
#CHECK: 4
|
||||
contains -i a -q -- a b c
|
||||
#CHECK: 3
|
||||
contains -i -- -- a b c; or echo nothing
|
||||
#CHECK: nothing
|
||||
contains -i -- -- a b c -- v
|
||||
|
||||
@@ -153,10 +153,11 @@ end
|
||||
complete -c repeated_short_options -f -s h
|
||||
complete -c repeated_short_options -f -s v
|
||||
complete -c repeated_short_options -f -s x
|
||||
complete -C'repeated_short_options -xx' | count
|
||||
# CHECK: 0
|
||||
complete -C'repeated_short_options -xxh' | count
|
||||
# CHECK: 0
|
||||
complete -C'repeated_short_options -xx'
|
||||
# CHECK: -xxh
|
||||
# CHECK: -xxv
|
||||
complete -C'repeated_short_options -xxh'
|
||||
# CHECK: -xxhv
|
||||
complete -C'repeated_short_options -x'
|
||||
# CHECK: -xh
|
||||
# CHECK: -xv
|
||||
@@ -670,21 +671,10 @@ abbr cat cat
|
||||
complete -C ca | string match -r '^cat(?:\t.*)?$'
|
||||
# CHECK: cat{{\t}}Abbreviation: cat
|
||||
|
||||
# anywhere-position abbrs complete in non-command position
|
||||
abbr --position anywhere __test_pgr '| grep -i'
|
||||
complete -C'echo __test_pgr' | string match -r '^__test_pgr.*'
|
||||
# CHECK: __test_pgr{{\t}}Abbreviation: | grep -i
|
||||
|
||||
# anywhere-position abbrs still complete in command position (regression guard)
|
||||
complete -C__test_pgr | string match -r '^__test_pgr.*'
|
||||
# CHECK: __test_pgr{{\t}}Abbreviation: | grep -i
|
||||
|
||||
# command-position-only abbrs do NOT complete in non-command position
|
||||
abbr --position command __test_cmd_only 'git status'
|
||||
complete -C'echo __test_cmd' | string match -rq '^__test_cmd'
|
||||
echo $status
|
||||
# CHECK: 1
|
||||
abbr --erase __test_pgr __test_cmd_only
|
||||
touch somefile
|
||||
abbr --position anywhere gr '| grep -i'
|
||||
complete -C'rm '
|
||||
# CHECK: somefile
|
||||
|
||||
complete complete-list -xa '(__fish_complete_list , "seq 2")'
|
||||
complete -C "complete-list 1,"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#RUN: %fish %s
|
||||
#RUN: fish=%fish %fish %s
|
||||
#REQUIRES: command -v tmux
|
||||
|
||||
isolated-tmux-start
|
||||
@@ -18,7 +18,26 @@ isolated-tmux capture-pane -p
|
||||
# (I've seen this print " world", I guess it depends on tmux version and how big it thinks the terminal is)
|
||||
# CHECK: {{.*}} world
|
||||
|
||||
isolated-tmux send-keys C-u C-l "sleep 3 | cat &" Enter "bg %1" Enter
|
||||
isolated-tmux send-keys C-u C-l "sleep 1 | cat &" Enter "bg %1" Enter
|
||||
tmux-sleep
|
||||
isolated-tmux capture-pane -p | string match '*to background*'
|
||||
# CHECK: Send job 1 'sleep 3 | cat &' to background
|
||||
# CHECK: Send job 1 'sleep 1 | cat &' to background
|
||||
|
||||
sleep 1.5
|
||||
|
||||
isolated-tmux send-keys C-l '
|
||||
status job-control full
|
||||
for x in (seq 10)
|
||||
sleep 0.0001 &
|
||||
fg
|
||||
end
|
||||
'
|
||||
tmux-sleep
|
||||
isolated-tmux capture-pane -p |
|
||||
string match -rv '^fg: There are no suitable jobs' |
|
||||
string match -rv '^killpg\(\d+, SIGCONT\): No such process$' |
|
||||
string match -rv '^Send job \d+ \(sleep 0.0001 &\) to foreground$' |
|
||||
string match -rv '^warning: Could not send job \d+ \(\'sleep 0.0001 &\'\) with pgid \d+ to foreground' |
|
||||
string match -rv '^tcsetpgrp: No such process'
|
||||
|
||||
# CHECK: prompt 3>
|
||||
|
||||
@@ -5,7 +5,7 @@ import sys
|
||||
import signal
|
||||
import platform
|
||||
|
||||
if "CI" in os.environ and platform.system() == "Darwin":
|
||||
if "CI" in os.environ and platform.system() in ["Darwin", "FreeBSD"]:
|
||||
sys.exit(127)
|
||||
|
||||
sp = SpawnedProc()
|
||||
|
||||
@@ -6,7 +6,7 @@ import sys
|
||||
import time
|
||||
import platform
|
||||
|
||||
if "CI" in os.environ and platform.system() == "Darwin":
|
||||
if "CI" in os.environ and platform.system() in ["Darwin", "FreeBSD"]:
|
||||
sys.exit(127)
|
||||
|
||||
sp = SpawnedProc()
|
||||
|
||||
@@ -5,7 +5,7 @@ import signal
|
||||
import sys
|
||||
from pexpect_helper import SpawnedProc
|
||||
|
||||
if "CI" in os.environ and platform.system() == "Darwin":
|
||||
if "CI" in os.environ and platform.system() in ["Darwin", "FreeBSD"]:
|
||||
sys.exit(127)
|
||||
|
||||
sp = SpawnedProc()
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
name: "Update Linux docker images"
|
||||
|
||||
sources:
|
||||
alpine_latest_version:
|
||||
kind: dockerimage
|
||||
spec:
|
||||
image: alpine
|
||||
tagfilter: "^[0-9]+\\.[0-9]+$"
|
||||
versionfilter:
|
||||
kind: semver
|
||||
ubuntu_latest_lts_version:
|
||||
kind: shell
|
||||
spec:
|
||||
@@ -24,14 +17,6 @@ sources:
|
||||
tail -1
|
||||
|
||||
targets:
|
||||
update_alpine_dockerfile:
|
||||
name: "Update Alpine Linux version"
|
||||
sourceid: alpine_latest_version
|
||||
kind: file
|
||||
spec:
|
||||
file: docker/alpine.Dockerfile
|
||||
matchpattern: "FROM alpine:.*"
|
||||
replacepattern: 'FROM alpine:{{ source "alpine_latest_version" }}'
|
||||
ubuntu_latest_version_dockerfile:
|
||||
name: "Update oldest non-EOL Ubuntu Linux version"
|
||||
sourceid: ubuntu_latest_lts_version
|
||||
|
||||
Reference in New Issue
Block a user