git: 1594084f3fa8 - main - man(1): Add full search (-K) flag
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 26 Jan 2022 11:28:02 UTC
The branch main has been updated by fernape (doc, ports committer): URL: https://cgit.FreeBSD.org/src/commit/?id=1594084f3fa8daf95c0d8cdbd6487939506e268a commit 1594084f3fa8daf95c0d8cdbd6487939506e268a Author: Fernando Apesteguía <fernape@FreeBSD.org> AuthorDate: 2022-01-25 12:12:27 +0000 Commit: Fernando Apesteguía <fernape@FreeBSD.org> CommitDate: 2022-01-26 11:24:20 +0000 man(1): Add full search (-K) flag This flag allows a full text search on man pages. Although this is a last resort option, it can be useful to pin point a certain man page. It can be used with -S to narrow the search. Unlike the Linux version, the search takes place in the rendered text so it avoids false-positives when the text is found in comments in the source files. It relies on `grep(1)` and `mandoc(1)` to do its job. Add flag documentation and EXAMPLES to the manual page (bump .Dd). Usage example: man -w -K '\<arm\>' -S 1:8 Reviewed By: ceri, emaste, pauamma_gundo.com Approved by: manpages (bcr@), debdrup@ Differential Revision: https://reviews.freebsd.org/D30984 --- usr.bin/man/man.1 | 19 ++++++++++++++++++- usr.bin/man/man.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1 index 42fd60a86164..9a611eff3005 100644 --- a/usr.bin/man/man.1 +++ b/usr.bin/man/man.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 9, 2021 +.Dd January 26, 2022 .Dt MAN 1 .Os .Sh NAME @@ -43,6 +43,9 @@ .Op Ar mansect .Ar page ... .Nm +.Fl K +.Ar regexp ... +.Nm .Fl f .Ar keyword ... .Nm @@ -93,6 +96,14 @@ Options that .Nm understands: .Bl -tag -width indent +.It Fl K Ar regexp +Does a full text search in all manual pages. +.Ar regexp +is a regular expression as understood by +.Dq Li "grep -E" . +This option requires +.Xr mandoc 1 . +This is a slow operation. .It Fl M Ar manpath Forces a specific colon separated manual path instead of the default search path. @@ -392,8 +403,14 @@ manual page: $ man -w ls .Ed .Pp +Show the location of manual pages in sections 1 and 8 which contain the word +.Ql arm : +.Bd -literal -offset indent +$ ./man -w -K '\e<arm\e>' -S 1:8 +.Ed .Sh SEE ALSO .Xr apropos 1 , +.Xr egrep 1 , .Xr intro 1 , .Xr mandoc 1 , .Xr manpath 1 , diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh index 084f4a06829b..2c2f1bf648de 100755 --- a/usr.bin/man/man.sh +++ b/usr.bin/man/man.sh @@ -548,8 +548,10 @@ man_parse_args() { local IFS cmd_arg OPTIND=1 - while getopts 'M:P:S:adfhkm:op:tw' cmd_arg; do + while getopts 'K:M:P:S:adfhkm:op:tw' cmd_arg; do case "${cmd_arg}" in + K) Kflag=Kflag + REGEXP=$OPTARG ;; M) MANPATH=$OPTARG ;; P) MANPAGER=$OPTARG ;; S) MANSECT=$OPTARG ;; @@ -570,7 +572,11 @@ man_parse_args() { shift $(( $OPTIND - 1 )) # Check the args for incompatible options. - case "${fflag}${kflag}${tflag}${wflag}" in + + case "${Kflag}${fflag}${kflag}${tflag}${wflag}" in + Kflagfflag*) echo "Incompatible options: -K and -f"; man_usage ;; + Kflag*kflag*) echo "Incompatible options: -K and -k"; man_usage ;; + Kflag*tflag) echo "Incompatible options: -K and -t"; man_usage ;; fflagkflag*) echo "Incompatible options: -f and -k"; man_usage ;; fflag*tflag*) echo "Incompatible options: -f and -t"; man_usage ;; fflag*wflag) echo "Incompatible options: -f and -w"; man_usage ;; @@ -711,7 +717,7 @@ man_setup_locale() { # Display usage for the man utility. man_usage() { echo 'Usage:' - echo ' man [-adho] [-t | -w] [-M manpath] [-P pager] [-S mansect]' + echo ' man [-adho] [-t | -w] [-K regexp] [-M manpath] [-P pager] [-S mansect]' echo ' [-m arch[:machine]] [-p [eprtv]] [mansect] page [...]' echo ' man -f page [...] -- Emulates whatis(1)' echo ' man -k page [...] -- Emulates apropos(1)' @@ -965,14 +971,49 @@ do_apropos() { search_whatis apropos "$@" } +# Usage: do_full_search reg_exp +# Do a full search of the regular expression passed +# as parameter in all man pages +do_full_search() { + local gflags re + re=${1} + + # Build grep(1) flags + gflags="-H" + + # wflag implies -l for grep(1) + if [ -n "$wflag" ]; then + gflags="${gflags} -l" + fi + + gflags="${gflags} --label" + + set +f + for mpath in $(echo "${MANPATH}" | tr : [:blank:]); do + for section in $(echo "${MANSECT}" | tr : [:blank:]); do + for manfile in ${mpath}/man${section}/*.${section}*; do + mandoc "${manfile}" 2>/dev/null | + grep -E ${gflags} "${manfile}" -e ${re} + done + done + done + set -f +} + do_man() { man_parse_args "$@" - if [ -z "$pages" ]; then + if [ -z "$pages" -a -z "${Kflag}" ]; then echo 'What manual page do you want?' >&2 exit 1 fi man_setup + if [ ! -z "${Kflag}" ]; then + # Short circuit because -K flag does a sufficiently + # different thing like not showing the man page at all + do_full_search "${REGEXP}" + fi + for page in $pages; do decho "Searching for $page" man_find_and_display "$page"