From d4f816bdcf482285be5e52384a72c181fbee70b8 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 17 May 2021 22:06:02 +0900 Subject: [PATCH] mandb: work around old groff in macOS --- lib/core-complete.sh | 95 ++++++++++++++++++++++++++++++++++++++++++-- memo/ChangeLog.md | 1 + note.txt | 74 +++++++++++++++++++++++++++++++++- 3 files changed, 164 insertions(+), 6 deletions(-) diff --git a/lib/core-complete.sh b/lib/core-complete.sh index 73d3f9f5..82e7d09b 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -2725,6 +2725,14 @@ function ble/complete/action:mandb/get-desc { desc=${fields[3]} } +function ble/complete/mandb/search-file/.extract-path { + local command=$1 + [[ $_ble_complete_mandb_lang ]] && + local LC_ALL=$$_ble_complete_mandb_lang + ble/util/assign path 'ble/bin/man -w "$command"' 2>/dev/null +} +ble/function#suppress-stderr ble/complete/mandb/search-file/.extract-path + function ble/complete/mandb/search-file/.check { local path=$1 if [[ $path && -s $path ]]; then @@ -2737,8 +2745,9 @@ function ble/complete/mandb/search-file/.check { function ble/complete/mandb/search-file { local command=$1 - # Try "man -w" first - ble/complete/mandb/search-file/.check "$(ble/bin/man -w "$command" 2>/dev/null)" && return + local path + ble/complete/mandb/search-file/.extract-path "$command" + ble/complete/mandb/search-file/.check "$path" && return local manpath=${MANPATH:-/usr/share/man:/usr/local/share/man:/usr/local/man} ble/string#split manpath : "$manpath" @@ -2768,15 +2777,93 @@ function ble/complete/mandb/search-file { return 1 } +if ble/bin/.freeze-utility-path preconv; then + function ble/complete/mandb/.preconv { ble/bin/preconv; } +else + # macOS では preconv がない + function ble/complete/mandb/.preconv { + ble/bin/od -A n -t u1 -v | ble/bin/awk ' + BEGIN { + ECHAR = 65533; # U+FFFD + + # Initialize table + byte = 0; + for (i = 0; byte < 128; byte++) { mtable[byte] = 0; vtable[byte] = i++; } + for (i = 0; byte < 192; byte++) { mtable[byte] = 0; vtable[byte] = ECHAR; } + for (i = 0; byte < 224; byte++) { mtable[byte] = 1; vtable[byte] = i++; } + for (i = 0; byte < 240; byte++) { mtable[byte] = 2; vtable[byte] = i++; } + for (i = 0; byte < 248; byte++) { mtable[byte] = 3; vtable[byte] = i++; } + for (i = 0; byte < 252; byte++) { mtable[byte] = 4; vtable[byte] = i++; } + for (i = 0; byte < 254; byte++) { mtable[byte] = 5; vtable[byte] = i++; } + for (i = 0; byte < 256; byte++) { mtable[byte] = 0; vtable[byte] = ECHAR; } + + M = 0; C = 0; + } + function put_uchar(uchar) { + if (uchar < 128) + printf("%c", uchar); + else + printf("\\[u%04X]", uchar); + } + function process_byte(byte) { + if (M) { + if (128 <= byte && byte < 192) { + C = C * 64 + byte % 64; + if (--M == 0) put_uchar(C); + return; + } else { + # while (M--) C *= 64; put_uchar(C); + put_uchar(ECHAR); + M = 0; + } + } + + M = mtable[byte]; + C = vtable[byte]; + if (M == 0) put_uchar(C); + } + { for (i = 1; i <= NF; i++) process_byte($i); } + ' + } +fi + +_ble_complete_mandb_lang= if ble/is-function ble/bin/groff; then + # ENCODING: UTF-8 _ble_complete_mandb_convert_type=man function ble/complete/mandb/convert-mandoc { - ble/bin/groff -k -Tutf8 -man + if [[ $_ble_util_locale_encoding == UTF-8 ]]; then + ble/bin/groff -k -Tutf8 -man + else + ble/bin/groff -Tascii -man + fi } + + # Note #D1551: macOS (groff-1.19.2) では groff -k も preconv も既定では存在しない + if [[ $OSTYPE == darwin* ]] && ! ble/bin/groff -k -Tutf8 -man &>/dev/null <<< 'α'; then + if ble/bin/groff -T utf8 -m man &>/dev/null <<< '\[u03B1]'; then + function ble/complete/mandb/convert-mandoc { + if [[ $_ble_util_locale_encoding == UTF-8 ]]; then + ble/complete/mandb/.preconv | ble/bin/groff -T utf8 -m man + else + ble/bin/groff -T ascii -m man + fi + } + else + _ble_complete_mandb_lang=C + function ble/complete/mandb/convert-mandoc { + ble/bin/groff -T ascii -m man + } + fi + fi elif ble/is-function ble/bin/nroff; then _ble_complete_mandb_convert_type=man function ble/complete/mandb/convert-mandoc { - ble/bin/nroff -Tutf8 -man + if [[ $_ble_util_locale_encoding == UTF-8 ]]; then + ble/bin/nroff -Tutf8 -man + else + ble/bin/groff -Tascii -man + fi } elif ble/is-function ble/bin/mandoc; then # bsd diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index aa4bc001..523c6d93 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -10,6 +10,7 @@ - mandb: fix an encoding prpblem of utf8 manuals `#D1446` 7a4a480 - mandb: improve extraction and cache for each locale `#D1480` 3588158 - mandb: fix an infinite loop by a leak variable (reported by rlanore, riblo) `#D1550` 0000000 + - mandb: work around old groff in macOS (reported by killermoehre) `#D1551` 0000000 - decode (`ble-decode-kbd`): support various specifications of key sequences `#D1439` 0f01cab - edit: support new options `bleopt edit_line_type={logical,graphical}` (motivated by 3ximus) `#D1442` 40ae242 - complete: support new options `bleopt complete_limit{,_auto}` (contributed by timjrd) `#D1445` b13f114 5504bbc diff --git a/note.txt b/note.txt index 70024ea0..34f4f5a6 100644 --- a/note.txt +++ b/note.txt @@ -1369,7 +1369,7 @@ bash_tips 2021-05-17 - * 履歴が消滅しすぎるので ble.sh の側で独立した履歴の仕組みを作りたい + * history: 履歴が余りに消滅するので ble.sh の側で独立した履歴の仕組みを作りたい 然し何処に履歴ファイルを置くのかという問題がある。 @@ -1381,7 +1381,14 @@ bash_tips に書き込まないで欲しいという話もある。 d 結局、.local/share/blesh/xxxx に置く事になるのだろうか。まあ、 - .local/share/blesh/data 辺りに置いて置けば良いだろう。 + .local/share/blesh/data 辺りに置いて置けば良いだろう。然しその為には更に + 新しいディレクトリを生成する必要がある。現在は _ble_base, cache, run の三 + 種類のディレクトリがある。 + + 履歴はどの様に記録するのが良いか。日付は unix time で記録するのが人間に分か + る様に記録するのか。カレントディレクトリも記録したいし、存在する相対パスも + 記録したい。所で存在する相対パスはどの様にして抽出するのが良いのだろうか。 + 単語着色の時に検知した物を何処かに記録しておく必要がある。 * 色見本について探した @@ -4591,6 +4598,69 @@ bash_tips 2021-05-17 + * macOS で groff のエラーが出る (reported by killermoehre) [#D1551] + + groff -k というオプションが使えないという事。macOS の groff は v1.19 らしく + これは 2004 の version である。実に17年前の groff である。このオプションは + UTF-8 の man を処理する為に追加した物。実質的に preconv | groff と同じらし + い。しかし、そもそも macOS には preconv がないそうだ。というか。そもそも + groff 1.19 は Unicode に対応しているのだろうか。 + + 取り敢えず groff をインストールして確かめてみる。うーん。全然駄目。そもそも + utf8 device が存在していない様である。何か別の物をインストールすれば良いと + いう訳でもなさそう。device として ascii, latin1, cpxxxx しかない。ascii に + するしかない。man は LANG=C で探す。 + + 然し英語の man を探したとしても本当に groff -man が使えるのかも怪しい。と思っ + たが検索してみると一応 -man には対応している様な気がする。と思ったが -man + ではなくて -m man としなければならない? + https://www.unix.com/man-page/osx/5/groff_tmac/ + + どうも試してみたら最新版でも -m man で動作している気がする。 -man と -m man + は synonym という事だろうか。取り敢えず groff -T ascii -m man <<< X | uniq + が動くかどうかを確認する。 + + と思ったが返信がない。取り敢えずこれで良いのかどうか分からないが #D1550 と + 一緒に変更を加えてみる事にする。それでも治らなかったら使う事にする。何か変 + 更し残している事はあるだろうか? + + 2021-05-17 と思ったら返事が来た。どうも macOS の groff で -T utf8 も一応は + 使える様子である。うーん。という事は \[uXXXX] も取り扱えるのだろうか。 + + * もし \[uXXXX] が取り扱えるのであれば適当に \[uXXXX] に全て置換してしまえ + ば良い。。。と思ったがどうやってやるのか微妙である。awk で変換しようにも + awk では文字コードを取り出せないので uXXXX の形式に変換するのにも苦労する。 + うーん。od を使って binary に変換してそれから nawk で色々処理して、それか + らまた od で元に戻すという様な面倒な処理を実装しなければならない。 + + % と思ったが binary に戻す方法は不明である。うーん。調べると bash の + % printf \x?? 経由で出力するという事になっている? awk の printf は NUL + % が出力できないとしている。他の文字は大丈夫だろうか。というより何故 NUL + % が出力できないのだろうか。 + + awk の printf を使うとしたらテストが必要? と思ったが macOS で動けば良いの + だから BSD awk で動けば十分である→今試した限りだと nawk, mawk, gawk で何 + れもちゃんとできる。NULもちゃんと出力できるのでOK。 + + * もしそのまま通過してくれるのであれば特に気にする事はない。が恐らくそうい + う事はないのだろうという気がする。 + + * 或いは結局全然駄目の可能性もある。うーん。どうなんだろうか。 + + 返事があった。\[uXXXX] で行ける様である。取り敢えず .preconv を実装した。手 + 許で試してみる限りは動いている気がする。まあ、実際に動かして変な事が起こっ + たらその時にまた考え直せば良い。取り敢えず遠隔で実装できるのは此処までであ + る。 + + * 此処で思ったのだが nawk は Unicode の対象を取り扱えるのだろうか。。。UTF-8 + ならば通常の制御文字はそのままなので問題は生じないのではないかという気もす + るが。文字数を数えて何かする様な処理では何か変な事が起こるかもしれないが、 + そうでなければ大丈夫の気がする。 + + 問題が起こるかもしれないのは brace expansion の形式でファイル名一覧を挿入す + る処理。これに関しては UTF-8 だと例えば平仮名の途中で分断されたりして変な事 + が起こる可能性がある。 + * complete: ssh -option の後の補完が固まる (reported by rlanore, riblo) [#D1550] https://github.com/akinomyoga/ble.sh/issues/98