fish-shell/share/functions/help.fish
Fabian Homborg d5cba5fe12 Teach help to pick the correct page
Given that we no longer have that massive "index" page with
everything, it's become harder to open the correct section
immediately.

So this hardcodes the section titles for each page in help itself.

This was half-automated with

grep -o 'a class="headerlink" href="#[^"]*"' /usr/share/doc/fish/faq.html | sort -u | string replace -r '.*#' '' | string trim -c '"'

The completions still need to be adjusted.
2021-03-30 17:14:14 +02:00

271 lines
13 KiB
Fish

function help --description 'Show help for the fish shell'
set -l options h/help
argparse -n help $options -- $argv
or return
if set -q _flag_help
__fish_print_help help
return 0
end
set -l fish_help_item $argv[1]
if test (count $argv) -gt 1
if string match -q string $argv[1]
set fish_help_item (string join '-' $argv[1] $argv[2])
else
echo "help: Expected at most 1 args, got 2"
return 1
end
end
# Find a suitable browser for viewing the help pages.
# The first thing we try is $fish_help_browser.
set -l fish_browser $fish_help_browser
# A list of graphical browsers we know about.
set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla
set -a graphical_browsers konqueror epiphany opera netscape rekonq google-chrome chromium-browser
# On mac we may have to write a temporary file that redirects to the desired
# help page, since `open` will drop fragments from file URIs (issue #4480).
set -l need_trampoline
if not set -q fish_browser[1]
if set -q BROWSER
# User has manually set a preferred browser, so we respect that
echo $BROWSER | read -at fish_browser
else
# No browser set up, inferring.
# We check a bunch and use the last we find.
# Check for a text-based browser.
for i in htmlview www-browser links elinks lynx w3m
if type -q -f $i
set fish_browser $i
break
end
end
# If we are in a graphical environment, check if there is a graphical
# browser to use instead.
if test -n "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
for i in $graphical_browsers
if type -q -f $i
set fish_browser $i
break
end
end
end
# If we have an open _command_ we use it - otherwise it's our function,
# which might not have a backend to use.
# Note that we prefer xdg-open, because this open might also be a symlink to "openvt"
# like it is on Debian.
if command -sq open
set fish_browser open
# The open command needs a trampoline because the macOS version can't handle #-fragments.
set need_trampoline 1
end
# If the OS appears to be Windows (graphical), try to use cygstart
if type -q cygstart
set fish_browser cygstart
# If xdg-open is available, just use that
else if type -q xdg-open
set fish_browser xdg-open
end
# Try to find cmd.exe via $PATH or one of the paths that it's often at.
#
# We use this instead of xdg-open because that's useless without a backend
# like wsl-open which we'll check in a minute.
if test -f /proc/version
and string match -riq 'Microsoft|WSL|MSYS|MINGW' </proc/version
and set -l cmd (command -s cmd.exe /mnt/c/Windows/System32/cmd.exe)
# Use the first of these.
set fish_browser $cmd[1]
end
if type -q wsl-open
set fish_browser wsl-open
end
end
end
if not set -q fish_browser[1]
printf (_ '%s: Could not find a web browser.\n') help
printf (_ 'Please try `BROWSER=some_browser help`, `man fish-doc`, or `man fish-tutorial`.\n\n')
return 1
end
# In Cygwin, start the user-specified browser using cygstart,
# only if a Windows browser is to be used.
if type -q cygstart
if test $fish_browser != cygstart
and not command -sq $fish_browser[1]
# Escaped quotes are necessary to work with spaces in the path
# when the command is finally eval'd.
set fish_browser cygstart $fish_browser
else
set need_trampoline 1
end
end
# HACK: Hardcode all section titles for each page.
# This could possibly be automated.
# All sections in "language.html"
set -l langpages argument-handling autoloading-functions brace-expansion \
builtin-commands combining-different-expansions combining-lists-cartesian-product \
command-substitution comments conditions defining-aliases escaping-characters expand exporting-variables \
functions home-directory-expansion index-range-expansion input-output-redirection job-control lists \
loops-and-blocks more-on-universal-variables overriding-variables-for-a-single-command pager-color-variables \
path-variables piping quotes shell-variable-and-function-names \
shell-variables special-variables syntax-highlighting-variables syntax-overview \
terminology the-fish-language the-status-variable variable-expansion \
variable-scope variable-scope-for-functions variables-locale wildcards-globbing
# All sections in "interactive.html"
set -l interactivepages abbreviations autosuggestions command-line-editor configurable-greeting \
copy-and-paste-kill-ring custom-bindings directory-stack emacs-mode-commands \
help interactive-use multiline-editing navigating-directories private-mode \
programmable-prompt programmable-title searchable-command-history shared-bindings \
syntax-highlighting tab-completion vi-mode-command vi-mode-commands \
vi-mode-insert vi-mode-visual
set -l for_bash_pages arithmetic-expansion blocks-and-loops builtins-and-other-commands \
command-substitutions fish-for-bash-users heredocs process-substitution prompts \
quoting special-variables string-manipulation test-test variables wildcards-globs
set -l faqpages frequently-asked-questions how-can-i-use-as-a-shortcut-for-cd \
how-do-i-change-the-greeting-message how-do-i-check-whether-a-variable-is-defined \
how-do-i-check-whether-a-variable-is-not-empty how-do-i-customize-my-syntax-highlighting-colors \
how-do-i-get-the-exit-status-of-a-command how-do-i-make-fish-my-default-shell \
how-do-i-run-a-command-every-login-what-s-fish-s-equivalent-to-bashrc-or-profile how-do-i-run-a-command-from-history \
how-do-i-run-a-subcommand-the-backtick-doesn-t-work how-do-i-set-my-prompt \
how-do-i-set-or-clear-an-environment-variable i-accidentally-entered-a-directory-path-and-fish-changed-directory-what-happened \
i-m-getting-weird-graphical-glitches-a-staircase-effect-ghost-characters i-m-seeing-weird-output-before-each-prompt-when-using-screen-what-s-wrong \
my-command-pkg-config-gives-its-output-as-a-single-long-string my-command-prints-no-matches-for-wildcard-but-works-in-bash \
the-open-command-doesn-t-work uninstalling-fish \
what-is-the-equivalent-to-this-thing-from-bash-or-other-shells where-can-i-find-extra-tools-for-fish \
why-does-my-prompt-show-a-i why-doesn-t-history-substitution-etc-work \
why-doesn-t-set-ux-exported-universal-variables-seem-to-work why-won-t-ssh-scp-rsync-connect-properly-when-fish-is-my-login-shell
set -l fish_help_page
switch "$fish_help_item"
case "."
set fish_help_page "cmds/source.html"
case globbing
set fish_help_page "language.html#expand"
case (builtin -n) (__fish_print_commands)
# If the docs aren't installed, __fish_print_commands won't print anything
# Since we document all our builtins, check those at least.
# The alternative is to create this list at build time.
set fish_help_page "cmds/$fish_help_item.html"
case 'completion-*'
set fish_help_page "completions.html#$fish_help_item"
case 'tut-*'
set fish_help_page "tutorial.html#"(string sub -s 5 -- $fish_help_item | string replace -a -- _ -)
case tutorial
set fish_help_page "tutorial.html"
case releasenotes
set fish_help_page relnotes.html
case completions
set fish_help_page completions.html
case faq
set fish_help_page faq.html
case fish-for-bash-users
set fish_help_page fish_for_bash_users.html
case $faqpages
set fish_help_page "faq.html#$fish_help_item"
case $for_bash_pages
set fish_help_page "fish_for_bash_users.html#$fish_help_item"
case $langpages
set fish_help_page "language.html#$fish_help_item"
case $interactivepages
set fish_help_page "interactive.html#$fish_help_item"
case ''
set fish_help_page "index.html"
case "*"
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; 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
# but only if a Windows browser is being used
if type -q cygpath
and string match -qr '(cygstart|\.exe)(\s+|$)' $fish_browser[1]
set page_url file://(cygpath -m $__fish_help_dir)/$fish_help_page
else if type -q wslpath
and string match -qr '\.exe(\s+|$)' $fish_browser[1]
set page_url file://(wslpath -w $__fish_help_dir)/$fish_help_page
end
else
# Go to the web. Only include one dot in the version string
set -l version_string (string split . -f 1,2 -- $version | string join .)
set page_url https://fishshell.com/docs/$version_string/$fish_help_page
# We don't need a trampoline for a remote URL.
set need_trampoline
end
if set -q need_trampoline[1]
# If string replace doesn't replace anything, we don't actually need a
# trampoline (they're only needed if there's a fragment in the path)
if set -l clean_url (string match -re '#' $page_url)
# Write a temporary file that will redirect where we want.
set -q TMPDIR
or set -l TMPDIR /tmp
set -l tmpdir (mktemp -d $TMPDIR/help.XXXXXX)
or return 1
set -l tmpname $tmpdir/help.html
echo '<meta http-equiv="refresh" content="0;URL=\''$clean_url'\'" />' >$tmpname
set page_url file://$tmpname
# 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]
set page_url file://(cygpath -m $tmpname)
else if type -q wslpath
and string match -qr '\.exe(\s+|$)' $fish_browser[1]
set page_url file://(wslpath -w $tmpname)
end
end
end
# cmd.exe needs more coaxing.
if string match -qr 'cmd\.exe$' -- $fish_browser[1]
# The space before the /c is to prevent msys2 from expanding it to a path
$fish_browser " /c" start $page_url
# If browser is known to be graphical, put into background
else if contains -- $fish_browser[1] $graphical_browsers
switch $fish_browser[1]
case htmlview x-www-browser
printf (_ 'help: Help is being displayed in your default browser.\n')
case '*'
printf (_ 'help: Help is being displayed in %s.\n') $fish_browser[1]
end
$fish_browser $page_url &
disown $last_pid >/dev/null 2>&1
else
# Work around lynx bug where <div class="contents"> always has the same formatting as links (unreadable)
# by using a custom style sheet. See https://github.com/fish-shell/fish-shell/issues/4170
if string match -qr '^lynx' -- $fish_browser
set fish_browser $fish_browser -lss={$__fish_data_dir}/lynx.lss
end
$fish_browser $page_url
end
end