Compare commits

..

89 Commits
3.2.0 ... 3.2.2

Author SHA1 Message Date
David Adam
0c2cbfc01f Release 3.2.2
Closes #7889.
2021-04-07 20:31:43 +08:00
David Adam
da0c9da880 CHANGELOG: work on 3.2.2 2021-04-06 23:32:51 +08:00
ridiculousfish
fa890dc233 Prevent hanging when restoring the foreground process group at exit
When fish starts, it notices which pgroup owns the tty, and then it
restores that pgroup's tty ownership when it exits. However if fish does
not own the tty, then (on Mac at least) the tcsetpgrp call triggers a
SIGSTOP and fish will hang while trying to exit.

The first change is to ignore SIGTTOU instead of defaulting it. This
prevents the hang; however it risks re-introducing #7060.

The second change somewhat mitigates the risk of the first: only do the
restore if the initial pgroup is different than fish's pgroup. This
prevents some useless calls which might potentially steal the tty from
another process (e.g. in #7060).
2021-04-05 18:05:06 -07:00
ridiculousfish
797fbbb5f5 Remove the SIGIO signal handler and universal notifier
If fish launches a program and that program marks stdin as O_ASYNC, then
fish will start receiving SIGIO events on Mac. This occurs even though
the file descriptor itself does not have the O_ASYNC flag set.

SIGIO is reported as interrupting select which then breaks multiple-key
bindings, especially in vi-mode.

As the SIGIO based universal notifier is disabled, remove it and the
SIGIO handler itself. This allows fish to ignore properly ignore SIGIO.

Fixes #7853
2021-04-03 18:17:34 -07:00
Johannes Altmanninger
a4a42fa2c3 completions/aura: remove outdated flag
Commit a0b46e620 ("Update Aura completions") removed "abs", but forgot
it here.

Fixes #7865

(cherry picked from commit dc417f58ae)
2021-04-01 22:54:04 +08:00
Jannik Vieten
0efc55cbe9 Fix completion errors for tshark when running as root (#7858)
(cherry picked from commit 0f3274d5eb)
2021-04-01 22:54:04 +08:00
Fabian Homborg
92c28291df Only donate term if we're interactive *and* have the terminal
As it turns out otherwise fish would hang when sddm starts it as the login shell.

Belongs to #7842.

(cherry picked from commit 7f7cfcf339)
2021-04-01 22:54:04 +08:00
ridiculousfish
e31096d7ed Skip long arguments in syntax highlighting path detection
When fish performs syntax highlighting, it attempts to determine which
arguments are valid paths and underline them. Skip paths whose length
exceeds PATH_MAX. This is an optimization: such strings are almost
certainly not valid paths and checking them may be expensive.

Relevant is #7837

(cherry picked from commit 8d54d2b60e)
2021-04-01 22:54:04 +08:00
ridiculousfish
8b825bf760 Reimplement wbasename and wdirname
Previously wbasename and wdirname wrapped the system-provided basename
and dirname. But these have thread-safety issues and some surprising
error conditions on Mac. Just reimplement these per the OpenGroup spec.

In particular these no longer trigger a null-dereference if the input
exceeds PATH_MAX.

Add some tests too.

This fixes #7837

(cherry picked from commit cf35431af9)
2021-04-01 22:54:04 +08:00
ridiculousfish
951fc6b954 Add some tests for dirname and basename
This is in preparation for replacing our wrappers around the C versions,
with custom versions instead.

(cherry picked from commit 6e1b324343)
2021-04-01 22:54:04 +08:00
ridiculousfish
3a8e0e4c37 Don't block certain error signals on background threads
Previously fish attempted to block all signals on background threads, so
that they would be delivered to the main thread. But on Mac, SIGSEGV
and probably some others just get silently dropped, leading to potential
infinite loops instead of crashing. So stop blocking these signals.

With this change the null-deref in #7837 will properly crash instead of
spinning.

(cherry picked from commit a7c37e4af4)
2021-04-01 22:54:04 +08:00
ridiculousfish
0b144baa79 Switch fish.pc dependency from FBVF file to CHECK-FBVF target
Previously, both fish.pc and libfish had generating the
FISH-BUILD-VERSION-FILE attached as a command. In principle they could
both try to run the command simultaneously and now CMake complains about
this with the Xcode generator.

Switch to having fish.pc depend on the CHECK-FISH-BUILD-VERSION-FILE as a
target instead of a command. This allows it to participate in dependency
resolution and CMake will succeed again.

Fixes #7838

(cherry picked from commit 1b950f5f3b)
2021-04-01 22:54:04 +08:00
Fabian Homborg
9221a3deca Only set modes after config.fish if we're *interactive*
013a563ed0 made it so we only try to
adjust terminal modes if we are in the terminal pgroup, but that's not
enough.

Fish starts background jobs in events inside its own pgroup, so

    function on-foo --on-event foo
        fish -c 'sleep 3' &
    end

would have the backgrounded fish try to fiddle with the terminal and
succeed.

Instead, only fiddle with the terminal if we're interactive (this
should probably be extended to other bits, but this is the particular
problematic part)

Fixes #7842.

(cherry picked from commit e4fd664bbb)
2021-04-01 22:54:04 +08:00
Fabian Homborg
b2baf110c5 Disable pacman command-not-found handler
Apparently it's too slow on some systems

Fixes #7841.

(cherry picked from commit 95dc821a44)
2021-04-01 22:54:04 +08:00
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
92 changed files with 1438 additions and 865 deletions

View File

@@ -1,3 +1,53 @@
fish 3.2.2 (released April 7, 2021)
====================================
This release of fish fixes a number of additional issues identified in the fish 3.2 series:
- The command-not-found handler used suggestions from ``pacman`` on Arch Linux, but this caused major slowdowns on some systems and has been disabled (:issue:`7841`).
- fish will no longer hang on exit if another process is in the foreground on macOS (:issue:`7901`).
- Certain programs (such as ``lazygit``) could create situations where fish would not receive keystrokes correctly, but it is now more robust in these situations (:issue:`7853`).
- Arguments longer than 1024 characters no longer trigger excessive CPU usage on macOS (:issue:`7837`).
- fish builds correctly on macOS when using new versions of Xcode (:issue:`7838`).
- Completions for ``aura`` (:issue:`7865`) and ``tshark`` (:issue:`7858`) should no longer produce errors.
- Background jobs no longer interfere with syntax highlighting (a regression introduced in fish 3.2.1, :issue:`7842`).
If you are upgrading from version 3.1.2 or before, please also review the release notes for 3.2.1 and 3.2.0 (included below).
--------------
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)
===================================

View File

@@ -17,8 +17,6 @@ set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man")
# Prepend the output dir of fish_indent to PATH.
add_custom_target(sphinx-docs
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"
${SPHINX_EXECUTABLE}
-q -b html

View File

@@ -110,7 +110,7 @@ add_custom_command(OUTPUT fish.pc
COMMAND printf "Version: " >> fish.pc
COMMAND sed 's/FISH_BUILD_VERSION=//\;s/\"//g' ${FBVF} >> fish.pc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FBVF} ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion)
DEPENDS CHECK-FISH-BUILD-VERSION-FILE ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion)
add_custom_target(build_fish_pc ALL DEPENDS fish.pc)

View File

