Compare commits

...

75 Commits
3.2.0 ... 3.2.1

Author SHA1 Message Date
David Adam
156d57d270 Release 3.2.1
Closes #7772.
2021-03-18 11:05:28 +08:00
David Adam
a1653c928e CHANGELOG: work on 3.2.1 2021-03-17 21:51:02 +08:00
David Adam
0988d2fc15 Merge branch 'master' into Integration_3.2.1 2021-03-16 18:00:36 +08:00
Johannes Altmanninger
efcfec0ba1 fixup! Show an error when "builtin -h" fails to find a man page 2021-03-15 23:14:17 +01:00
Johannes Altmanninger
f9e131aa93 Show an error when "builtin -h" fails to find a man page
Prior to this commit "builtin -h" would silently fail when no
documentation is installed. This happens when running fish without
installing it, or when the docs are not installed.

See #7824
2021-03-15 23:07:08 +01:00
Johannes Altmanninger
582675c96a completions/git: restore forward-compatibility by using "complete -c"
After a fish installation is upgraded to 3.2.0, active shells could
throw an error attempting to load Git completions. It's just a
transient error but also easily avoidable by using the old style.

See #7822
2021-03-15 22:34:30 +01:00
lapingenieur
f95f12f5e7 changed 'rm' to 'command rm'
if rm is aliased to 'rm -i' then rm will ask to delete the cache file after funced edited the file which is anoying
2021-03-15 21:07:39 +01:00
exploide
38cd373ca3 added completions for mkpasswd 2021-03-14 16:46:38 -07:00
lapingenieur
dfd1e3a362 Added a ':' at the end of a french translation 2021-03-14 21:13:27 +01:00
Fabian Homborg
771db6018e Revert "fish.spec: drop RHEL 6 elements"
The 3.2 branch still supports it

This reverts commit 63fa8dfd26.
2021-03-14 12:56:16 +01:00
Johannes Altmanninger
865abebd11 Simplify highlight tests by changing into dedicated test dir 2021-03-13 17:51:49 +01:00
Fabian Homborg
29ebd4a5ff tests: Don't break when a file unexpectedly exists
Creating a file called "xfoo" could break the highlight tests because
we'd suddenly get a color with valid_path set to true.

So what we do is simply compare foreground/background and forced
underline, but only check for path validity if we're expecting a valid
path.

If we're not expecting a valid path, we don't fail whether it is there
or not.

This means that we can't check for a non-valid path, but we don't
currently do that anyway and we can just burn that bridge when we get
to it.

cc @siteshwar @krobelus, who both came across this
2021-03-13 17:25:23 +01:00
Fabian Homborg
3c3bf7ffd7 completions/git: Show recent commits *on all branches* for rebase
Doesn't make a ton of sense for the current branch
2021-03-12 18:12:03 +01:00
Fabian Homborg
873d7f6bb3 completions/git: Add recent commits for rebase
Fixes #7817
2021-03-12 18:10:11 +01:00
Fabian Homborg
018f1f7e20 docs: Document the math functions better 2021-03-11 19:46:52 +01:00
Ilya Grigoriev
1a03c23b58 Improve error when help fails to find a browser
Previously, this message told the user to "set $BROWSER and try again". However,
when I first saw this error, I didn't know how I can set `BROWSER` in fish. Moreover,
I often see this error in situations when no browser will work. For instance, I might be
using fish over ssh, and I might either not know whether that system has a text-mode
browser installed or not want to use it.

A further improvement would be to report this message if a browser fails to start.
2021-03-11 18:32:24 +01:00
Fabian Homborg
c23f311956 pythonista prompt: Remove single-argument test 2021-03-11 16:55:17 +01:00
ridiculousfish
9ab77c7ddc Relnote fix for #7770 2021-03-10 22:50:57 -08:00
ridiculousfish
3cb105adbd Restore terminal modes after running key bindings with external commands
This concerns the behavior when running an external command from a key
binding. The history is:

