1
1
mirror of https://github.com/mawww/kakoune.git synced 2024-11-25 10:32:19 +03:00
kakoune/rc/core/man.kak
Frank LENORMAND 21847a5f85 rc man: Avoid undefined behavior on expr
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.
2017-07-17 21:24:41 +03:00

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"
} }