From a79280ef84b490acc19c574e5ff95769f64c805e Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Tue, 7 Dec 2021 16:13:29 +0900 Subject: [PATCH] mandb: support man-page format of "wget", "bc", "mv", "fish", and "ping" --- docs/ChangeLog.md | 25 ++++---- lib/core-complete.sh | 148 +++++++++++++++++++++++++++++++++++-------- note.txt | 11 ++++ 3 files changed, 146 insertions(+), 38 deletions(-) diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index e833f0e0..3a9935de 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -77,9 +77,9 @@ - prompt: support `bleopt prompt_ruler` (motivated by Barbarossa93) `#D1666` 05cf638 - prompt: fix hanging by a zero-width `prompt_ruler` `#D1673` 9033f29 - edit: support `bleopt canvas_winch_action` (requested by Johann-Goncalves-Pereira, guptapriyanshu7) `#D1679` 2243e91 - - blerc: fix the name of the option `bleopt canvas_winch_action` (reported by Knusper) 0000000 -- menu (menu-style:desc): improve descriptions (motivated by Shahabaz-Bagwan) `#D1685` 0000000 -- menu (menu-style:desc): support multicolumns (motivated by Shahabaz-Bagwan) `#D1686` 0000000 + - blerc: fix the name of the option `bleopt canvas_winch_action` (reported by Knusper) b1be640 +- menu (menu-style:desc): improve descriptions (motivated by Shahabaz-Bagwan) `#D1685` 4de1b45 +- menu (menu-style:desc): support multicolumns (motivated by Shahabaz-Bagwan) `#D1686` 231dc39 ## Changes @@ -118,9 +118,9 @@ - repo: add subdirectories `make` and `docs` `#D1657` 75bd04c - util: time out CPR requests `#D1669` 1481d48 - main: suppress non-interactive warnings from manually sourced startup files (reported by andreclerigo) `#D1676` 0525528 88e2df5 -- mandb: integrate `mandb` with `bash-completion` (motivated by Shahabaz-Bagwan, bbyfacekiller and EmilySeville7cfg) `#D1688` 0000000 -- syntax: do not start argument completions immediately after previous word (reported by EmilySeville7cfg) `#D1690` 0000000 -- syntax: strictly check variable names of `for`-statements `#D1692` 0000000 +- mandb: integrate `mandb` with `bash-completion` (motivated by Shahabaz-Bagwan, bbyfacekiller and EmilySeville7cfg) `#D1688` c1cd666 +- syntax: do not start argument completions immediately after previous word (reported by EmilySeville7cfg) `#D1690` 371a5a4 +- syntax: strictly check variable names of `for`-statements `#D1692` d056547 ## Fixes @@ -134,8 +134,9 @@ - mandb: fix an infinite loop by a leak variable (reported by rlanore, riblo) `#D1550` 0efcb65 - mandb: work around old groff in macOS (reported by killermoehre) `#D1551` d4f816b - mandb: use `manpath` and `man -w`, and read `/etc/man_db.conf` and `~/.manpath` `#D1637` 2365e09 - - mandb: support the formats of the man pages of `awk` and `sed` (reported by bbyfacekiller) `#D1687` 0000000 - - mandb: generate completions of options also for the empty word `#D1689` 0000000 + - mandb: support the formats of the man pages of `awk` and `sed` (reported by bbyfacekiller) `#D1687` 6932018 + - mandb: generate completions of options also for the empty word `#D1689` b90ac78 + - mandb: support the man-page formats of `wget`, `fish`, and `ping` (reported by bbyfacekiller) `#D1687` 0000000 - edit: work around the wrong job information of Bash in trap handlers (reported by 3ximus) `#D1435` `#D1436` bc4735e - edit (command-help): work around the Bash bug that tempenv vanishes with `builtin eval` `#D1438` 8379d4a - global: suppress missing locale errors (reported by 3ximus) `#D1440` 4d3c595 @@ -189,8 +190,8 @@ - decode (`cmap/initialize`): fix unquoted special chars in the cmap cache `#D1647` 7434d2d - decode: fix a bug that the characters input while initialization are delayed `#D1670` 430f449 - util (`ble/util/readfile`): fix a bug of always exiting with 1 in `bash <= 3.2` (reported by laoshaw) `#D1678` 61705bf -- trace: fix wrong positioning of the ellipses on overflow `#D1684` 0000000 -- complete: do not generate keywords for quoted command names `#D1691` 0000000 +- trace: fix wrong positioning of the ellipses on overflow `#D1684` b90ac78 +- complete: do not generate keywords for quoted command names `#D1691` 60d244f ## Documentation @@ -241,8 +242,8 @@ - main: work around self-modifying `PROMPT_COMMAND` by `bash-preexec` (reported by cornfeedhobo) `#D1650` 39ebf53 - decode: work around openSUSE broken `/etc/inputrc` `#D1662` e5b0c86 - decode: work around the overwritten builtin `set` (reported by eadmaster) `#D1680` a6b4e2c -- complete: work around the variable leaks by `virsh` completion from `libvirt` (reported by telometto) `#D1682` 0000000 -- stty: do not remove keydefs for C-u, C-v, C-w, and C-? (reported by laoshaw) `#D1683` 0000000 +- complete: work around the variable leaks by `virsh` completion from `libvirt` (reported by telometto) `#D1682` f985b9a +- stty: do not remove keydefs for C-u, C-v, C-w, and C-? (reported by laoshaw) `#D1683` 82f74f0 ## Internal changes and fixes diff --git a/lib/core-complete.sh b/lib/core-complete.sh index 7bf25eb3..488b655b 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -3436,25 +3436,32 @@ function ble/complete/mandb/.generate-cache { topic_start = ".TP"; } mode = "begin"; + + fmt3_state = ""; + fmt5_state = ""; } function flush_topic(_, i) { - if (g_keys_count == 0) return; - for (i = 0; i < g_keys_count; i++) { - print ""; - print "__ble_key__"; - if (topic_start != "") print topic_start; - print g_keys[i]; - print ""; - print "__ble_desc__"; - print ""; - print g_desc; + if (g_keys_count != 0) { + for (i = 0; i < g_keys_count; i++) { + print ""; + print "__ble_key__"; + if (topic_start != "") print topic_start; + print g_keys[i]; + print ""; + print "__ble_desc__"; + print ""; + print g_desc; + } } g_keys_count = 0; g_desc = ""; + + fmt3_flush(); + fmt5_state = ""; } -#% # .Dd マクロ読み込み命令? -#% # .Nm (mdoc) 記述対象の名前 + # ".Dd" seems to be the include directive for macros? + # ".Nm" (in mdoc) specifies the name of the target the man page describes mode == "begin" && /^\.(Dd|Nm)[[:space:]]/ { if (type == "man" && /^\.Dd[[:space:]]+\$Mdoc/) topic_start = ""; print $0; @@ -3472,31 +3479,120 @@ function ble/complete/mandb/.generate-cache { next; } - /^\.(S[Ss]|S[Hh]|P[Pp])([^_[:alnum:]]|$)/ { flush_topic(); next; } + { + sub(/[[:space:]]+$/, ""); + REQ = match($0, /^\.[_[:alnum:]]+/) ? substr($0, 2, RLENGTH) : ""; + } + + REQ ~ /^(S[Ss]|S[Hh]|Pp)$/ { flush_topic(); next; } + + #-------------------------------------------------------------------------- + # Format #5: [.PP \n key \n .RS \n desc \n .RE] + # used by "ping". + + REQ == "PP" { + flush_topic(); + fmt5_state = "key"; + fmt5_key = ""; + fmt5_desc = ""; + next; + } + + fmt5_state { + if (fmt5_state == "key") { + if (/^\.RS([^_[:alnum:]]|$)/) + fmt5_state = "desc"; + else if (/^\.RE([^_[:alnum:]]|$)/) + fmt5_state = "none"; + else + fmt5_key = (fmt5_key ? "\n" : "") $0; + } else if (fmt5_state == "desc") { + if (/^\.RE([^_[:alnum:]]|$)/) { + register_key(fmt5_key); + g_desc = fmt5_desc; + flush_topic(); + fmt5_state = ""; + } else + fmt5_desc = (fmt5_desc ? "\n" : "") $0; + } + } #-------------------------------------------------------------------------- # Format #3: [.HP \n keys \n .IP \n desc] # GNU sed seems to use this format. - /^\.HP[[:space:]]*$/ { - if (g_keys_count && g_desc != "") flush_topic(); - mode = "fmt3_key"; + # GNU coreutils mv seems to contain [.HP \n key desc ] (for option "-b") + + REQ == "HP" { + flush_topic(); + fmt3_state = "key"; + fmt3_key_count = 0; + fmt3_desc = ""; + next; + } + + function fmt3_process(_, key) { + if (REQ == "TP") { fmt3_flush(); return; } + if (REQ == "PD") return; + + if (fmt3_state == "key") { + if (REQ == "IP") { fmt3_state = "desc"; return; } + if (match($0, /( | )[[:space:]]*/)) { + fmt3_keys[fmt3_key_count++] = substr($0, 1, RSTART - 1); + fmt3_desc = substr($0, RSTART + RLENGTH); + fmt3_state = "desc"; + } else { + fmt3_keys[fmt3_key_count++] = $0; + } + } else if (fmt3_state == "desc") { + if (fmt3_desc != "") fmt3_desc = fmt3_desc "\n"; + fmt3_desc = fmt3_desc $0; + } + } + function fmt3_flush(_, i) { + if (fmt3_state == "desc" && fmt3_key_count > 0) { + for (i = 0; i < fmt3_key_count; i++) + register_key(fmt3_keys[i]); + g_desc = fmt3_desc; + } + fmt3_state = ""; + fmt3_key_count = 0; + fmt3_desc = ""; } - mode == "fmt3_key" { - if (/^\.TP[[:space:]]*/) { flush_topic(); mode = "none"; next; } - if (/^\.PD([^_[:alnum:]]|$)/) next; - if (/^\.IP/) { mode = "fmt3_desc"; next; } + fmt3_state { fmt3_process(); } + + #-------------------------------------------------------------------------- + # Format #4: [[.IP "key" 4 \n .IX Item "..."]+ \n .PD \n desc] + # This format is used by "wget". + /^\.IP[[:space:]]+".*"([[:space:]]+[0-9]+)?$/ && fmt3_state != "key" { + if (!(g_keys_count && g_desc == "")) flush_topic(); + gsub(/^\.IP[[:space:]]+"|"([[:space:]]+[0-9]+)?$/, ""); register_key($0); + mode = "fmt4_desc"; next; } - mode == "fmt3_desc" { - if (/^\.TP[[:space:]]*/) { flush_topic(); mode = "none"; next; } - if (/^\.PD([^_[:alnum:]]|$)/) next; + mode == "fmt4_desc" { + if ($0 == "") { flush_topic(); mode = "none"; next; } + + # fish has a special format of [.IP "\(bu" 2 \n keys desc] + if (g_keys_count == 1 && g_keys[0] == "\\(bu" && match($0, /^\\fC[^\\]+\\fP( or \\fC[^\\]+\\fP)?/) > 0) { + _key = substr($0, 1, RLENGTH); + _desc = substr($0, RLENGTH + 1); + if (match(_key, / or \\fC[^\\]+\\fP/) > 0) + _key = substr(_key, 1, RSTART - 1) ", " substr(_key, RSTART + 4); + g_keys[0] = _key; + g_desc = _desc; + next; + } + + if (REQ == "PD") next; + if (/^\.IX[[:space:]]+Item[[:space:]]+/) next; if (g_desc != "") g_desc = g_desc "\n"; g_desc = g_desc $0; next; } + #-------------------------------------------------------------------------- # Format #2: [.It Fl key \n desc] or [.It Fl Xo \n key \n .Xc desc] # This form was found in both "mdoc" and "man" @@ -3515,7 +3611,7 @@ function ble/complete/mandb/.generate-cache { mode == "fmt2_keyc" { if (/^\.PD[[:space:]]*([0-9]+[[:space:]]*)?$/) next; g_current_key = g_current_key "\n" $0; - if (/^\.Xc/) { + if (REQ == "Xc") { register_key(g_current_key); mode = "desc"; } @@ -3524,7 +3620,7 @@ function ble/complete/mandb/.generate-cache { #-------------------------------------------------------------------------- # Format #1: [.TP \n key \n desc] # This is the typical format in "man". - type == "man" && /^\.TP([^_[:alnum:]]|$)/ { + type == "man" && REQ == "TP" { if (g_keys_count && g_desc != "") flush_topic(); mode = "key1"; next; @@ -3536,7 +3632,7 @@ function ble/complete/mandb/.generate-cache { next; } mode == "desc" { - if (/^\.PD([^_[:alnum:]]|$)/) next; + if (REQ == "PD") next; if (g_desc != "") g_desc = g_desc "\n"; g_desc = g_desc $0; diff --git a/note.txt b/note.txt index 8ebcacee..c032b6ff 100644 --- a/note.txt +++ b/note.txt @@ -5585,6 +5585,17 @@ bash_tips 更に、awk の man page の中にある ".ig ... .." はコメントセクションの様だ。 古いオプションや文章が含まれているらしい。 + 2021-12-07 更に "wget" も補完されないという事が報告されていた。他にもあるか + もしれないと思って色々動作を確認する。"bc", "mv", "fish" 等に対して追加で抽 + 出コードの修正を行った。man のオプションの説明の形式には一貫性が全然ないの + でコマンド毎に表現の仕方が異なるというのは問題である。それでも、典型的なパ + ターンというのは有限である筈なので、それで大体カバーできると思うしかない。 + + 2021-12-08 更に "ping" もちゃんと man から抽出できていなかった。 + + 2021-12-12 "top" の抽出に失敗していると思ったら fmt4 の desc が終 + 端できていなかった。空行がある場合には強制的に中断する事にした。 + * 2021-09-06 menu: fish の様に twocolumn 形式で表示する desc を作っても良いのではないか (motivated by Shahabaz-Bagwan) [#D1686] https://www.youtube.com/watch?v=YS1vxEhd2Pc https://github.com/akinomyoga/ble.sh/issues/132