Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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.elgodocコマンドの出力を表示する際に、デフォルトの「Fundamental mode」を使用していたという問題があります。godocはGo言語のソースコードからドキュメントを生成し、その出力は通常、閲覧のみを目的としたものです。しかし、「Fundamental mode」はEmacsの最も基本的なメジャーモードであり、特別な編集制限を持たないため、ユーザーが誤ってgodocの出力バッファの内容を編集してしまう可能性がありました。

Emacsの慣習として、閲覧専用のファイルやバッファは「View mode」で表示されるべきです。「View mode」はマイナーモードであり、バッファを読み取り専用に設定し、誤った変更を防ぎながら、スクロールや検索などの閲覧操作を可能にします。このコミットは、この慣習に合わせることで、ユーザーエクスペリエンスを向上させ、意図しないデータ変更のリスクを排除することを目的としています。具体的には、Go言語のIssue #4322で報告された問題の修正として実施されました。

前提知識の解説

Emacsのモード

Emacsには、テキストの編集や表示を制御するための「モード」という概念があります。

  • メジャーモード (Major Mode): バッファごとに1つだけ設定されるモードで、特定のプログラミング言語(例: go-modepython-mode)やファイルタイプ(例: text-mode)に特化した機能(シンタックスハイライト、インデント、補完など)を提供します。
    • Fundamental mode: Emacsの最も基本的なメジャーモードです。特定の言語やファイルタイプに特化した機能を持たず、すべてのEmacsコマンドが最も一般的な振る舞いをします。特別な設定がないため、編集が自由にできてしまいます。
  • マイナーモード (Minor Mode): 複数のマイナーモードを同時に有効にできるモードで、メジャーモードの機能を補完したり、特定の振る舞いを変更したりします。
    • View mode: このコミットで重要なマイナーモードです。バッファを読み取り専用にし、誤った編集を防ぎます。閲覧に便利なコマンド(ページスクロールなど)を提供し、qで終了したり、eで読み取り専用を解除して編集モードに移行したりできます。

Emacs Lispのバッファ表示関数

Emacs Lispには、バッファをウィンドウに表示するためのいくつかの関数があります。

  • display-buffer: Emacs Lispでバッファをウィンドウに表示するための主要かつ最もカスタマイズ可能な関数です。バッファを表示する最適なウィンドウを決定し、ACTION引数を通じて表示方法(新しいウィンドウで開く、既存のウィンドウを再利用するなど)を細かく制御できます。
    • 'not-this-window (旧来のACTION引数): display-bufferACTION引数として使用されるシンボルで、バッファを現在の選択されているウィンドウ以外に表示しようと試みます。これは、display-buffer-alistというカスタマイズ変数を通じて、より柔軟な表示ルールが設定される前の古い形式の指定方法です。
  • view-buffer: この関数は、特定のバッファを「View mode」で開くためのものです。display-bufferとは異なり、直接的にバッファを読み取り専用の閲覧モードに切り替えることを意図しています。
    • 'kill-buffer (view-bufferACTION引数): 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-bufferACTION引数として渡されており、ユーザーが「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コマンドがバックグラウンドで実行され、そのプロセスが終了した際に呼び出されるフィルター関数です。

  1. (with-current-buffer (process-buffer proc)): godocコマンドの出力が書き込まれたバッファを一時的に現在のバッファとして設定します。
  2. (cond ((string= event "finished\\n") ...)): プロセスが正常に終了したかどうか(event"finished\\n"であるか)をチェックします。
  3. (goto-char (point-min)): バッファの先頭にカーソルを移動させます。これは、ドキュメントの表示を開始する前に、常に先頭から表示されるようにするためです。
  4. 変更点:
    • 変更前: (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 になるのを防ぎます。

関連リンク

参考にした情報源リンク