@@ -113,6 +113,7 @@ endforeach(TESTTYPE)
# Now add a dependency chain between the serial versions.
# 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_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:
- ``abs``
- ``acos``
- ``asin``
- ``atan``
- ``atan2``
- ``abs`` - the absolute value, with positive sign
- ``acos`` - arc cosine
- ``asin`` - arc sine
- ``atan`` - arc tangent
- ``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.
- ``ceil``
- ``cos``
- ``cosh``
- ``ceil`` - round number up to nearest integer
- ``cos`` - the cosine
- ``cosh`` - hyperbolic cosine
- ``exp`` - the base-e exponential function
- ``fac`` - factorial
- ``floor``
- ``fac`` - factorial - also known as ``x!`` (``x * (x - 1) * (x - 2) * ... * 1``)
- ``floor`` - round number down to nearest integer
- ``ln`` - the base-e logarithm
- ``log`` or ``log10`` - the base-10 logarithm
- ``ncr``
- ``npr``
- ``ncr`` - "from n choose r" combination function - how many subsets of size r can be taken from n (order doesn't matter)
- ``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``)
- ``round`` - rounds to the nearest integer, away from 0
- ``sin``
- ``sinh``
- ``sqrt``
- ``tan``
- ``tanh``
- ``sin`` - the sine function
- ``sinh`` - the hyperbolic sine
- ``sqrt`` - the square root - (can also be written as ``x ^ 0.5``)
- ``tan`` - the tangent
- ``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
--------
@@ -124,6 +124,8 @@ Examples
``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
-------------------

View File

