From 6c54f79f55e72d9f616491bab074ab992ef7523d Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 10 Dec 2020 15:58:44 +0900 Subject: [PATCH] complete/mandb: support BSD man --- ble.pp | 2 +- lib/core-complete.sh | 70 ++++++++++++++++++++++++++++++++++---------- memo/ChangeLog.md | 4 ++- note.txt | 8 +++++ 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/ble.pp b/ble.pp index b90f1062..ccee4189 100644 --- a/ble.pp +++ b/ble.pp @@ -720,7 +720,7 @@ function ble-update { ble/bin/.freeze-utility-path "${_ble_init_posix_command_list[@]}" # <- this uses ble/util/assign. ble/bin/.freeze-utility-path man -ble/bin/.freeze-utility-path gzip nroff # used by core-complete.sh +ble/bin/.freeze-utility-path nroff mandoc gzip bzcat lzcat xzcat # used by core-complete.sh # Solaris: .freeze-utility-path で上書きされた awk を戻す ble/bin/awk.use-solaris-xpg4 diff --git a/lib/core-complete.sh b/lib/core-complete.sh index e8eb9728..4f251da9 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -2505,38 +2505,70 @@ function ble/complete/mandb/search-file { ble/string#split manpath : "$manpath" local path for path in "${manpath[@]}"; do - ble/complete/mandb/search-file/.check "$path/man1/$man.1.gz" && return ble/complete/mandb/search-file/.check "$path/man1/$man.1" && return - ble/complete/mandb/search-file/.check "$path/man1/$man.8.gz" && return ble/complete/mandb/search-file/.check "$path/man1/$man.8" && return + if ble/is-function ble/bin/gzip; then + ble/complete/mandb/search-file/.check "$path/man1/$man.1.gz" && return + ble/complete/mandb/search-file/.check "$path/man1/$man.8.gz" && return + fi + if ble/is-function ble/bin/bzcat; then + ble/complete/mandb/search-file/.check "$path/man1/$man.1.bz" && return + ble/complete/mandb/search-file/.check "$path/man1/$man.1.bz2" && return + ble/complete/mandb/search-file/.check "$path/man1/$man.8.bz" && return + ble/complete/mandb/search-file/.check "$path/man1/$man.8.bz2" && return + fi + if ble/is-function ble/bin/xzcat; then + ble/complete/mandb/search-file/.check "$path/man1/$man.1.xz" && return + ble/complete/mandb/search-file/.check "$path/man1/$man.8.xz" && return + fi + if ble/is-function ble/bin/lzcat; then + ble/complete/mandb/search-file/.check "$path/man1/$man.1.lzma" && return + ble/complete/mandb/search-file/.check "$path/man1/$man.8.lzma" && return + fi done return 1 } +if ble/is-function ble/bin/nroff; then + _ble_complete_mandb_convert_type=man + function ble/complete/mandb/convert-mandoc { + ble/bin/nroff -Tutf8 -man + } +elif ble/is-function ble/bin/mandoc; then + # bsd + _ble_complete_mandb_convert_type=mdoc + function ble/complete/mandb/convert-mandoc { + ble/bin/mandoc -mdoc + } +fi + function ble/complete/mandb/.generate-cache { ble/is-function ble/bin/man && - ble/is-function ble/bin/gzip && - ble/is-function ble/bin/nroff || return 1 + ble/is-function ble/complete/mandb/convert-mandoc || return 1 local command=$1 local ret ble/complete/mandb/search-file "$command" || return 1 local path=$ret - if [[ $ret == *.gz ]]; then - ble/bin/gzip -cd "$path" - else - ble/bin/cat "$path" - fi | ble/bin/awk ' + case $ret in + (*.gz) ble/bin/gzip -cd "$path" ;; + (*.bz|*.bz2) ble/bin/bzcat "$path" ;; + (*.lzma) ble/bin/lzcat "$path" ;; + (*.xz) ble/bin/xzcat "$path" ;; + (*) ble/bin/cat "$path" ;; + esac | ble/bin/awk -v type="$_ble_complete_mandb_convert_type" ' BEGIN { g_key = ""; g_desc = ""; - print ".TH __ble_ignore__ 1 __ble_ignore__ __ble_ignore__"; - print ".ll 9999" + if (type == "man") { + print ".TH __ble_ignore__ 1 __ble_ignore__ __ble_ignore__"; + print ".ll 9999" + } } function flush_topic() { if (g_key == "") return; print "__ble_key__"; - print ".TP"; + if (type == "man") print ".TP"; print g_key; print ""; print "__ble_desc__"; @@ -2548,8 +2580,14 @@ function ble/complete/mandb/.generate-cache { g_desc = ""; } - /^\.TP\y/ { flush_topic(); mode = "key"; next; } - /^\.(SS|SH)\y/ { flush_topic(); next; } + type == "man" && /^\.TP([^_[:alnum:]]|$)/ { + flush_topic(); mode = "key"; next; + } + type == "mdoc" && /^\.It Fl([^_[:alnum:]]|$)/ { + flush_topic(); mode = "key"; + sub(/^\.It Fl/, ".Fl"); + } + /^\.(S[Ss]|S[Hh]|P[Pp])([^_[:alnum:]]|$)/ { flush_topic(); next; } mode == "key" { g_key = $0; @@ -2563,7 +2601,7 @@ function ble/complete/mandb/.generate-cache { } END { flush_topic(); } - ' | ble/bin/nroff -Tutf8 -man | ble/bin/awk ' + ' | ble/complete/mandb/convert-mandoc | ble/bin/awk ' function process_pair(name, desc) { if (!(g_name ~ /^-/)) return; @@ -2610,7 +2648,7 @@ function ble/complete/mandb/.generate-cache { mode == "key" { line = $0; gsub(/\x1b\[[ -?]*[@-~]/, "", line); # CSI seq - gsub(/\x1b[ -/]*[0-~]/, "", line); # ESC seq + gsub(/\x1b[ -\/]*[0-~]/, "", line); # ESC seq gsub(/.\x08/, "", line); # CHAR BS gsub(/\x0E/, "", line); # SO gsub(/\x0F/, "", line); # SI diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index 90e8944c..b29159e2 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -5,9 +5,11 @@ ## New features +- complete/mandb: support mandb in FreeBSD `#D1432` 0000000 + ## Changes -- syntax: exclude \\ + LF at the word beginning from words (motivated by cmplstofB) `#D1431` 0000000 +- syntax: exclude \\ + LF at the word beginning from words (motivated by cmplstofB) `#D1431` 67e62d6 ## Fixes diff --git a/note.txt b/note.txt index 6c747ce6..689dfc3c 100644 --- a/note.txt +++ b/note.txt @@ -3702,6 +3702,14 @@ bash_tips 2020-12-10 + * complete/mandb: FreeBSD 上で man 情報の抽出に失敗している [#D1432] + 対応した。FreeBSD では mandoc というコマンドを使って変換を行っている。 + nroff と同様に -man 等を指定する事ができる様だが、 + どうやら FreeBSD は -man ではなくて -mdoc を想定して man pages を書いている様だ。 + という訳なので -mdoc を前提として抽出をする様に書き換えた。 + + ちゃんと nroff を使う版も動いている。OK + * highlight: command \^J-a とした時に -a がコマンドとして着色されない (reported by cmplstofB) [#D1431] https://github.com/akinomyoga/ble.sh/issues/76