Keeps the location of original function definition, and also stores
where it was copied. `functions` and `type` show both locations,
instead of none. It also retains the line numbers in the stack trace.
This keeps tripping people up. We can't mention it *everywhere*, but
lets see if it works just in "match", since that sees to be where
people hit it most.
This allows linking them from elsewhere (currently fish_indent) and
also improves the formatting - the code formatting here isn't actually a good look.
This now means `abbr --add` has two modes:
```fish
abbr --add name --function foo --regex regex
```
```fish
abbr --add name --regex regex replacement
```
This is because `--function` was seen to be confusing as a boolean flag.
This committed the sin of introducing a concept by giving it two
names:
> An alias, or wrapper, around ``ls`` might look like this
The term "wrapper" doesn't pull its weight here. It's simpler to just
call them aliases throughout. We do use "a simple wrapping function"
in another place, but that's to define "alias", not as a separate name.
Also default the marker to '%'. So you may write:
abbr -a L --position anywhere --set-cursor "% | less"
or set an explicit marker:
abbr -a L --position anywhere --set-cursor=! "! | less"
This renames abbreviation triggers from `--trigger-on entry` and
`--trigger-on exec` to `--on-space` and `--on-enter`. These names are less
precise, as abbreviations trigger on any character that terminates a word
or any key binding that triggers exec, but they're also more human friendly
and that's a better tradeoff.
Prior to this change, abbreviations were stored as fish variables, often
universal. However we intend to add additional features to abbreviations
which would be very awkward to shoe-horn into variables.
Re-implement abbreviations using a builtin, managing them internally.
Existing abbreviations stored in universal variables are still imported,
for compatibility. However new abbreviations will need to be added to a
function. A follow-up commit will add it.
Now that abbr is a built-in, remove the abbr function; but leave the
abbr.fish file so that stale files from past installs do not override
the abbr builtin.
It reads nicer to not have the "see also" thing right in the first
paragraph. I'm not even done reading this, why are you sending me
elsewhere?
(of course if it's a hotlink on a specific word that's different)
It's fine if it doesn't show up in the synopsis above, but putting it
under "Notes" is just too awkward.
It's a short option that exists, and so it should be documented.
I tried to make the synopsis a little less theoretical with
the placeholders and instead introduced the actual scope
options, long and short once, then refer to them as -Uflg from
then on.
I mentioned that list indicies are accepted / work to erase stuff.
In the list of options, we pretend like --unexport is long-only.
Especially with --unpath and --path, and what would go wrong
if one confused it with --univeral, and how rarely it's used,
I think it's better this way. I mention it as a synonym later
in the document so that it's not literally undocumented.
Changed phrasing such as:
"Causes the specified shell variable to be given a global scope"
Which can be read as we are taking a shell variable that exists
and giving it global scope, upgrading it to global (retaining
the value).
Redid the example section using the > syntax for things entered
into a prompt, with shell output following. The explanatory
Added in missing newlines at the ends of sentences.
I'm not sure if line continuations are covered anywhere else in the docs, but I
think the escapes section of the language page is a good place to mention them.
Makes it possible to retrieve the currently executing command line as
opposed to the currently executing command (`status current-command`).
Closes#8905.
- Clean up the wording a little.
- Highlight the limitations of the "debugger" more clearly and don't mislead
people into thinking it's possible to really interactively set/remove
breakpoints except in select circumstances.
Sidenote: I can't believe we're using a markup language that doesn't support
nested inline markup. What a crying shame, rST!
Up to now, in normal locales \x was essentially the same as \X, except
that it errored if given a value > 0x7f.
That's kind of annoying and useless.
A subtle change is that `\xHH` now represents the character (if any)
encoded by the byte value "HH", so even for values <= 0x7f if that's
not the same as the ASCII value we would diverge.
I do not believe anyone has ever run fish on a system where that
distinction matters. It isn't a thing for UTF-8, it isn't a thing for
ASCII, it isn't a thing for UTF-16, it isn't a thing for any extended
ASCII scheme - ISO8859-X, it isn't a thing for SHIFT-JIS.
I am reasonably certain we are making that same assumption in other
places.
Fixes#1352
There are many applications with "primitive" argument parsing capabalities that
cannot handle munging two short options together (`-xf` for `-x -f`) or a short
option and its required value (`-dall` for `-d all`). To prevent fish from
suggesting munged arguments/payloads, the options (both long and short, not just
long!) can be specified as `-o` or `--old-option` but none of this is
documented.
Hyphenation in our documentation is aggressive, even to the point of caus-
ing options themselves to be broken across lines. This makes the document-
ation hard to read, especially when you have an option like `string colle-
ct` which gets a weird hyphen.
Remove the hyphenation from the CSS.
This makes it so we link to the very top of the document instead of a
special anchor we manually include.
So clicking e.g. :doc:`string <cmds/string>` will link you to
cmds/string.html instead of cmds/string.html#cmd-string.
I would love to have a way to say "this document from the root of the
document path", but that doesn't appear to work, I tried
`/cmds/string`.
So we'll just have to use cmds/string in normal documents and plain
`string` from other commands.
This is essentially the inverse of `string pad`.
Where that adds characters to get up to the specified width,
this adds an ellipsis to a string if it goes over a specific maximum width.
The char can be given, but defaults to our ellipsis string.
("…" if the locale can handle it and "..." otherwise)
If the ellipsis string is empty, it just truncates.
For arguments given via argv, it goes line-by-line,
because otherwise length makes no sense.
If "--no-newline" is given, it adds an ellipsis instead and removes all subsequent lines.
Like pad and `length --visible`, it goes by visible width,
skipping recognized escape sequences, as those have no influence on width.
The default target width is the shortest of the given widths that is non-zero.
If the ellipsis is already wider than the target width,
we truncate instead. This is safer overall, so we don't e.g. move into a new line.
This is especially important given our default ellipsis might be width 3.
This was written while we changed how our synopses are formatted, so
we missed adding a "synopsis" marker to it.
The tokenizer here is a bit cheesy, so we can't mark continuation
lines with a "\", and we also can't mark the general options with a
":=". Tbh that's not a big deal.
Fixes#9154
Note that every change to the search field still starts a new search, from
the end of history. We could change this in future but it's unclear to me
what the expected behavior is. I don't find the traditional readline behavior
very intuitive.
This reimplements ridiculousfish/control_r which is a more future-proof
approach than #6686.
Pressing Control+R shows history in our pager and allows to search filter
commands with the pager search field.
On the surface, this works just like in other shells; though there are
some differences.
- Our pager shows multiple results at a time.
- Other shells allow to use up arrow/down arrow to select adjacent entries
in history. Shouldn't be hard to implement but the hidden state might
confuse users and it doesn't play well with up-or-search, so this is
left out.
Users might expect the history pager to use subsequence matching (fuzzy
matching) like the completion pager, however due to the history pager design it
uses substring matching. We could change this in future, however that means
we would also want to change the ordering from "reverse-chronological" to
"longest common subsequence" (e.g. what fuzzy finders do), because otherwise
a query "fis" might give this ordering:
fsck /dev/disk/by-partlabel/Linux\x20filesystem
fish
which is probably not what the user wants.
The pager shows only a small number of history items at a time. This is
because, as explained above, the history pager does not support subsequence
matching, so navigating it does not scale well.
Closes#602
PR #6777 changed all the keys to uppercase, but many Vi commands are case
sensitive.
PR #7908 changed the "u" binding but the documentation still had the old
meaning.
This can be used to print the modification time, like `stat` with some
options.
The reason is that `stat` has caused us a number of portability
headaches:
1. It's not available everywhere by default
2. The versions are quite different
For instance, with GNU stat it's `stat -c '%Y'`, with macOS it's `stat
-f %m`.
So now checking a cache file can be done just with builtins.
It's still useful without, for instance to implement a command that
takes no options, or to check min-args or max-args.
(technically no optspecs, no min/max args and --ignore-unknown does
nothing, but that's a very specific error that we don't need to forbid)
Fixes#9006
This enhances our documentation to look for the file
/release_version.json in the root of our site. If found, and if it
contains a RELEASE_VERSION other than this version, then unhide a banner
warning about the stale documentation and linking to the current.
Unlike before, this doesn't force the number to be on the same line as
strongly, that's fine.
So short footnotes look like
-------------
[1] Some text
-------------
Longer footnotes may look like
--------------
[2]
Some more text
--------------
The "Warning:" on the warning (in index.html#default shell) wasn't in
the line with the text, the features list had more padding and some
headers were smaller, some table stuff
This has required workarounds a few times, plus if it changes it might
break our theme. See e.g.
4712da3eb1e27456df24a6d484836e85522036f5
So we import the rules we *use* and throw away the rest. Note that
this might still have rules that are no longer necessary - e.g. some
that are required to work around sphinx bugs would still be left.
It could benefit from some cleanup and simplification, and from
switching to a flex layout instead of the 230px hardcoded
sidebar - sphinx tried that, but it doesn't really work with our
narrow layout, so we disabled it again.
This makes it so
1. The informative status can work without showing untracked
files (previously it was disabled if bash.showUntrackedFiles was
false)
2. If untrackedfiles isn't explicitly enabled, we use -uno, so git
doesn't have to scan all the files.
In a large repository (like the FreeBSD ports repo), this can improve
performance by a factor of 5 or up.
Previously, `kill-whole-line` kills the line and its following
newline. This is insufficient when we are on the last line, because
it would not actually clear the line. The cursor would stay on the
line, which is not the correct behavior for bindings like `dd`.
Also, `cc` in vi-mode used `kill-whole-line`, which is not correct
because it should not remove any newlines. We have to introduce
another special input function (`kill-inner-line`) to fix this.
This is broken in narrow screens - the sidebar shrinks to unusable
proportions but still stays.
So instead we go the *other* way, force the left margin and undo the flexifying.
(again we should really stop relying on sphinx' css)
Sphinx 5.0 makes the document div a flex container, which clashes
badly with the margin that earlier versions need.
So we remove the margin and flex the div ourselves, which should work
with either.
It's time we make this freestanding - these changes are annoying.
This makes it so `complete -c foo -n test1 -n test2` registers *both*
conditions, and when it comes time to check the candidate, tries both,
in that order. If any fails it stops, if all succeed the completion is offered.
The reason for this is that it helps with caching - we have a
condition cache, but conditions like
```fish
test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] length
test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] sub
```
defeats it pretty easily, because the cache only looks at the entire
script as a string - it can't tell that the first `test` is the same
in both.
So this means we separate it into
```fish
complete -f -c string -n "test (count (commandline -opc)) -ge 2; and contains -- (commandline -opc)[2] length" -s V -l visible -d "Use the visible width, excluding escape sequences"
+complete -f -c string -n "test (count (commandline -opc)) -ge 2" -n "contains -- (commandline -opc)[2] length" -s V -l visible -d "Use the visible width, excluding escape sequences"
```
which allows the `test` to be cached.
In tests, this improves performance for the string completions by 30%
by reducing all the redundant `test` calls.
The `git` completions can also greatly benefit from this.
This adds a path builtin to deal with paths.
It offers the following subcommands:
filter to go through a list of paths and only print the ones that pass some filter - exist, are a directory, have read permission, ...
is as a shortcut for filter -q to only return true if one of the paths passed the filter
basename, dirname and extension to print certain parts of the path
change-extension to change the extension to a different one (as a string operation)
normalize and resolve to canonicalize the paths in various flavors
sort to sort paths, also only using the basename or dirname as a key
The definition of "extension" here was carefully considered and should line up with how extensions are actually used - ~/.bashrc doesn't have an extension, but ~/.conf.d does (".d").
These subcommands all compose well - they can read from arguments or stdin (like string), they can use null-delimited input or output (input is autodetected - if a NULL happens in the first PATH_MAX bytes it switches automatically).
It is both a failglob exception (so like set if a glob passed to it fails it just doesn't get any arguments for it instead of triggering an error), and passes output to command substitution buffers explicitly split (like string split0) so newlines are easy to handle.
This is now added to the two commands that definitely deal with
relative paths.
It doesn't work for e.g. `path basename`, because after removing the
dirname prepending a "./" doesn't refer to the same file, and the
basename is also expected to not contain any slashes.
This includes the "." in what `path extension` prints.
This allows distinguishing between an empty extension (just `.`) and a
non-existent extension (no `.` at all).
These are short flags for "--perm=read" and "--type=link" and such.
Not every type or permission has a shorthand - we don't want "-s" for
"suid". So just the big three each get one.
This is theoretically sound, because a path can only be PATH_MAX - 1
bytes long, so at least the PATH_MAXest byte needs to be a NULL.
The one case this could break is when something has a NULL-output mode
but doesn't bother printing the NULL for only one path, and that path
contains a newline. So we leave --null-in there, to force it on.
This adds a "path" builtin that can handle paths.
Implemented so far:
- "path filter PATHS", filters paths according to existence and optionally type and permissions
- "path base" and "path dir", run basename and dirname, respectively
- "path extension PATHS", prints the extension, if any
- "path strip-extension", prints the path without the extension
- "path normalize PATHS", normalizes paths - removing "/./" components
- and such.
- "path real", does realpath - i.e. normalizing *and* link resolution.
Some of these - base, dir, {strip-,}extension and normalize operate on the paths only as strings, so they handle nonexistent paths. filter and real ignore any nonexistent paths.
All output is split explicitly, so paths with newlines in them are
handled correctly. Alternatively, all subcommands have a "--null-input"/"-z" and "--null-output"/"-Z" option to handle null-terminated input and create null-terminated output. So
find . -print0 | path base -z
prints the basename of all files in the current directory,
recursively.
With "-Z" it also prints it null-separated.
(if stdout is going to a command substitution, we probably want to
skip this)
All subcommands also have a "-q"/"--quiet" flag that tells them to skip output. They return true "when something happened". For match/filter that's when a file passed, for "base"/"dir"/"extension"/"strip-extension" that's when something about the path *changed*.
Filtering
---------
`filter` supports all the file*types* `test` has - "dir", "file", "link", "block"..., as well as the permissions - "read", "write", "exec" and things like "suid".
It is missing the tty check and the check for the file being non-empty. The former is best done via `isatty`, the latter I don't think I've ever seen used.
There currently is no way to only get "real" files, i.e. ignore links pointing to files.
Examples
--------
> path real /bin///sh
/usr/bin/bash
> path extension foo.mp4
mp4
> path extension ~/.config
(nothing, because ".config" isn't an extension.)
This teaches `--on-signal SIGINT` (and by extension `trap cmd SIGINT`)
to work properly in scripts, not just interactively. Note any such
function will suppress the default behavior of exiting. Do this for
SIGTERM as well.
With sphinx 4.5.0:
1. Some of our builtins actually give results (cd, end, set)
2. Some give broken results (and, if, or)
3. Only "for" even triggers the help page we hacked in
So this is of dubious use, and removing it gets us out of the awkward situation of shipping it.
Plus upstream sphinx has ditched jquery, so we would have to rewrite it anyway.