@@ -52,12 +52,6 @@ def setup(app):
)
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_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,
# relative to this directory. They are copied after the builtin static files,
# 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
# 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?
---------------------------------------------------------------------
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
in ``ssh_exchange_identification`` messages in the debug log.
These problems are generally caused by the :ref:`user initialization file <initialization>` (usually
``~/.config/fish/config.fish``) producing output when started in non-interactive mode.
This usually happens because fish reads the :ref:`user configuration file <initialization>` (``~/.config/fish/config.fish``) *always*,
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
...
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:
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``.
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>`.
.. _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. #}
{% set rellinks = [] %}
{% block rootrellink %}
<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>
{% if theme_root_include_title %}
<a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}
@@ -41,9 +41,6 @@
{% block sidebar2 %} {% endblock %}
{% block extrahead %}
<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() }}
{% 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 {
background: none;
@@ -276,3 +276,31 @@ dl > dt span ~ em {
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
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
msgid ""

View File

@@ -87,7 +87,7 @@ for condition in query sync
complete -c aura -n $$condition -s s -l search -r -d 'Search packages for regexp'
end
for condition in abs aur
for condition in aur
complete -c aura -n $$condition -s a -l delmakedeps -d 'Remove packages only needed during installation'
complete -c aura -n $$condition -s d -l deps -d 'View package dependencies'
complete -c aura -n $$condition -s i -l info -d 'View package information'

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 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 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 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 w -d 'Use write-mode test'
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 '^@' '') ''))"
# 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 -s a -l append -d '(FTP SFTP) Upload: append to the target file'
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 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 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 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 -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 -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)'
@@ -129,83 +129,83 @@ complete -c curl -l proto-redir -d 'Limit what protocols it may use on redirect'
# TODO: args
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-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-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 -d 'Same as -E, --cert 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. Added in 7. 52. 0'
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-digest -d 'Tells curl to use HTTP Digest authentication when communicating with the give…'
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'
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'
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-insecure -d 'Same as -k, --insecure 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. 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'
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-ntlm -d 'Tells curl to use HTTP NTLM authentication when communicating with the given …'
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-pinnedpubkey -d '(TLS) Tells curl to use the specified public key file (or hashes) to verify t…'
complete -c curl -l proxy-negotiate -d 'Use HTTP Negotiate authentication to communicate with proxy'
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'
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-ssl-allow-beast -d 'Same as --ssl-allow-beast but used in HTTPS proxy context. Added in 7. 52'
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-tlsauthtype -d 'Same as --tlsauthtype 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. Added in 7. 52. 0'
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-tlsv1 -d 'Same as -1, --tlsv1 but used in HTTPS proxy context. Added in 7. 52. 0'
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) 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'
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'
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 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 -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 -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 -s r -l range -d '(HTTP FTP SFTP FILE) Retrieve a byte range (i. e'
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'
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 -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 J -l remote-header-name -d '(HTTP) This option tells the -O, --remote-name option to use the server-speci…'
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 -s J -l remote-header-name -d '(HTTP) Save output to filename from Content-Disposition'
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 R -l remote-time -d 'When used, this will make curl attempt to figure out the timestamp of the rem…'
complete -c curl -l request-target -d '(HTTP) Tells curl to use an alternative "target" (path) instead of using the …'
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 R -l remote-time -d 'Use timestamp of remote file on output'
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 HTTP method'
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-delay -d 'Make curl sleep this amount of time before each retry when a transfer has fai…'
complete -c curl -l retry-connrefused -d 'Consider ECONNREFUSED a transient error'
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 -d 'If a transient error is returned when curl tries to perform a transfer, it wi…'
complete -c curl -l sasl-ir -d 'Enable initial response in SASL authentication. Added in 7. 31. 0'
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'
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 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 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-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-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 -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-time -d 'If a download is slower than speed-limit bytes per second during a speed-time…'
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 -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 'Abort download if it\'s slower than speed for given speed-time (s)'
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-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 -s 2 -l sslv2 -d '(SSL) Forces curl to use SSL version 2 when negotiating with a remote SSL ser…'
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 2 -l sslv2 -d '(SSL) Use SSL version 2'
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 styled-output -d 'Enables the automatic use of bold font styles when writing HTTP headers to th…'
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 tcp-fastopen -d 'Enable use of TCP Fast Open (RFC7413). Added in 7. 49. 0'
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 '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'
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 -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 -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 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 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'
@@ -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.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 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-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'

View File

@@ -47,7 +47,7 @@ function __fish_git_recent_commits
# Like __fish_git_commits, but not on all branches and limited to
# the last 50 commits. Used for fixup, where only the current branch
# 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
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_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_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 -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'
@@ -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_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_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' -l continue -d 'Restart the rebasing process'
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
complete -C "git-$subcommand " >/dev/null
if [ (complete git-$subcommand | count) -gt 0 ]
complete git -f -n "__fish_git_using_command $subcommand" -a "(__fish_git_complete_custom_command $subcommand)"
if [ (complete -c git-$subcommand | count) -gt 0 ]
complete -c git -f -n "__fish_git_using_command $subcommand" -a "(__fish_git_complete_custom_command $subcommand)"
end
set -a __fish_git_custom_commands_completion $subcommand
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'
# 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 -l ssl -d 'Enable 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 g -l global -d "Make variable scope global"
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 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 S -l shell -d "Use syntax highlighting, tab completions and command termination suitable for entering shellscript code"
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 shell -d "Read like the shell would"
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 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

View File

@@ -2,8 +2,24 @@ function __rsync_remote_target
commandline -ct | string match -r '.*::?(?:.*/)?' | string unescape
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 -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 -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 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)"
@@ -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 -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 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 -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 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 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 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 p -l perms -d "Preserve permissions"
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 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 g -l group -d "Preserve group"
complete -c rsync -l devices -d "Preserve device files (super-user only)"
complete -c rsync -l specials -d "Preserve special files"
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 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 fake-super -d "Store/recover privileged attrs using xattrs"
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 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 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"
@@ -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-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-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-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 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-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 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-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 -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 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 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 -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"
@@ -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 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 -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 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'"
@@ -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 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 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 port -d "Specify double-colon alternate port number"
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 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 -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 -l progress -d "Show progress during transfer"
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 -l log-format -x -d "Output filenames using the specified format"
complete -c rsync -l password-file -x -d "Read password from FILE"
complete -c rsync -s M -l remote-option -d "Send OPTION to the remote side only"
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 bwlimit -x -d "Limit I/O bandwidth; KBytes per second"
complete -c rsync -l write-batch -x -d "Write a batched update to FILE"
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 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 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 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 -s 4 -l ipv4 -d "Prefer IPv4"
complete -c rsync -s 6 -l ipv6 -d "Prefer IPv6"
complete -c rsync -l version -d "Display version and exit"
complete -c rsync -l help -d "Display help and exit"
complete -c rsync -l daemon -d "Run as an rsync daemon"
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

View File

@@ -1,2 +1,2 @@
complete source -k -xa '(__fish_complete_suffix .fish)'
complete source -s h -l help -d 'Display help and exit'
complete -c source -k -xa '(__fish_complete_suffix .fish)'
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 "Enables forwarding of the authentication agent"
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 b -d "Local address to bind to" -a '(__fish_print_addresses)'
complete -x -c ssh -s e -d "Escape character" -a "\^ none"
complete -c ssh -s f -d "Go to background"

View File

@@ -5,14 +5,14 @@ __fish_complete_wireshark tshark
function __fish_tshark_protocols
set -l tok (commandline -ct | string collect)
set -l tok_param (string replace -r -- '^-O' '' $tok)
command tshark -G protocols | while read -l -d \t name shortname identifier
command tshark -G protocols 2>/dev/null | while read -l -d \t name shortname identifier
printf "%s%s\t%s\n" (string replace -r -- '(.+),[^,]*$' '$1,' $tok_param) $tok_no_comma $identifier $name
end
end
complete -c tshark -s 2 -d 'Perform a two-pass analysis'
# This is fairly expensive, but only done upon the user pressing tab.
complete -c tshark -s e -d 'Add a field to the list of fields to display' -xa '(command tshark -G fields | awk -F\t \'{print $3"\t"$2}\')'
complete -c tshark -s e -d 'Add a field to the list of fields to display' -xa '(command tshark -G fields 2> /dev/null | awk -F\t \'{print $3"\t"$2}\')'
complete -c tshark -s E -d 'Set an option controlling the printing of fields' -xa '
bom=y\t"Prepend output with the UTF-8 byte order mark"
header=y\t"Print a list of the selected field names"
@@ -24,7 +24,7 @@ quote=\t"Set the quote character to use to surround fields d=\", s=\', n=no quot
complete -c tshark -s F -d 'Set the output capture file format' -xa '(command tshark -F 2>| string replace -rf "\s+(\S+) - (.*)" \'$1\t$2\')'
complete -c tshark -s G -d 'Print a glossary' -xa '(
printf "help\tList available report types\n"
command tshark -G help | string replace -rf "\s+-G (\S+)\s+(.*)" \'$1\t$2\'
command tshark -G help 2>/dev/null | string replace -rf "\s+-G (\S+)\s+(.*)" \'$1\t$2\'
)'
complete -c tshark -s H -d 'Read a list of entries from a "hosts" file' -r
complete -c tshark -s j -d 'Protocol match filter used for ek|json|jsonraw|pdml output file types' -x

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 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 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 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 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 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 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))
end
MANPATH="$cache" apropos $argv
MANPATH="$cache" apropos -- $argv
if test $age -ge $max_age
mkdir -m 700 -p $cache
/usr/libexec/makewhatis -o $db (man --path | string split :) >/dev/null 2>&1 </dev/null &
end
else
apropos $argv
apropos -- $argv
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 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 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 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"

View File

@@ -6,15 +6,15 @@ end
function __fish_wireshark_interface
# no remote capture yet
command tshark -D | string replace -r ".*\. (\S+)\s*\(?([^)]*)\)?\$" '$1\t$2'
command tshark -D 2>/dev/null | string replace -r ".*\. (\S+)\s*\(?([^)]*)\)?\$" '$1\t$2'
end
function __fish_wireshark_protocol
command tshark -G protocols | awk -F\t '{print $3"\t"$1}'
command tshark -G protocols 2>/dev/null | awk -F\t '{print $3"\t"$1}'
end
function __fish_wireshark_heuristic
command tshark -G heuristic-decodes | awk -F\t '{print $2"\t"$1}'
command tshark -G heuristic-decodes 2>/dev/null | awk -F\t '{print $2"\t"$1}'
end
function __fish_tshark_name_resolving_flags
@@ -67,10 +67,10 @@ packets:\t"Switch to the next file after it contains N packets"'
complete -c $shark -l list-time-stamp-types -d 'List time stamp types supported for the interface'
complete -c $shark -s p -l no-promiscuous-mode -d "Don't put the interface into promiscuous mode"
complete -c $shark -s s -l snapshot-length -d 'Set the default snapshot length in bytes to use when capturing live data' -x
complete -c $shark -l time-stamp-type -d "Change the interface's timestamp method" -xa '(__fish_wireshark_choices (command tshark --list-time-stamp-types))'
complete -c $shark -l time-stamp-type -d "Change the interface's timestamp method" -xa '(__fish_wireshark_choices (command tshark --list-time-stamp-types 2>/dev/null))'
complete -c $shark -s v -l version -d 'Print the version and exit'
complete -c $shark -s w -d 'Write raw packet data to the given file ("-" means stdout)' -r
complete -c $shark -s y -l linktype -d 'Set the data link type to use while capturing packets' -xa '(__fish_wireshark_choices (command tshark -L))'
complete -c $shark -s y -l linktype -d 'Set the data link type to use while capturing packets' -xa '(__fish_wireshark_choices (command tshark -L 2>/dev/null))'
switch $shark
case dumpcap tshark
@@ -81,7 +81,7 @@ packets:\t"Switch to the next file after it contains N packets"'
switch $shark
case wireshark tshark
complete -c $shark -s C -d 'Run with the given configuration profile' -xa '(
set -l folders (tshark -G folders | awk \'/Personal configuration/{ print $NF}\')/profiles/*
set -l folders (tshark -G folders 2>/dev/null | awk \'/Personal configuration/{ print $NF}\')/profiles/*
string match -r "[^/]*\\$" -- $folders)'
complete -c $shark -s d -d 'Specify how a layer type should be dissected' -xa '(__fish_tshark_decode_as)'
complete -c $shark -l enable-protocol -d 'Enable dissection of the given protocol' -xa '(__fish_wireshark_protocol)'
@@ -92,7 +92,7 @@ string match -r "[^/]*\\$" -- $folders)'
complete -c $shark -s n -d 'Disable network object name resolution (hostname, TCP and UDP port names)'
complete -c $shark -s N -d 'Turn on name resolution only for particular types of addresses and port numbers' -xa '( __fish_tshark_name_resolving_flags)'
complete -c $shark -s o -d 'Override a preference value' -xa '(
command tshark -G defaultprefs | string replace -rf -- \'^#([a-z].*):.*\' \'$1:\')'
command tshark -G defaultprefs 2>/dev/null | string replace -rf -- \'^#([a-z].*):.*\' \'$1:\')'
complete -c $shark -s r -l read-file -d 'Read packet data from the given file' -r
complete -c $shark -s R -l read-filter -d 'Apply the given read filter' -x
complete -c $shark -s t -d 'Set the format of the packet timestamp printed in summary lines' -xa '

View File

@@ -109,21 +109,6 @@ function __fish_config_interactive -d "Initializations that should be performed
fish_greeting
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
# 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"
# $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=" +- +" '{
split($1, 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
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
# This is for OSX/BSD
# 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
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
# 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]
echo error: missing argument >&2
status print-stacktrace >&2
status print-stack-trace >&2
return 1
end
@@ -28,8 +28,10 @@ function __fish_print_pipestatus --description "Print pipestatus for prompt"
if test "$last_status" -ne "$argv[-1]"
set last_status_string " "$status_color$last_status
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 \
$brace_sep_color $right_brace $last_status_string (set_color normal)
$normal $brace_sep_color $right_brace $normal $last_status_string $normal
end
end

View File

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

View File

@@ -26,7 +26,7 @@ function fish_clipboard_paste
# in order to turn it into a single literal token.
#
# 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 status test-feature regex-easyesc
set data (string replace -ra "(['\\\])" '\\\\$1' -- $data)

View File

@@ -57,16 +57,21 @@ else if type -q pkgfile
__fish_default_command_not_found_handler $argv[1]
end
end
else if type -q pacman
function fish_command_not_found
set -l paths $argv[1]
# If we've not been given an absolute path, try $PATH as the starting point,
# otherwise pacman will try *every path*, and e.g. bash-completion
# isn't helpful.
string match -q '/*' -- $argv[1]; or set paths $PATH/$argv[1]
# Pacman only prints the path, so we still need to print the error.
__fish_default_command_not_found_handler $argv[1]
pacman -F $paths
# pacman is too slow, see #7841.
# else if type -q pacman
# function fish_command_not_found
# set -l paths $argv[1]
# # If we've not been given an absolute path, try $PATH as the starting point,
# # otherwise pacman will try *every path*, and e.g. bash-completion
# # isn't helpful.
# string match -q '/*' -- $argv[1]; or set paths $PATH/$argv[1]
# # Pacman only prints the path, so we still need to print the error.
# __fish_default_command_not_found_handler $argv[1]
# pacman -F $paths
# 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
# 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
set -a varargs --on-variable __fish_git_prompt_$var
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 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
@@ -776,8 +776,6 @@ function __fish_git_prompt_repaint $varargs --description "Event handler, repain
# Clear init so we reset the chars next time.
set -e ___fish_git_prompt_init
end
commandline -f repaint 2>/dev/null
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
end
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
set -e ___fish_git_prompt_init
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
end
end
commandline -f repaint 2>/dev/null
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
set -a varargs --on-variable __fish_git_prompt_char_$var
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
set -e ___fish_git_prompt_init
set -e _$argv[3]
commandline -f repaint 2>/dev/null
end
end

View File

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

View File

@@ -94,7 +94,7 @@ function help --description 'Show help for the fish shell'
if not set -q fish_browser[1]
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
end
@@ -142,12 +142,20 @@ function help --description 'Show help for the fish shell'
set fish_help_page "index.html#$fish_help_item"
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
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
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
if type -q cygpath
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%);
font-family: monospace, fixed;
color: #222;
min-height: 100vh; /* at least 1 screen high - to prevent the gradient from running out on a short tab */
}
#ancestor {
width: 90%;
margin-left: auto;
margin-right: auto;
-moz-box-shadow: 0 0 1px 1px #333;
-webkit-box-shadow: 0 0 1px 1px #333;
box-shadow: 0 0 5px 1px #333;
border-radius: 8px;
}
code {
@@ -33,6 +36,7 @@ code {
display: table-cell;
border: 1px solid #ccc;
border-right: none;
border-top: none;
padding-bottom: 15px;
padding-top: 15px;
padding-left: 3px;
@@ -45,22 +49,13 @@ code {
#tab_parent :first-child {
border-top-left-radius: 8px;
border-left: none;
}
#tab_parent :last-child {
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 {
background-color: #eeeefa;
border-bottom: none;
@@ -70,11 +65,24 @@ code {
padding-top: 20px;
padding-bottom: 20px;
width: 100%;
min-height: 80vh;
min-height: 90vh;
background-color: #eeeefa;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
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 {
@@ -429,7 +437,10 @@ code {
.prompt_choices_scrollview {
padding-top: 5px;
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,

View File

@@ -1,6 +1,6 @@
<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 -->
<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>

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. -->
<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 style="position: absolute; right: 5px; bottom: 5px; color:">
<span class="save_button"
ng-show="showSaveButton"
style="color: #777"
ng-click="setPrompt()">{{ savePromptButtonTitle }}</span>
ng-show="showSaveButton"
style="color: #CCC"
ng-click="setPrompt()">{{ savePromptButtonTitle }}</span>
</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_list">
<div ng-repeat="prompt in samplePrompts">
<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>
<div ng-repeat="prompt in samplePrompts">
<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>
</div>
</div>
</div>

View File

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

View File

@@ -23,7 +23,7 @@ from itertools import chain
COMMON_WSL_CMD_PATHS = (
"/mnt/c/Windows/System32",
"/windir/c/Windows/System32",
"/c/Windows/System32"
"/c/Windows/System32",
)
FISH_BIN_PATH = False # will be set later
IS_PY2 = sys.version_info[0] == 2
@@ -37,6 +37,21 @@ else:
import socketserver as SocketServer
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=()):
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")
# 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
try:
import json
except ImportError:
import simplejson as json
def is_chromeos_garcon():
""" Return whether we are running in Chrome OS and the browser can't see local files """
# 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 for example
# https://chromium.googlesource.com/chromiumos/platform2/+/master/vm_tools/garcon/#opening-urls
# https://source.chromium.org/search?q=garcon-url-handler
return "garcon-url-handler" in webbrowser.get().name
def run_fish_cmd(text):
@@ -982,7 +992,7 @@ class FishConfigHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
vars[name].exported = True
# Do not return history as a variable, it may be so large the browser hangs.
vars.pop('history', None)
vars.pop("history", None)
return [
vars[key].get_json_obj()
@@ -1549,6 +1559,8 @@ def runThing():
sys.exit(-1)
elif is_termux():
subprocess.call(["termux-open-url", url])
elif is_chromeos_garcon():
webbrowser.open(url)
else:
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.
void builtin_print_help(parser_t &parser, const io_streams_t &streams, const wchar_t *name,
wcstring *error_message) {
UNUSED(streams);
// This won't ever work if no_exec is set.
if (no_exec()) return;
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
ios.push_back(std::make_shared<io_fd_t>(STDOUT_FILENO, STDERR_FILENO));
}
parser.eval(cmd, ios);
// ignore the exit status of __fish_print_help
auto res = parser.eval(cmd, ios);
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.

View File

@@ -36,6 +36,10 @@ enum { COMMAND_NOT_BUILTIN, BUILTIN_REGULAR, BUILTIN_FUNCTION };
/// Error message on missing argument.
#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.
#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()) {
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
return STATUS_INVALID_ARGS;
}
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);
return STATUS_CMD_OK;
}

View File

@@ -183,7 +183,7 @@ struct options_t { //!OCLINT(too many fields)
long max = 0;
long start = 0;
long end = 0;
size_t width = 0;
ssize_t width = 0;
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
size_t max_width = 0;
ssize_t max_width = 0;
std::vector<wcstring> inputs;
arg_iterator_t aiter_width(argv, optind, streams);
while (const wcstring *arg = aiter_width.nextstr()) {
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;
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) {
wcstring padded;
size_t padded_width = fish_wcswidth(input);
ssize_t padded_width = fish_wcswidth(input);
if (pad_width >= padded_width) {
size_t pad = (pad_width - padded_width) / pad_char_width;
size_t remaining_width = (pad_width - padded_width) % pad_char_width;
ssize_t pad = (pad_width - padded_width) / pad_char_width;
ssize_t remaining_width = (pad_width - padded_width) % pad_char_width;
if (opts.left) {
padded.append(pad, opts.char_to_pad);
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"force-path", no_argument, nullptr, 'P'},
{L"query", no_argument, nullptr, 'q'},
{L"quiet", no_argument, nullptr, 'q'},
{nullptr, 0, nullptr, 0}};
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
: info.dli_sname == nullptr ? symbols[i]
: 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);
} else {
swprintf(text, sizeof(text) / sizeof(wchar_t), L"%-3d %s", i - skip_levels, symbols[i]);
@@ -1789,12 +1789,15 @@ void save_term_foreground_process_group() {
}
void restore_term_foreground_process_group_for_exit() {
if (initial_fg_process_group != -1) {
// This is called during shutdown and from a signal handler. We don't bother to complain on
// failure because doing so is unlikely to be noticed.
// However we want this to fail if we are not the tty owner (#7060), so clear our SIGTTOU
// handler to allow it to fail properly. Note that we are about to exit.
(void)signal(SIGTTOU, SIG_DFL);
// We wish to restore the tty to the initial owner. There's two ways this can go wrong:
// 1. We may steal the tty from someone else (#7060).
// 2. The call to tcsetpgrp may deliver SIGSTOP to us, and we will not exit.
// Hanging on exit seems worse, so ensure that SIGTTOU is ignored so we do not get SIGSTOP.
// Note initial_fg_process_group == 0 is possible with Linux pid namespaces.
// This is called during shutdown and from a signal handler. We don't bother to complain on
// failure because doing so is unlikely to be noticed.
if (initial_fg_process_group > 0 && initial_fg_process_group != getpgrp()) {
(void)signal(SIGTTOU, SIG_IGN);
(void)tcsetpgrp(STDIN_FILENO, initial_fg_process_group);
}
}

View File

@@ -1306,119 +1306,6 @@ static autoclose_fd_t make_fifo(const wchar_t *test_path, const wchar_t *suffix)
return res;
}
// A universal notifier which uses SIGIO with a named pipe. This relies on the following behavior
// which appears to work on Linux: if data becomes available on the pipe then all processes get
// SIGIO even if the data is read (i.e. there is no race between SIGIO and another proc reading).
//
// A key difference between Linux and Mac is that on Linux SIGIO is only delivered if the pipe was
// previously empty. That is, two successive writes with no reads will produce two SIGIOs on Mac but
// only one on Linux.
//
// So, to post a notification, write anything to the pipe; if that would block drain the pipe and
// try again.
//
// To receive a notification, watch for SIGIO on the read end, then read out the data to enable
// SIGIO to be delivered again.
class universal_notifier_sigio_t final : public universal_notifier_t {
#ifdef SIGIO
public:
// Note we use a different suffix from universal_notifier_named_pipe_t to produce different
// FIFOs. This is because universal_notifier_named_pipe_t is level triggered while we are edge
// triggered. If they shared the same FIFO, then the named_pipe variant would keep firing
// forever.
explicit universal_notifier_sigio_t(const wchar_t *test_path)
: pipe_(try_make_pipe(test_path, L".notify")) {}
~universal_notifier_sigio_t() = default;
void post_notification() override {
if (!pipe_.valid()) return;
// Write a byte to send SIGIO. If the pipe is full, read some and try again.
while (!write_1_byte()) {
if (errno == EINTR) {
continue;
} else if (errno == EAGAIN) {
// The pipe is full. Try once more.
drain_some();
write_1_byte();
break;
} else {
break;
}
}
}
bool poll() override {
if (sigio_count_ != signal_get_sigio_count()) {
// On Mac, SIGIO is generated on every write to the pipe.
// On Linux, it is generated only when the pipe goes from empty to non-empty.
// Read from the pipe so that SIGIO may be delivered again.
drain_some();
// We may have gotten another SIGIO because the pipe just became writable again.
// In particular BSD sends SIGIO on read even if there is no data to be read.
// Re-fetch the sigio count.
sigio_count_ = signal_get_sigio_count();
return true;
}
return false;
}
private:
// Construct a pipe for a given fifo path, arranging for SIGIO to be delivered.
// \return an invalid fd on failure.
static autoclose_fd_t try_make_pipe(const wchar_t *test_path, const wchar_t *suffix) {
autoclose_fd_t pipe = make_fifo(test_path, suffix);
if (!pipe.valid()) {
return autoclose_fd_t{};
}
// Note that O_ASYNC cannot be passed to open() (see Linux kernel bug #5993).
// We have to set it afterwards like so.
// Linux got support for O_ASYNC on fifos in 2.6 (released 2003). Treat its absence as a
// failure, but don't be noisy if this fails. Non-Linux platforms without O_ASYNC should use
// a different notifier strategy to avoid running into this.
#ifdef O_ASYNC
if (fcntl(pipe.fd(), F_SETFL, O_NONBLOCK | O_ASYNC) == -1)
#endif
{
FLOGF(uvar_file,
_(L"fcntl(F_SETFL) failed, universal variable notifications disabled"));
return autoclose_fd_t{};
}
if (fcntl(pipe.fd(), F_SETOWN, getpid()) == -1) {
FLOGF(uvar_file,
_(L"fcntl(F_SETOWN) failed, universal variable notifications disabled"));
return autoclose_fd_t{};
}
return pipe;
}
// Try writing a single byte to our pipe.
// \return true on success, false on error, in which case errno will be set.
bool write_1_byte() const {
assert(pipe_.valid() && "Invalid pipe");
char c = 0x42;
ssize_t amt = write(pipe_.fd(), &c, sizeof c);
return amt > 0;
}
// Read some data off of the pipe, discarding it.
void drain_some() const {
if (!pipe_.valid()) return;
char buff[256];
ignore_result(read(pipe_.fd(), buff, sizeof buff));
}
autoclose_fd_t pipe_{};
uint32_t sigio_count_{0};
#else
public:
[[noreturn]] universal_notifier_sigio_t() {
DIE("universal_notifier_sigio_t cannot be used on this system");
}
#endif
};
// Named-pipe based notifier. All clients open the same named pipe for reading and writing. The
// pipe's readability status is a trigger to enter polling mode.
//
@@ -1582,17 +1469,6 @@ universal_notifier_t::notifier_strategy_t universal_notifier_t::resolve_default_
return strategy_notifyd;
#elif defined(__CYGWIN__)
return strategy_shmem_polling;
#elif defined(SIGIO) && (defined(__APPLE__) || defined(__BSD__) || defined(__linux__))
// 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
// POSIX and POSIX-like systems, so we only explicitly enable it on platforms where it's known
// to work. See discussion in #6585 for examples of breakage.
//
// The SIGIO notifier does not yet work on WSL. See #7429
if (is_windows_subsystem_for_linux()) {
return strategy_named_pipe;
}
return strategy_sigio;
#else
return strategy_named_pipe;
#endif
@@ -1613,9 +1489,6 @@ std::unique_ptr<universal_notifier_t> universal_notifier_t::new_notifier_for_str
case strategy_shmem_polling: {
return make_unique<universal_notifier_shmem_poller_t>();
}
case strategy_sigio: {
return make_unique<universal_notifier_sigio_t>(test_path);
}
case strategy_named_pipe: {
return make_unique<universal_notifier_named_pipe_t>(test_path);
}

View File

@@ -166,9 +166,6 @@ class universal_notifier_t {
// Mac-specific notify(3) implementation.
strategy_notifyd,
// Set up a fifo and then waits for SIGIO to be delivered on it.
strategy_sigio,
// Strategy that uses a named pipe. Somewhat complex, but portable and doesn't require
// polling most of the time.
strategy_named_pipe,

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.
static bool handler_matches(const event_handler_t &classv, const event_t &instance) {
/// Tests if one event instance matches the definition of an event class.
/// 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 != 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: {
if (classv.desc.param1.pid == EVENT_ANY_PID) return true;
only_once = true;
return classv.desc.param1.pid == instance.desc.param1.pid;
}
case event_type_t::caller_exit: {
only_once = true;
return classv.desc.param1.caller_id == instance.desc.param1.caller_id;
}
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};
// Capture the event handlers that match this event.
event_handler_list_t fire;
for (const auto &handler : *s_event_handlers.acquire()) {
// Check if this event is a match.
if (handler_matches(*handler, event)) {
fire.push_back(handler);
struct firing_handler_t {
std::shared_ptr<event_handler_t> handler;
bool delete_after_call;
};
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.
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.
// 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
// 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

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.
// We will write directly to it.
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);
}

View File

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

View File

@@ -491,6 +491,9 @@ int main(int argc, char **argv) {
if (!opts.no_exec) {
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).
parser.set_last_statuses(statuses_t::just(STATUS_CMD_OK));

View File

@@ -20,6 +20,26 @@ static void become_foreground_then_print_stderr() {
fprintf(stderr, "become_foreground_then_print_stderr done\n");
}
static void nohup_wait() {
pid_t init_parent = getppid();
if (signal(SIGHUP, SIG_IGN)) {
perror("tcsetgrp");
exit(EXIT_FAILURE);
}
// Note: these silly close() calls are necessary to prevent our parent process (presumably fish)
// from getting stuck in the "E" state ("Trying to exit"). This appears to be a (kernel?) bug on
// macOS: the process is no longer running but is not a zombie either, and so cannot be reaped.
// It is unclear why closing these fds successfully works around this issue.
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// To avoid leaving fish_test_helpers around, we exit once our parent changes, meaning the fish
// instance exited.
while (getppid() == init_parent) {
usleep(1000000 / 4);
}
}
static void report_foreground_loop() {
int was_fg = -1;
const auto grp = getpgrp();
@@ -146,6 +166,7 @@ struct fth_command_t {
static fth_command_t s_commands[] = {
{"become_foreground_then_print_stderr", become_foreground_then_print_stderr,
"Claim the terminal (tcsetpgrp) and then print to stderr"},
{"nohup_wait", nohup_wait, "Ignore SIGHUP and just wait"},
{"report_foreground", report_foreground, "Report to stderr whether we own the terminal"},
{"report_foreground_loop", report_foreground_loop,
"Continually report to stderr whether we own the terminal"},

View File

@@ -195,6 +195,16 @@ static void popd() {
env_stack_t::principal().set_pwd_from_getcwd();
}
// Helper to return a string whose length greatly exceeds PATH_MAX.
wcstring get_overlong_path() {
wcstring longpath;
longpath.reserve(PATH_MAX * 2 + 10);
while (longpath.size() <= PATH_MAX * 2) {
longpath += L"/overlong";
}
return longpath;
}
// The odd formulation of these macros is to avoid "multiple unary operator" warnings from oclint
// were we to use the more natural "if (!(e)) err(..." form. We have to do this because the rules
// for the C preprocessor make it practically impossible to embed a comment in the body of a macro.
@@ -3977,8 +3987,7 @@ static void trigger_or_wait_for_notification(universal_notifier_t::notifier_stra
usleep(40000);
break;
}
case universal_notifier_t::strategy_named_pipe:
case universal_notifier_t::strategy_sigio: {
case universal_notifier_t::strategy_named_pipe: {
break; // nothing required
}
}
@@ -3989,9 +3998,6 @@ static void test_notifiers_with_strategy(universal_notifier_t::notifier_strategy
std::unique_ptr<universal_notifier_t> notifiers[16];
size_t notifier_count = sizeof notifiers / sizeof *notifiers;
// Set up SIGIO handler as needed.
signal_set_handlers(false);
// Populate array of notifiers.
for (size_t i = 0; i < notifier_count; i++) {
notifiers[i] = universal_notifier_t::new_notifier_for_strategy(strategy, UVARS_TEST_PATH);
@@ -4041,12 +4047,6 @@ static void test_notifiers_with_strategy(universal_notifier_t::notifier_strategy
// Nobody should poll now.
for (size_t i = 0; i < notifier_count; i++) {
// On BSD, SIGIO may be delivered by read() even if it returns EAGAIN;
// that is the polling itself may trigger a SIGIO. Therefore we poll twice.
if (strategy == universal_notifier_t::strategy_sigio) {
(void)poll_notifier(notifiers[i]);
}
if (poll_notifier(notifiers[i])) {
err(L"Universal variable notifier polled true after all changes, with strategy %d",
(int)strategy);
@@ -5058,9 +5058,11 @@ static void test_error_messages() {
static void test_highlighting() {
say(L"Testing syntax highlighting");
if (system("mkdir -p test/fish_highlight_test/")) err(L"mkdir failed");
if (system("touch test/fish_highlight_test/foo")) err(L"touch failed");
if (system("touch test/fish_highlight_test/bar")) err(L"touch failed");
if (!pushd("test/fish_highlight_test/")) return;
cleanup_t pop{[] { popd(); }};
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.
struct highlight_component_t {
@@ -5079,14 +5081,14 @@ static void test_highlighting() {
param_valid_path.valid_path = true;
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}});
highlight_tests.push_back({
{L"command", highlight_role_t::keyword},
{L"echo", highlight_role_t::command},
{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},
});
@@ -5105,12 +5107,12 @@ static void test_highlighting() {
// Verify that cd shows errors for non-directories.
highlight_tests.push_back({
{L"cd", highlight_role_t::command},
{L"test/fish_highlight_test", param_valid_path},
{L"dir", param_valid_path},
});
highlight_tests.push_back({
{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({
@@ -5334,6 +5336,13 @@ static void test_highlighting() {
{L"# comment", highlight_role_t::comment},
});
// Overlong paths don't crash (#7837).
const wcstring overlong = get_overlong_path();
highlight_tests.push_back({
{L"touch", highlight_role_t::command},
{overlong.c_str(), highlight_role_t::param},
});
highlight_tests.push_back({
{L"a", highlight_role_t::param},
{L"=", highlight_role_t::operat, ns},
@@ -6182,6 +6191,47 @@ void test_normalize_path() {
do_test(path_normalize_for_cd(L"/abc/def/", L"../ghi/..") == L"/abc/ghi/..");
}
void test_dirname_basename() {
say(L"Testing wdirname and wbasename");
const struct testcase_t {
const wchar_t *path;
const wchar_t *dir;
const wchar_t *base;
} testcases[] = {
{L"", L".", L"."},
{L"foo//", L".", L"foo"},
{L"foo//////", L".", L"foo"},
{L"/////foo", L"/", L"foo"},
{L"/////foo", L"/", L"foo"},
{L"//foo/////bar", L"//foo", L"bar"},
{L"foo/////bar", L"foo", L"bar"},
// Examples given in XPG4.2.
{L"/usr/lib", L"/usr", L"lib"},
{L"usr", L".", L"usr"},
{L"/", L"/", L"/"},
{L".", L".", L"."},
{L"..", L".", L".."},
};
for (const auto &tc : testcases) {
wcstring dir = wdirname(tc.path);
if (dir != tc.dir) {
err(L"Wrong dirname for \"%ls\": expected \"%ls\", got \"%ls\"", tc.path, tc.dir,
dir.c_str());
}
wcstring base = wbasename(tc.path);
if (base != tc.base) {
err(L"Wrong basename for \"%ls\": expected \"%ls\", got \"%ls\"", tc.path, tc.base,
base.c_str());
}
}
// Ensures strings which greatly exceed PATH_MAX still work (#7837).
wcstring longpath = get_overlong_path();
wcstring longpath_dir = longpath.substr(0, longpath.rfind(L'/'));
do_test(wdirname(longpath) == longpath_dir);
do_test(wbasename(longpath) == L"overlong");
}
static void test_topic_monitor() {
say(L"Testing topic monitor");
topic_monitor_t monitor;
@@ -6527,6 +6577,7 @@ int main(int argc, char **argv) {
if (should_test_function("layout_cache")) test_layout_cache();
if (should_test_function("prompt")) test_prompt_truncation();
if (should_test_function("normalize")) test_normalize_path();
if (should_test_function("dirname")) test_dirname_basename();
if (should_test_function("topics")) test_topic_monitor();
if (should_test_function("topics")) test_topic_monitor_torture();
if (should_test_function("pipes")) test_pipes();

View File

@@ -918,6 +918,11 @@ void highlighter_t::color_as_argument(const ast::node_t &node) {
static bool range_is_potential_path(const wcstring &src, const source_range_t &range,
const operation_context_t &ctx,
const wcstring &working_directory) {
// Skip strings exceeding PATH_MAX. See #7837.
// Note some paths may exceed PATH_MAX, but this is just for highlighting.
if (range.length > PATH_MAX) {
return false;
}
// Get the node source, unescape it, and then pass it to is_potential_path along with the
// working directory (as a one element list).
bool result = false;

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
// 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
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");
if (!target_name.has_value() || !tmp_name_template.has_value()) {
if (!possibly_indirect_target_name.has_value() || !tmp_name_template.has_value()) {
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
// Remember that we have to close this fd!
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++) {
// Open any target file, but do not lock it right away
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
bool wrote = this->rewrite_to_temporary_file(target_fd_before.fd(), tmp_fd);
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.
// If the open fails, then proceed; this may be because there is no current history
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()) {
// critical to take the lock before checking file IDs,
// and hold it until after we are done replacing
// 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
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);
if (!can_replace_file) {
@@ -841,8 +849,9 @@ bool history_impl_t::save_internal_via_rewrite() {
}
// Slide it into place
if (wrename(tmp_name, *target_name) == -1) {
FLOGF(history_file, L"Error %d when renaming history file", errno);
if (wrename(tmp_name, target_name) == -1) {
const char *error = std::strerror(errno);
FLOGF(error, _(L"Error when renaming history file: %s"), error);
}
// We did it

View File

@@ -397,11 +397,18 @@ void iothread_perform_on_main(void_function_t &&func) {
}
bool make_detached_pthread(void *(*func)(void *), void *param) {
// The spawned thread inherits our signal mask. We don't want the thread to ever receive signals
// on the spawned thread, so temporarily block all signals, spawn the thread, and then restore
// it.
// The spawned thread inherits our signal mask. Temporarily block signals, spawn the thread, and
// then restore it. But we must not block SIGBUS, SIGFPE, SIGILL, or SIGSEGV; that's undefined
// (#7837). Conservatively don't try to mask SIGKILL or SIGSTOP either; that's ignored on Linux
// but maybe has an effect elsewhere.
sigset_t new_set, saved_set;
sigfillset(&new_set);
sigdelset(&new_set, SIGILL); // bad jump
sigdelset(&new_set, SIGFPE); // divide by zero
sigdelset(&new_set, SIGBUS); // unaligned memory access
sigdelset(&new_set, SIGSEGV); // bad memory access
sigdelset(&new_set, SIGSTOP); // unblockable
sigdelset(&new_set, SIGKILL); // unblockable
DIE_ON_FAILURE(pthread_sigmask(SIG_BLOCK, &new_set, &saved_set));
// Spawn a thread. If this fails, it means there's already a bunch of threads; it is very

View File

@@ -179,12 +179,14 @@ void outputter_t::set_color(rgb_color_t fg, rgb_color_t bg) {
reset_modes();
}
if (!last_color2.is_normal() && !last_color2.is_reset()) {
if (!last_color2.is_special()) {
// Background was set.
// "Special" here refers to the special "normal", "reset" and "none" colors,
// that really jus disable the background.
last_bg_set = true;
}
if (!bg.is_normal()) {
if (!bg.is_special()) {
// Background is set.
bg_set = true;
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;
}
// 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.
auto reason =
this->determine_redirections(statement.args_or_redirs, allow_high_fds, &redirections);
auto reason = this->determine_redirections(statement.args_or_redirs, &redirections);
if (reason != end_execution_reason_t::ok) {
return reason;
}
// Determine the process type.
process_type = process_type_for_command(statement, cmd);
}
// 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(
const ast::argument_or_redirection_list_t &list, bool allow_high_fds,
redirection_spec_list_t *out_redirections) {
const ast::argument_or_redirection_list_t &list, redirection_spec_list_t *out_redirections) {
// Get all redirection nodes underneath the statement.
for (const ast::argument_or_redirection_t &arg_or_redir : list) {
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)};
// Validate this spec.
if (spec.mode == redirection_mode_t::fd && !spec.is_close()) {
maybe_t<int> target_fd = spec.get_target_as_fd();
if (!target_fd.has_value()) {
// Like `cmd >&gibberish`.
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);
}
if (spec.mode == redirection_mode_t::fd && !spec.is_close() && !spec.get_target_as_fd()) {
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());
}
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");
redirection_spec_list_t redirections;
auto reason =
this->determine_redirections(*args_or_redirs, false /* no high fds */, &redirections);
auto reason = this->determine_redirections(*args_or_redirs, &redirections);
if (reason == end_execution_reason_t::ok) {
proc->type = process_type_t::block_node;
proc->block_node_source = pstree;

View File

@@ -130,11 +130,7 @@ class parse_execution_context_t {
globspec_t glob_behavior);
// 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,
bool allow_high_fds,
redirection_spec_list_t *out_redirections);
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 "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.
// 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
@@ -81,36 +78,6 @@ static bool path_get_path_core(const wcstring &cmd, wcstring *out_path,
return true;
}
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;
}
// Prepare events for completed jobs, except for jobs that themselves came from event
// handlers.
if (!j->from_event_handler() && j->is_completed()) {
if (j->should_report_process_exits()) {
// Prepare events for completed jobs
if (j->is_completed()) {
// If this job already came from an event handler,
// 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();
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(
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;

View File

@@ -839,13 +839,15 @@ static void redirect_tty_after_sighup() {
}
/// Give up control of terminal.
static void term_donate() {
static void term_donate(bool quiet = false) {
while (true) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) {
if (errno == EIO) redirect_tty_output();
if (errno != EINTR) {
FLOGF(warning, _(L"Could not set terminal mode for new job"));
wperror(L"tcsetattr");
if (!quiet) {
FLOGF(warning, _(L"Could not set terminal mode for new job"));
wperror(L"tcsetattr");
}
break;
}
} else
@@ -853,9 +855,8 @@ static void term_donate() {
}
}
/// Grab control of terminal.
static void term_steal() {
// Copy the (potentially changed) terminal modes and use them from now on.
/// Copy the (potentially changed) terminal modes and use them from now on.
void term_copy_modes() {
struct termios modes;
tcgetattr(STDIN_FILENO, &modes);
std::memcpy(&tty_modes_for_external_cmds, &modes, sizeof tty_modes_for_external_cmds);
@@ -872,8 +873,11 @@ static void term_steal() {
} else {
shell_modes.c_iflag &= ~IXOFF;
}
}
/// Grab control of terminal.
void term_steal() {
term_copy_modes();
while (true) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
if (errno == EIO) redirect_tty_output();
@@ -1336,6 +1340,13 @@ void reader_init() {
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 (is_interactive_session() &&
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
// setting the COLUMNS and LINES env vars.
termsize_container_t::shared().updating(parser);
@@ -2817,14 +2828,25 @@ struct readline_loop_state_t {
/// Run a sequence of commands from an input binding.
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();
for (const wcstring &cmd : cmds) {
parser().eval(cmd, io_chain_t{});
}
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.

View File

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

View File

@@ -207,11 +207,6 @@ void signal_clear_cancel() { s_cancellation_signal = 0; }
int signal_check_cancel() { return s_cancellation_signal; }
/// Number of SIGIO events.
static volatile relaxed_atomic_t<uint32_t> s_sigio_count{0};
uint32_t signal_get_sigio_count() { return s_sigio_count; }
/// The single signal handler. By centralizing signal handling we ensure that we can never install
/// the "wrong" signal handler (see #5969).
static void fish_signal_handler(int sig, siginfo_t *info, void *context) {
@@ -276,14 +271,6 @@ static void fish_signal_handler(int sig, siginfo_t *info, void *context) {
// test, to verify that we behave correctly when receiving lots of irrelevant signals.
break;
#if defined(SIGIO)
case SIGIO:
// An async FD became readable/writable/etc.
// Don't try to look at si_code, it is not set under BSD.
// Don't use ++ to avoid a CAS.
s_sigio_count = s_sigio_count + 1;
break;
#endif
}
errno = saved_errno;
}
@@ -366,11 +353,6 @@ void signal_set_handlers(bool interactive) {
act.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &act, nullptr);
// Apply our SIGIO handler.
act.sa_sigaction = &fish_signal_handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGIO, &act, nullptr);
// Whether or not we're interactive we want SIGCHLD to not interrupt restartable syscalls.
act.sa_sigaction = &fish_signal_handler;
act.sa_flags = SA_SIGINFO | SA_RESTART;

View File

@@ -42,10 +42,6 @@ int signal_check_cancel();
/// In generaly this should only be done in interactive sessions.
void signal_clear_cancel();
/// \return a count of SIGIO signals.
/// This is used by universal variables, and is a simple unsigned counter which wraps to 0.
uint32_t signal_get_sigio_count();
enum class topic_t : uint8_t;
/// A sigint_detector_t can be used to check if a SIGINT (or SIGHUP) has been delivered.
class sigchecker_t {

View File

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

View File

@@ -400,16 +400,51 @@ wcstring path_normalize_for_cd(const wcstring &wd, const wcstring &path) {
return result;
}
wcstring wdirname(const wcstring &path) {
std::string tmp = wcs2string(path);
const char *narrow_res = dirname(&tmp[0]);
return str2wcstring(narrow_res);
wcstring wdirname(wcstring path) {
// Do not use system-provided dirname (#7837).
// On Mac it's not thread safe, and will error for paths exceeding PATH_MAX.
// This follows OpenGroup dirname recipe.
// 1: Double-slash stays.
if (path == L"//") return path;
// 2: All slashes => return slash.
if (!path.empty() && path.find_first_not_of(L'/') == wcstring::npos) return L"/";
// 3: Trim trailing slashes.
while (!path.empty() && path.back() == L'/') path.pop_back();
// 4: No slashes left => return period.
size_t last_slash = path.rfind(L'/');
if (last_slash == wcstring::npos) return L".";
// 5: Remove trailing non-slashes.
path.erase(last_slash + 1, wcstring::npos);
// 6: Skip as permitted.
// 7: Remove trailing slashes again.
while (!path.empty() && path.back() == L'/') path.pop_back();
// 8: Empty => return slash.
if (path.empty()) path = L"/";
return path;
}
wcstring wbasename(const wcstring &path) {
std::string tmp = wcs2string(path);
char *narrow_res = basename(&tmp[0]);
return str2wcstring(narrow_res);
wcstring wbasename(wcstring path) {
// This follows OpenGroup basename recipe.
// 1: empty => allowed to return ".". This is what system impls do.
if (path.empty()) return L".";
// 2: Skip as permitted.
// 3: All slashes => return slash.
if (!path.empty() && path.find_first_not_of(L'/') == wcstring::npos) return L"/";
// 4: Remove trailing slashes.
while (!path.empty() && path.back() == L'/') path.pop_back();
// 5: Remove up to and including last slash.
size_t last_slash = path.rfind(L'/');
if (last_slash != wcstring::npos) path.erase(0, last_slash + 1);
return path;
}
// Really init wgettext.

View File

@@ -75,10 +75,10 @@ bool wreaddir_resolving(DIR *dir, const std::wstring &dir_path, wcstring &out_na
bool wreaddir_for_dirs(DIR *dir, wcstring *out_name);
/// Wide character version of dirname().
std::wstring wdirname(const std::wstring &path);
std::wstring wdirname(std::wstring path);
/// Wide character version of basename().
std::wstring wbasename(const std::wstring &path);
std::wstring wbasename(std::wstring path);
/// Wide character wrapper around the gettext function. For historic reasons, unlike the real
/// gettext function, wgettext takes care of setting the correct domain, etc. using the textdomain

View File

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

View File

@@ -2,7 +2,19 @@
# Test ALL THE FISH FILES
# in share/, that is - the tests are exempt because they contain syntax errors, on purpose
for file in $__fish_data_dir/**.fish
$fish -n $file
set timestamp_file ./last_check_all_files
set -l find_args
if test -f $timestamp_file
set find_args -newer $timestamp_file
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

View File

@@ -23,9 +23,6 @@ $helper print_fds </dev/null
$helper print_fds 3</dev/null
# 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
# has the same fd as the redirection. In this case, the dup2
# 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"
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

View File

@@ -24,7 +24,7 @@ git init >/dev/null 2>&1
# 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,
# 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)
#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
# 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' &
wait
#CHECKERR: background

View File

@@ -101,3 +101,18 @@ echo $status
#CHECK: Command
#CHECK: sleep
#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 <&-
#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"
# 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
# fish is supposed to detect this case and dup the pipe to something else
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 8 <&8 8<&-" | source 8<&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 4
#CHECK: pipe 5
@@ -145,3 +123,6 @@ echo "/bin/echo pipe 9 <&9 9<&-" | source 9<&0
#CHECK: pipe 7
#CHECK: pipe 8
#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
false
set -h >/dev/null
# CHECKERR: fish: Missing man page {{.*}}
echo 8 $status # no passthrough
#CHECK: 8 0
true

View File

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

View File

@@ -713,3 +713,8 @@ end
string escape \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 '['
echo $status
# CHECK: 0
# Confirm that --quiet is still a thing
type --quiet '['
echo $status
# CHECK: 0
# Test that we print a command path
type sh

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
from pexpect_helper import SpawnedProc
import subprocess
import sys
import signal
import time
import os
sp = SpawnedProc()
send, sendline, sleep, expect_prompt, expect_re = (
sp.send,
sp.sendline,
sp.sleep,
sp.expect_prompt,
sp.expect_re,
)
# Helper to print an error and exit.
def error_and_exit(text):
keys = sp.colors()
print("{RED}Test failed: {NORMAL}{TEXT}".format(TEXT=text, **keys))
sys.exit(1)
fish_pid = sp.spawn.pid
# Launch fish_test_helper.
expect_prompt()
exe_path = os.environ.get("fish_test_helper")
sp.sendline(exe_path + " nohup_wait")
# We expect it to transfer tty ownership to fish_test_helper.
sleep(0.1)
tty_owner = os.tcgetpgrp(sp.spawn.child_fd)
if fish_pid == tty_owner:
os.kill(fish_pid, signal.SIGKILL)
error_and_exit(
"Test failed: outer fish %d did not transfer tty owner to fish_test_helper"
% (fish_pid)
)
# Now we are going to tell fish to exit.
# It must not hang. But it might hang when trying to restore the tty.
os.kill(fish_pid, signal.SIGTERM)
# Loop a bit until the process exits (correct) or stops (incorrrect).
# When it exits it should be due to the SIGTERM that we sent it.
for i in range(10):
pid, status = os.waitpid(fish_pid, os.WUNTRACED | os.WNOHANG)
if pid == 0:
# No process ready yet, loop again.
sleep(0.1)
elif pid != fish_pid:
# Some other process exited (??)
os.kill(fish_pid, signal.SIGKILL)
error_and_exit(
"unexpected pid returned from waitpid. Got %d, expected %d"
% (pid, fish_pid)
)
elif os.WIFSTOPPED(status):
# Our pid stopped instead of exiting.
# Probably it stopped because of its tcsetpgrp call during exit.
# Kill it and report a failure.
os.kill(fish_pid, signal.SIGKILL)
error_and_exit("pid %d stopped instead of exiting on SIGTERM" % pid)
elif not os.WIFSIGNALED(status):
error_and_exit("pid %d did not signal-exit" % pid)
elif os.WTERMSIG(status) != signal.SIGTERM:
error_and_exit(
"pid %d signal-exited with %d instead of %d (SIGTERM)"
% (os.WTERMSIG(status), signal.SIGTERM)
)
else:
# Success!
sys.exit(0)
else:
# Our loop completed without the process being returned.
error_and_exit("fish with pid %d hung after SIGTERM" % fish_pid)
# Should never get here.
error_and_exit("unknown, should be unreachable")

View File

@@ -35,9 +35,10 @@ expect_str("bryellow")
expect_str("cyan")
expect_str("green")
expect_str("magenta")
expect_str("\x1b[31mred")
expect_str("\x1b[37mwhite")
expect_str("\x1b[33myellow")
# These should be anchored at the beginning of the line, no e.g. bold sequence before.
expect_str("\n\x1b[31mred")
expect_str("\n\x1b[37mwhite")
expect_str("\n\x1b[33myellow")
expect_str("normal")
expect_prompt()
@@ -60,3 +61,24 @@ expect_str("white")
expect_str("yellow")
expect_str("normal")
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()