21847a5f85
Looking up the man page for `index` was failing on systems using GNU/coreutils. The `:man` command matched whatever page it was given with the `expr` utility. This tool behaves as expected when it follows strictly the POSIX standard but the GNU implementation introduces additional commands (including `index`), about which the standard states: ``` The use of string arguments length, substr, index, or match produces unspecified results. ``` As a result, parsing the man page number is now implemented with pure shell expansions, to avoid triggering an undefined behavior when the topic searched is one of the keywords above.
80 lines
2.6 KiB
Plaintext
80 lines
2.6 KiB
Plaintext
decl -docstring "name of the client in which documentation is to be displayed" \
|
|
str docsclient
|
|
|
|
decl -hidden str manpage
|
|
|
|
hook -group man-highlight global WinSetOption filetype=man %{
|
|
add-highlighter group man-highlight
|
|
# Sections
|
|
add-highlighter -group man-highlight regex ^\S.*?$ 0:blue
|
|
# Subsections
|
|
add-highlighter -group man-highlight regex '^ {3}\S.*?$' 0:default+b
|
|
# Command line options
|
|
add-highlighter -group man-highlight regex '^ {7}-[^\s,]+(,\s+-[^\s,]+)*' 0:yellow
|
|
# References to other manpages
|
|
add-highlighter -group man-highlight regex [-a-zA-Z0-9_.]+\([a-z0-9]+\) 0:green
|
|
}
|
|
|
|
hook global WinSetOption filetype=man %{
|
|
hook -group man-hooks window WinResize .* %{
|
|
man-impl %opt{manpage}
|
|
}
|
|
}
|
|
|
|
hook -group man-highlight global WinSetOption filetype=(?!man).* %{ remove-highlighter man-highlight }
|
|
|
|
hook global WinSetOption filetype=(?!man).* %{
|
|
remove-hooks window man-hooks
|
|
}
|
|
|
|
def -hidden -params 1..2 man-impl %{ %sh{
|
|
manout=$(mktemp "${TMPDIR:-/tmp}"/kak-man-XXXXXX)
|
|
colout=$(mktemp "${TMPDIR:-/tmp}"/kak-man-XXXXXX)
|
|
MANWIDTH=${kak_window_width} man "$@" > $manout
|
|
retval=$?
|
|
col -b -x > ${colout} < ${manout}
|
|
rm ${manout}
|
|
if [ "${retval}" -eq 0 ]; then
|
|
printf %s\\n "
|
|
edit -scratch '*man*'
|
|
exec '%|cat<space>${colout}<ret>gk'
|
|
nop %sh{rm ${colout}}
|
|
set buffer filetype man
|
|
set window manpage '$@'
|
|
"
|
|
else
|
|
printf %s\\n "echo -color Error %{man '$@' failed: see *debug* buffer for details }"
|
|
rm ${colout}
|
|
fi
|
|
} }
|
|
|
|
def -params ..1 \
|
|
-shell-completion %{
|
|
prefix=$(printf %s\\n "$1" | cut -c1-${kak_pos_in_token} 2>/dev/null)
|
|
for page in /usr/share/man/*/${prefix}*.[1-8]*; do
|
|
candidate=$(basename ${page%%.[1-8]*})
|
|
pagenum=$(printf %s\\n "$page" | sed 's,^.*\.\([1-8][^.]*\).*$,\1,')
|
|
case $candidate in
|
|
*\*) ;;
|
|
*) printf %s\\n "$candidate($pagenum)";;
|
|
esac
|
|
done
|
|
} \
|
|
-docstring %{man [<page>]: manpage viewer wrapper
|
|
If no argument is passed to the command, the selection will be used as page
|
|
The page can be a word, or a word directly followed by a section number between parenthesis, e.g. kak(1)} \
|
|
man %{ %sh{
|
|
subject=${@-$kak_selection}
|
|
|
|
## The completion suggestions display the page number, strip them if present
|
|
case "${subject}" in
|
|
*\([1-8]*\))
|
|
pagenum="${subject##*(}"
|
|
pagenum="${pagenum%)}"
|
|
subject="${subject%%(*}"
|
|
;;
|
|
esac
|
|
|
|
printf %s\\n "eval -collapse-jumps -try-client %opt{docsclient} man-impl $pagenum $subject"
|
|
} }
|