Prior to 5f16a299a7, fish would run these external commands in shell
modes. This meant that fish would pick up any tty changes from external
commands (see #2114).

After 5f16a299a7, fish would save and restore its shell modes around
these external commands. This introduced a regression where anything the
user typed while a bound external command was executing would be echoed,
because external command mode has ECHO set in c_lflag. (This can be
reproed easily with `bind -q 'sleep 1'` and then pressing q and typing).
So 5f16a299a7 was reverted in fd9355966.

This commit partially reverts fd9355966. It has it both ways: external
commands are launched with shell modes, but/and shell modes are restored
after the external command completes. This allows commands to muck with
the tty, as long as they can handle getting shell modes; but it does not
enable ECHO mode so it fixes the regression found in #7770.

Fixes #7770. Fixes #2114 (for the third time!)

This partially reverts commit fd9355966e.
2021-03-10 22:36:33 -08:00
ridiculousfish
7e8b8345e7 Fix some graphical glitches in fish_config
fish_config has some shadows and other elements which don't align
propertly. Fix these, and apply some other miscellaneous polish.

Fixes #7811
2021-03-10 18:46:06 -08:00
Fabian Homborg
fd9355966e Stop donating the terminal for bind functions
Unfortunately this causes input coming in while bind functions are
running to show up on screen.

Since the cure is worse than the disease let's just stop doing it.

My guess is this needs to *only* be done while running an external
command.

Fixes #7770
Reintroduces #2114

Partially reverts 5f16a299a7
2021-03-10 21:21:19 +01:00
Fabian Homborg
600c0d5b3f tests: Remove unnecessary status fish-path
This is broken on OpenBSD because it apparently doesn't have a /proc
we can query, so it just gives "fish".

Since it's unnecessary in this context just skip it.
2021-03-10 18:04:04 +01:00
Fabian Homborg
013a563ed0 Only modify terminal modes after config.fish if we have the terminal
This tried fiddling with the terminal even if fish didn't own it, e.g.
in

    fish -c 'sleep 5' &

Fixes #7808.
2021-03-10 09:38:16 +01:00
Fabian Homborg
f204fd147d CHANGELOG Updates 2021-03-10 07:30:27 +01:00
Fabian Homborg
dfebfcf376 __fish_apropos: Also add "--" separator
This actually *worked* in my tests which confuses me.

It really shouldn't, `apropos -foo` will complain about "-o" not being
a valid option.

It should be `apropos -- -foo`.

Now, of course there are awful apropos implementations, so let's see
if someone complains
2021-03-10 07:22:17 +01:00
Fabian Homborg
d2fc1c47ac __fish_describe_command: Add missing --
Fixes #7809.
2021-03-10 07:17:23 +01:00
Joel Rosdahl
76b6959cad Fix parallel build race condition for test targets
When executing “make test -jX” (with X > 1) to build and run tests in a
build directory, there is a race condition between the
serial_test_low_level target and the test_prep target (a dependency of
serial_test_fishscript and serial_test_interactive).

As far as I can tell, these events happen in a serial build scenario
(“make test” with the “Unix Makefiles” CMake generator):

  1. The fish_tests binary is built and executed.
  2. The test_prep target (a dependency of serial_test_fishscript)
     cleans up test directories.
  3. Tests in test.fish are executed.

In a parallel build scenario, this often happens:

  1. Build of the fish_tests binary is started.
  2. The test_prep target cleans up test directories.
  3. Build of the fish_tests binary is finished.
  4. Execution of the fish_tests binary starts.
  5. Execution of the fish_tests binary finishes.
  6. Tests in test.fish are executed.

However, if building the fish_tests binary is fast enough but not
instant (e.g. when using ccache), this can happen:

  1. Build of the fish_tests binary is started.
  2. Build of the fish_tests binary is finished.
  3. Execution of the fish_tests binary starts.
  4. The test_prep target cleans up test directories.
  5. fish_tests tests that depend on said test directories may,
     depending on timing, fail because they are wiped by test_prep.

Fix this by making test_prep a dependency of serial_test_low_level so
that test_prep can’t interfere with fish_tests execution.
2021-03-09 21:49:52 +01:00
Caroleq
9fe2b27bba Shorten description in completions (#7788)
* Fix long descriptions in completions

* PR review modifications
2021-03-09 20:28:25 +01:00
Fabian Homborg
daa3cc17c4 Fix crash in string pad
Try:

    string pad -w 8 he \eh
2021-03-09 18:36:02 +01:00
Fabian Homborg
a7df92e187 Fix crash with set_color --print-colors --background normal
Found in conjunction with #7805.
2021-03-09 13:46:08 +01:00
Fabian Homborg
4762d52e52 output: A background is set if it's not a special non-color
For reasons unclear to me, fish enables bold mode unconditionally if
the background is set.

However, this called a background "set" if it wasn't exactly the
"normal" color, whereas set_color --print-colors would set a color
of *none*.

We have three special non-color colors:

- "normal"
- "reset"
- "none"

All of these specify some form of absence of background color, so all
of them should be checked.

Fixes #7805
2021-03-09 13:25:00 +01:00
Fabian Homborg
4218c1f1a4 faq: Reword ssh question
This was a bit stuffy

Also let's mention tmux because that's another thing that may cause this.
2021-03-08 22:28:26 +01:00
Fabian Homborg
76f7b3e98e Update CHANGELOG 2021-03-08 18:01:51 +01:00
exploide
274be5eeeb added descriptions to __fish_print_addresses
added --all flag to include 0.0.0.0 and ::
adapted use of this function in existing completions
fixes #7787
2021-03-08 17:47:29 +01:00
Ilya Grigoriev
762f3aa0ce Rewrite the real file if history file is a symlink (#7754)
* Rewrite the real file if history file is a symlink

When the history file is a symbolic link, `fish` used to overwrite
the link with a real file whenever it saved history. This makes
it follow the symlink and overwrite the real file instead.

The same issue was fixed for the `fish_variables` file in 622f2868e
from https://github.com/fish-shell/fish-shell/pull/7728.
This makes `fish_history` behave in the same way. The implementation
is nearly identical.

Since the tests for the two issues are so similar, I combined them
together and slightly expanded the older test.

This also addresses https://github.com/fish-shell/fish-shell/issues/7553.

* Add user-facing error when history renaming fails

Currently, when history file renaming fails, no message is shown to the
user. This happens, for instance, if the history file is a symlink
pointing to another filesystem.

This copies code (with a bit of variation, after reviewer comments) from

589eb34571/src/env_universal_common.cpp (L486-L491)

into `history.cpp`, so that a message is shown to the user.

* fixup! Rewrite the real file if history file is a symlink
2021-03-08 17:46:17 +01:00
Kid
a85edbfbcd Fix typo in __fish_print_pipestatus 2021-03-07 12:51:57 +01:00
Fabian Homborg
dbb74f87ba Re-read terminal modes after config.fish
Before now, we would be getting the terminal modes before config.fish,
then running config.fish without any of the term "stealing" and modes
copying. This meant that changes made to the terminal modes in there
were simply lost.

So, what we do is simply set the modes before config and then copy
them after, once.

Note that this does *not* turn off flow control again - if you turn it
on in config.fish that should work.

Fixes #7783.
2021-03-07 11:23:59 +01:00
Fabian Homborg
c7c9ff9a4a Update CHANGELOG 2021-03-07 10:26:56 +01:00
Fabian Homborg
56e1109609 Add test for caller-exit events
This was a bit fiddly!
2021-03-07 10:22:35 +01:00
Fabian Homborg
371516382d Create job-exit caller events inside event handlers
f7e2e7d26b forbid any job exit events
from happening inside jobs that were themselves event handlers, but
that causes e.g.

```fish
function f --on-event fish_prompt
source (echo "echo hello world" | psub)
end
```

to not trigger psub's cleanup, so it leaves files in $TMPDIR behind.

This was hit by pyenv, because that still uses `source (thing |
psub)`.

Fixes #7792.
2021-03-07 10:00:52 +01:00
Ilya Grigoriev
fe70c29c48 Incorporate black suggestions & rearrange imports slightly
This isn't really necessary, but it makes the file look nicer to
my eyes. Let me know if you want me to remove this commit.
2021-03-07 09:42:41 +01:00
Ilya Grigoriev
f725cd402d Make help and fish_config work on Chrome OS
When `fish` is running in the Chrome OS Linux VM (Crostini),
both `help` and `fish_config` opened a "file not found"
page. That is because on Crostini, `BROWSER` is usually set to
`garcon-url-handler`, which opens URLs in the host OS Chrome
browser. That browser lacks access to the Linux file system.

This commit fixes these commands. `help` now opens the URL on
www.fishshell.com.  `fish_config` now opens the URL for the
server it starts. Previously, it opened a local file that
redirects to the same URL.

In the case of `help`, the situation could be improved further
by starting a web server to serve help. I don't know of another
way to access `/share/fish` from outside the VM without user
intervention, and I think that might be a part of the security
model for the Crostini VM.

It's hard to write a test for this. I checked that `help math`,
`python2 webconfig.py`, and `python3 webconfig.py` work on my
machine running in Crostini.
2021-03-07 09:42:41 +01:00
Mahmoud Al-Qudsi
8a07db8e8f Revert "Revert "Speed up check-all-fish-files when executed locally""
This reverts commit e240d81ff8 and
introduces a more compatible method of finding newly added fish scripts
to syntax check.

`find -newer` is the original and is supported by everything under the
sun (including FreeBSD, NetBSD, Solaris, OpenIndiana, macOS 10.10, WSL,
and more), and if not, the tests will succeed anyway. `find -mnewer` was
added later around the time `find -cnewer` and co (which checks the
creation date rather than the modification date) was introduced, but
apparently the GNU version of coreutils never introduced the `-mnewer`
alias for `-newer`.

Yes, this is hacky and yes it would be ideal if the build system is the
one that picked which tests to run rather than the test itself picking.
But let's not pretend that our tests are idealogically ideal or pure
right now and until we fix the mess that is our CMake test integration
(e.g. use ctest and configure each test to be run separately with
configurable payloads, etc) eight seconds is still eight seconds, and
again, the CI isn't affected.
2021-03-06 17:13:20 -06:00
Fabian Homborg
e240d81ff8 Revert "Speed up check-all-fish-files when executed locally"
My find (GNU findutils 4.8.0) prints

> find: unknown predicate `-mnewer'

So we would have to test for support.

Also this is *super* hacky - tests aren't supposed to keep files
around, this is something you would do in the build system.

This reverts commit ddd0e28b4f.
2021-03-06 09:36:56 +01:00
Fabian Homborg
10ef0d9daf Fix clipboard_paste nicer
Instead of hacking in arbitrary characters to avoid splitting, just
use `string collect`.

This reverts commit e450190d50.

Fixes #7782, but nicer.
2021-03-06 08:40:07 +01:00
Fabian Homborg
25d85bdc64 path_get_path: Remove error on unknown errno
This seems like a good idea, but there isn't anything we or anyone
else can *do* in this case. All we ever do is pile on additional
errors on the ignore pile, we can't handle any of them differently.
The command isn't a thing, so we check the next path.

The impetus for this is Cygwin apparently returning a wonderfully
useless 0, and it's not even the first one to do so.

Fixes #7785
2021-03-06 08:12:27 +01:00
Mahmoud Al-Qudsi
a536ab810a Don't set check-all-fish-files timestamp in case of error
I'm not sure if this is necessary or if littlecheck would abort before
the for loop completed and `touch` was executed.
2021-03-05 22:50:26 -06:00
Mahmoud Al-Qudsi
ddd0e28b4f Speed up check-all-fish-files when executed locally
Only check fish files that have been modified since the last time they
were checked. (This continues with the assumption that we are testing
for broken /usr/share fish scripts and not breakage of the fish parser,
which is covered by all the other tests.)

This saves 8 seconds on an NVMe disk under WSL. Won't affect integrity
of CI runs, which start with a blank slate each time.
2021-03-05 22:40:40 -06:00
Mahmoud Al-Qudsi
11951a245f Optimize pruning of job/proc exit handlers
Pre-emptively delete the handler while we have possession of the lock
before calling the event itself. It's crude, but it works.
2021-03-05 22:40:06 -06:00
Mahmoud Al-Qudsi
e7398c0248 Prune job exit handlers after running
While pid values may be reused, it is logical to assume that fish event
handlers coded against a particular job or process id mean just the job
that is currently referred to be any given pid/pgrp rather than in
perpetuity.

This trims the list of registered event handlers nice and early, and as
a bonus avoids the issue described in #7721.

The cleanup song-and-dance is extremely ugly due to the repeated locking
and unlocking of the event handler list.

Closes #7221.
2021-03-05 22:32:57 -06:00
Mahmoud Al-Qudsi
99e02ba47a Add #7782 to CHANGELOG.rst
[ci skip]
2021-03-05 17:13:51 -06:00
Mahmoud Al-Qudsi
e450190d50 Fix regression causing error and prompt corruption on paste
Closes #7782

[ci skip]
2021-03-05 17:13:28 -06:00
Fabian Homborg
6bc0064a2a demangled_backtrace: Cast a thing to const char* instead of char*
Apparently this is const char* on NetBSD, so it complains.

Since it should be harmless to allow this one to be const, just do
that.
2021-03-05 19:40:44 +01:00
Fabian Homborg
69c71052ef Remove __fish_repaint
This was a handler for various prompt variables that called a repaint.

Unfortunately, if you set one of those *inside* the prompt (a logical
place for it), this would lead to something like #7775.

So, because this isn't actually *useful* as far as I can see (how do
you set these variables in a way that you're not already inside a
prompt or about to draw a prompt? in a key binding?), we remove it,
like we removed the repaint from git's variable handlers.
2021-03-04 19:20:31 +01:00
Fabian Homborg
b1c5e003ef fish_command_not_found: Actually define default handler
Fixes #7777
2021-03-04 18:30:12 +01:00
Jake
ece0aa5324 Update rsync completions (#7763)
* Add rsync flags completion

* Add missing rsync completions

* Remove bracket expansion and fix aka long options

* Improve rsync flags function code

* Replace "newness" with birth for creation times

* Improve rsync version option description

* Clarify rsync append-verify
2021-03-04 18:15:25 +01:00
Fabian Homborg
8bb2ca95c8 checks/git: Give grep a literal tab
Apparently the grep on FreeBSD doesn't do \s or \t. Since we're
looking for an actual tab, just give it an actual tab.

See https://builds.sr.ht/~faho/job/448496.
2021-03-04 16:25:41 +01:00
Fabian Homborg
a561904afd Add CHANGELOG for 3.2.1
(to be clear the current state, this isn't yet the release)
2021-03-04 16:17:27 +01:00
Fabian Homborg
d85bdf120f fish_add_path: Handle moving multiple arguments correctly
This `set -e` had a cartesian product that caused it to remove the
indexes separately, so the later indexes were off - removing the first
and then the second ends up removing the first and then the
old-*third* which is now the second.

Just quote the expansion so it runs in one go.

Fixes #7776
2021-03-04 16:10:27 +01:00
Fabian Homborg
76457bdc4e fish_git_prompt: Remove repaint from variable handlers
Because we removed repaint coalescing, currently setting any of the
git prompt variables in fish_prompt leads to a repaint loop (that
presumably aborts once it reaches the recursion limit).

Since repainting on these variables isn't really useful (when you
`set` them interactively you already get a new prompt), just remove
it.

There's two cases this "breaks":

- When you set a variable *after* the call to fish_git_prompt
- When you set a variable via a binding

In both of these it's not too much to expect an explicit "commandline
-f repaint", especially since for bindings that's already needed in
most cases, and setting a variable after using it isn't normal.

Fixes #7775.
2021-03-04 15:58:20 +01:00
Fabian Homborg
c96a07dc96 Revert "Prevent redirecting internal processes to file descriptors above 2"
FDs are inherited, and redirecting those is harmless, and forbidding
that is worse than allowing all.

Fixes #7769.

This reverts commit 11a373f121.
2021-03-03 22:26:33 +01:00
Fabian Homborg
791b42f065 Disable SIGIO notifier
It doesn't work on WSL, Solaris and Archlinux (and presumably that
means future versions of other linux distros).

In its current state I don't trust it enough to enable it anywhere by
default, especially since I'm not aware of an actual issue with the
named pipe (other than that the code is ugly).

Fixes #7774
2021-03-03 22:26:28 +01:00
Fabian Homborg
0a3fec5e8b __fish_print_pipestatus: Reset modifiers again
Called as

__fish_print_pipestatus "[foo" "oof]" "|" (set_color green) (set_color --bold blue) 0 1 2

it would make the closing `oof]` bold green.

Fixes #7771.
2021-03-03 19:20:28 +01:00
Fabian Homborg
a36dbad3b8 cmake: Stop copying css files
custom no longer exists and pygments is just with the theme
2021-03-02 17:04:47 +01:00
Fabian Homborg
54ff7b29a9 docs: Give logo a specific width 2021-03-02 17:03:32 +01:00
Fabian Homborg
5b4db4a6ea docs: Remove some useless wrappers
The "classic" theme is a mostly useless wrapper around the basic theme
that just adds a collapsible sidebar (that we no longer have).

Moving to basic directly drops a layer of indirection and a file that
needs to be transferred over the net.

Same thing goes for "default.css" which literally just includes
classic.css (WHYYYY???)

(also this removes some useless javascript)
2021-03-02 16:59:38 +01:00
Fabian Homborg
edfa6746c6 docs: Move pygments css 2021-03-02 16:52:28 +01:00
Fabian Homborg
bf801afef8 docs: Move custom.css into the main css
There's no real separation here so one file is preferable.

We'll leave the pygments.css intact because that handles a different thing
2021-03-02 16:49:23 +01:00
Fabian Homborg
955c0003ca fd_monitor: Explicity include <thread>
Might fix issues with gcc 11.0.1.

See #7764.
2021-03-02 15:27:13 +01:00
Fabian Homborg
119b978cbc type: Add --quiet back
It's supposed to be *deprecated*, not removed. The documentation even
specifically calls it out.

Fixes #7766
2021-03-02 14:53:02 +01:00
Fabian Homborg
12e059adf8 docs: Hardcode a list of short builtins for unmatched search
Unfortunately this has both stopwords and a length limit, and things
like "and" just are tough to search.

So what we do is leave everything as it is, but when a search fails,
we show a list of things that are hard to search for, currently that's
"and", "for", "if" and such.

Fixes #7757.
2021-03-02 14:17:29 +01:00
Érico Rolim
d948b34420 Include <termios.h> instead of <sys/termios.h>.
Slipped by with ffa24eb361. Given
daf5ef1bbd, fish should be using
<termios.h> in all cases.
2021-03-02 12:05:07 +01:00
Fabian Homborg
abaa057e5c Replace our only dynamic_cast with old-school casting
dynamic_cast requires rtti to be enabled. Now, this isn't a big
problem, but since this is our only dynamic_cast in the entire
codebase, and it's not serving an important function, we can just
replace it.

See #7764
2021-03-02 09:44:23 +01:00
David Adam
d655d24148 CHANGELOG: add headers for next release 2021-03-01 22:53:29 +08:00
David Adam
63fa8dfd26 fish.spec: drop RHEL 6 elements
RHEL/CentOS 6 are now out of support by upstream and fish.
2021-03-01 22:16:01 +08:00
79 changed files with 1169 additions and 666 deletions

View File

@@ -1,3 +1,36 @@
fish 3.2.1 (released March 18, 2021)
====================================
This release of fish fixes the following problems identified in fish 3.2.0:
- Commands in key bindings are run with fish's internal terminal modes, instead of the terminal modes typically used for commands. This fixes a bug introduced in 3.2.0, where text would unexpectedly appear on the terminal, especially when pasting (:issue:`7770`).
- Prompts which use the internal ``__fish_print_pipestatus`` function will display correctly rather than carrying certain modifiers (such as bold) further than intended (:issue:`7771`).
- Redirections to internal file descriptors is allowed again, reversing the changes in 3.2.0. This fixes a problem with Midnight Commander (:issue:`7769`).
- Universal variables should be fully reliable regardless of operating system again (:issue:`7774`).
- ``fish_git_prompt`` no longer causes screen flickering in certain terminals (:issue:`7775`).
- ``fish_add_path`` manipulates the ``fish_user_paths`` variable correctly when moving multiple paths (:issue:`7776`).
- Pasting with a multi-line command no longer causes a ``__fish_tokenizer_state`` error (:issue:`7782`).
- ``psub`` inside event handlers cleans up temporary files properly (:issue:`7792`).
- Event handlers declared with ``--on-job-exit $fish_pid`` no longer run constantly (:issue:`7721`), although these functions should use ``--on-event fish_exit`` instead.
- Changing terminal modes inside ``config.fish`` works (:issue:`7783`).
- ``set_color --print-colors`` no longer prints all colors in bold (:issue:`7805`)
- Completing commands starting with a ``-`` no longer prints an error (:issue:`7809`).
- Running ``fish_command_not_found`` directly no longer produces an error on macOS or other OSes which do not have a handler available (:issue:`7777`).
- The new ``type`` builtin now has the (deprecated) ``--quiet`` long form of ``-q`` (:issue:`7766`).
It also includes some small enhancements:
- ``help`` and ``fish_config`` work correctly when fish is running in a Chrome OS Crostini Linux VM (:issue:`7789`).
- The history file can be made a symbolic link without it being overwritten (:issue:`7754`), matching a similar improvement for the universal variable file in 3.2.0.
- An unhelpful error ("access: No error"), seen on Cygwin, is no longer produced (:issue:`7785`).
- Improvements to the ``rsync`` completions (:issue:`7763`), some completion descriptions (:issue:`7788`), and completions that use IP address (:issue:`7787`).
- Improvements to the appearance of ``fish_config`` (:issue:`7811`).
If you are upgrading from version 3.1.2 or before, please also review
the release notes for 3.2.0 (included below).
--------------
fish 3.2.0 (released March 1, 2021) fish 3.2.0 (released March 1, 2021)
=================================== ===================================

View File

@@ -17,8 +17,6 @@ set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man")
# Prepend the output dir of fish_indent to PATH. # Prepend the output dir of fish_indent to PATH.
add_custom_target(sphinx-docs add_custom_target(sphinx-docs
mkdir -p ${SPHINX_HTML_DIR}/_static/ mkdir -p ${SPHINX_HTML_DIR}/_static/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SPHINX_SRC_DIR}/_static/pygments.css ${SPHINX_HTML_DIR}/_static/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SPHINX_SRC_DIR}/_static/custom.css ${SPHINX_HTML_DIR}/_static/
COMMAND env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH" COMMAND env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
${SPHINX_EXECUTABLE} ${SPHINX_EXECUTABLE}
-q -b html -q -b html

View File

@@ -113,6 +113,7 @@ endforeach(TESTTYPE)
# Now add a dependency chain between the serial versions. # Now add a dependency chain between the serial versions.
# This ensures they run in order. # This ensures they run in order.
add_dependencies(serial_test_low_level test_prep)
add_dependencies(serial_test_fishscript serial_test_low_level) add_dependencies(serial_test_fishscript serial_test_low_level)
add_dependencies(serial_test_interactive serial_test_fishscript) add_dependencies(serial_test_interactive serial_test_fishscript)

View File

@@ -1,27 +0,0 @@
.sphinxsidebar ul.current > li.current { font-weight: bold }
.gray { color: #555555 }
.purple { color: #551a8b }
.red { color: #FF0000 }
/* Color based on the Name.Function (.nf) class from pygments.css. */
.command { color: #005fd7 }
/* Color based on the Name.Constant (.no) class from pygments.css. */
.param { color: #00afff }
/* Color based on the Name.Constant (.no) class from pygments.css. */
/* Used for underlining file paths in interactive code examples. */
.param-valid-path { color: #00afff; text-decoration: underline }
/* Color based on the Generic.Prompt (.gp) class from pygments.css. */
.prompt { color: #8f5902 }
kbd {
background-color: #f9f9f9;
border: 1px solid #aaa;
border-radius: .2em;
box-shadow: 0.1em 0.1em 0.2em rgba(0,0,0,0.1);
color: #000;
padding: 0.1em 0.3em;
}

View File

@@ -73,31 +73,31 @@ Functions
``math`` supports the following functions: ``math`` supports the following functions:
- ``abs`` - ``abs`` - the absolute value, with positive sign
- ``acos`` - ``acos`` - arc cosine
- ``asin`` - ``asin`` - arc sine
- ``atan`` - ``atan`` - arc tangent
- ``atan2`` - ``atan2`` - arc tangent of two variables
- ``bitand``, ``bitor`` and ``bitxor`` to perform bitwise operations. These will throw away any non-integer parts and interpret the rest as an int. - ``bitand``, ``bitor`` and ``bitxor`` to perform bitwise operations. These will throw away any non-integer parts and interpret the rest as an int.
- ``ceil`` - ``ceil`` - round number up to nearest integer
- ``cos`` - ``cos`` - the cosine
- ``cosh`` - ``cosh`` - hyperbolic cosine
- ``exp`` - the base-e exponential function - ``exp`` - the base-e exponential function
- ``fac`` - factorial - ``fac`` - factorial - also known as ``x!`` (``x * (x - 1) * (x - 2) * ... * 1``)
- ``floor`` - ``floor`` - round number down to nearest integer
- ``ln`` - the base-e logarithm - ``ln`` - the base-e logarithm
- ``log`` or ``log10`` - the base-10 logarithm - ``log`` or ``log10`` - the base-10 logarithm
- ``ncr`` - ``ncr`` - "from n choose r" combination function - how many subsets of size r can be taken from n (order doesn't matter)
- ``npr`` - ``npr`` - the number of subsets of size r that can be taken from a set of n elements (including different order)
- ``pow(x,y)`` returns x to the y (and can be written as ``x ^ y``) - ``pow(x,y)`` returns x to the y (and can be written as ``x ^ y``)
- ``round`` - rounds to the nearest integer, away from 0 - ``round`` - rounds to the nearest integer, away from 0
- ``sin`` - ``sin`` - the sine function
- ``sinh`` - ``sinh`` - the hyperbolic sine
- ``sqrt`` - ``sqrt`` - the square root - (can also be written as ``x ^ 0.5``)
- ``tan`` - ``tan`` - the tangent
- ``tanh`` - ``tanh`` - the hyperbolic tangent
All of the trigonometric functions use radians. All of the trigonometric functions use radians (the pi-based scale, not 360°).
Examples Examples
-------- --------
@@ -124,6 +124,8 @@ Examples
``math --base=hex 192`` prints ``0xc0``. ``math --base=hex 192`` prints ``0xc0``.
``math 'ncr(49,6)'`` prints 13983816 - that's the number of possible picks in 6-from-49 lotto.
Compatibility notes Compatibility notes
------------------- -------------------

View File

@@ -52,12 +52,6 @@ def setup(app):
) )
lexers["fish-docs-samples"] = fish_indent_lexer lexers["fish-docs-samples"] = fish_indent_lexer
# add_css_file only appears in Sphinx 1.8.0
if hasattr(app, "add_css_file"):
app.add_css_file("custom.css")
else:
app.add_stylesheet("custom.css")
app.add_config_value("issue_url", default=None, rebuild="html") app.add_config_value("issue_url", default=None, rebuild="html")
app.add_role("issue", issue_role) app.add_role("issue", issue_role)
@@ -154,7 +148,7 @@ html_copy_source = False
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"] # html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names # Custom sidebar templates, must be a dictionary that maps document names
# to template names. # to template names.

View File

@@ -301,20 +301,24 @@ The ``open`` command uses the MIME type database and the ``.desktop`` files used
Why won't SSH/SCP/rsync connect properly when fish is my login shell? Why won't SSH/SCP/rsync connect properly when fish is my login shell?
--------------------------------------------------------------------- ---------------------------------------------------------------------
This problem may manifest as messages such as "``Received message too long``", "``open terminal This problem may show up as messages like "``Received message too long``", "``open terminal
failed: not a terminal``", "``Bad packet length``", or "``Connection refused``" with strange output failed: not a terminal``", "``Bad packet length``", or "``Connection refused``" with strange output
in ``ssh_exchange_identification`` messages in the debug log. in ``ssh_exchange_identification`` messages in the debug log.
These problems are generally caused by the :ref:`user initialization file <initialization>` (usually This usually happens because fish reads the :ref:`user configuration file <initialization>` (``~/.config/fish/config.fish``) *always*,
``~/.config/fish/config.fish``) producing output when started in non-interactive mode. whether it's in an interactive or login or non-interactive or non-login shell.
This simplifies matters, but it also means when config.fish generates output, it will do that even in non-interactive shells like the one ssh/scp/rsync start when they connect.
Anything in config.fish that produces output should be guarded with ``status is-interactive`` (or ``status is-login`` if you prefer)::
All statements in initialization files that output to the terminal should be guarded with something
like the following::
if status is-interactive if status is-interactive
... ...
end end
The same applies for example when you start ``tmux`` in config.fish without guards, which will cause a message like ``sessions should be nested with care, unset $TMUX to force``.
.. _faq-unicode: .. _faq-unicode:
I'm getting weird graphical glitches (a staircase effect, ghost characters,...)? I'm getting weird graphical glitches (a staircase effect, ghost characters,...)?

View File

@@ -269,8 +269,6 @@ Any arbitrary file descriptor can used in a redirection by prefixing the redirec
For example, ``echo hello 2> output.stderr`` writes the standard error (file descriptor 2) to ``output.stderr``. For example, ``echo hello 2> output.stderr`` writes the standard error (file descriptor 2) to ``output.stderr``.
It is an error to redirect a builtin, function, or block to a file descriptor above 2. However this is supported for external commands.
.. [#] Previous versions of fish also allowed specifying this as ``^DESTINATION``, but that made another character special so it was deprecated and will be removed in the future. See :ref:`feature flags<featureflags>`. .. [#] Previous versions of fish also allowed specifying this as ``^DESTINATION``, but that made another character special so it was deprecated and will be removed in the future. See :ref:`feature flags<featureflags>`.
.. _pipes: .. _pipes:

View File

@@ -1,10 +1,10 @@
{% extends "classic/layout.html" %} {% extends "basic/layout.html" %}
{# Remove broken "genindex" link - unfortunately this takes with it the acceptable "next" and "previous" links, but they're not super necessary. #} {# Remove broken "genindex" link - unfortunately this takes with it the acceptable "next" and "previous" links, but they're not super necessary. #}
{% set rellinks = [] %} {% set rellinks = [] %}
{% block rootrellink %} {% block rootrellink %}
<li><img src="{{ pathto('_static/' + theme_root_icon, 1) }}" alt="" <li><img src="{{ pathto('_static/' + theme_root_icon, 1) }}" alt=""
style="max-width: 80px; vertical-align: middle; margin-top: -1px"/></li> style="width: 80px; vertical-align: middle; margin-top: -1px"/></li>
<li><a href="{{theme_root_url}}">{{theme_root_name}}</a>{{ reldelim1 }}</li> <li><a href="{{theme_root_url}}">{{theme_root_name}}</a>{{ reldelim1 }}</li>
{% if theme_root_include_title %} {% if theme_root_include_title %}
<a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }} <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}
@@ -41,9 +41,6 @@
{% block sidebar2 %} {% endblock %} {% block sidebar2 %} {% endblock %}
{% block extrahead %} {% block extrahead %}
<link rel="shortcut icon" type="image/png" href="{{ pathto('_static/' + theme_root_icon, 1) }}" /> <link rel="shortcut icon" type="image/png" href="{{ pathto('_static/' + theme_root_icon, 1) }}" />
{% if builder != "htmlhelp" %}
{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
{% endif %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}

View File

@@ -1,64 +0,0 @@
$(document).ready(function() {
/* Add a [>>>] button on the top-right corner of code samples to hide
* the >>> and ... prompts and the output and thus make the code
* copyable. */
var div = $('.highlight-python .highlight,' +
'.highlight-python3 .highlight,' +
'.highlight-pycon .highlight,' +
'.highlight-default .highlight');
var pre = div.find('pre');
// get the styles from the current theme
pre.parent().parent().css('position', 'relative');
var hide_text = 'Hide the prompts and output';
var show_text = 'Show the prompts and output';
var border_width = pre.css('border-top-width');
var border_style = pre.css('border-top-style');
var border_color = pre.css('border-top-color');
var button_styles = {
'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
'border-color': border_color, 'border-style': border_style,
'border-width': border_width, 'color': border_color, 'text-size': '75%',
'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
'border-radius': '0 3px 0 0'
}
// create and add the button to all the code blocks that contain >>>
div.each(function(index) {
var jthis = $(this);
if (jthis.find('.gp').length > 0) {
var button = $('<span class="copybutton">&gt;&gt;&gt;</span>');
button.css(button_styles)
button.attr('title', hide_text);
button.data('hidden', 'false');
jthis.prepend(button);
}
// tracebacks (.gt) contain bare text elements that need to be
// wrapped in a span to work with .nextUntil() (see later)
jthis.find('pre:has(.gt)').contents().filter(function() {
return ((this.nodeType == 3) && (this.data.trim().length > 0));
}).wrap('<span>');
});
// define the behavior of the button when it's clicked
$('.copybutton').click(function(e){
e.preventDefault();
var button = $(this);
if (button.data('hidden') === 'false') {
// hide the code output
button.parent().find('.go, .gp, .gt').hide();
button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
button.css('text-decoration', 'line-through');
button.attr('title', show_text);
button.data('hidden', 'true');
} else {
// show the code output
button.parent().find('.go, .gp, .gt').show();
button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
button.css('text-decoration', 'none');
button.attr('title', hide_text);
button.data('hidden', 'false');
}
});
});

View File

@@ -1,4 +1,4 @@
@import url("default.css"); @import url("classic.css");
html { html {
background: none; background: none;
@@ -276,3 +276,31 @@ dl > dt span ~ em {
margin: 0; margin: 0;
} }
} }
.sphinxsidebar ul.current > li.current { font-weight: bold }
.gray { color: #555555 }
.purple { color: #551a8b }
.red { color: #FF0000 }
/* Color based on the Name.Function (.nf) class from pygments.css. */
.command { color: #005fd7 }
/* Color based on the Name.Constant (.no) class from pygments.css. */
.param { color: #00afff }
/* Color based on the Name.Constant (.no) class from pygments.css. */
/* Used for underlining file paths in interactive code examples. */
.param-valid-path { color: #00afff; text-decoration: underline }
/* Color based on the Generic.Prompt (.gp) class from pygments.css. */
.prompt { color: #8f5902 }
kbd {
background-color: #f9f9f9;
border: 1px solid #aaa;
border-radius: .2em;
box-shadow: 0.1em 0.1em 0.2em rgba(0,0,0,0.1);
color: #000;
padding: 0.1em 0.3em;
}

View File

@@ -0,0 +1,539 @@
/*
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
* This file taken for fish from sphinx 3.5.1 to add a special error message
* that lists short builtins.
*
*/
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
htmlToText : function(htmlString) {
var virtualDocument = document.implementation.createHTMLDocument('virtual');
var htmlElement = $(htmlString, virtualDocument);
htmlElement.find('.headerlink').remove();
docContent = htmlElement.find('[role=main]')[0];
if(docContent === undefined) {
console.warn("Content block not found. Sphinx search tries to obtain it " +
"via '[role=main]'. Could you check your theme or template.");
return "";
}
return docContent.textContent || docContent.innerText;
},
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
// prevent stemmer from cutting word smaller than two chars
if(word.length < 3 && tmp[i].length >= 3) {
word = tmp[i];
}
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
var listItem = $('<li></li>');
if (results.length) {
var item = results.pop();
var requestUrl = "";
var linkUrl = "";
if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
}
listItem.append($('<a/>').attr('href',
linkUrl +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.ajax({url: requestUrl,
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
}
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}});
} else {
// no source available, just display title
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount) {
Search.status.text(_('Your search did not match any documents. Unfortunately search does not work with short terms, so here are some commonly used short builtins:'));
var shortbuiltins = {
"and": "conditionally execute a command",
"cd": "change directory",
"end": "end a block of commands",
"for": "perform a set of commands multiple times",
"if": "conditionally execute a command",
"or": "condtionally execute a command",
"set": "display and change shell variables",
};
for (var sb in shortbuiltins) {
var li = $('<li><a href="cmds/' + sb + '.html">' + sb + " - " + shortbuiltins[sb] + '</a></li>');
Search.output.append(li);
}
} else {
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
}
Search.status.fadeIn(500);
}
}
displayNextItem();
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var docnames = this._index.docnames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var i;
var results = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
var fullnameLower = fullname.toLowerCase()
if (fullnameLower.indexOf(object) > -1) {
var score = 0;
var parts = fullnameLower.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
}
}
}
return results;
},
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
*/
escapeRegExp : function(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
var docnames = this._index.docnames;
var filenames = this._index.filenames;
var titles = this._index.titles;
var i, j, file;
var fileMap = {};
var scoreMap = {};
var results = [];
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
var files = [];
var _o = [
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
// add support for partial matches
if (word.length > 2) {
var word_regex = this.escapeRegExp(word);
for (var w in terms) {
if (w.match(word_regex) && !terms[word]) {
_o.push({files: terms[w], score: Scorer.partialTerm})
}
}
for (var w in titleterms) {
if (w.match(word_regex) && !titleterms[word]) {
_o.push({files: titleterms[w], score: Scorer.partialTitle})
}
}
}
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
break;
}
// found search word in contents
$u.each(_o, function(o) {
var _files = o.files;
if (_files === undefined)
return
if (_files.length === undefined)
_files = [_files];
files = files.concat(_files);
// set score for the word in each file to Scorer.term
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {};
scoreMap[file][word] = o.score;
}
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap && fileMap[file].indexOf(word) === -1)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
// check if all requirements are matched
var filteredTermCount = // as search terms with length < 3 are discarded: ignore
searchterms.filter(function(term){return term.length > 2}).length
if (
fileMap[file].length != searchterms.length &&
fileMap[file].length != filteredTermCount
) continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
titleterms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file) ||
$u.contains(titleterms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it to the result list
if (valid) {
// select one (max) score for the file.
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
}
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(htmlText, keywords, hlwords) {
var text = Search.htmlToText(htmlText);
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
};
$(document).ready(function() {
Search.init();
});

View File

@@ -1,194 +0,0 @@
/*
* sidebar.js
* ~~~~~~~~~~
*
* This script makes the Sphinx sidebar collapsible and implements intelligent
* scrolling. This is a slightly modified version of Sphinx's own sidebar.js.
*
* .sphinxsidebar contains .sphinxsidebarwrapper. This script adds in
* .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to
* collapse and expand the sidebar.
*
* When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the
* width of the sidebar and the margin-left of the document are decreased.
* When the sidebar is expanded the opposite happens. This script saves a
* per-browser/per-session cookie used to remember the position of the sidebar
* among the pages. Once the browser is closed the cookie is deleted and the
* position reset to the default (expanded).
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
$(function() {
// global elements used by the functions.
// the 'sidebarbutton' element is defined as global after its
// creation, in the add_sidebar_button function
var jwindow = $(window);
var jdocument = $(document);
var bodywrapper = $('.bodywrapper');
var documentwrapper = $('.documentwrapper');
var sidebar = $('.sphinxsidebar');
var sidebarwrapper = $('.sphinxsidebarwrapper');
// original margin-left of the bodywrapper and width of the sidebar
// with the sidebar expanded
var bw_margin_expanded = bodywrapper.css('margin-left');
var ssb_width_expanded = sidebar.width();
// margin-left of the bodywrapper and width of the sidebar
// with the sidebar collapsed
var bw_margin_collapsed = '.8em';
var ssb_width_collapsed = '.8em';
// colors used by the current theme
var dark_color = '#AAAAAA';
var light_color = '#CCCCCC';
function get_viewport_height() {
if (window.innerHeight)
return window.innerHeight;
else
return jwindow.height();
}
function sidebar_is_collapsed() {
return sidebarwrapper.is(':not(:visible)');
}
function toggle_sidebar() {
if (sidebar_is_collapsed())
expand_sidebar();
else
collapse_sidebar();
// adjust the scrolling of the sidebar
scroll_sidebar();
}
function collapse_sidebar() {
sidebarwrapper.hide();
sidebar.css('width', ssb_width_collapsed);
bodywrapper.css('margin-left', bw_margin_collapsed);
sidebarbutton.css({
'margin-left': '0',
'height': documentwrapper.height(),
'border-radius': '5px'
});
sidebarbutton.find('span').text('»');
sidebarbutton.attr('title', _('Expand sidebar'));
document.cookie = 'sidebar=collapsed';
}
function expand_sidebar() {
bodywrapper.css('margin-left', bw_margin_expanded);
sidebar.css('width', ssb_width_expanded);
sidebarwrapper.show();
sidebarbutton.css({
'margin-left': ssb_width_expanded-12,
'height': Math.max(sidebarwrapper.height(), documentwrapper.height()),
'border-radius': '0 5px 5px 0'
});
sidebarbutton.find('span').text('«');
sidebarbutton.attr('title', _('Collapse sidebar'));
//sidebarwrapper.css({'padding-top':
// Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)});
document.cookie = 'sidebar=expanded';
}
function add_sidebar_button() {
sidebarwrapper.css({
'float': 'left',
'margin-right': '0',
'width': ssb_width_expanded - 28
});
// create the button
sidebar.append(
'<div id="sidebarbutton"><span>&laquo;</span></div>'
);
var sidebarbutton = $('#sidebarbutton');
// find the height of the viewport to center the '<<' in the page
var viewport_height = get_viewport_height();
var sidebar_offset = sidebar.offset().top;
var sidebar_height = Math.max(documentwrapper.height(), sidebar.height());
sidebarbutton.find('span').css({
'display': 'block',
'position': 'fixed',
'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10
});
sidebarbutton.click(toggle_sidebar);
sidebarbutton.attr('title', _('Collapse sidebar'));
sidebarbutton.css({
'border-radius': '0 5px 5px 0',
'color': '#444444',
'background-color': '#CCCCCC',
'font-size': '1.2em',
'cursor': 'pointer',
'height': sidebar_height,
'padding-top': '1px',
'padding-left': '1px',
'margin-left': ssb_width_expanded - 12
});
sidebarbutton.hover(
function () {
$(this).css('background-color', dark_color);
},
function () {
$(this).css('background-color', light_color);
}
);
}
function set_position_from_cookie() {
if (!document.cookie)
return;
var items = document.cookie.split(';');
for(var k=0; k<items.length; k++) {
var key_val = items[k].split('=');
var key = key_val[0];
if (key == 'sidebar') {
var value = key_val[1];
if ((value == 'collapsed') && (!sidebar_is_collapsed()))
collapse_sidebar();
else if ((value == 'expanded') && (sidebar_is_collapsed()))
expand_sidebar();
}
}
}
add_sidebar_button();
var sidebarbutton = $('#sidebarbutton');
set_position_from_cookie();
/* intelligent scrolling */
function scroll_sidebar() {
var sidebar_height = sidebarwrapper.height();
var viewport_height = get_viewport_height();
var offset = sidebar.position()['top'];
var wintop = jwindow.scrollTop();
var winbot = wintop + viewport_height;
var curtop = sidebarwrapper.position()['top'];
var curbot = curtop + sidebar_height;
// does sidebar fit in window?
if (sidebar_height < viewport_height) {
// yes: easy case -- always keep at the top
sidebarwrapper.css('top', $u.min([$u.max([0, wintop - offset - 10]),
jdocument.height() - sidebar_height - 200]));
}
else {
// no: only scroll if top/bottom edge of sidebar is at
// top/bottom edge of window
if (curtop > wintop && curbot > winbot) {
sidebarwrapper.css('top', $u.max([wintop - offset - 10, 0]));
}
else if (curtop < wintop && curbot < winbot) {
sidebarwrapper.css('top', $u.min([winbot - sidebar_height - offset - 20,
jdocument.height() - sidebar_height - 200]));
}
}
}
jwindow.scroll(scroll_sidebar);
});

View File

@@ -3556,7 +3556,7 @@ msgstr ""
#: /tmp/fish/explicit/share/functions/cdh.fish:5 #: /tmp/fish/explicit/share/functions/cdh.fish:5
msgid "Select directory by letter or number: " msgid "Select directory by letter or number: "
msgstr "Sélectionner un dossier par lettre ou chiffre" msgstr "Sélectionner un dossier par lettre ou chiffre : "
#: /tmp/fish/explicit/share/functions/cdh.fish:6 #: /tmp/fish/explicit/share/functions/cdh.fish:6
msgid "" msgid ""

View File

@@ -7,13 +7,13 @@
complete -c badblocks -s b -d 'Block-size Specify the size of blocks in bytes' complete -c badblocks -s b -d 'Block-size Specify the size of blocks in bytes'
complete -c badblocks -s c -d 'Number of blocks is the number of blocks which are tested at a time' complete -c badblocks -s c -d 'Number of blocks is the number of blocks which are tested at a time'
complete -c badblocks -s f -d 'Normally, badblocks will refuse to do a read/write or a nondestructive test on a device which is mounted, since either can cause the system to potentially crash and/or damage the filesystem even if it is mounted read-only' complete -c badblocks -s f -d 'Execute test even when device is mounted (dangerous!)'
complete -c badblocks -s i -d 'Input_file Read a list of already existing known bad blocks' complete -c badblocks -s i -d 'Input_file Read a list of already existing known bad blocks'
complete -c badblocks -s o -d 'Output_file Write the list of bad blocks to the specified file' complete -c badblocks -s o -d 'Output_file Write the list of bad blocks to the specified file'
complete -c badblocks -s p -d 'Repeat scanning the disk until there are no new blocks discovered in specified number of consecutive scans of the disk' complete -c badblocks -s p -d 'Repeat until no new blocks are found in provided number of scans'
complete -c badblocks -s t -d 'Test_pattern Specify a test pattern to be read (and written) to disk blocks' complete -c badblocks -s t -d 'Test_pattern Specify a test pattern to be read (and written) to disk blocks'
complete -c badblocks -s n -d 'Use non-destructive read-write mode' complete -c badblocks -s n -d 'Use non-destructive read-write mode'
complete -c badblocks -s s -d 'Show the progress of the scan by writing out the block numbers as they are checked' complete -c badblocks -s s -d 'Show scan progress'
complete -c badblocks -s v -d 'Verbose mode' complete -c badblocks -s v -d 'Verbose mode'
complete -c badblocks -s w -d 'Use write-mode test' complete -c badblocks -s w -d 'Use write-mode test'
complete -c badblocks -s X -d 'Internal flag only to be used by e2fsck(8) and mke2fs(8)' complete -c badblocks -s X -d 'Internal flag only to be used by e2fsck(8) and mke2fs(8)'

View File

@@ -1,7 +1,7 @@
complete -c curl -n 'string match -qr "^@" -- (commandline -ct)' -k -xa "(printf '%s\n' -- @(__fish_complete_suffix (commandline -ct | string replace -r '^@' '') ''))" complete -c curl -n 'string match -qr "^@" -- (commandline -ct)' -k -xa "(printf '%s\n' -- @(__fish_complete_suffix (commandline -ct | string replace -r '^@' '') ''))"
# These based on the autogenerated completions. # These based on the autogenerated completions.
complete -c curl -l abstract-unix-socket -d '(HTTP) Connect through an abstract Unix domain socket, instead of using the n…' complete -c curl -l abstract-unix-socket -d '(HTTP) Connect through an abstract Unix domain socket'
complete -c curl -l anyauth -d '(HTTP) Use most secure authentication method automatically' complete -c curl -l anyauth -d '(HTTP) Use most secure authentication method automatically'
complete -c curl -s a -l append -d '(FTP SFTP) Upload: append to the target file' complete -c curl -s a -l append -d '(FTP SFTP) Upload: append to the target file'
complete -c curl -l basic -d '(HTTP) Use HTTP Basic authentication' complete -c curl -l basic -d '(HTTP) Use HTTP Basic authentication'
@@ -65,12 +65,12 @@ complete -c curl -l ftp-ssl-control -d '(FTP) Require SSL/TLS for the FTP login,
complete -c curl -s G -l get -d 'Use GET instead of POST' complete -c curl -s G -l get -d 'Use GET instead of POST'
complete -c curl -s g -l globoff -d 'This option switches off the "URL globbing parser"' complete -c curl -s g -l globoff -d 'This option switches off the "URL globbing parser"'
complete -c curl -l happy-eyeballs-timeout-ms -d 'Attempt to connect to both IPv4 and IPv6 in parallel' complete -c curl -l happy-eyeballs-timeout-ms -d 'Attempt to connect to both IPv4 and IPv6 in parallel'
complete -c curl -l haproxy-protocol -d '(HTTP) Send a HAProxy PROXY protocol v1 header at the beginning of the connection' complete -c curl -l haproxy-protocol -d '(HTTP) Use HAProxy PROXY protocol'
complete -c curl -s I -l head -d '(HTTP FTP FILE) Fetch the headers only' complete -c curl -s I -l head -d '(HTTP FTP FILE) Fetch the headers only'
complete -c curl -s H -l header -d '(HTTP) Extra header to include in the request when sending HTTP to a server' complete -c curl -s H -l header -d '(HTTP) Extra header to include in the request when sending HTTP to a server'
complete -c curl -s h -l help -d 'Usage help' complete -c curl -s h -l help -d 'Usage help'
complete -c curl -l hostpubmd5 -d '(SFTP SCP) Pass a string containing 32 hexadecimal digits' complete -c curl -l hostpubmd5 -d '(SFTP SCP) Pass a string containing 32 hexadecimal digits'
complete -c curl -l 'http0.9' -d '(HTTP) Tells curl to be fine with HTTP version 0. 9 response. HTTP/0' complete -c curl -l 'http0.9' -d '(HTTP) Accept HTTP version 0.9 response'
complete -c curl -s 0 -l 'http1.0' -d '(HTTP) Use HTTP version 1' complete -c curl -s 0 -l 'http1.0' -d '(HTTP) Use HTTP version 1'
complete -c curl -l 'http1.1' -d '(HTTP) Use HTTP version 1.1' complete -c curl -l 'http1.1' -d '(HTTP) Use HTTP version 1.1'
complete -c curl -l http2-prior-knowledge -d '(HTTP) Use HTTP/2 immediately (without trying HTTP1)' complete -c curl -l http2-prior-knowledge -d '(HTTP) Use HTTP/2 immediately (without trying HTTP1)'
@@ -129,83 +129,83 @@ complete -c curl -l proto-redir -d 'Limit what protocols it may use on redirect'
# TODO: args # TODO: args
complete -c curl -l proto -d 'Limit what protocols it may use in the transfer' complete -c curl -l proto -d 'Limit what protocols it may use in the transfer'
complete -c curl -l proxy-anyauth -d 'Like --anyauth but for the proxy' complete -c curl -l proxy-anyauth -d 'Like --anyauth but for the proxy'
complete -c curl -l proxy-basic -d 'Tells curl to use HTTP Basic authentication when communicating with the given…' complete -c curl -l proxy-basic -d 'Use HTTP Basic authentication to communicate with proxy'
complete -c curl -l proxy-cacert -d 'Same as --cacert but used in HTTPS proxy context' complete -c curl -l proxy-cacert -d 'Same as --cacert but used in HTTPS proxy context'
complete -c curl -l proxy-capath -d 'Same as --capath but used in HTTPS proxy context' complete -c curl -l proxy-capath -d 'Same as --capath but used in HTTPS proxy context'
complete -c curl -l proxy-cert-type -d 'Same as --cert-type but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-cert-type -d 'Same as --cert-type but used in HTTPS proxy context'
complete -c curl -l proxy-cert -d 'Same as -E, --cert but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-cert -d 'Same as -E, --cert but used in HTTPS proxy context'
complete -c curl -l proxy-ciphers -d 'Same as --ciphers but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-ciphers -d 'Same as --ciphers but used in HTTPS proxy context'
complete -c curl -l proxy-crlfile -d 'Same as --crlfile but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-crlfile -d 'Same as --crlfile but used in HTTPS proxy context'
complete -c curl -l proxy-digest -d 'Tells curl to use HTTP Digest authentication when communicating with the give…' complete -c curl -l proxy-digest -d 'Use HTTP Digest authentication to communicate with proxy'
complete -c curl -l proxy-header -d '(HTTP) Extra header to include in the request when sending HTTP to a proxy' complete -c curl -l proxy-header -d '(HTTP) Extra header to include in the request when sending HTTP to a proxy'
complete -c curl -l proxy-insecure -d 'Same as -k, --insecure but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-insecure -d 'Same as -k, --insecure but used in HTTPS proxy context'
complete -c curl -l proxy-key-type -d 'Same as --key-type but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-key-type -d 'Same as --key-type but used in HTTPS proxy context'
complete -c curl -l proxy-key -d 'Same as --key but used in HTTPS proxy context' complete -c curl -l proxy-key -d 'Same as --key but used in HTTPS proxy context'
complete -c curl -l proxy-negotiate -d 'Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating w…' complete -c curl -l proxy-negotiate -d 'Use HTTP Negotiate authentication to communicate with proxy'
complete -c curl -l proxy-ntlm -d 'Tells curl to use HTTP NTLM authentication when communicating with the given …' complete -c curl -l proxy-ntlm -d 'Use HTTP NTLM authentication when to communicate with proxy'
complete -c curl -l proxy-pass -d 'Same as --pass but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-pass -d 'Same as --pass but used in HTTPS proxy context'
complete -c curl -l proxy-pinnedpubkey -d '(TLS) Tells curl to use the specified public key file (or hashes) to verify t…' complete -c curl -l proxy-pinnedpubkey -d '(TLS) Use specified public key file or hashes to verify proxy'
complete -c curl -l proxy-service-name -d 'This option allows you to change the service name for proxy negotiation' complete -c curl -l proxy-service-name -d 'This option allows you to change the service name for proxy negotiation'
complete -c curl -l proxy-ssl-allow-beast -d 'Same as --ssl-allow-beast but used in HTTPS proxy context. Added in 7. 52' complete -c curl -l proxy-ssl-allow-beast -d 'Same as --ssl-allow-beast but used in HTTPS proxy context'
complete -c curl -l proxy-tls13-ciphers -d '(TLS) Specifies which cipher suites to use in the connection to your HTTPS pr…' complete -c curl -l proxy-tls13-ciphers -d '(TLS) Specify cipher suites for TLS 1.3 proxy connection'
complete -c curl -l proxy-tlsauthtype -d 'Same as --tlsauthtype but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-tlsauthtype -d 'Same as --tlsauthtype but used in HTTPS proxy context'
complete -c curl -l proxy-tlspassword -d 'Same as --tlspassword but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-tlspassword -d 'Same as --tlspassword but used in HTTPS proxy context'
complete -c curl -l proxy-tlsuser -d 'Same as --tlsuser but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-tlsuser -d 'Same as --tlsuser but used in HTTPS proxy context'
complete -c curl -l proxy-tlsv1 -d 'Same as -1, --tlsv1 but used in HTTPS proxy context. Added in 7. 52. 0' complete -c curl -l proxy-tlsv1 -d 'Same as -1, --tlsv1 but used in HTTPS proxy context'
complete -c curl -s U -l proxy-user -d 'Specify the user name and password to use for proxy authentication' complete -c curl -s U -l proxy-user -d 'Specify the user name and password to use for proxy authentication'
complete -c curl -s x -l proxy -d 'Use the specified proxy' complete -c curl -s x -l proxy -d 'Use the specified proxy'
complete -c curl -l 'proxy1.0' -d 'Use the specified HTTP 1.0 proxy' complete -c curl -l 'proxy1.0' -d 'Use the specified HTTP 1.0 proxy'
complete -c curl -s p -l proxytunnel -d 'When an HTTP proxy is used -x, --proxy, this option will cause non-HTTP proto…' complete -c curl -s p -l proxytunnel -d 'If HTTP proxy is used, make curl tunnel through it'
complete -c curl -l pubkey -d '(SFTP SCP) Public key file name' complete -c curl -l pubkey -d '(SFTP SCP) Public key file name'
complete -c curl -s Q -l quote -d '(FTP SFTP) Send an arbitrary command to the remote FTP or SFTP server' complete -c curl -s Q -l quote -d '(FTP SFTP) Send an arbitrary command to the remote FTP or SFTP server'
complete -c curl -l random-file -d 'Specify the path name to file containing what will be considered as random da' complete -c curl -l random-file -d 'Specify file containing random data'
complete -c curl -s r -l range -d '(HTTP FTP SFTP FILE) Retrieve a byte range (i. e' complete -c curl -s r -l range -d '(HTTP FTP SFTP FILE) Retrieve a byte range'
complete -c curl -o 500 -d 'specifies the last 500 bytes' complete -c curl -o 500 -d 'specifies the last 500 bytes'
complete -c curl -s 1 -d 'specifies the first and last byte only(*)(HTTP)' complete -c curl -s 1 -d 'specifies the first and last byte only(*)(HTTP)'
complete -c curl -l raw -d '(HTTP) When used, it disables all internal HTTP decoding of content or transf…' complete -c curl -l raw -d '(HTTP) Pass raw data (no HTTP decoding or transfer encoding)'
complete -c curl -s e -l referer -d '(HTTP) Sends the "Referrer Page" information to the HTTP server' complete -c curl -s e -l referer -d '(HTTP) Sends the "Referrer Page" information to the HTTP server'
complete -c curl -s J -l remote-header-name -d '(HTTP) This option tells the -O, --remote-name option to use the server-speci…' complete -c curl -s J -l remote-header-name -d '(HTTP) Save output to filename from Content-Disposition'
complete -c curl -l remote-name-all -d 'This option changes the default action for all given URLs to be dealt with as…' complete -c curl -l remote-name-all -d 'For every URL write output to local file by default'
complete -c curl -s O -l remote-name -d 'Write output to a local file named like the remote file we get' complete -c curl -s O -l remote-name -d 'Write output to a local file named like the remote file we get'
complete -c curl -s R -l remote-time -d 'When used, this will make curl attempt to figure out the timestamp of the rem…' complete -c curl -s R -l remote-time -d 'Use timestamp of remote file on output'
complete -c curl -l request-target -d '(HTTP) Tells curl to use an alternative "target" (path) instead of using the …' complete -c curl -l request-target -d '(HTTP) Use an alternative request target'
complete -c curl -s X -l request -d '(HTTP) Specifies a custom request method to use when communicating with the H…' complete -c curl -s X -l request -d '(HTTP) Specifies a custom HTTP method'
complete -c curl -l resolve -d 'Provide a custom address for a specific host and port pair' complete -c curl -l resolve -d 'Provide a custom address for a specific host and port pair'
complete -c curl -l retry-connrefused -d 'In addition to the other conditions, consider ECONNREFUSED as a transient err' complete -c curl -l retry-connrefused -d 'Consider ECONNREFUSED a transient error'
complete -c curl -l retry-delay -d 'Make curl sleep this amount of time before each retry when a transfer has fai…' complete -c curl -l retry-delay -d 'Time to wait between transfer retries'
complete -c curl -l retry-max-time -d 'The retry timer is reset before the first transfer attempt' complete -c curl -l retry-max-time -d 'The retry timer is reset before the first transfer attempt'
complete -c curl -l retry -d 'If a transient error is returned when curl tries to perform a transfer, it wi…' complete -c curl -l retry -d 'Number of retries when transient error occurs'
complete -c curl -l sasl-ir -d 'Enable initial response in SASL authentication. Added in 7. 31. 0' complete -c curl -l sasl-ir -d 'Enable initial response in SASL authentication'
complete -c curl -l service-name -d 'This option allows you to change the service name for SPNEGO' complete -c curl -l service-name -d 'This option allows you to change the service name for SPNEGO'
complete -c curl -s S -l show-error -d 'When used with -s, --silent, it makes curl show an error message if it fails' complete -c curl -s S -l show-error -d 'When used with -s, --silent, it makes curl show an error message if it fails'
complete -c curl -s s -l silent -d 'Silent or quiet mode. Don\'t show progress meter or error messages' complete -c curl -s s -l silent -d 'Silent or quiet mode. Don\'t show progress meter or error messages'
complete -c curl -l socks4 -d 'Use the specified SOCKS4 proxy' complete -c curl -l socks4 -d 'Use the specified SOCKS4 proxy'
complete -c curl -l socks4a -d 'Use the specified SOCKS4a proxy' complete -c curl -l socks4a -d 'Use the specified SOCKS4a proxy'
complete -c curl -l socks5-basic -d 'Tells curl to use username/password authentication when connecting to a SOCKS' complete -c curl -l socks5-basic -d 'Use username/password authentication to connect to SOCKS5 proxy'
complete -c curl -l socks5-gssapi-nec -d 'As part of the GSS-API negotiation a protection mode is negotiated' complete -c curl -l socks5-gssapi-nec -d 'As part of the GSS-API negotiation a protection mode is negotiated'
complete -c curl -l socks5-gssapi-service -d 'The default service name for a socks server is rcmd/server-fqdn' complete -c curl -l socks5-gssapi-service -d 'The default service name for a socks server is rcmd/server-fqdn'
complete -c curl -l socks5-gssapi -d 'Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy' complete -c curl -l socks5-gssapi -d 'Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy'
complete -c curl -l socks5-hostname -d 'Use the specified SOCKS5 proxy (and let the proxy resolve the host name)' complete -c curl -l socks5-hostname -d 'Use the specified SOCKS5 proxy (and let the proxy resolve the host name)'
complete -c curl -l socks5 -d 'Use the specified SOCKS5 proxy - but resolve the host name locally' complete -c curl -l socks5 -d 'Use the specified SOCKS5 proxy - but resolve the host name locally'
complete -c curl -s Y -l speed-limit -d 'If a download is slower than this given speed (in bytes per second) for speed…' complete -c curl -s Y -l speed-limit -d 'Abort download if it\'s slower than given speed (Bps) for speed-time'
complete -c curl -s y -l speed-time -d 'If a download is slower than speed-limit bytes per second during a speed-time…' complete -c curl -s y -l speed-time -d 'Abort download if it\'s slower than speed for given speed-time (s)'
complete -c curl -l ssl-allow-beast -d 'This option tells curl to not work around a security flaw in the SSL3 and TLS…' complete -c curl -l ssl-allow-beast -d 'Don\'t work around BEAST security flaw in SSL3 and TLS1.0'
complete -c curl -l ssl-no-revoke -d '(Schannel) This option tells curl to disable certificate revocation checks' complete -c curl -l ssl-no-revoke -d '(Schannel) This option tells curl to disable certificate revocation checks'
complete -c curl -l ssl-reqd -d '(FTP IMAP POP3 SMTP) Require SSL/TLS for the connection' complete -c curl -l ssl-reqd -d '(FTP IMAP POP3 SMTP) Require SSL/TLS for the connection'
complete -c curl -l ssl -d '(FTP IMAP POP3 SMTP) Try to use SSL/TLS for the connection' complete -c curl -l ssl -d '(FTP IMAP POP3 SMTP) Try to use SSL/TLS for the connection'
complete -c curl -s 2 -l sslv2 -d '(SSL) Forces curl to use SSL version 2 when negotiating with a remote SSL ser…' complete -c curl -s 2 -l sslv2 -d '(SSL) Use SSL version 2'
complete -c curl -s 3 -l sslv3 -d '(SSL) Forces curl to use SSL version 3 when negotiating with a remote SSL ser…' complete -c curl -s 3 -l sslv3 -d '(SSL) Use SSL version 3'
complete -c curl -l stderr -d 'Redirect all writes to stderr to the specified file instead' complete -c curl -l stderr -d 'Redirect all writes to stderr to the specified file instead'
complete -c curl -l styled-output -d 'Enables the automatic use of bold font styles when writing HTTP headers to th…' complete -c curl -l styled-output -d 'Use bold font styles when writing HTTP headers to terminal'
complete -c curl -l suppress-connect-headers -d 'When -p, --proxytunnel is used and a CONNECT request is made don\'t output pro…' complete -c curl -l suppress-connect-headers -d 'Don\'t print response headers for CONNECT request if -p is set'
complete -c curl -l tcp-fastopen -d 'Enable use of TCP Fast Open (RFC7413). Added in 7. 49. 0' complete -c curl -l tcp-fastopen -d 'Enable use of TCP Fast Open'
complete -c curl -l tcp-nodelay -d 'Turn on the TCP_NODELAY option' complete -c curl -l tcp-nodelay -d 'Turn on the TCP_NODELAY option'
complete -c curl -s t -l telnet-option -d 'Pass options to the telnet protocol' complete -c curl -s t -l telnet-option -d 'Pass options to the telnet protocol'
complete -c curl -l tftp-blksize -d '(TFTP) Set TFTP BLKSIZE option (must be >512)' complete -c curl -l tftp-blksize -d '(TFTP) Set TFTP BLKSIZE option (must be >512)'
complete -c curl -l tftp-no-options -d '(TFTP) Tells curl not to send TFTP options requests' complete -c curl -l tftp-no-options -d '(TFTP) Tells curl not to send TFTP options requests'
complete -c curl -s z -l time-cond -d '(HTTP FTP) Request a file that has been modified later than the given time an…' complete -c curl -s z -l time-cond -d '(HTTP FTP) Request file modified before or later than given time'
complete -c curl -l tls-max -d '(SSL) VERSION defines maximum supported TLS version' complete -c curl -l tls-max -d '(SSL) VERSION defines maximum supported TLS version'
complete -c curl -l tls13-ciphers -d '(TLS) Specifies which cipher suites to use in the connection if it negotiates…' complete -c curl -l tls13-ciphers -d '(TLS) Specifies cipher suites to use for TLS 1.3'
complete -c curl -l tlsauthtype -d 'Set TLS authentication type' complete -c curl -l tlsauthtype -d 'Set TLS authentication type'
complete -c curl -l tlspassword -d 'Set password for use with the TLS authentication method' complete -c curl -l tlspassword -d 'Set password for use with the TLS authentication method'
complete -c curl -l tlsuser -d 'Set username for use with the TLS authentication method' complete -c curl -l tlsuser -d 'Set username for use with the TLS authentication method'
@@ -214,7 +214,7 @@ complete -c curl -l 'tlsv1.1' -d '(TLS) Forces curl to use TLS version 1.1'
complete -c curl -l 'tlsv1.2' -d '(TLS) Forces curl to use TLS version 1.2' complete -c curl -l 'tlsv1.2' -d '(TLS) Forces curl to use TLS version 1.2'
complete -c curl -l 'tlsv1.3' -d '(TLS) Forces curl to use TLS version 1.3' complete -c curl -l 'tlsv1.3' -d '(TLS) Forces curl to use TLS version 1.3'
complete -c curl -l tlsv1 -d '(SSL) Tells curl to use at least TLS version 1' complete -c curl -l tlsv1 -d '(SSL) Tells curl to use at least TLS version 1'
complete -c curl -l tr-encoding -d '(HTTP) Request a compressed Transfer-Encoding response using one of the algor…' complete -c curl -l tr-encoding -d '(HTTP) Request compressed Transfer-Encoding, uncompress on receive'
complete -c curl -l trace-ascii -d 'Enables a full trace dump of all incoming and outgoing data' complete -c curl -l trace-ascii -d 'Enables a full trace dump of all incoming and outgoing data'
complete -c curl -l trace-time -d 'Prepends a time stamp to each trace or verbose line that curl displays' complete -c curl -l trace-time -d 'Prepends a time stamp to each trace or verbose line that curl displays'
complete -c curl -l trace -d 'Enables a full trace dump of all incoming and outgoing data' complete -c curl -l trace -d 'Enables a full trace dump of all incoming and outgoing data'

View File

@@ -47,7 +47,7 @@ function __fish_git_recent_commits
# Like __fish_git_commits, but not on all branches and limited to # Like __fish_git_commits, but not on all branches and limited to
# the last 50 commits. Used for fixup, where only the current branch # the last 50 commits. Used for fixup, where only the current branch
# and the latest commits make sense. # and the latest commits make sense.
__fish_git log --pretty=tformat:"%h"\t"%<(64,trunc)%s" --max-count=50 2>/dev/null __fish_git log --pretty=tformat:"%h"\t"%<(64,trunc)%s" --max-count=50 $argv 2>/dev/null
end end
function __fish_git_branches function __fish_git_branches
@@ -972,7 +972,7 @@ complete -k -f -c git -n '__fish_git_using_command checkout; and not contains --
complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_heads)' -d Head complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_heads)' -d Head
complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_branches)' complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_branches)'
complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_unique_remote_branches)' -d 'Unique Remote Branch' complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_unique_remote_branches)' -d 'Unique Remote Branch'
complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_recent_commits)' complete -k -f -c git -n '__fish_git_using_command checkout; and not contains -- -- (commandline -opc)' -a '(__fish_git_recent_commits --all)'
complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_files modified deleted)' complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_files modified deleted)'
complete -f -c git -n '__fish_git_using_command checkout' -s b -d 'Create a new branch' complete -f -c git -n '__fish_git_using_command checkout' -s b -d 'Create a new branch'
complete -f -c git -n '__fish_git_using_command checkout' -s t -l track -d 'Track a new branch' complete -f -c git -n '__fish_git_using_command checkout' -s t -l track -d 'Track a new branch'
@@ -1505,6 +1505,7 @@ complete -f -c git -n __fish_git_needs_command -a rebase -d 'Forward-port local
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_remotes)' -d 'Remote alias' complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_remotes)' -d 'Remote alias'
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_branches)' complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_branches)'
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_heads)' -d Head complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_heads)' -d Head
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_recent_commits)'
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_tags)' -d Tag complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_tags)' -d Tag
complete -f -c git -n '__fish_git_using_command rebase' -l continue -d 'Restart the rebasing process' complete -f -c git -n '__fish_git_using_command rebase' -l continue -d 'Restart the rebasing process'
complete -f -c git -n '__fish_git_using_command rebase' -l abort -d 'Abort the rebase operation' complete -f -c git -n '__fish_git_using_command rebase' -l abort -d 'Abort the rebase operation'
@@ -1922,8 +1923,8 @@ for file in $PATH/git-*
and continue and continue
complete -C "git-$subcommand " >/dev/null complete -C "git-$subcommand " >/dev/null
if [ (complete git-$subcommand | count) -gt 0 ] if [ (complete -c git-$subcommand | count) -gt 0 ]
complete git -f -n "__fish_git_using_command $subcommand" -a "(__fish_git_complete_custom_command $subcommand)" complete -c git -f -n "__fish_git_using_command $subcommand" -a "(__fish_git_complete_custom_command $subcommand)"
end end
set -a __fish_git_custom_commands_completion $subcommand set -a __fish_git_custom_commands_completion $subcommand
end end

View File

@@ -0,0 +1,12 @@
function __fish_mkpasswd_methods --description "Complete hashing methods for mkpasswd"
mkpasswd -m help | tail -n +2 | string replace -r '^(\S+)\s+(\S.*)' '$1\t$2'
echo -e "help\tList available methods"
end
complete -c mkpasswd -f
complete -c mkpasswd -s S -l salt -x -d 'Use given string as salt'
complete -c mkpasswd -s R -l rounds -x -d 'Use given number of rounds'
complete -c mkpasswd -s m -l method -xa "(__fish_mkpasswd_methods)" -d 'Compute the password using the given method'
complete -c mkpasswd -s 5 -d 'Like --method=md5crypt'
complete -c mkpasswd -s P -l password-fd -x -d 'Read the password from the given file descriptor'
complete -c mkpasswd -s s -l stdin -d 'Read the password from stdin'

View File

@@ -24,7 +24,7 @@ complete -c msfdb -l db-port -x -d 'Database port'
complete -c msfdb -l db-pool -x -d 'Database connection pool size' complete -c msfdb -l db-pool -x -d 'Database connection pool size'
# Web Service Options # Web Service Options
complete -c msfdb -s a -l address -x -a "(__fish_print_addresses)" -d 'Bind to host address' complete -c msfdb -s a -l address -x -a "(__fish_print_addresses --all)" -d 'Bind to host address'
complete -c msfdb -s p -l port -x -d 'Web service port' complete -c msfdb -s p -l port -x -d 'Web service port'
complete -c msfdb -l ssl -d 'Enable SSL' complete -c msfdb -l ssl -d 'Enable SSL'
complete -c msfdb -l no-ssl -d 'Disable SSL' complete -c msfdb -l no-ssl -d 'Disable SSL'

View File

@@ -5,12 +5,12 @@ complete -c read -s P -l prompt-str -d "Set prompt using provided string" -x
complete -c read -s x -l export -d "Export variable to subprocess" complete -c read -s x -l export -d "Export variable to subprocess"
complete -c read -s g -l global -d "Make variable scope global" complete -c read -s g -l global -d "Make variable scope global"
complete -c read -s l -l local -d "Make variable scope local" complete -c read -s l -l local -d "Make variable scope local"
complete -c read -s U -l universal -d "Make variable scope universal, i.e. share variable with all the users fish processes on this computer" complete -c read -s U -l universal -d "Share variable with all the users fish processes on the computer"
complete -c read -s u -l unexport -d "Do not export variable to subprocess" complete -c read -s u -l unexport -d "Do not export variable to subprocess"
complete -c read -s m -l mode-name -d "Name to load/save history under" -r -a "read fish" complete -c read -s m -l mode-name -d "Name to load/save history under" -r -a "read fish"
complete -c read -s c -l command -d "Initial contents of read buffer when reading interactively" -r complete -c read -s c -l command -d "Initial contents of read buffer when reading interactively" -r
complete -c read -s S -l shell -d "Use syntax highlighting, tab completions and command termination suitable for entering shellscript code" complete -c read -s S -l shell -d "Read like the shell would"
complete -c read -s s -l silent -d "Secure mode: mask characters at the command line (suitable for passwords)" complete -c read -s s -l silent -d "Mask input with ●"
complete -c read -s n -l nchars -d "Read the specified number of characters" -x complete -c read -s n -l nchars -d "Read the specified number of characters" -x
complete -c read -s a -l list -l array -d "Store the results as an array" complete -c read -s a -l list -l array -d "Store the results as an array"
complete -c read -s R -l right-prompt -d "Set right-hand prompt command" -x complete -c read -s R -l right-prompt -d "Set right-hand prompt command" -x

View File

@@ -2,8 +2,24 @@ function __rsync_remote_target
commandline -ct | string match -r '.*::?(?:.*/)?' | string unescape commandline -ct | string match -r '.*::?(?:.*/)?' | string unescape
end end
function __rsync_parse_flags -d "Print info|help FLAGS from help output"
set -l helptext $argv[2..-1] # Skips header line
for line in $helptext
set -l tokens (string match -r "([A-Z]+)(?: {2,})(.+)" $line)
if test (count $tokens) -ge 3
echo $tokens[2]\t$tokens[3]
end
end
end
complete -c rsync -s v -l verbose -d "Increase verbosity" complete -c rsync -s v -l verbose -d "Increase verbosity"
complete -c rsync -l info -d "Fine-grained informational verbosity" -xa "
(__rsync_parse_flags (rsync --info=help))"
complete -c rsync -l debug -d "Fine-grained debug verbosity" -xa "
(__rsync_parse_flags (rsync --debug=help))"
complete -c rsync -l stderr -xa 'errors all client' -d "change stderr output mode, default: errors"
complete -c rsync -s q -l quiet -d "Suppress non-error messages" complete -c rsync -s q -l quiet -d "Suppress non-error messages"
complete -c rsync -l no-motd -d "Suppress daemon-mode MOTD"
complete -c rsync -s c -l checksum -d "Skip based on checksum, not mod-time & size" complete -c rsync -s c -l checksum -d "Skip based on checksum, not mod-time & size"
complete -c rsync -s a -l archive -d "Archive mode; same as -rlptgoD (no -H)" complete -c rsync -s a -l archive -d "Archive mode; same as -rlptgoD (no -H)"
complete -c rsync -l no-OPTION -d "Turn off an implied OPTION (e.g. --no-D)" complete -c rsync -l no-OPTION -d "Turn off an implied OPTION (e.g. --no-D)"
@@ -15,31 +31,42 @@ complete -c rsync -l backup-dir -xa '(__fish_complete_directories)' -d "Make bac
complete -c rsync -l suffix -d "Backup suffix (default ~ w/o --backup-dir)" complete -c rsync -l suffix -d "Backup suffix (default ~ w/o --backup-dir)"
complete -c rsync -s u -l update -d "Skip files that are newer on the receiver" complete -c rsync -s u -l update -d "Skip files that are newer on the receiver"
complete -c rsync -l inplace -d "Update destination files in-place" complete -c rsync -l inplace -d "Update destination files in-place"
complete -c rsync -l append -d "Append data onto shorter files" complete -c rsync -l append -d "Append data onto shorter files without verifing old content"
complete -c rsync -l append-verify -d "Append with full file checksum, including old data"
complete -c rsync -s d -l dirs -d "Transfer directories without recursing" complete -c rsync -s d -l dirs -d "Transfer directories without recursing"
complete -c rsync -l mkpath -d "Create the destination's path component"
complete -c rsync -s l -l links -d "Copy symlinks as symlinks" complete -c rsync -s l -l links -d "Copy symlinks as symlinks"
complete -c rsync -s L -l copy-links -d "Transform symlink into referent file/dir" complete -c rsync -s L -l copy-links -d "Transform symlink into referent file/dir"
complete -c rsync -l copy-unsafe-links -d "Only \"unsafe\" symlinks are transformed" complete -c rsync -l copy-unsafe-links -d "Only \"unsafe\" symlinks are transformed"
complete -c rsync -l safe-links -d "Ignore symlinks that point outside the tree" complete -c rsync -l safe-links -d "Ignore symlinks that point outside the tree"
complete -c rsync -l munge-links -d "Munge symlinks to make them safe & unusable"
complete -c rsync -s k -l copy-dirlinks -d "Transform symlink to dir into referent dir" complete -c rsync -s k -l copy-dirlinks -d "Transform symlink to dir into referent dir"
complete -c rsync -s K -l keep-dirlinks -d "Treat symlinked dir on receiver as dir" complete -c rsync -s K -l keep-dirlinks -d "Treat symlinked dir on receiver as dir"
complete -c rsync -s H -l hard-links -d "Preserve hard links" complete -c rsync -s H -l hard-links -d "Preserve hard links"
complete -c rsync -s p -l perms -d "Preserve permissions" complete -c rsync -s p -l perms -d "Preserve permissions"
complete -c rsync -s E -l executability -d "Preserve executability" complete -c rsync -s E -l executability -d "Preserve executability"
complete -c rsync -l chmod -d "Change destination permissions"
complete -c rsync -s A -l acls -d "Preserve ACLs (implies -p) [non-standard]" complete -c rsync -s A -l acls -d "Preserve ACLs (implies -p) [non-standard]"
complete -c rsync -s X -l xattrs -d "Preserve extended attrs (implies -p) [n.s.]" complete -c rsync -s X -l xattrs -d "Preserve extended attrs (implies -p) [n.s.]"
complete -c rsync -l chmod -d "Change destination permissions"
complete -c rsync -s o -l owner -d "Preserve owner (super-user only)" complete -c rsync -s o -l owner -d "Preserve owner (super-user only)"
complete -c rsync -s g -l group -d "Preserve group" complete -c rsync -s g -l group -d "Preserve group"
complete -c rsync -l devices -d "Preserve device files (super-user only)" complete -c rsync -l devices -d "Preserve device files (super-user only)"
complete -c rsync -l specials -d "Preserve special files" complete -c rsync -l specials -d "Preserve special files"
complete -c rsync -s D -d "Same as --devices --specials" complete -c rsync -s D -d "Same as --devices --specials"
complete -c rsync -s t -l times -d "Preserve times" complete -c rsync -s t -l times -d "Preserve modification times"
complete -c rsync -s U -l atimes -d "Preserve access (use) times"
complete -c rsync -l open-noatime -d "Avoid changing the atime on opened files"
complete -c rsync -l crtimes -d "Preserve creation (birth) times"
complete -c rsync -s O -l omit-dir-times -d "Omit directories when preserving times" complete -c rsync -s O -l omit-dir-times -d "Omit directories when preserving times"
complete -c rsync -s J -l omit-link-times -d "Omit symlinks when preserving times"
complete -c rsync -l super -d "Receiver attempts super-user activities" complete -c rsync -l super -d "Receiver attempts super-user activities"
complete -c rsync -l fake-super -d "Store/recover privileged attrs using xattrs"
complete -c rsync -s S -l sparse -d "Handle sparse files efficiently" complete -c rsync -s S -l sparse -d "Handle sparse files efficiently"
complete -c rsync -l preallocate -d "Allocate dest files before writing them"
complete -c rsync -l write-devices -d "Write to devices as files (implies --inplace)"
complete -c rsync -s n -l dry-run -d "Show what would have been transferred" complete -c rsync -s n -l dry-run -d "Show what would have been transferred"
complete -c rsync -s W -l whole-file -d "Copy files whole (without rsync algorithm)" complete -c rsync -s W -l whole-file -d "Copy files whole (without rsync algorithm)"
complete -c rsync -l cc -l checksum-choice -xa 'xxh128 xxh3 xxh64 md5 md4 none' -d "Choose the checksum algorithm"
complete -c rsync -s x -l one-file-system -d "Dont cross filesystem boundaries" complete -c rsync -s x -l one-file-system -d "Dont cross filesystem boundaries"
complete -c rsync -s B -l block-size -x -d "Force a fixed checksum block-size" complete -c rsync -s B -l block-size -x -d "Force a fixed checksum block-size"
complete -c rsync -s e -l rsh -x -d "Specify the remote shell to use" complete -c rsync -s e -l rsh -x -d "Specify the remote shell to use"
@@ -52,19 +79,27 @@ complete -c rsync -l del -d "An alias for --delete-during"
complete -c rsync -l delete -d "Delete files that dont exist on sender" complete -c rsync -l delete -d "Delete files that dont exist on sender"
complete -c rsync -l delete-before -d "Receiver deletes before transfer (default)" complete -c rsync -l delete-before -d "Receiver deletes before transfer (default)"
complete -c rsync -l delete-during -d "Receiver deletes during xfer, not before" complete -c rsync -l delete-during -d "Receiver deletes during xfer, not before"
complete -c rsync -l delete-delay -d "Find deletions during, delete after"
complete -c rsync -l delete-after -d "Receiver deletes after transfer, not before" complete -c rsync -l delete-after -d "Receiver deletes after transfer, not before"
complete -c rsync -l delete-excluded -d "Also delete excluded files on receiver" complete -c rsync -l delete-excluded -d "Also delete excluded files on receiver"
complete -c rsync -l ignore-missing-args -d "Ignore missing source args without error"
complete -c rsync -l delete-missing-args -d "Delete missing source args from destination"
complete -c rsync -l ignore-errors -d "Delete even if there are I/O errors" complete -c rsync -l ignore-errors -d "Delete even if there are I/O errors"
complete -c rsync -l force -d "Force deletion of dirs even if not empty" complete -c rsync -l force -d "Force deletion of dirs even if not empty"
complete -c rsync -l max-delete -xa '(seq 0 10)' -d "Dont delete more than NUM files" complete -c rsync -l max-delete -xa '(seq 0 10)' -d "Dont delete more than NUM files"
complete -c rsync -l max-size -xa '(seq 0 10){K,M,G}' -d "Dont transfer any file larger than SIZE" complete -c rsync -l max-size -xa '(seq 0 10){K,M,G}' -d "Dont transfer any file larger than SIZE"
complete -c rsync -l min-size -xa '(seq 0 10){K,M,G}' -d "Dont transfer any file smaller than SIZE" complete -c rsync -l min-size -xa '(seq 0 10){K,M,G}' -d "Dont transfer any file smaller than SIZE"
complete -c rsync -l max-alloc -xa '(seq 0 10){K,M,G}' -d "Change process memory allocation limit"
complete -c rsync -l partial -d "Keep partially transferred files" complete -c rsync -l partial -d "Keep partially transferred files"
complete -c rsync -l partial-dir -xa '(__fish_complete_directories)' -d "Put a partially transferred file into DIR" complete -c rsync -l partial-dir -xa '(__fish_complete_directories)' -d "Put a partially transferred file into DIR"
complete -c rsync -l delay-updates -d "Put all updated files into place at end" complete -c rsync -l delay-updates -d "Put all updated files into place at end"
complete -c rsync -s m -l prune-empty-dirs -d "Prune empty directory chains from file-list" complete -c rsync -s m -l prune-empty-dirs -d "Prune empty directory chains from file-list"
complete -c rsync -l numeric-ids -d "Dont map uid/gid values by user/group name" complete -c rsync -l numeric-ids -d "Dont map uid/gid values by user/group name"
complete -c rsync -l usermap -xa '(__fish_complete_users)' -d "Custom username mapping"
complete -c rsync -l groupmap -xa '(__fish_complete_groups)' -d "Custom username mapping"
complete -c rsync -l chown -xa '(__fish_complete_users;__fish_complete_groups)' -d "Combined username/groupname mapping"
complete -c rsync -l timeout -d "Set I/O timeout in seconds" complete -c rsync -l timeout -d "Set I/O timeout in seconds"
complete -c rsync -l cotimeout -d "Set daemon connection timeout in seconds"
complete -c rsync -s I -l ignore-times -d "Dont skip files that match size and time" complete -c rsync -s I -l ignore-times -d "Dont skip files that match size and time"
complete -c rsync -l size-only -d "Skip files that match in size" complete -c rsync -l size-only -d "Skip files that match in size"
complete -c rsync -l modify-window -xa '(seq 0 10)' -d "Compare NUM mod-times with reduced accuracy" complete -c rsync -l modify-window -xa '(seq 0 10)' -d "Compare NUM mod-times with reduced accuracy"
@@ -74,7 +109,9 @@ complete -c rsync -l compare-dest -xa '(__fish_complete_directories)' -d "Also c
complete -c rsync -l copy-dest -xa '(__fish_complete_directories)' -d "Also compare received files relative to DIR and include copies of unchanged files" complete -c rsync -l copy-dest -xa '(__fish_complete_directories)' -d "Also compare received files relative to DIR and include copies of unchanged files"
complete -c rsync -l link-dest -xa '(__fish_complete_directories)' -d "Hardlink to files in DIR when unchanged" complete -c rsync -l link-dest -xa '(__fish_complete_directories)' -d "Hardlink to files in DIR when unchanged"
complete -c rsync -s z -l compress -d "Compress file data during the transfer" complete -c rsync -s z -l compress -d "Compress file data during the transfer"
complete -c rsync -l compress-level -d "Explicitly set compression level" complete -c rsync -l zc -l compress-choice -xa 'zstd lz4 zlibx zlib none' -d "Choose the compression algorithm"
complete -c rsync -l compress-level -x -d "Explicitly set compression level (aka --zl)"
complete -c rsync -l skip-compress -x -d "Skip compressing files with suffix in LIST"
complete -c rsync -s C -l cvs-exclude -d "Auto-ignore files in the same way CVS does" complete -c rsync -s C -l cvs-exclude -d "Auto-ignore files in the same way CVS does"
complete -c rsync -s f -l filter -d "Add a file-filtering RULE" complete -c rsync -s f -l filter -d "Add a file-filtering RULE"
complete -c rsync -s F -d "Same as --filter=dir-merge /.rsync-filter repeated: --filter='- .rsync-filter'" complete -c rsync -s F -d "Same as --filter=dir-merge /.rsync-filter repeated: --filter='- .rsync-filter'"
@@ -84,29 +121,43 @@ complete -c rsync -l include -d "Dont exclude files matching PATTERN"
complete -c rsync -l include-from -r -d "Read include patterns from FILE" complete -c rsync -l include-from -r -d "Read include patterns from FILE"
complete -c rsync -l files-from -r -d "Read list of source-file names from FILE" complete -c rsync -l files-from -r -d "Read list of source-file names from FILE"
complete -c rsync -s 0 -l from0 -d "All *from/filter files are delimited by 0s" complete -c rsync -s 0 -l from0 -d "All *from/filter files are delimited by 0s"
complete -c rsync -s s -l protect-args -d "No space-splitting; wildcard chars only"
complete -c rsync -l copy-as -xa '(__fish_complete_users;__fish_complete_groups)' -d "Specify user & optional group for the copy"
complete -c rsync -l address -d "Bind address for outgoing socket to daemon" complete -c rsync -l address -d "Bind address for outgoing socket to daemon"
complete -c rsync -l port -d "Specify double-colon alternate port number" complete -c rsync -l port -d "Specify double-colon alternate port number"
complete -c rsync -l sockopts -d "Specify custom TCP options" complete -c rsync -l sockopts -d "Specify custom TCP options"
complete -c rsync -l blocking-io -d "Use blocking I/O for the remote shell" complete -c rsync -l blocking-io -d "Use blocking I/O for the remote shell"
complete -c rsync -l outbuf -xa 'N L B' -d "Set out buffering to None, Line, or Block"
complete -c rsync -l stats -d "Give some file-transfer stats" complete -c rsync -l stats -d "Give some file-transfer stats"
complete -c rsync -s 8 -l 8-bit-output -d "Leave high-bit chars unescaped in output" complete -c rsync -s 8 -l 8-bit-output -d "Leave high-bit chars unescaped in output"
complete -c rsync -s h -l human-readable -d "Output numbers in a human-readable format" complete -c rsync -s h -l human-readable -d "Output numbers in a human-readable format"
complete -c rsync -l progress -d "Show progress during transfer" complete -c rsync -l progress -d "Show progress during transfer"
complete -c rsync -s P -d "Same as --partial --progress" complete -c rsync -s P -d "Same as --partial --progress"
complete -c rsync -s i -l itemize-changes -d "Output a change-summary for all updates" complete -c rsync -s i -l itemize-changes -d "Output a change-summary for all updates"
complete -c rsync -l log-format -x -d "Output filenames using the specified format" complete -c rsync -s M -l remote-option -d "Send OPTION to the remote side only"
complete -c rsync -l password-file -x -d "Read password from FILE" complete -c rsync -l out-format -x -d "Output updates using the specified FORMAT"
complete -c rsync -l log-file -d "log what we're doing to the specified FILE"
complete -c rsync -l log-file-format -x -d "log updates using the specified FMT"
complete -c rsync -l password-file -r -d "Read password from FILE"
complete -c rsync -l early-input -d "Use FILE for daemon's early exec input"
complete -c rsync -l list-only -d "List the files instead of copying them" complete -c rsync -l list-only -d "List the files instead of copying them"
complete -c rsync -l bwlimit -x -d "Limit I/O bandwidth; KBytes per second" complete -c rsync -l bwlimit -xa '(seq 0 10){K,M,G}' -d "Limit I/O bandwidth; optional unit (KB/s default)"
complete -c rsync -l write-batch -x -d "Write a batched update to FILE" complete -c rsync -l stop-after -x -d "Stop rsync after MINS minutes have elapsed"
complete -c rsync -l stop-at -x -d "Stop rsync at the specified point in time"
complete -c rsync -l write-batch -r -d "Write a batched update to FILE"
complete -c rsync -l only-write-batch -d "Like --write-batch but w/o updating dest" complete -c rsync -l only-write-batch -d "Like --write-batch but w/o updating dest"
complete -c rsync -l read-batch -x -d "Read a batched update from FILE" complete -c rsync -l read-batch -r -d "Read a batched update from FILE"
complete -c rsync -l protocol -x -d "Force an older protocol version to be used" complete -c rsync -l protocol -x -d "Force an older protocol version to be used"
complete -c rsync -l iconv -x -d "Request charset conversion of filenames"
complete -c rsync -l checksum-seed -x -d "Set block/file checksum seed (advanced)" complete -c rsync -l checksum-seed -x -d "Set block/file checksum seed (advanced)"
complete -c rsync -s 4 -l ipv4 -d "Prefer IPv4" complete -c rsync -s 4 -l ipv4 -d "Prefer IPv4"
complete -c rsync -s 6 -l ipv6 -d "Prefer IPv6" complete -c rsync -s 6 -l ipv6 -d "Prefer IPv6"
complete -c rsync -l version -d "Display version and exit" complete -c rsync -l daemon -d "Run as an rsync daemon"
complete -c rsync -l help -d "Display help and exit" complete -c rsync -l config -r -d "Specify alternate rsyncd.conf file"
complete -c rsync -l dparam -x -d "Override global daemon config parameter"
complete -c rsync -l no-detach -x -d "Do not detach from the parent"
complete -c rsync -s V -l version -d "Display version and feature info"
complete -c rsync -s h -l help -d "Display help and exit"
# #
# Hostname completion # Hostname completion

View File

@@ -1,2 +1,2 @@
complete source -k -xa '(__fish_complete_suffix .fish)' complete -c source -k -xa '(__fish_complete_suffix .fish)'
complete source -s h -l help -d 'Display help and exit' complete -c source -s h -l help -d 'Display help and exit'

View File

@@ -18,19 +18,7 @@ complete -c ssh -n 'test (__fish_number_of_cmd_args_wo_opts) -ge 2' -d "Command
complete -c ssh -s a -d "Disables forwarding of the authentication agent" complete -c ssh -s a -d "Disables forwarding of the authentication agent"
complete -c ssh -s A -d "Enables forwarding of the authentication agent" complete -c ssh -s A -d "Enables forwarding of the authentication agent"
complete -x -c ssh -s b -d "Local address to bind to" -a '(__fish_print_addresses)'
function __ssh_print_local_addresses_with_labels
if command -sq ip
command ip --oneline address | string replace -r '\d+:\s+(\S+)\s+\S+\s+(.+)/.*' '$2\t$1'
else if command -sq ifconfig
# This is for OSX/BSD/anything else that doesn't have `ip` installed.
# Since ifconfig output is not guaranteed to be the same on these systems,
# for now we will limit the completions to just the IP address.
# TODO: check ifconfig output on each system and rework below to include label.
ifconfig | awk '/^\tinet/ { print $2 } '
end
end
complete -x -c ssh -s b -d "Local address to bind to" -a '(__ssh_print_local_addresses_with_labels)'
complete -x -c ssh -s e -d "Escape character" -a "\^ none" complete -x -c ssh -s e -d "Escape character" -a "\^ none"
complete -c ssh -s f -d "Go to background" complete -c ssh -s f -d "Go to background"

View File

@@ -10,13 +10,13 @@ complete -c useradd -s d -l home -d 'Home directory for the new user' -x -a '(__
complete -c useradd -s G -l groups -d 'Supplementary groups' -xa '(__fish_append , (string split -f1 : /etc/group))' complete -c useradd -s G -l groups -d 'Supplementary groups' -xa '(__fish_append , (string split -f1 : /etc/group))'
complete -c useradd -s h -l help -d 'Display help message and exit' complete -c useradd -s h -l help -d 'Display help message and exit'
complete -c useradd -s m -l create-home -d 'The user\'s home directory will be created if it does not exist' complete -c useradd -s m -l create-home -d 'The user\'s home directory will be created if it does not exist'
complete -c useradd -s n -d 'A group having the same name as the user being added to the system will be created by default (when -g is not specified)' complete -c useradd -s n -d 'Create group with name of added user if -g is not specified'
complete -c useradd -s K -l key -d 'Overrides default key/value pairs from /etc/login' complete -c useradd -s K -l key -d 'Overrides default key/value pairs from /etc/login'
complete -c useradd -s o -l non-unique -d 'Allow the creation of a user account with a duplicate (non-unique) UID' complete -c useradd -s o -l non-unique -d 'Allow user account with a duplicate UID'
complete -c useradd -s p -l password -d 'The encrypted password, as returned by crypt(3)' -r complete -c useradd -s p -l password -d 'The encrypted password, as returned by crypt(3)' -r
complete -c useradd -s u -l uid -d 'The numerical value of the user\'s ID' -r complete -c useradd -s u -l uid -d 'The numerical value of the user\'s ID' -r
complete -c useradd -s b -l base-dir -d 'The initial path prefix for a new user\'s home directory' -r -a '(__fish_complete_directories)' complete -c useradd -s b -l base-dir -d 'The initial path prefix for a new user\'s home directory' -r -a '(__fish_complete_directories)'
complete -c useradd -s e -l expiredate -d 'The date on which the user account is disabled' -r complete -c useradd -s e -l expiredate -d 'The date on which the user account is disabled' -r
complete -c useradd -s f -l inactive -d 'The number of days after a password has expired before the account will be disabled' -r complete -c useradd -s f -l inactive -d 'Number of days to disable account after password expiration' -r
complete -c useradd -s g -l gid -d 'The group name or ID for a new user\'s initial group' -x -a '(string match -r "^[^#].*" < /etc/group | string split -f1,3 ":" | string join ":" | string replace -a ":" \n)' complete -c useradd -s g -l gid -d 'The group name or ID for a new user\'s initial group' -x -a '(string match -r "^[^#].*" < /etc/group | string split -f1,3 ":" | string join ":" | string replace -a ":" \n)'
complete -c useradd -s s -l shell -d 'Name of the new user\'s login shell' -x -a '(string match -r "^[^#].*" < /etc/shells)' complete -c useradd -s s -l shell -d 'Name of the new user\'s login shell' -x -a '(string match -r "^[^#].*" < /etc/shells)'

View File

@@ -30,13 +30,13 @@ function __fish_apropos
set age (math (date +%s) - (/usr/bin/stat -f %m $db)) set age (math (date +%s) - (/usr/bin/stat -f %m $db))
end end
MANPATH="$cache" apropos $argv MANPATH="$cache" apropos -- $argv
if test $age -ge $max_age if test $age -ge $max_age
mkdir -m 700 -p $cache mkdir -m 700 -p $cache
/usr/libexec/makewhatis -o $db (man --path | string split :) >/dev/null 2>&1 </dev/null & /usr/libexec/makewhatis -o $db (man --path | string split :) >/dev/null 2>&1 </dev/null &
end end
else else
apropos $argv apropos -- $argv
end end
end end

View File

@@ -16,7 +16,7 @@ function __fish_complete_bittorrent
complete -c $argv -l timeout_check_interval -x --description "Time between checking timeouts" complete -c $argv -l timeout_check_interval -x --description "Time between checking timeouts"
complete -c $argv -l max_slice_length -x --description "Maximum outgoing slice length" complete -c $argv -l max_slice_length -x --description "Maximum outgoing slice length"
complete -c $argv -l max_rate_period -x --description "Maximum time to guess rate" complete -c $argv -l max_rate_period -x --description "Maximum time to guess rate"
complete -c $argv -l bind -x --description "IP to bind to locally" -a "(__fish_print_addresses)" complete -c $argv -l bind -x --description "IP to bind to locally" -a "(__fish_print_addresses --all)"
complete -c $argv -l display_interval -x --description "Time between screen updates" complete -c $argv -l display_interval -x --description "Time between screen updates"
complete -c $argv -l rerequest_interval -x --description "Time to wait between requesting more peers" complete -c $argv -l rerequest_interval -x --description "Time to wait between requesting more peers"
complete -c $argv -l min_peers -x --description "Minimum number of peers to not do requesting" complete -c $argv -l min_peers -x --description "Minimum number of peers to not do requesting"

View File

@@ -109,21 +109,6 @@ function __fish_config_interactive -d "Initializations that should be performed
fish_greeting fish_greeting
end end
#
# This event handler makes sure the prompt is repainted when
# fish_color_cwd{,_root} changes value. Like all event handlers, it can't be
# autoloaded.
#
set -l varargs --on-variable fish_key_bindings
for var in user host{,_remote} cwd{,_root} status error
set -a varargs --on-variable fish_color_$var
end
function __fish_repaint $varargs -d "Event handler, repaints the prompt when fish_color_cwd* changes"
if status --is-interactive
commandline -f repaint 2>/dev/null
end
end
# #
# Completions for SysV startup scripts. These aren't bound to any # Completions for SysV startup scripts. These aren't bound to any
# specific command, so they can't be autoloaded. # specific command, so they can't be autoloaded.

View File

@@ -11,7 +11,7 @@ end
function __fish_describe_command -d "Command used to find descriptions for commands" function __fish_describe_command -d "Command used to find descriptions for commands"
# $argv will be inserted directly into the awk regex, so it must be escaped # $argv will be inserted directly into the awk regex, so it must be escaped
set -l argv_regex (string escape --style=regex "$argv") set -l argv_regex (string escape --style=regex -- "$argv")
__fish_apropos $argv 2>/dev/null | awk -v FS=" +- +" '{ __fish_apropos $argv 2>/dev/null | awk -v FS=" +- +" '{
split($1, names, ", "); split($1, names, ", ");
for (name in names) for (name in names)

View File

@@ -1,6 +1,11 @@
function __fish_print_addresses --description "Print a list of known network addresses" function __fish_print_addresses --description "List own network addresses with interface as description"
# if --all is given, also print 0.0.0.0 and ::
if contains -- --all $argv
echo -e "0.0.0.0\tall"
echo -e "::\tall"
end
if command -sq ip if command -sq ip
command ip --oneline address | string replace -r '(\S+\s+){3}(.+)/.*' '$2' command ip --oneline address | string replace -r '^\d+:\s+(\S+)\s+inet6?\s+([^\s/]+).*' '$2\t$1'
else if command -sq ifconfig else if command -sq ifconfig
# This is for OSX/BSD # This is for OSX/BSD
# There's also linux ifconfig but that has at least two different output formats # There's also linux ifconfig but that has at least two different output formats

View File

@@ -10,7 +10,7 @@ function __fish_print_help --description "Print help message for the specified f
# Do nothing if the file does not exist # Do nothing if the file does not exist
if not test -e "$__fish_data_dir/man/man1/$item.1" -o -e "$__fish_data_dir/man/man1/$item.1.gz" if not test -e "$__fish_data_dir/man/man1/$item.1" -o -e "$__fish_data_dir/man/man1/$item.1.gz"
return return 2
end end
# Render help output, save output into the variable 'help' # Render help output, save output into the variable 'help'

View File

@@ -15,7 +15,7 @@ function __fish_print_pipestatus --description "Print pipestatus for prompt"
if not set -q argv[1] if not set -q argv[1]
echo error: missing argument >&2 echo error: missing argument >&2
status print-stacktrace >&2 status print-stack-trace >&2
return 1 return 1
end end
@@ -28,8 +28,10 @@ function __fish_print_pipestatus --description "Print pipestatus for prompt"
if test "$last_status" -ne "$argv[-1]" if test "$last_status" -ne "$argv[-1]"
set last_status_string " "$status_color$last_status set last_status_string " "$status_color$last_status
end end
printf "%s" $brace_sep_color $left_brace \ set -l normal (set_color normal)
# The "normal"s are to reset modifiers like bold - see #7771.
printf "%s" $normal $brace_sep_color $left_brace \
$status_color $last_pipestatus_string \ $status_color $last_pipestatus_string \
$brace_sep_color $right_brace $last_status_string (set_color normal) $normal $brace_sep_color $right_brace $normal $last_status_string $normal
end end
end end

View File

@@ -63,7 +63,7 @@ function fish_add_path --description "Add paths to the PATH"
set -l newvar $$var set -l newvar $$var
if set -q _flag_move; and set -q indexes[1] if set -q _flag_move; and set -q indexes[1]
# We remove in one step, so the indexes don't move. # We remove in one step, so the indexes don't move.
set -e newvar[$indexes] set -e newvar["$indexes"]
end end
set $mode newvar $newpaths set $mode newvar $newpaths

View File

@@ -26,7 +26,7 @@ function fish_clipboard_paste
# in order to turn it into a single literal token. # in order to turn it into a single literal token.
# #
# This eases pasting non-code (e.g. markdown or git commitishes). # This eases pasting non-code (e.g. markdown or git commitishes).
set -l quote_state (__fish_tokenizer_state -- (commandline -ct)) set -l quote_state (__fish_tokenizer_state -- (commandline -ct | string collect))
if contains -- $quote_state single single-escaped if contains -- $quote_state single single-escaped
if status test-feature regex-easyesc if status test-feature regex-easyesc
set data (string replace -ra "(['\\\])" '\\\\$1' -- $data) set data (string replace -ra "(['\\\])" '\\\\$1' -- $data)

View File

@@ -68,5 +68,9 @@ else if type -q pacman
__fish_default_command_not_found_handler $argv[1] __fish_default_command_not_found_handler $argv[1]
pacman -F $paths pacman -F $paths
end end
else
# Use standard fish command not found handler otherwise
function fish_command_not_found --on-event fish_command_not_found
__fish_default_command_not_found_handler $argv
end
end end
# Use standard fish command not found handler otherwise

View File

@@ -766,7 +766,7 @@ set -l varargs
for var in repaint describe_style show_informative_status use_informative_chars showdirtystate showstashstate showuntrackedfiles showupstream for var in repaint describe_style show_informative_status use_informative_chars showdirtystate showstashstate showuntrackedfiles showupstream
set -a varargs --on-variable __fish_git_prompt_$var set -a varargs --on-variable __fish_git_prompt_$var
end end
function __fish_git_prompt_repaint $varargs --description "Event handler, repaints prompt when functionality changes" function __fish_git_prompt_reset $varargs --description "Event handler, resets prompt when functionality changes"
if status --is-interactive if status --is-interactive
if contains -- $argv[3] __fish_git_prompt_show_informative_status __fish_git_prompt_use_informative_chars if contains -- $argv[3] __fish_git_prompt_show_informative_status __fish_git_prompt_use_informative_chars
# Clear characters that have different defaults with/without informative status # Clear characters that have different defaults with/without informative status
@@ -776,8 +776,6 @@ function __fish_git_prompt_repaint $varargs --description "Event handler, repain
# Clear init so we reset the chars next time. # Clear init so we reset the chars next time.
set -e ___fish_git_prompt_init set -e ___fish_git_prompt_init
end end
commandline -f repaint 2>/dev/null
end end
end end
@@ -786,7 +784,7 @@ for var in '' _prefix _suffix _bare _merging _cleanstate _invalidstate _upstream
set -a varargs --on-variable __fish_git_prompt_color$var set -a varargs --on-variable __fish_git_prompt_color$var
end end
set -a varargs --on-variable __fish_git_prompt_showcolorhints set -a varargs --on-variable __fish_git_prompt_showcolorhints
function __fish_git_prompt_repaint_color $varargs --description "Event handler, repaints prompt when any color changes" function __fish_git_prompt_reset_color $varargs --description "Event handler, resets prompt when any color changes"
if status --is-interactive if status --is-interactive
set -e ___fish_git_prompt_init set -e ___fish_git_prompt_init
set -l var $argv[3] set -l var $argv[3]
@@ -799,7 +797,6 @@ function __fish_git_prompt_repaint_color $varargs --description "Event handler,
set -e ___fish_git_prompt_color_{$name}_done set -e ___fish_git_prompt_color_{$name}_done
end end
end end
commandline -f repaint 2>/dev/null
end end
end end
@@ -807,10 +804,9 @@ set -l varargs
for var in cleanstate dirtystate invalidstate stagedstate stashstate stateseparator untrackedfiles upstream_ahead upstream_behind upstream_diverged upstream_equal upstream_prefix for var in cleanstate dirtystate invalidstate stagedstate stashstate stateseparator untrackedfiles upstream_ahead upstream_behind upstream_diverged upstream_equal upstream_prefix
set -a varargs --on-variable __fish_git_prompt_char_$var set -a varargs --on-variable __fish_git_prompt_char_$var
end end
function __fish_git_prompt_repaint_char $varargs --description "Event handler, repaints prompt when any char changes" function __fish_git_prompt_reset_char $varargs --description "Event handler, resets prompt when any char changes"
if status --is-interactive if status --is-interactive
set -e ___fish_git_prompt_init set -e ___fish_git_prompt_init
set -e _$argv[3] set -e _$argv[3]
commandline -f repaint 2>/dev/null
end end
end end

View File

@@ -130,7 +130,7 @@ function funced --description 'Edit function definition'
end end
set -l stat $status set -l stat $status
rm $tmpname >/dev/null command rm $tmpname >/dev/null
and rmdir $tmpdir >/dev/null and rmdir $tmpdir >/dev/null
return $stat return $stat
end end

View File

@@ -94,7 +94,7 @@ function help --description 'Show help for the fish shell'
if not set -q fish_browser[1] if not set -q fish_browser[1]
printf (_ '%s: Could not find a web browser.\n') help printf (_ '%s: Could not find a web browser.\n') help
printf (_ 'Please set the variable $BROWSER or fish_help_browser and try again.\n\n') printf (_ 'Please try `BROWSER=some_browser help`, `man fish-doc`, or `man fish-tutorial`.\n\n')
return 1 return 1
end end
@@ -142,12 +142,20 @@ function help --description 'Show help for the fish shell'
set fish_help_page "index.html#$fish_help_item" set fish_help_page "index.html#$fish_help_item"
end end
# In Crostini Chrome OS Linux, the default browser opens URLs in Chrome running outside the
# linux VM. This browser does not have access to the Linux filesystem. This uses Garcon, see e.g.
# https://chromium.googlesource.com/chromiumos/platform2/+/master/vm_tools/garcon/#opening-urls
# https://source.chromium.org/search?q=garcon-url-handler
string match -q '*garcon-url-handler*' $fish_browser[1]
and set -l chromeos_linux_garcon
set -l page_url set -l page_url
if test -f $__fish_help_dir/index.html if test -f $__fish_help_dir/index.html; and not set -lq chromeos_linux_garcon
# Help is installed, use it # Help is installed, use it
set page_url file://$__fish_help_dir/$fish_help_page set page_url file://$__fish_help_dir/$fish_help_page
# For Windows (Cygwin, msys2 and WSL), we need to convert the base help dir to a Windows path before converting it to a file URL # For Windows (Cygwin, msys2 and WSL), we need to convert the base
# help dir to a Windows path before converting it to a file URL
# but only if a Windows browser is being used # but only if a Windows browser is being used
if type -q cygpath if type -q cygpath
and string match -qr '(cygstart|\.exe)(\s+|$)' $fish_browser[1] and string match -qr '(cygstart|\.exe)(\s+|$)' $fish_browser[1]

View File

@@ -2,13 +2,16 @@ body {
background: linear-gradient(to bottom, #a7cfdf 0%, #23538a 100%); background: linear-gradient(to bottom, #a7cfdf 0%, #23538a 100%);
font-family: monospace, fixed; font-family: monospace, fixed;
color: #222; color: #222;
min-height: 100vh; /* at least 1 screen high - to prevent the gradient from running out on a short tab */ }
#ancestor {
width: 90%; width: 90%;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
-moz-box-shadow: 0 0 1px 1px #333; -moz-box-shadow: 0 0 1px 1px #333;
-webkit-box-shadow: 0 0 1px 1px #333; -webkit-box-shadow: 0 0 1px 1px #333;
box-shadow: 0 0 5px 1px #333; box-shadow: 0 0 5px 1px #333;
border-radius: 8px;
} }
code { code {
@@ -33,6 +36,7 @@ code {
display: table-cell; display: table-cell;
border: 1px solid #ccc; border: 1px solid #ccc;
border-right: none; border-right: none;
border-top: none;
padding-bottom: 15px; padding-bottom: 15px;
padding-top: 15px; padding-top: 15px;
padding-left: 3px; padding-left: 3px;
@@ -45,22 +49,13 @@ code {
#tab_parent :first-child { #tab_parent :first-child {
border-top-left-radius: 8px; border-top-left-radius: 8px;
border-left: none;
} }
#tab_parent :last-child { #tab_parent :last-child {
border-top-right-radius: 8px; border-top-right-radius: 8px;
} }
.tab_first {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.tab_last {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.selected_tab { .selected_tab {
background-color: #eeeefa; background-color: #eeeefa;
border-bottom: none; border-bottom: none;
@@ -70,11 +65,24 @@ code {
padding-top: 20px; padding-top: 20px;
padding-bottom: 20px; padding-bottom: 20px;
width: 100%; width: 100%;
min-height: 80vh; min-height: 90vh;
background-color: #eeeefa; background-color: #eeeefa;
border-bottom-left-radius: 8px; border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px; border-bottom-right-radius: 8px;
margin-bottom: 20px; margin-bottom: 20px;
position: relative;
box-sizing: border-box;
}
/* This may be placed directly inside a tab, to prevent its contents from growing vertically. */
.height_limiter {
display: flex;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
flex-direction: column;
} }
.footer { .footer {
@@ -429,7 +437,10 @@ code {
.prompt_choices_scrollview { .prompt_choices_scrollview {
padding-top: 5px; padding-top: 5px;
overflow-y: scroll; overflow-y: scroll;
max-height: 70vh; /* fill out roughly the rest of the screen once scrolled to the preview */ }
.prompt_choices_scrollview {
position: relative;
} }
.color_scheme_choices_list, .color_scheme_choices_list,

View File

@@ -1,6 +1,6 @@
<div title="Background color for illustration only. <div title="Background color for illustration only.
fish cannot change the background color of your terminal and it will not be saved. Refer to your terminal documentation to set its background color."> fish cannot change the background color of your terminal. Refer to your terminal documentation to set its background color.">
<!-- ko with: color_picker --> <!-- ko with: color_picker -->
<div class="colorpicker_text_sample" ng-style="{'background-color': terminalBackgroundColor}"> <div class="colorpicker_text_sample" ng-style="{'background-color': terminalBackgroundColor}">
<span style="position: absolute; left: 10px; top: 3px;" data-ng-style="{'color': text_color_for_color(terminalBackgroundColor || 'black')}">{{ selectedColorScheme.name }}</span><br> <span style="position: absolute; left: 10px; top: 3px;" data-ng-style="{'color': text_color_for_color(terminalBackgroundColor || 'black')}">{{ selectedColorScheme.name }}</span><br>

View File

@@ -1,20 +1,22 @@
<div class="height_limiter">
<!-- The first 'sample' prompt is the current one; the remainders are samples. This ought to be cleaned up. --> <!-- The first 'sample' prompt is the current one; the remainders are samples. This ought to be cleaned up. -->
<div class="current_prompt" style="min-height: 7.5em;" ng-style="{'background-color': terminalBackgroundColor}"> <div class="current_prompt" style="min-height: 7.5em;" ng-style="{'background-color': terminalBackgroundColor}">
<div class="prompt_demo_choice_label" style="color: #FFF;">{{ selectedPrompt.name }}</div> <div class="prompt_demo_choice_label" style="color: #FFF;">{{ selectedPrompt.name }}</div>
<div ng-bind-html='selectedPrompt.demo | to_trusted' class="prompt_demo unbordered"></div> <div ng-bind-html='selectedPrompt.demo | to_trusted' class="prompt_demo unbordered"></div>
<div style="position: absolute; right: 5px; bottom: 5px; color:"> <div style="position: absolute; right: 5px; bottom: 5px; color:">
<span class="save_button" <span class="save_button"
ng-show="showSaveButton" ng-show="showSaveButton"
style="color: #777" style="color: #CCC"
ng-click="setPrompt()">{{ savePromptButtonTitle }}</span> ng-click="setPrompt()">{{ savePromptButtonTitle }}</span>
</div> </div>
</div> </div>
<div style="margin: 10px 0 7px 35px;">Preview a prompt below:</div> <div style="margin: 10px 15px 7px 15px; padding-bottom: 10px; border-bottom: solid 1px #999">Preview a prompt below:</div>
<div class="prompt_choices_scrollview"> <div class="prompt_choices_scrollview">
<div class="prompt_choices_list"> <div class="prompt_choices_list">
<div ng-repeat="prompt in samplePrompts"> <div ng-repeat="prompt in samplePrompts">
<div class="prompt_demo_choice_label">{{ prompt.name }}</div> <div class="prompt_demo_choice_label">{{ prompt.name }}</div>
<div ng-bind-html='prompt.demo | to_trusted' class="prompt_demo" ng-click="selectPrompt(prompt)"></div> <div ng-bind-html='prompt.demo | to_trusted' class="prompt_demo" ng-click="selectPrompt(prompt)"></div>
</div> </div>
</div>
</div> </div>
</div> </div>

View File

@@ -22,7 +22,7 @@ function fish_prompt
# Line 2 # Line 2
echo echo
if test $VIRTUAL_ENV if test -n "$VIRTUAL_ENV"
printf "(%s) " (set_color blue)(basename $VIRTUAL_ENV)(set_color normal) printf "(%s) " (set_color blue)(basename $VIRTUAL_ENV)(set_color normal)
end end
printf '↪ ' printf '↪ '

View File

@@ -23,7 +23,7 @@ from itertools import chain
COMMON_WSL_CMD_PATHS = ( COMMON_WSL_CMD_PATHS = (
"/mnt/c/Windows/System32", "/mnt/c/Windows/System32",
"/windir/c/Windows/System32", "/windir/c/Windows/System32",
"/c/Windows/System32" "/c/Windows/System32",
) )
FISH_BIN_PATH = False # will be set later FISH_BIN_PATH = False # will be set later
IS_PY2 = sys.version_info[0] == 2 IS_PY2 = sys.version_info[0] == 2
@@ -37,6 +37,21 @@ else:
import socketserver as SocketServer import socketserver as SocketServer
from urllib.parse import parse_qs from urllib.parse import parse_qs
try:
import json
except ImportError:
import simplejson as json
# Disable CLI web browsers
term = os.environ.pop("TERM", None)
# This import must be done with an empty $TERM, otherwise a command-line browser may be started
# which will block the whole process - see https://docs.python.org/3/library/webbrowser.html
import webbrowser
if term:
os.environ["TERM"] = term
def find_executable(exe, paths=()): def find_executable(exe, paths=()):
final_path = os.environ["PATH"].split(os.pathsep) final_path = os.environ["PATH"].split(os.pathsep)
@@ -71,19 +86,14 @@ def is_termux():
return "com.termux" in os.environ["PATH"] and find_executable("termux-open-url") return "com.termux" in os.environ["PATH"] and find_executable("termux-open-url")
# Disable CLI web browsers def is_chromeos_garcon():
term = os.environ.pop("TERM", None) """ Return whether we are running in Chrome OS and the browser can't see local files """
# This import must be done with an empty $TERM, otherwise a command-line browser may be started # In Crostini Chrome OS Linux, the default browser opens URLs in Chrome
# which will block the whole process - see https://docs.python.org/3/library/webbrowser.html # running outside the linux VM. This browser does not have access to the
import webbrowser # Linux filesystem. This uses Garcon, see for example
# https://chromium.googlesource.com/chromiumos/platform2/+/master/vm_tools/garcon/#opening-urls
if term: # https://source.chromium.org/search?q=garcon-url-handler
os.environ["TERM"] = term return "garcon-url-handler" in webbrowser.get().name
try:
import json
except ImportError:
import simplejson as json
def run_fish_cmd(text): def run_fish_cmd(text):
@@ -982,7 +992,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
vars[name].exported = True vars[name].exported = True
# Do not return history as a variable, it may be so large the browser hangs. # Do not return history as a variable, it may be so large the browser hangs.
vars.pop('history', None) vars.pop("history", None)
return [ return [
vars[key].get_json_obj() vars[key].get_json_obj()
@@ -1549,6 +1559,8 @@ def runThing():
sys.exit(-1) sys.exit(-1)
elif is_termux(): elif is_termux():
subprocess.call(["termux-open-url", url]) subprocess.call(["termux-open-url", url])
elif is_chromeos_garcon():
webbrowser.open(url)
else: else:
webbrowser.open(fileurl) webbrowser.open(fileurl)

View File

@@ -155,7 +155,6 @@ int parse_help_only_cmd_opts(struct help_only_cmd_opts_t &opts, int *optind, int
/// Process and print help for the specified builtin or function. /// Process and print help for the specified builtin or function.
void builtin_print_help(parser_t &parser, const io_streams_t &streams, const wchar_t *name, void builtin_print_help(parser_t &parser, const io_streams_t &streams, const wchar_t *name,
wcstring *error_message) { wcstring *error_message) {
UNUSED(streams);
// This won't ever work if no_exec is set. // This won't ever work if no_exec is set.
if (no_exec()) return; if (no_exec()) return;
const wcstring name_esc = escape_string(name, ESCAPE_ALL); const wcstring name_esc = escape_string(name, ESCAPE_ALL);
@@ -166,8 +165,10 @@ void builtin_print_help(parser_t &parser, const io_streams_t &streams, const wch
// If it's an error, redirect the output of __fish_print_help to stderr // If it's an error, redirect the output of __fish_print_help to stderr
ios.push_back(std::make_shared<io_fd_t>(STDOUT_FILENO, STDERR_FILENO)); ios.push_back(std::make_shared<io_fd_t>(STDOUT_FILENO, STDERR_FILENO));
} }
parser.eval(cmd, ios); auto res = parser.eval(cmd, ios);
// ignore the exit status of __fish_print_help if (res.status.exit_code() == 2) {
streams.err.append_format(BUILTIN_ERR_MISSING_HELP, name_esc.c_str());
}
} }
/// Perform error reporting for encounter with unknown option. /// Perform error reporting for encounter with unknown option.

View File

@@ -36,6 +36,10 @@ enum { COMMAND_NOT_BUILTIN, BUILTIN_REGULAR, BUILTIN_FUNCTION };
/// Error message on missing argument. /// Error message on missing argument.
#define BUILTIN_ERR_MISSING _(L"%ls: Expected argument for option %ls\n") #define BUILTIN_ERR_MISSING _(L"%ls: Expected argument for option %ls\n")
/// Error message on missing man page.
#define BUILTIN_ERR_MISSING_HELP \
_(L"fish: Missing man page for '%ls'. Did you install the documentation?\n")
/// Error message on invalid combination of options. /// Error message on invalid combination of options.
#define BUILTIN_ERR_COMBO _(L"%ls: Invalid combination of options\n") #define BUILTIN_ERR_COMBO _(L"%ls: Invalid combination of options\n")

View File

@@ -188,13 +188,19 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
} }
} }
const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L""); rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
if (bgcolor && bg.is_none()) { if (bgcolor && bg.is_none()) {
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor); streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
return STATUS_INVALID_ARGS; return STATUS_INVALID_ARGS;
} }
if (print) { if (print) {
// Hack: Explicitly setting a background of "normal" crashes
// for --print-colors. Because it's not interesting in terms of display,
// just skip it.
if (bgcolor && bg.is_special()) {
bg = rgb_color_t(L"");
}
print_colors(streams, bold, underline, italics, dim, reverse, bg); print_colors(streams, bold, underline, italics, dim, reverse, bg);
return STATUS_CMD_OK; return STATUS_CMD_OK;
} }

View File

@@ -183,7 +183,7 @@ struct options_t { //!OCLINT(too many fields)
long max = 0; long max = 0;
long start = 0; long start = 0;
long end = 0; long end = 0;
size_t width = 0; ssize_t width = 0;
wchar_t char_to_pad = L' '; wchar_t char_to_pad = L' ';
@@ -1181,24 +1181,24 @@ static int string_pad(parser_t &parser, io_streams_t &streams, int argc, wchar_t
} }
// Find max width of strings and keep the inputs // Find max width of strings and keep the inputs
size_t max_width = 0; ssize_t max_width = 0;
std::vector<wcstring> inputs; std::vector<wcstring> inputs;
arg_iterator_t aiter_width(argv, optind, streams); arg_iterator_t aiter_width(argv, optind, streams);
while (const wcstring *arg = aiter_width.nextstr()) { while (const wcstring *arg = aiter_width.nextstr()) {
wcstring input_string = *arg; wcstring input_string = *arg;
size_t width = fish_wcswidth(input_string); ssize_t width = fish_wcswidth(input_string);
if (width > max_width) max_width = width; if (width > max_width) max_width = width;
inputs.push_back(std::move(input_string)); inputs.push_back(std::move(input_string));
} }
size_t pad_width = max_width > opts.width ? max_width : opts.width; ssize_t pad_width = max_width > opts.width ? max_width : opts.width;
for (auto &input : inputs) { for (auto &input : inputs) {
wcstring padded; wcstring padded;
size_t padded_width = fish_wcswidth(input); ssize_t padded_width = fish_wcswidth(input);
if (pad_width >= padded_width) { if (pad_width >= padded_width) {
size_t pad = (pad_width - padded_width) / pad_char_width; ssize_t pad = (pad_width - padded_width) / pad_char_width;
size_t remaining_width = (pad_width - padded_width) % pad_char_width; ssize_t remaining_width = (pad_width - padded_width) % pad_char_width;
if (opts.left) { if (opts.left) {
padded.append(pad, opts.char_to_pad); padded.append(pad, opts.char_to_pad);
padded.append(remaining_width, L' '); padded.append(remaining_width, L' ');

View File

@@ -40,6 +40,7 @@ static const struct woption long_options[] = {{L"help", no_argument, nullptr, 'h
{L"path", no_argument, nullptr, 'p'}, {L"path", no_argument, nullptr, 'p'},
{L"force-path", no_argument, nullptr, 'P'}, {L"force-path", no_argument, nullptr, 'P'},
{L"query", no_argument, nullptr, 'q'}, {L"query", no_argument, nullptr, 'q'},
{L"quiet", no_argument, nullptr, 'q'},
{nullptr, 0, nullptr, 0}}; {nullptr, 0, nullptr, 0}};
static int parse_cmd_opts(type_cmd_opts_t &opts, int *optind, int argc, wchar_t **argv, static int parse_cmd_opts(type_cmd_opts_t &opts, int *optind, int argc, wchar_t **argv,

View File

@@ -212,7 +212,7 @@ bool is_windows_subsystem_for_linux() {
status == 0 ? demangled status == 0 ? demangled
: info.dli_sname == nullptr ? symbols[i] : info.dli_sname == nullptr ? symbols[i]
: info.dli_sname, : info.dli_sname,
static_cast<char *>(callstack[i]) - static_cast<char *>(info.dli_saddr)); static_cast<char *>(callstack[i]) - static_cast<const char *>(info.dli_saddr));
free(demangled); free(demangled);
} else { } else {
swprintf(text, sizeof(text) / sizeof(wchar_t), L"%-3d %s", i - skip_levels, symbols[i]); swprintf(text, sizeof(text) / sizeof(wchar_t), L"%-3d %s", i - skip_levels, symbols[i]);

View File

@@ -1582,11 +1582,10 @@ universal_notifier_t::notifier_strategy_t universal_notifier_t::resolve_default_
return strategy_notifyd; return strategy_notifyd;
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
return strategy_shmem_polling; return strategy_shmem_polling;
#elif defined(SIGIO) && (defined(__APPLE__) || defined(__BSD__) || defined(__linux__)) #elif 0 && defined(SIGIO) && (defined(__APPLE__) || defined(__BSD__) || defined(__linux__))
// The SIGIO notifier relies on an extremely specific interaction between signal handling and // FIXME: The SIGIO notifier relies on an extremely specific interaction between signal handling and
// O_ASYNC writes, and doesn't excercise codepaths that are particularly well explored on all // O_ASYNC writes, and doesn't currently work particularly well, so it's disabled.
// POSIX and POSIX-like systems, so we only explicitly enable it on platforms where it's known // See discussion in #6585 and #7774 for examples of breakage.
// to work. See discussion in #6585 for examples of breakage.
// //
// The SIGIO notifier does not yet work on WSL. See #7429 // The SIGIO notifier does not yet work on WSL. See #7429
if (is_windows_subsystem_for_linux()) { if (is_windows_subsystem_for_linux()) {

View File

@@ -97,8 +97,11 @@ static void set_signal_observed(int sig, bool val) {
} }
} }
/// Tests if one event instance matches the definition of a event class. /// Tests if one event instance matches the definition of an event class.
static bool handler_matches(const event_handler_t &classv, const event_t &instance) { /// In case of a match, \p only_once indicates that the event cannot match again by nature.
static bool handler_matches(const event_handler_t &classv, const event_t &instance,
bool &only_once) {
only_once = false;
if (classv.desc.type == event_type_t::any) return true; if (classv.desc.type == event_type_t::any) return true;
if (classv.desc.type != instance.desc.type) return false; if (classv.desc.type != instance.desc.type) return false;
@@ -111,9 +114,11 @@ static bool handler_matches(const event_handler_t &classv, const event_t &instan
} }
case event_type_t::exit: { case event_type_t::exit: {
if (classv.desc.param1.pid == EVENT_ANY_PID) return true; if (classv.desc.param1.pid == EVENT_ANY_PID) return true;
only_once = true;
return classv.desc.param1.pid == instance.desc.param1.pid; return classv.desc.param1.pid == instance.desc.param1.pid;
} }
case event_type_t::caller_exit: { case event_type_t::caller_exit: {
only_once = true;
return classv.desc.param1.caller_id == instance.desc.param1.caller_id; return classv.desc.param1.caller_id == instance.desc.param1.caller_id;
} }
case event_type_t::generic: { case event_type_t::generic: {
@@ -234,22 +239,54 @@ static void event_fire_internal(parser_t &parser, const event_t &event) {
scoped_push<bool> suppress_trace{&ld.suppress_fish_trace, true}; scoped_push<bool> suppress_trace{&ld.suppress_fish_trace, true};
// Capture the event handlers that match this event. // Capture the event handlers that match this event.
event_handler_list_t fire; struct firing_handler_t {
for (const auto &handler : *s_event_handlers.acquire()) { std::shared_ptr<event_handler_t> handler;
// Check if this event is a match. bool delete_after_call;
if (handler_matches(*handler, event)) { };
fire.push_back(handler); std::vector<firing_handler_t> fire;
{
for (const auto &handler : *s_event_handlers.acquire()) {
// Check if this event is a match.
bool only_once = false;
if (!handler_matches(*handler, event, only_once)) {
continue;
}
// If the nature of the event means it can't be fired more than once, deregister the
// event. This also works around a bug where jobs run without job control (no separate
// pgrp) cause handlers to run for each subsequent job started without job control
// (#7721). We can't erase it here because we check if the event is still extant before
// actually calling it below, so we instead push it along with its "delete after
// calling" value.
fire.push_back(firing_handler_t{handler, only_once});
} }
} }
// Iterate over our list of matching events. Fire the ones that are still present. // Iterate over our list of matching events. Fire the ones that are still present.
for (const shared_ptr<event_handler_t> &handler : fire) { for (const auto &firing_event : fire) {
auto &handler = firing_event.handler;
// Only fire if this event is still present. // Only fire if this event is still present.
// TODO: this is kind of crazy. We want to support removing (and thereby suppressing) an // TODO: this is kind of crazy. We want to support removing (and thereby suppressing) an
// event handler from another, but we also don't want to hold the lock across callouts. How // event handler from another, but we also don't want to hold the lock across callouts. How
// can we make this less silly? // can we make this less silly?
if (!contains(*s_event_handlers.acquire(), handler)) { {
continue; auto event_handlers = s_event_handlers.acquire();
if (!contains(*event_handlers, handler)) {
continue;
}
// Delete the event before firing it so we don't have to lock and unlock the event
// handlers list when handing control off to the handler.
if (firing_event.delete_after_call) {
FLOGF(event, L"Pruning handler '%ls' before firing", event.desc.str_param1.c_str());
for (auto event_handler = event_handlers->begin();
event_handler != event_handlers->end(); ++event_handler) {
if (event_handler->get() == firing_event.handler.get()) {
event_handlers->erase(event_handler);
break;
}
}
}
} }
// Construct a buffer to evaluate, starting with the function name and then all the // Construct a buffer to evaluate, starting with the function name and then all the

View File

@@ -445,7 +445,9 @@ static std::unique_ptr<output_stream_t> create_output_stream_for_builtin(
// Our IO redirection is to an internal buffer, e.g. a command substitution. // Our IO redirection is to an internal buffer, e.g. a command substitution.
// We will write directly to it. // We will write directly to it.
std::shared_ptr<io_buffer_t> buffer = std::shared_ptr<io_buffer_t> buffer =
dynamic_cast<const io_bufferfill_t *>(io.get())->buffer(); // (this is not a dynamic_cast because that needs rtti,
// and we currently use it nowhere else)
((const io_bufferfill_t *)io.get())->buffer();
return make_unique<buffered_output_stream_t>(buffer); return make_unique<buffered_output_stream_t>(buffer);
} }

View File

@@ -4,6 +4,7 @@
#include "fd_monitor.h" #include "fd_monitor.h"
#include <cstring> #include <cstring>
#include <thread> //this_thread::sleep_for
#include "flog.h" #include "flog.h"
#include "io.h" #include "io.h"

View File

@@ -491,6 +491,9 @@ int main(int argc, char **argv) {
if (!opts.no_exec) { if (!opts.no_exec) {
read_init(parser, paths); read_init(parser, paths);
} }
// Re-read the terminal modes after config, it might have changed them.
term_copy_modes();
// Stomp the exit status of any initialization commands (issue #635). // Stomp the exit status of any initialization commands (issue #635).
parser.set_last_statuses(statuses_t::just(STATUS_CMD_OK)); parser.set_last_statuses(statuses_t::just(STATUS_CMD_OK));

View File

@@ -5058,9 +5058,11 @@ static void test_error_messages() {
static void test_highlighting() { static void test_highlighting() {
say(L"Testing syntax highlighting"); say(L"Testing syntax highlighting");
if (system("mkdir -p test/fish_highlight_test/")) err(L"mkdir failed"); if (!pushd("test/fish_highlight_test/")) return;
if (system("touch test/fish_highlight_test/foo")) err(L"touch failed"); cleanup_t pop{[] { popd(); }};
if (system("touch test/fish_highlight_test/bar")) err(L"touch failed"); if (system("mkdir -p dir")) err(L"mkdir failed");
if (system("touch foo")) err(L"touch failed");
if (system("touch bar")) err(L"touch failed");
// Here are the components of our source and the colors we expect those to be. // Here are the components of our source and the colors we expect those to be.
struct highlight_component_t { struct highlight_component_t {
@@ -5079,14 +5081,14 @@ static void test_highlighting() {
param_valid_path.valid_path = true; param_valid_path.valid_path = true;
highlight_tests.push_back({{L"echo", highlight_role_t::command}, highlight_tests.push_back({{L"echo", highlight_role_t::command},
{L"test/fish_highlight_test/foo", param_valid_path}, {L"./foo", param_valid_path},
{L"&", highlight_role_t::statement_terminator}}); {L"&", highlight_role_t::statement_terminator}});
highlight_tests.push_back({ highlight_tests.push_back({
{L"command", highlight_role_t::keyword}, {L"command", highlight_role_t::keyword},
{L"echo", highlight_role_t::command}, {L"echo", highlight_role_t::command},
{L"abc", highlight_role_t::param}, {L"abc", highlight_role_t::param},
{L"test/fish_highlight_test/foo", param_valid_path}, {L"foo", param_valid_path},
{L"&", highlight_role_t::statement_terminator}, {L"&", highlight_role_t::statement_terminator},
}); });
@@ -5105,12 +5107,12 @@ static void test_highlighting() {
// Verify that cd shows errors for non-directories. // Verify that cd shows errors for non-directories.
highlight_tests.push_back({ highlight_tests.push_back({
{L"cd", highlight_role_t::command}, {L"cd", highlight_role_t::command},
{L"test/fish_highlight_test", param_valid_path}, {L"dir", param_valid_path},
}); });
highlight_tests.push_back({ highlight_tests.push_back({
{L"cd", highlight_role_t::command}, {L"cd", highlight_role_t::command},
{L"test/fish_highlight_test/foo", highlight_role_t::error}, {L"foo", highlight_role_t::error},
}); });
highlight_tests.push_back({ highlight_tests.push_back({

View File

@@ -774,12 +774,20 @@ bool history_impl_t::save_internal_via_rewrite() {
// We want to rewrite the file, while holding the lock for as briefly as possible // We want to rewrite the file, while holding the lock for as briefly as possible
// To do this, we speculatively write a file, and then lock and see if our original file changed // To do this, we speculatively write a file, and then lock and see if our original file changed
// Repeat until we succeed or give up // Repeat until we succeed or give up
const maybe_t<wcstring> target_name = history_filename(name); const maybe_t<wcstring> possibly_indirect_target_name = history_filename(name);
const maybe_t<wcstring> tmp_name_template = history_filename(name, L".XXXXXX"); const maybe_t<wcstring> tmp_name_template = history_filename(name, L".XXXXXX");
if (!target_name.has_value() || !tmp_name_template.has_value()) { if (!possibly_indirect_target_name.has_value() || !tmp_name_template.has_value()) {
return false; return false;
} }
// If the history file is a symlink, we want to rewrite the real file so long as we can find it.
wcstring target_name;
if (auto maybe_real_path = wrealpath(*possibly_indirect_target_name)) {
target_name = *maybe_real_path;
} else {
target_name = *possibly_indirect_target_name;
}
// Make our temporary file // Make our temporary file
// Remember that we have to close this fd! // Remember that we have to close this fd!
wcstring tmp_name; wcstring tmp_name;
@@ -792,7 +800,7 @@ bool history_impl_t::save_internal_via_rewrite() {
for (int i = 0; i < max_save_tries && !done; i++) { for (int i = 0; i < max_save_tries && !done; i++) {
// Open any target file, but do not lock it right away // Open any target file, but do not lock it right away
autoclose_fd_t target_fd_before{ autoclose_fd_t target_fd_before{
wopen_cloexec(*target_name, O_RDONLY | O_CREAT, history_file_mode)}; wopen_cloexec(target_name, O_RDONLY | O_CREAT, history_file_mode)};
file_id_t orig_file_id = file_id_for_fd(target_fd_before.fd()); // possibly invalid file_id_t orig_file_id = file_id_for_fd(target_fd_before.fd()); // possibly invalid
bool wrote = this->rewrite_to_temporary_file(target_fd_before.fd(), tmp_fd); bool wrote = this->rewrite_to_temporary_file(target_fd_before.fd(), tmp_fd);
target_fd_before.close(); target_fd_before.close();
@@ -805,14 +813,14 @@ bool history_impl_t::save_internal_via_rewrite() {
// were rewriting it. Make an effort to take the lock before checking, to avoid racing. // were rewriting it. Make an effort to take the lock before checking, to avoid racing.
// If the open fails, then proceed; this may be because there is no current history // If the open fails, then proceed; this may be because there is no current history
file_id_t new_file_id = kInvalidFileID; file_id_t new_file_id = kInvalidFileID;
autoclose_fd_t target_fd_after{wopen_cloexec(*target_name, O_RDONLY)}; autoclose_fd_t target_fd_after{wopen_cloexec(target_name, O_RDONLY)};
if (target_fd_after.valid()) { if (target_fd_after.valid()) {
// critical to take the lock before checking file IDs, // critical to take the lock before checking file IDs,
// and hold it until after we are done replacing // and hold it until after we are done replacing
// Also critical to check the file at the path, NOT based on our fd // Also critical to check the file at the path, NOT based on our fd
// It's only OK to replace the file while holding the lock // It's only OK to replace the file while holding the lock
history_file_lock(target_fd_after.fd(), LOCK_EX); history_file_lock(target_fd_after.fd(), LOCK_EX);
new_file_id = file_id_for_path(*target_name); new_file_id = file_id_for_path(target_name);
} }
bool can_replace_file = (new_file_id == orig_file_id || new_file_id == kInvalidFileID); bool can_replace_file = (new_file_id == orig_file_id || new_file_id == kInvalidFileID);
if (!can_replace_file) { if (!can_replace_file) {
@@ -841,8 +849,9 @@ bool history_impl_t::save_internal_via_rewrite() {
} }
// Slide it into place // Slide it into place
if (wrename(tmp_name, *target_name) == -1) { if (wrename(tmp_name, target_name) == -1) {
FLOGF(history_file, L"Error %d when renaming history file", errno); const char *error = std::strerror(errno);
FLOGF(error, _(L"Error when renaming history file: %s"), error);
} }
// We did it // We did it

View File

@@ -179,12 +179,14 @@ void outputter_t::set_color(rgb_color_t fg, rgb_color_t bg) {
reset_modes(); reset_modes();
} }
if (!last_color2.is_normal() && !last_color2.is_reset()) { if (!last_color2.is_special()) {
// Background was set. // Background was set.
// "Special" here refers to the special "normal", "reset" and "none" colors,
// that really jus disable the background.
last_bg_set = true; last_bg_set = true;
} }
if (!bg.is_normal()) { if (!bg.is_special()) {
// Background is set. // Background is set.
bg_set = true; bg_set = true;
if (fg == bg) fg = (bg == rgb_color_t::white()) ? rgb_color_t::black() : rgb_color_t::white(); if (fg == bg) fg = (bg == rgb_color_t::white()) ? rgb_color_t::black() : rgb_color_t::white();

View File

@@ -900,19 +900,14 @@ end_execution_reason_t parse_execution_context_t::populate_plain_process(
return arg_result; return arg_result;
} }
// Determine the process type.
process_type = process_type_for_command(statement, cmd);
// Only external commands and exec may redirect arbitrary fds.
bool allow_high_fds =
(process_type == process_type_t::external || process_type == process_type_t::exec);
// The set of IO redirections that we construct for the process. // The set of IO redirections that we construct for the process.
auto reason = auto reason = this->determine_redirections(statement.args_or_redirs, &redirections);
this->determine_redirections(statement.args_or_redirs, allow_high_fds, &redirections);
if (reason != end_execution_reason_t::ok) { if (reason != end_execution_reason_t::ok) {
return reason; return reason;
} }
// Determine the process type.
process_type = process_type_for_command(statement, cmd);
} }
// Populate the process. // Populate the process.
@@ -985,8 +980,7 @@ end_execution_reason_t parse_execution_context_t::expand_arguments_from_nodes(
} }
end_execution_reason_t parse_execution_context_t::determine_redirections( end_execution_reason_t parse_execution_context_t::determine_redirections(
const ast::argument_or_redirection_list_t &list, bool allow_high_fds, const ast::argument_or_redirection_list_t &list, redirection_spec_list_t *out_redirections) {
redirection_spec_list_t *out_redirections) {
// Get all redirection nodes underneath the statement. // Get all redirection nodes underneath the statement.
for (const ast::argument_or_redirection_t &arg_or_redir : list) { for (const ast::argument_or_redirection_t &arg_or_redir : list) {
if (!arg_or_redir.is_redirection()) continue; if (!arg_or_redir.is_redirection()) continue;
@@ -1014,18 +1008,10 @@ end_execution_reason_t parse_execution_context_t::determine_redirections(
redirection_spec_t spec{oper->fd, oper->mode, std::move(target)}; redirection_spec_t spec{oper->fd, oper->mode, std::move(target)};
// Validate this spec. // Validate this spec.
if (spec.mode == redirection_mode_t::fd && !spec.is_close()) { if (spec.mode == redirection_mode_t::fd && !spec.is_close() && !spec.get_target_as_fd()) {
maybe_t<int> target_fd = spec.get_target_as_fd(); const wchar_t *fmt =
if (!target_fd.has_value()) { _(L"Requested redirection to '%ls', which is not a valid file descriptor");
// Like `cmd >&gibberish`. return report_error(STATUS_INVALID_ARGS, redir_node, fmt, spec.target.c_str());
const wchar_t *fmt =
_(L"Requested redirection to '%ls', which is not a valid file descriptor");
return report_error(STATUS_INVALID_ARGS, redir_node, fmt, spec.target.c_str());
} else if (*target_fd > STDERR_FILENO && !allow_high_fds) {
// Like `echo foo 2>&5`. Don't allow internal procs to write to internal fish fds.
const wchar_t *fmt = _(L"Redirection to fd %d is only valid for external commands");
return report_error(STATUS_INVALID_ARGS, redir_node, fmt, *target_fd);
}
} }
out_redirections->push_back(std::move(spec)); out_redirections->push_back(std::move(spec));
@@ -1080,8 +1066,7 @@ end_execution_reason_t parse_execution_context_t::populate_block_process(
assert(args_or_redirs && "Should have args_or_redirs"); assert(args_or_redirs && "Should have args_or_redirs");
redirection_spec_list_t redirections; redirection_spec_list_t redirections;
auto reason = auto reason = this->determine_redirections(*args_or_redirs, &redirections);
this->determine_redirections(*args_or_redirs, false /* no high fds */, &redirections);
if (reason == end_execution_reason_t::ok) { if (reason == end_execution_reason_t::ok) {
proc->type = process_type_t::block_node; proc->type = process_type_t::block_node;
proc->block_node_source = pstree; proc->block_node_source = pstree;

View File

@@ -130,11 +130,7 @@ class parse_execution_context_t {
globspec_t glob_behavior); globspec_t glob_behavior);
// Determines the list of redirections for a node. // Determines the list of redirections for a node.
// If \p allow_high_fds is false, then report an error for an fd redirection other than to
// in/out/err. This is set when constructing an internal process and prevents writing random
// data to internal fish fds.
end_execution_reason_t determine_redirections(const ast::argument_or_redirection_list_t &list, end_execution_reason_t determine_redirections(const ast::argument_or_redirection_list_t &list,
bool allow_high_fds,
redirection_spec_list_t *out_redirections); redirection_spec_list_t *out_redirections);
end_execution_reason_t run_1_job(const ast::job_t &job, const block_t *associated_block); end_execution_reason_t run_1_job(const ast::job_t &job, const block_t *associated_block);

View File

@@ -24,9 +24,6 @@
#include "wcstringutil.h" #include "wcstringutil.h"
#include "wutil.h" // IWYU pragma: keep #include "wutil.h" // IWYU pragma: keep
/// Unexpected error in path_get_path().
#define MISSING_COMMAND_ERR_MSG _(L"Error while searching for command '%ls'")
// Note that PREFIX is defined in the `Makefile` and is thus defined when this module is compiled. // Note that PREFIX is defined in the `Makefile` and is thus defined when this module is compiled.
// This ensures we always default to "/bin", "/usr/bin" and the bin dir defined for the fish // This ensures we always default to "/bin", "/usr/bin" and the bin dir defined for the fish
// programs. Possibly with a duplicate dir if PREFIX is empty, "/", "/usr" or "/usr/". If the PREFIX // programs. Possibly with a duplicate dir if PREFIX is empty, "/", "/usr" or "/usr/". If the PREFIX
@@ -81,36 +78,6 @@ static bool path_get_path_core(const wcstring &cmd, wcstring *out_path,
return true; return true;
} }
err = EACCES; err = EACCES;
} else {
switch (errno) {
case EACCES:
case ENAMETOOLONG:
case ENOENT:
case ENOTDIR: {
break;
}
#ifdef __sun
// Solaris 5.11 can return any of the following three if the path
// does not exist. Yes, even 0. No, none of this is documented.
case 0:
case EAGAIN:
case EEXIST: {
break;
}
#endif
// WSL has a bug where access(2) can return EINVAL
// See https://github.com/Microsoft/BashOnWindows/issues/2522
// The only other way EINVAL can happen is if the wrong
// mode was specified, but we have X_OK hard-coded above.
case EINVAL: {
break;
}
default: {
FLOGF(warning, MISSING_COMMAND_ERR_MSG, next_path.c_str());
wperror(L"access");
break;
}
}
} }
} }

View File

@@ -649,13 +649,17 @@ static bool process_clean_after_marking(parser_t &parser, bool allow_interactive
printed = true; printed = true;
} }
// Prepare events for completed jobs, except for jobs that themselves came from event // Prepare events for completed jobs
// handlers. if (j->is_completed()) {
if (!j->from_event_handler() && j->is_completed()) { // If this job already came from an event handler,
if (j->should_report_process_exits()) { // don't create an event or it's easy to get an infinite loop.
if (!j->from_event_handler() && j->should_report_process_exits()) {
pid_t pgid = *j->get_pgid(); pid_t pgid = *j->get_pgid();
exit_events.push_back(proc_create_event(L"JOB_EXIT", event_type_t::exit, -pgid, 0)); exit_events.push_back(proc_create_event(L"JOB_EXIT", event_type_t::exit, -pgid, 0));
} }
// Caller exit events we still create, which anecdotally fixes `source (thing | psub)` inside event handlers.
// This seems benign since this event is barely used (basically only psub), and it seems hard
// to construct an infinite loop with it.
exit_events.push_back( exit_events.push_back(
proc_create_event(L"JOB_EXIT", event_type_t::caller_exit, j->job_id(), 0)); proc_create_event(L"JOB_EXIT", event_type_t::caller_exit, j->job_id(), 0));
exit_events.back().desc.param1.caller_id = j->internal_job_id; exit_events.back().desc.param1.caller_id = j->internal_job_id;

View File

@@ -839,13 +839,15 @@ static void redirect_tty_after_sighup() {
} }
/// Give up control of terminal. /// Give up control of terminal.
static void term_donate() { static void term_donate(bool quiet = false) {
while (true) { while (true) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) { if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) {
if (errno == EIO) redirect_tty_output(); if (errno == EIO) redirect_tty_output();
if (errno != EINTR) { if (errno != EINTR) {
FLOGF(warning, _(L"Could not set terminal mode for new job")); if (!quiet) {
wperror(L"tcsetattr"); FLOGF(warning, _(L"Could not set terminal mode for new job"));
wperror(L"tcsetattr");
}
break; break;
} }
} else } else
@@ -853,9 +855,8 @@ static void term_donate() {
} }
} }
/// Grab control of terminal. /// Copy the (potentially changed) terminal modes and use them from now on.
static void term_steal() { void term_copy_modes() {
// Copy the (potentially changed) terminal modes and use them from now on.
struct termios modes; struct termios modes;
tcgetattr(STDIN_FILENO, &modes); tcgetattr(STDIN_FILENO, &modes);
std::memcpy(&tty_modes_for_external_cmds, &modes, sizeof tty_modes_for_external_cmds); std::memcpy(&tty_modes_for_external_cmds, &modes, sizeof tty_modes_for_external_cmds);
@@ -872,8 +873,11 @@ static void term_steal() {
} else { } else {
shell_modes.c_iflag &= ~IXOFF; shell_modes.c_iflag &= ~IXOFF;
} }
}
/// Grab control of terminal.
void term_steal() {
term_copy_modes();
while (true) { while (true) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) { if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
if (errno == EIO) redirect_tty_output(); if (errno == EIO) redirect_tty_output();
@@ -1336,6 +1340,12 @@ void reader_init() {
term_fix_modes(&shell_modes); term_fix_modes(&shell_modes);
// Set up our fixed terminal modes once,
// so we don't get flow control just because we inherited it.
if (getpgrp() == tcgetpgrp(STDIN_FILENO)) {
term_donate(/* quiet */ true);
}
// We do this not because we actually need the window size but for its side-effect of correctly // We do this not because we actually need the window size but for its side-effect of correctly
// setting the COLUMNS and LINES env vars. // setting the COLUMNS and LINES env vars.
termsize_container_t::shared().updating(parser); termsize_container_t::shared().updating(parser);
@@ -2817,14 +2827,25 @@ struct readline_loop_state_t {
/// Run a sequence of commands from an input binding. /// Run a sequence of commands from an input binding.
void reader_data_t::run_input_command_scripts(const wcstring_list_t &cmds) { void reader_data_t::run_input_command_scripts(const wcstring_list_t &cmds) {
// Need to donate/steal the tty - see #2114.
term_donate();
auto last_statuses = parser().get_last_statuses(); auto last_statuses = parser().get_last_statuses();
for (const wcstring &cmd : cmds) { for (const wcstring &cmd : cmds) {
parser().eval(cmd, io_chain_t{}); parser().eval(cmd, io_chain_t{});
} }
parser().set_last_statuses(std::move(last_statuses)); parser().set_last_statuses(std::move(last_statuses));
term_steal();
// Restore tty to shell modes.
// Some input commands will take over the tty - see #2114 for an example where vim is invoked
// from a key binding. However we do NOT want to invoke term_donate(), because that will enable
// ECHO mode, causing a race between new input and restoring the mode (#7770). So we leave the
// tty alone, run the commands in shell mode, and then restore shell modes.
int res;
do {
res = tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes);
} while (res < 0 && errno == EINTR);
if (res < 0) {
wperror(L"tcsetattr");
}
termsize_container_t::shared().invalidate_tty();
} }
/// Read normal characters, inserting them into the command line. /// Read normal characters, inserting them into the command line.

View File

@@ -141,6 +141,7 @@ void reader_sighup();
/// Initialize the reader. /// Initialize the reader.
void reader_init(); void reader_init();
void term_copy_modes();
/// Restore the term mode at startup. /// Restore the term mode at startup.
void restore_term_mode(); void restore_term_mode();

View File

@@ -8,7 +8,7 @@
#include "wutil.h" #include "wutil.h"
#ifdef HAVE_WINSIZE #ifdef HAVE_WINSIZE
#include <sys/termios.h> #include <termios.h>
#endif #endif
// A counter which is incremented every SIGWINCH, or when the tty is otherwise invalidated. // A counter which is incremented every SIGWINCH, or when the tty is otherwise invalidated.

View File

@@ -113,22 +113,28 @@ echo comment after conjunction
# --help works # --help works
builtin and --help >/dev/null builtin and --help >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo $status echo $status
and --help >/dev/null and --help >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo $status echo $status
# CHECK: 0 # CHECK: 0
# CHECK: 0 # CHECK: 0
builtin or --help >/dev/null builtin or --help >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo $status echo $status
or --help >/dev/null or --help >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo $status echo $status
# CHECK: 0 # CHECK: 0
# CHECK: 0 # CHECK: 0
builtin not --help >/dev/null builtin not --help >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo $status echo $status
not --help >/dev/null not --help >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo $status echo $status
# CHECK: 0 # CHECK: 0
# CHECK: 0 # CHECK: 0

View File

@@ -2,7 +2,19 @@
# Test ALL THE FISH FILES # Test ALL THE FISH FILES
# in share/, that is - the tests are exempt because they contain syntax errors, on purpose # in share/, that is - the tests are exempt because they contain syntax errors, on purpose
for file in $__fish_data_dir/**.fish set timestamp_file ./last_check_all_files
$fish -n $file set -l find_args
if test -f $timestamp_file
set find_args -newer $timestamp_file
end end
set -l fail_count 0
for file in (find $__fish_data_dir/ -name "*.fish" $find_args 2>/dev/null; or find $__fish_data_dir/ -name "*.fish")
$fish -n $file; or set fail_count (math $fail_count + 1)
end
# Prevent setting timestamp if any errors were encountered
if test "$fail_count" -eq 0
touch $timestamp_file
end
# No output is good output # No output is good output

View File

@@ -23,9 +23,6 @@ $helper print_fds </dev/null
$helper print_fds 3</dev/null $helper print_fds 3</dev/null
# CHECK: 0 1 2 3 # CHECK: 0 1 2 3
$helper print_fds 5>&2
# CHECK: 0 1 2 5
# This attempts to trip a case where the file opened in fish # This attempts to trip a case where the file opened in fish
# has the same fd as the redirection. In this case, the dup2 # has the same fd as the redirection. In this case, the dup2
# does not clear the CLO_EXEC bit. # does not clear the CLO_EXEC bit.

View File

@@ -54,4 +54,8 @@ fish_add_path -nP $tmpdir/etc | string replace -- $tmpdir ''
test "$oldpath" = "$PATH" test "$oldpath" = "$PATH"
or echo "PATH CHANGED!!!" >&2 or echo "PATH CHANGED!!!" >&2
# See that moving multiple arguments removes the correct ones - #7776
PATH=$tmpdir/{bin,etc,link,sbin} fish_add_path -nPpm $tmpdir/{link,sbin} | string replace -a $tmpdir ''
# CHECK: set PATH /link /sbin /bin /etc
exit 0 exit 0

View File

@@ -24,7 +24,7 @@ git init >/dev/null 2>&1
# Note: We *can't* list all here because in addition to aliases, # Note: We *can't* list all here because in addition to aliases,
# git also uses all commands in $PATH called `git-something` as custom commands, # git also uses all commands in $PATH called `git-something` as custom commands,
# so this depends on system state! # so this depends on system state!
complete -C'git ' | grep '^add\s' complete -C'git ' | grep '^add'\t
# (note: actual tab character in the check here) # (note: actual tab character in the check here)
#CHECK: add Add file contents to the index #CHECK: add Add file contents to the index

View File

@@ -15,7 +15,6 @@ or echo "pgroups were the same, job control did not work"
# fish ignores SIGTTIN and so may transfer the tty even if it # fish ignores SIGTTIN and so may transfer the tty even if it
# doesn't own the tty. Ensure that doesn't happen. # doesn't own the tty. Ensure that doesn't happen.
set -l fish (status fish-path)
$fish -c 'status job-control full ; $fth report_foreground' & $fish -c 'status job-control full ; $fth report_foreground' &
wait wait
#CHECKERR: background #CHECKERR: background

View File

@@ -101,3 +101,18 @@ echo $status
#CHECK: Command #CHECK: Command
#CHECK: sleep #CHECK: sleep
#CHECK: 0 #CHECK: 0
function foo
function caller --on-job-exit caller
echo caller
end
echo foo
end
function bar --on-event bar
echo (foo)
end
emit bar
#CHECK: foo
#CHECK: caller

View File

@@ -100,35 +100,10 @@ echo $status
read abc <&- read abc <&-
#CHECKERR: read: stdin is closed #CHECKERR: read: stdin is closed
# This one should output nothing.
echo derp >&-
# Verify that builtins, blocks, and functions may not write to arbitrary fds.
echo derp >&12
#CHECKERR: {{.*}} Redirection to fd 12 is only valid for external commands
#CHECKERR: echo derp >&12
#CHECKERR: ^
begin
echo derp
end <&42
#CHECKERR: {{.*}} Redirection to fd 42 is only valid for external commands
#CHECKERR: end <&42
#CHECKERR: ^
outnerr 2>&7
#CHECKERR: {{.*}} Redirection to fd 7 is only valid for external commands
#CHECKERR: outnerr 2>&7
#CHECKERR: ^
# Redirection to 0, 1, 2 is allowed. We don't test 0 since writing to stdin is weird and unpredictable.
echo hooray1 >&1
echo hooray2 >&2
#CHECK: hooray1
#CHECKERR: hooray2
# "Verify that pipes don't conflict with fd redirections" # "Verify that pipes don't conflict with fd redirections"
# This code is very similar to eval. We go over a bunch of fds # This code is very similar to eval. We go over a bunch of fads
# to make it likely that we will nominally conflict with a pipe # to make it likely that we will nominally conflict with a pipe
# fish is supposed to detect this case and dup the pipe to something else # fish is supposed to detect this case and dup the pipe to something else
echo "/bin/echo pipe 3 <&3 3<&-" | source 3<&0 echo "/bin/echo pipe 3 <&3 3<&-" | source 3<&0
@@ -138,6 +113,9 @@ echo "/bin/echo pipe 6 <&6 6<&-" | source 6<&0
echo "/bin/echo pipe 7 <&7 7<&-" | source 7<&0 echo "/bin/echo pipe 7 <&7 7<&-" | source 7<&0
echo "/bin/echo pipe 8 <&8 8<&-" | source 8<&0 echo "/bin/echo pipe 8 <&8 8<&-" | source 8<&0
echo "/bin/echo pipe 9 <&9 9<&-" | source 9<&0 echo "/bin/echo pipe 9 <&9 9<&-" | source 9<&0
echo "/bin/echo pipe 10 <&10 10<&-" | source 10<&0
echo "/bin/echo pipe 11 <&11 11<&-" | source 11<&0
echo "/bin/echo pipe 12 <&12 12<&-" | source 12<&0
#CHECK: pipe 3 #CHECK: pipe 3
#CHECK: pipe 4 #CHECK: pipe 4
#CHECK: pipe 5 #CHECK: pipe 5
@@ -145,3 +123,6 @@ echo "/bin/echo pipe 9 <&9 9<&-" | source 9<&0
#CHECK: pipe 7 #CHECK: pipe 7
#CHECK: pipe 8 #CHECK: pipe 8
#CHECK: pipe 9 #CHECK: pipe 9
#CHECK: pipe 10
#CHECK: pipe 11
#CHECK: pipe 12

View File

@@ -241,6 +241,7 @@ echo 7 $status # no passthrough
#CHECK: 7 4 #CHECK: 7 4
false false
set -h >/dev/null set -h >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo 8 $status # no passthrough echo 8 $status # no passthrough
#CHECK: 8 0 #CHECK: 8 0
true true

View File

@@ -1,7 +1,6 @@
#RUN: %fish -C "set -g helper %fish_test_helper; set -g fish %fish" %s #RUN: %fish -C "set -g helper %fish_test_helper; set -g fish %fish" %s
# Check that nohup is propagated. # Check that nohup is propagated.
set fish (status fish-path)
set output_path (mktemp) set output_path (mktemp)
nohup $fish -c "$helper print_ignored_signals" 2>&1 > $output_path nohup $fish -c "$helper print_ignored_signals" 2>&1 > $output_path
cat $output_path cat $output_path

View File

@@ -713,3 +713,8 @@ end
string escape \x7F string escape \x7F
# CHECK: \x7f # CHECK: \x7f
# This used to crash.
string pad -w 8 he \eh
# CHECK: he
# CHECK: {{\x1bh}}

View File

@@ -1,18 +0,0 @@
#RUN: %fish -C 'set -g fish %fish' %s
begin
set -gx XDG_CONFIG_HOME (mktemp -d)
mkdir -p $XDG_CONFIG_HOME/fish
set -l target_file $XDG_CONFIG_HOME/fish/target_fish_variables
set -l fish_variables $XDG_CONFIG_HOME/fish/fish_variables
echo > $target_file
ln -sf $target_file $fish_variables
$fish -c 'set -U variable value'
if test -L $fish_variables
echo fish_variables is still a symlink
else
echo fish_variables has been overwritten
end
# CHECK: fish_variables is still a symlink
end

View File

@@ -0,0 +1,49 @@
#RUN: %fish -C 'set -g fish %fish' %s
set -gx XDG_CONFIG_HOME (mktemp -d)
set -gx XDG_DATA_HOME $XDG_CONFIG_HOME
mkdir -p $XDG_CONFIG_HOME/fish
# fish_variables
set -l target_file $XDG_CONFIG_HOME/fish/target_fish_variables
set -l fish_variables $XDG_CONFIG_HOME/fish/fish_variables
set -l backup_file $XDG_CONFIG_HOME/fish/fish_variables_backup
echo >$target_file
cp $target_file $backup_file
ln -sf $target_file $fish_variables
$fish -c 'set -U variable value'
if not test -L $fish_variables
echo fish_variables has been overwritten
else if cmp $target_file $backup_file >/dev/null
echo fish_variables was never written
else
echo fish_variables is still a symlink
end
# CHECK: fish_variables is still a symlink
# fish_history
set -l history_file $XDG_DATA_HOME/fish/fish_history
set -l target_file $XDG_DATA_HOME/fish/target_fish_history
set -l backup_file $XDG_DATA_HOME/fish/fish_history_backup
echo '- cmd: echo I will be deleted from history
when: 1614577746' >$target_file
cp $target_file $backup_file
ln -sf $target_file $history_file
# The one way to ensure non-interactive fish writes to the history file
$fish -c 'echo all | history delete deleted | grep echo'
# CHECK: [1] echo I will be deleted from history
if not test -L $history_file
echo fish_history has been overwritten
else if cmp $target_file $backup_file &>/dev/null
# cmp writes to stderr when one file is empty, thus &> above
echo fish_history was never written
else
echo fish_history is still a symlink
end
# CHECK: fish_history is still a symlink

View File

@@ -23,6 +23,10 @@ echo $status
type -q '[' type -q '['
echo $status echo $status
# CHECK: 0 # CHECK: 0
# Confirm that --quiet is still a thing
type --quiet '['
echo $status
# CHECK: 0
# Test that we print a command path # Test that we print a command path
type sh type sh

View File

@@ -35,9 +35,10 @@ expect_str("bryellow")
expect_str("cyan") expect_str("cyan")
expect_str("green") expect_str("green")
expect_str("magenta") expect_str("magenta")
expect_str("\x1b[31mred") # These should be anchored at the beginning of the line, no e.g. bold sequence before.
expect_str("\x1b[37mwhite") expect_str("\n\x1b[31mred")
expect_str("\x1b[33myellow") expect_str("\n\x1b[37mwhite")
expect_str("\n\x1b[33myellow")
expect_str("normal") expect_str("normal")
expect_prompt() expect_prompt()
@@ -60,3 +61,24 @@ expect_str("white")
expect_str("yellow") expect_str("yellow")
expect_str("normal") expect_str("normal")
expect_prompt() expect_prompt()
# This used to crash
sendline("set_color --print-colors --background normal")
expect_str("black")
expect_str("blue")
expect_str("brblack")
expect_str("brblue")
expect_str("brcyan")
expect_str("brgreen")
expect_str("brmagenta")
expect_str("brred")
expect_str("brwhite")
expect_str("bryellow")
expect_str("cyan")
expect_str("green")
expect_str("magenta")
expect_str("\n\x1b[31mred")
expect_str("\n\x1b[37mwhite")
expect_str("\n\x1b[33myellow")
expect_str("normal")
expect_prompt()