2021-10-23 22:46:15 +08:00
.. _cmd-fish_command_not_found:
Call "fish_command_not_found" if a command wasn't found
Previously, when a command wasn't found, fish would emit the
"fish_command_not_found" *event*.
This was annoying as it was hard to override (the code ended up
checking for a function called `__fish_command_not_found_handler`
anyway!), the setup was ugly,
and it's useless - there is no use case for multiple command-not-found handlers.
Instead, let's just call a function `fish_command_not_found` if it
exists, or print the default message otherwise.
The event is completely removed, but because a missing event is not an error
(MEISNAE in C++-speak) this isn't an issue.
Note that, for backwards-compatibility, we still keep the default
handler function around even tho the new one is hard-coded in C++.
Also, if we detect a previous handler, the new handler just calls it.
This way, the backwards-compatible way to install a custom handler is:
```fish
function __fish_command_not_found_handler --on-event fish_command_not_found
# do a little dance, make a little love, get down tonight
end
```
and the new hotness is
```fish
function fish_command_not_found
# do the thing
end
```
Fixes #7293.
2020-08-30 03:54:13 +08:00
fish_command_not_found - what to do when a command wasn't found
===============================================================
Synopsis
--------
docs synopsis: add HTML highlighing and automate manpage markup
Recent synopsis changes move from literal code blocks to
[RST line blocks]. This does not translate well to HTML: it's not
rendered in monospace, so aligment is lost. Additionally, we don't
get syntax highlighting in HTML, which adds differences to our code
samples which are highlighted.
We hard-wrap synopsis lines (like code blocks). To align continuation
lines in manpages we need [backslashes in weird places]. Combined with
the **, *, and `` markup, it's a bit hard to get the alignment right.
Fix these by moving synopsis sources back to code blocks and compute
HTML syntax highlighting and manpage markup with a custom Sphinx
extension.
The new Pygments lexer can tokenize a synopsis and assign the various
highlighting roles, which closely matches fish's syntax highlighing:
- command/keyword (dark blue)
- parameter (light blue)
- operator like and/or/not/&&/|| (cyan)
- grammar metacharacter (black)
For manpage output, we don't project the fish syntax highlighting
but follow the markup convention in GNU's man(1):
bold text type exactly as shown.
italic text replace with appropriate argument.
To make it easy to separate these two automatically, formalize that
(italic) placeholders must be uppercase; while all lowercase text is
interpreted literally (so rendered bold).
This makes manpages more consistent, see string-join(1) and and(1).
Implementation notes:
Since we want manpage formatting but Sphinx's Pygments highlighing
plugin does not support manpage output, add our custom "synopsis"
directive. This directive parses differently when manpage output is
specified. This means that the HTML and manpage build processes must
not share a cache, because the parsed doctrees are cached. Work around
this by using separate cache locations for build targets "sphinx-docs"
(which creates HTML) and "sphinx-manpages". A better solution would
be to only override Sphinx's ManualPageBuilder but that would take a
bit more code (ideally we could override ManualPageWriter but Sphinx
4.3.2 doesn't really support that).
---
Alternative solution: stick with line blocks but use roles like
:command: or :option: (or custom ones). While this would make it
possible to produce HTML that is consistent with code blocks (by adding
a bit of CSS), the source would look uglier and is harder to maintain.
(Let's say we want to add custom formatting to the [|] metacharacters
in HTML. This is much easier with the proposed patch.)
---
[RST line blocks]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#line-blocks
[backslashes in weird places]: https://github.com/fish-shell/fish-shell/pull/8626#discussion_r782837750
2022-01-09 22:09:46 +08:00
.. synopsis ::
function fish_command_not_found
...
end
Call "fish_command_not_found" if a command wasn't found
Previously, when a command wasn't found, fish would emit the
"fish_command_not_found" *event*.
This was annoying as it was hard to override (the code ended up
checking for a function called `__fish_command_not_found_handler`
anyway!), the setup was ugly,
and it's useless - there is no use case for multiple command-not-found handlers.
Instead, let's just call a function `fish_command_not_found` if it
exists, or print the default message otherwise.
The event is completely removed, but because a missing event is not an error
(MEISNAE in C++-speak) this isn't an issue.
Note that, for backwards-compatibility, we still keep the default
handler function around even tho the new one is hard-coded in C++.
Also, if we detect a previous handler, the new handler just calls it.
This way, the backwards-compatible way to install a custom handler is:
```fish
function __fish_command_not_found_handler --on-event fish_command_not_found
# do a little dance, make a little love, get down tonight
end
```
and the new hotness is
```fish
function fish_command_not_found
# do the thing
end
```
Fixes #7293.
2020-08-30 03:54:13 +08:00
Description
-----------
When fish tries to execute a command and can't find it, it invokes this function.
It can print a message to tell you about it, and it often also checks for a missing package that would include the command.
Fish ships multiple handlers for various operating systems and chooses from them when this function is loaded,
or you can define your own.
It receives the full commandline as one argument per token, so $argv[1] contains the missing command.
When you leave `` fish_command_not_found `` undefined (e.g. by adding an empty function file) or explicitly call `` __fish_default_command_not_found_handler `` , fish will just print a simple error.
Example
-------
A simple handler:
::
function fish_command_not_found
echo Did not find command $argv[1]
end
> flounder
Did not find command flounder
Or the handler for OpenSUSE's command-not-found::
function fish_command_not_found
/usr/bin/command-not-found $argv[1]
end
Or the simple default handler::
function fish_command_not_found
__fish_default_command_not_found_handler $argv
end
Backwards compatibility
-----------------------
This command was introduced in fish 3.2.0. Previous versions of fish used the "fish_command_not_found" :ref: `event <event>` instead.
To define a handler that works in older versions of fish as well, define it the old way::
function __fish_command_not_found_handler --on-event fish_command_not_found
echo COMMAND WAS NOT FOUND MY FRIEND $argv[1]
end
in which case fish will define a `` fish_command_not_found `` that calls it,
or define a wrapper::
function fish_command_not_found
echo "G'day mate, could not find your command: $argv"
end
function __fish_command_not_found_handler --on-event fish_command_not_found
fish_command_not_found $argv
end