[インデックス 15340] ファイルの概要
このコミットは、Go言語の公式Emacsモード(go-mode.el
)におけるgodoc
ドキュメントバッファの表示方法を改善するものです。具体的には、godoc
によって生成されたドキュメントを、編集可能な「Fundamental mode」ではなく、閲覧専用の「View mode」で表示するように変更しています。これにより、ユーザーが誤ってドキュメントの内容を編集してしまうことを防ぎ、Emacsの一般的な慣習に沿った振る舞いを実現しています。
コミット
commit 43da336b151993fa3b0d17dc443f5ba9d29d482f
Author: Steven Elliot Harris <seharris@gmail.com>
Date: Wed Feb 20 14:42:37 2013 -0800
misc/emacs: Present "godoc" documentation buffers using view-mode.
Mimic the Emacs convention of presenting read-only files meant
for browsing using view-mode, rather than Fundamental mode
which mistakenly allows editing of the "godoc" content.
Fixes #4322.
R=golang-dev, bradfitz, sameer
CC=golang-dev
https://golang.org/cl/7231055
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/43da336b151993fa3b0d17dc443f5ba9d29d482f
元コミット内容
misc/emacs: Present "godoc" documentation buffers using view-mode.
Mimic the Emacs convention of presenting read-only files meant
for browsing using view-mode, rather than Fundamental mode
which mistakenly allows editing of the "godoc" content.
Fixes #4322.
変更の背景
この変更の背景には、Emacsのgo-mode.el
がgodoc
コマンドの出力を表示する際に、デフォルトの「Fundamental mode」を使用していたという問題があります。godoc
はGo言語のソースコードからドキュメントを生成し、その出力は通常、閲覧のみを目的としたものです。しかし、「Fundamental mode」はEmacsの最も基本的なメジャーモードであり、特別な編集制限を持たないため、ユーザーが誤ってgodoc
の出力バッファの内容を編集してしまう可能性がありました。
Emacsの慣習として、閲覧専用のファイルやバッファは「View mode」で表示されるべきです。「View mode」はマイナーモードであり、バッファを読み取り専用に設定し、誤った変更を防ぎながら、スクロールや検索などの閲覧操作を可能にします。このコミットは、この慣習に合わせることで、ユーザーエクスペリエンスを向上させ、意図しないデータ変更のリスクを排除することを目的としています。具体的には、Go言語のIssue #4322で報告された問題の修正として実施されました。
前提知識の解説
Emacsのモード
Emacsには、テキストの編集や表示を制御するための「モード」という概念があります。
- メジャーモード (Major Mode): バッファごとに1つだけ設定されるモードで、特定のプログラミング言語(例:
go-mode
、python-mode
)やファイルタイプ(例:text-mode
)に特化した機能(シンタックスハイライト、インデント、補完など)を提供します。- Fundamental mode: Emacsの最も基本的なメジャーモードです。特定の言語やファイルタイプに特化した機能を持たず、すべてのEmacsコマンドが最も一般的な振る舞いをします。特別な設定がないため、編集が自由にできてしまいます。
- マイナーモード (Minor Mode): 複数のマイナーモードを同時に有効にできるモードで、メジャーモードの機能を補完したり、特定の振る舞いを変更したりします。
- View mode: このコミットで重要なマイナーモードです。バッファを読み取り専用にし、誤った編集を防ぎます。閲覧に便利なコマンド(ページスクロールなど)を提供し、
q
で終了したり、e
で読み取り専用を解除して編集モードに移行したりできます。
- View mode: このコミットで重要なマイナーモードです。バッファを読み取り専用にし、誤った編集を防ぎます。閲覧に便利なコマンド(ページスクロールなど)を提供し、
Emacs Lispのバッファ表示関数
Emacs Lispには、バッファをウィンドウに表示するためのいくつかの関数があります。
display-buffer
: Emacs Lispでバッファをウィンドウに表示するための主要かつ最もカスタマイズ可能な関数です。バッファを表示する最適なウィンドウを決定し、ACTION
引数を通じて表示方法(新しいウィンドウで開く、既存のウィンドウを再利用するなど)を細かく制御できます。'not-this-window
(旧来のACTION
引数):display-buffer
のACTION
引数として使用されるシンボルで、バッファを現在の選択されているウィンドウ以外に表示しようと試みます。これは、display-buffer-alist
というカスタマイズ変数を通じて、より柔軟な表示ルールが設定される前の古い形式の指定方法です。
view-buffer
: この関数は、特定のバッファを「View mode」で開くためのものです。display-buffer
とは異なり、直接的にバッファを読み取り専用の閲覧モードに切り替えることを意図しています。'kill-buffer
(view-buffer
のACTION
引数):view-buffer
関数に渡されるACTION
引数の一つで、View modeを終了した際に、そのバッファを自動的にキル(削除)することを指示します。これにより、一時的なドキュメント表示後にバッファが残り続けるのを防ぎます。
godocツール
godoc
はGo言語の公式ドキュメンテーションツールです。Goのソースコード内のコメントから自動的にドキュメントを抽出し、HTML形式やプレーンテキスト形式で表示します。Goのパッケージや関数の使い方を調べる際に非常に便利で、Goエコシステムにおける標準的なドキュメンテーション生成・閲覧ツールとして広く利用されています。godoc
はWebサーバーとして動作させることもでき、ブラウザ経由でドキュメントを閲覧することも可能です。
技術的詳細
このコミットは、misc/emacs/go-mode.el
ファイル内のgo-doc-buffer-process-filter
関数を変更しています。この関数は、godoc
コマンドの実行結果を処理し、その出力をEmacsバッファに表示する役割を担っています。
変更前は、godoc
コマンドが正常終了した場合(event "finished\\n"
)、display-buffer (current-buffer) 'not-this-window
というLisp式が実行されていました。これは、godoc
の出力が格納された現在のバッファを、現在のウィンドウ以外の場所に表示しようとするものです。しかし、この表示方法では、バッファのメジャーモードが「Fundamental mode」のままであり、読み取り専用の保護がありませんでした。
変更後は、この行がview-buffer (current-buffer) 'kill-buffer
に置き換えられています。
view-buffer (current-buffer)
:godoc
の出力が格納された現在のバッファを「View mode」で開きます。これにより、バッファは自動的に読み取り専用となり、誤った編集が防止されます。'kill-buffer
:view-buffer
のACTION
引数として渡されており、ユーザーが「View mode」を終了した際に、このgodoc
ドキュメントバッファを自動的にキル(削除)することを指示します。これは、一時的なドキュメント表示のために作成されたバッファが、用済みになった後にEmacs内に残り続けるのを防ぐためのクリーンアップ処理です。
この変更により、godoc
のドキュメントはEmacsの慣習に沿って読み取り専用で表示され、ユーザーがドキュメントを閲覧する際の安全性と利便性が向上します。
コアとなるコードの変更箇所
--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -875,7 +875,7 @@ Replace the current buffer on success; display errors on failure."
(with-current-buffer (process-buffer proc)
(cond ((string= event "finished\\n") ;; Successful exit.
(goto-char (point-min))
- (display-buffer (current-buffer) 'not-this-window))
+ (view-buffer (current-buffer) 'kill-buffer))
((not (= (process-exit-status proc) 0)) ;; Error exit.
(let ((output (buffer-string)))
(kill-buffer (current-buffer))
コアとなるコードの解説
変更はgo-mode.el
ファイル内のgo-doc-buffer-process-filter
関数にあります。この関数は、godoc
コマンドがバックグラウンドで実行され、そのプロセスが終了した際に呼び出されるフィルター関数です。
(with-current-buffer (process-buffer proc))
:godoc
コマンドの出力が書き込まれたバッファを一時的に現在のバッファとして設定します。(cond ((string= event "finished\\n") ...))
: プロセスが正常に終了したかどうか(event
が"finished\\n"
であるか)をチェックします。(goto-char (point-min))
: バッファの先頭にカーソルを移動させます。これは、ドキュメントの表示を開始する前に、常に先頭から表示されるようにするためです。- 変更点:
- 変更前:
(display-buffer (current-buffer) 'not-this-window)
display-buffer
: バッファを表示するための汎用関数。(current-buffer)
:godoc
の出力が格納されているバッファ。'not-this-window
: 現在のウィンドウ以外にバッファを表示しようとする指示。しかし、これによりバッファが読み取り専用になるわけではありませんでした。
- 変更後:
(view-buffer (current-buffer) 'kill-buffer)
view-buffer
: バッファを「View mode」で表示するための関数。これにより、バッファは自動的に読み取り専用になります。(current-buffer)
: 同上。'kill-buffer
: 「View mode」を終了した際に、このバッファを自動的にキル(削除)する指示。これにより、一時的なドキュメントバッファがEmacs内に残り続けるのを防ぎ、リソースのクリーンアップが行われます。
- 変更前:
この変更により、godoc
の出力は読み取り専用の「View mode」で表示されるようになり、ユーザーが誤ってドキュメントを編集してしまうことを防ぎます。また、ドキュメントの閲覧が終了した際には、そのバッファが自動的に閉じられるため、Emacsのバッファリストが不要なエントリで cluttered になるのを防ぎます。
関連リンク
- Go言語のIssue #4322: https://code.google.com/p/go/issues/detail?id=4322 (古いGoogle Codeのリンクですが、コミットメッセージに記載されています)
- Go言語の変更リスト (CL): https://golang.org/cl/7231055
参考にした情報源リンク
- Emacs Manual: Major Modes: https://www.gnu.org/software/emacs/manual/html_node/emacs/Major-Modes.html
- Emacs Manual: Minor Modes: https://www.gnu.org/software/emacs/manual/html_node/emacs/Minor-Modes.html
- Emacs Manual: View Mode: https://www.gnu.org/software/emacs/manual/html_node/emacs/View-Mode.html
- Emacs Lisp Reference Manual: Displaying Buffers: https://www.gnu.org/software/emacs/manual/html_node/elisp/Displaying-Buffers.html
- Go Documentation:
godoc
command: https://pkg.go.dev/cmd/godoc - StackExchange: Difference between
display-buffer
andpop-to-buffer
: https://emacs.stackexchange.com/questions/1000/difference-between-display-buffer-and-pop-to-buffer - Xah Lee's Emacs Blog:
display-buffer
anddisplay-buffer-alist
: http://xahlee.info/emacs/emacs/elisp_display_buffer.html