diff options
author | Kevin Ballard <kevin@sb.org> | 2014-10-09 23:32:54 -0700 |
---|---|---|
committer | Kevin Ballard <kevin@sb.org> | 2014-10-09 23:48:10 -0700 |
commit | ac8c5910eb0fa03b9384463cb2a86ac4f929362e (patch) | |
tree | 5b379d3e108469a0177c750a6f4ee6b14a6f0293 /share | |
parent | cc7f1755aa4d33c30f64cfcd6b286d539e3d0519 (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.fish | 100 |
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 |