gauche.interactiveモジュールのinfo関数を使うとマニュアルを読むことができる。ただし英語で。
gosh> (info 'info) 9.8 `gauche.interactive' - Utilities for interactive session ============================================================ -- Module: gauche.interactive Provides useful utilities for the interactive session. This module is automatically loaded when you run `gosh' interactively. This module also sets autoloads for functions defined in `gauche.reload' module (see *note Reloading modules::), so that those functions can be used by default in interactive development. -- Macro: apropos pattern &optional module Show a list of defined variables whose name matches PATTERN. If you give a module or a module name MODULE, only the variables defined in that module are listed. Without MODULE, the variables "visible" from the current module are listed.
でもちょっとライブラリのプログラムをいじれば、日本語のマニュアルを表示するようにできる。
gosh> (info 'info) 9.8 `gauche.interactive' - インタラクティブセッション ===================================================== -- Module: gauche.interactive インタラクティブセッションで便利なユーティリティ手続きを提供します。 `gosh'をインタラクティブモードで起動した場合、 このモジュールは自動的にロードされます。 また、このモジュールは`gauche.reload' (*note モジュールの再ロード::参照)で定義される 手続きに対してautoloadを設定し、それらの手続きが インタラクティブな開発時にデフォルトで使えるようにします。 -- Macro: apropos pattern &optional module 名前がPATTERNにマッチするような定義された変数のリストを表示します。 MODULEにモジュールオブジェクトまたはモジュール名を与えた場合は、 そのモジュール内で定義されている変数のみが表示されます。MODULEが 省略された場合は、カレントモジュールから「見える」変数が全て表示されます。 PATTERNはシンボルか正規表現オブジェクトでなければなりません。 シンボルの場合、そのシンボル名を部分文字列として名前に含むような変数が リストされます。正規表現オブジェクトの場合は、その正規表現にマッチする 名前を持つ変数がリストされます。 いくつか例を示します。
変更場所
いじる必要があるファイルは
- lib/text/info.scm
- lib/gauche/interactive/info.scm
の二つ。text.infoモジュールはinfo形式のファイルを読み込むためもので、gauche.interactive.infoモジュールがinfo関数を定義している。
まずlib/text/info.scmで、infoファイルを読み込む部分でエンコーディングを指定する。
(with-input-from-file file thunk))
(with-input-from-process #`",gunzip -c ,file" thunk))
を
(with-input-from-file file thunk :encoding "*jp"))
(with-input-from-process #`",gunzip -c ,file" thunk :encoding "*jp"))
にする。マニュアルのエンコーディングとGaucheの内部エンコーディングが同じなら変更しなくても動作するけど一応。
あとは、lib/gauche/interactive/info.scmを変更する。ひとつは、
(define *info-file* "gauche-refe.info")
を
(define *info-file* "gauche-refj.info")
に変える。
もうひとつは、info関数の定義に出てくる文字列リテラル「"Function and Syntax Index"」を「"Index - 手続きと構文索引"」に変えて、さらに適切にエンコードを指定する。あるいは「"Function and Syntax Index"」を
(list->string (map ucs->char '(73 110 100 101 120 32 45 32 25163 32154 12365 12392 27083 25991 32034 24341)))
に置き換えてもよい。
おまけの改変
指定した関数が見つからなかった場合にaproposっぽい挙動をするように変更してみる。
gosh> (info 'inf) open-inflating-port (zlib圧縮ライブラリ) inflate-sync (zlib圧縮ライブラリ) inflate-string (zlib圧縮ライブラリ) sys-getaddrinfo (Netdbインタフェース) sys-set-console-cursor-info (WindowsコンソールAPI) info (インタラクティブセッション) debug-source-info (デバッグ補助) sys-get-console-cursor-info (WindowsコンソールAPI) sys-get-console-screen-buffer-info (WindowsコンソールAPI) sys-set-console-window-info (WindowsコンソールAPI)
gosh> (apropos 'inf) debug-source-info (gauche) infinite? (gauche) info (gauche.interactive) procedure-info (gauche)
プログラムの変更場所: info関数の定義の
(let1 nodename (hash-table-get *info-index* (x->string fn) #f) (unless nodename (errorf "no info document for ~a" fn)) (viewer (ref (info-get-node *info* nodename) 'content)))
の部分を
(let1 nodename (hash-table-get *info-index* (x->string fn) #f) (if nodename (viewer (ref (info-get-node *info* nodename) 'content)) (let1 entries (remove not (hash-table-map *info-index* (lambda (name node-name) (and (string-scan name (x->string fn)) (format #f "~30a (~a)\n" name node-name))))) (if (pair? entries) (for-each display entries) (errorf "no info document for ~a" fn)))))
に変える(追記: aproposの挙動に合わせるなら、entriesをソートしたほうがよかった)。ちょうど一致するものがあっても一覧を見たい、って場合には対応していないので使い勝手はあまりよくないかも。
diff -ruN orig/lib/gauche/interactive/info.scm lib/gauche/interactive/info.scm --- orig/lib/gauche/interactive/info.scm 2009-04-02 21:14:08.000000000 +0900 +++ lib/gauche/interactive/info.scm 2010-03-26 22:02:37.000000000 +0900 @@ -44,7 +44,7 @@ ) (select-module gauche.interactive.info) -(define *info-file* "gauche-refe.info") +(define *info-file* "gauche-refj.info") (define *info* #f) (define *info-index* (make-hash-table 'string=?)) @@ -95,10 +95,19 @@ (for-each (lambda (p) (hash-table-put! *info-index* (car p) (cdr p))) (info-parse-menu (info-get-node *info* - "Function and Syntax Index")))) + (list->string (map ucs->char + '(73 110 100 101 120 32 45 32 25163 32154 12365 12392 27083 25991 32034 24341))))))) (let1 nodename (hash-table-get *info-index* (x->string fn) #f) - (unless nodename (errorf "no info document for ~a" fn)) - (viewer (ref (info-get-node *info* nodename) 'content))) + (if nodename + (viewer (ref (info-get-node *info* nodename) 'content)) + (let1 entries (remove not + (hash-table-map *info-index* + (lambda (name node-name) + (and (string-scan name (x->string fn)) + (format #f "~30a (~a)\n" name node-name))))) + (if (pair? entries) + (for-each display entries) + (errorf "no info document for ~a" fn))))) (values)) (provide "gauche/interactive/info") diff -ruN orig/lib/text/info.scm lib/text/info.scm --- orig/lib/text/info.scm 2009-04-02 21:14:08.000000000 +0900 +++ lib/text/info.scm 2010-03-26 21:58:28.000000000 +0900 @@ -70,9 +70,9 @@ (define (read-info-file-split file opts) (define (with-input-from-info thunk) (cond ((file-exists? file) - (with-input-from-file file thunk)) + (with-input-from-file file thunk :encoding "*jp")) ((file-exists? #`",|file|.gz") - (with-input-from-process #`",gunzip -c ,file" thunk)) + (with-input-from-process #`",gunzip -c ,file" thunk :encoding "*jp")) (else (error "can't find info file" file)))) (with-input-from-info