aboutsummaryrefslogtreecommitdiffhomepage
path: root/share
diff options
context:
space:
mode:
authorGravatar Kevin Ballard <kevin@sb.org>2014-10-09 23:32:54 -0700
committerGravatar Kevin Ballard <kevin@sb.org>2014-10-09 23:48:10 -0700
commitac8c5910eb0fa03b9384463cb2a86ac4f929362e (patch)
tree5b379d3e108469a0177c750a6f4ee6b14a6f0293 /share
parentcc7f1755aa4d33c30f64cfcd6b286d539e3d0519 (diff)
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.
Diffstat (limited to 'share')
-rw-r--r--share/functions/__fish_print_help.fish100
1 files changed, 74 insertions, 26 deletions
diff --git a/share/functions/__fish_print_help.fish b/share/functions/__fish_print_help.fish
index 8e4d3000..46246e34 100644
--- a/share/functions/__fish_print_help.fish
+++ b/share/functions/__fish_print_help.fish
@@ -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)
-
- # Print an empty line first
- echo
+ 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)
- # 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