mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-22 15:37:59 +08:00
Rewrite __fish_print_help to produce better results
As a result of this rewrite, the output now: * Expands to fit the terminal width, like `man` does * Preprocesses the manpage with `tbl` just in case, since `man` does this, even though I doubt any fish manpages use `tbl` formatting. * Handle bold/underline with the `ul` command as it was designed for instead of trying to fake it with `sed`. * Compresses blank lines as `man` does with the default `less -is` pager.
This commit is contained in:
parent
cc7f1755aa
commit
ac8c5910eb
|
@ -1,12 +1,6 @@
|
|||
|
||||
function __fish_print_help --description "Print help message for the specified fish function or builtin" --argument item
|
||||
|
||||
switch $argv[1]
|
||||
case '.'
|
||||
if test "$item" = '.'
|
||||
set item source
|
||||
|
||||
case '*'
|
||||
set item $argv[1]
|
||||
end
|
||||
|
||||
# Do nothing if the file does not exist
|
||||
|
@ -14,27 +8,81 @@ function __fish_print_help --description "Print help message for the specified f
|
|||
return
|
||||
end
|
||||
|
||||
# These two expressions take care of underlines (Should be italic)
|
||||
set -l cmd1 s/_\x08'\(.\)'/(set_color --underline)\\1(set_color normal)/g
|
||||
set -l cmd2 s/'\(.\)'\x08_/(set_color --underline)\\1(set_color normal)/g
|
||||
|
||||
# This expression should take care of bold characters. It's not
|
||||
# waterproof, since it doesn't check that the same character is
|
||||
# used both before and after the backspace, since regular
|
||||
# languages don't allow backreferences.
|
||||
set -l cmd3 s/.\x08'\(.\)'/(set_color --bold)\\1(set_color normal)/g
|
||||
|
||||
# Combine all expressions in a single variable
|
||||
set -l sed_cmd -e $cmd1 -e $cmd2 -e $cmd3
|
||||
set -l IFS \n\ \t
|
||||
|
||||
# Render help output, save output into the variable 'help'
|
||||
set -l help (nroff -man "$__fish_datadir/man/man1/$item.1" ^ /dev/null )
|
||||
set -l lines (count $help)
|
||||
set -l help
|
||||
set -l rLL
|
||||
if command test -t 1
|
||||
# We want to simulate `man`'s dynamic line length, because
|
||||
# defaulting to 80 kind of sucks.
|
||||
# Note: using `command test` instead of `test` because `test -t 1`
|
||||
# doesn't seem to work right.
|
||||
# Note: grab the size from the stdout terminal in case it's somehow
|
||||
# different than the stdin of fish.
|
||||
set -l cols
|
||||
begin
|
||||
# use fd 3 to copy our stdout because we need to pipe the output of stty
|
||||
stty size 0<&3 | read _ cols
|
||||
end 3<&1
|
||||
set cols (expr $cols - 4) # leave a bit of space on the right
|
||||
set rLL -rLL=$cols[1]n
|
||||
end
|
||||
set help (nroff -man -t $rLL "$__fish_datadir/man/man1/$item.1" ^/dev/null)
|
||||
|
||||
# Print an empty line first
|
||||
echo
|
||||
|
||||
# Filter and print help
|
||||
printf "%s\n" $help| tail -n (expr $lines - 5) | head -n (expr $lines - 8) | sed $sed_cmd
|
||||
# The original implementation trimmed off the top 5 lines and bottom 3 lines
|
||||
# from the nroff output. Perhaps that's reliable, but the magic numbers make
|
||||
# me extremely nervous. Instead, let's just strip out any lines that start
|
||||
# in the first column. "normal" manpages put all section headers in the first
|
||||
# column, but fish manpages only leave NAME like that, which we want to trim
|
||||
# away anyway.
|
||||
#
|
||||
# While we're at it, let's compress sequences of blank lines down to a single
|
||||
# blank line, to duplicate the default behavior of `man`, or more accurately,
|
||||
# the `-s` flag to `less` that `man` passes.
|
||||
set -l state blank
|
||||
for line in $help
|
||||
# categorize the line
|
||||
set -l line_type
|
||||
switch $line
|
||||
case ' *' \t\*
|
||||
# starts with whitespace, check if it has non-whitespace
|
||||
printf "%s\n" $line | read -l word _
|
||||
if test -n $word
|
||||
set line_type normal
|
||||
else
|
||||
# lines with just spaces probably shouldn't happen
|
||||
# but let's consider them to be blank
|
||||
set line_type blank
|
||||
end
|
||||
case ''
|
||||
set line_type blank
|
||||
case '*'
|
||||
# not leading space, and not empty, so must contain a non-space
|
||||
# in the first column. That makes it a header/footer.
|
||||
set line_type meta
|
||||
end
|
||||
|
||||
switch $state
|
||||
case normal
|
||||
switch $line_type
|
||||
case normal
|
||||
printf "%s\n" $line
|
||||
case blank
|
||||
set state blank
|
||||
case meta
|
||||
# skip it
|
||||
end
|
||||
case blank
|
||||
switch $line_type
|
||||
case normal
|
||||
echo # print the blank line
|
||||
printf "%s\n" $line
|
||||
set state normal
|
||||
case blank meta
|
||||
# skip it
|
||||
end
|
||||
end
|
||||
end | ul # post-process with `ul`, to interpret the old-style grotty escapes
|
||||
echo # print a trailing blank line
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user