[インデックス 15632] ファイルの概要
このコミットは、Go言語のEmacsモード(go-mode.el
)におけるgofmt
関数の実装を大幅に改善するものです。具体的には、gofmt
の出力に依存してdiff-mode
でパッチを適用する従来の方式から、Emacs内でRCS形式の差分を生成し、それを独自関数で適用する新しい方式へと変更しています。これにより、既存の未解決の問題が修正され、より堅牢で柔軟なフォーマット機能が提供されます。
コミット
commit 77ddbf1ff0278f7399509014b7078a3364248f67
Author: Dominik Honnef <dominik.honnef@gmail.com>
Date: Thu Mar 7 13:12:37 2013 -0500
misc/emacs: Rewrite gofmt to use own function for applying patch instead of using diff-mode.
Instead of relying on gofmt's diff output (which is a unified
diff), we manually invoke diff -n and produce an RCS format diff,
which can easily be parsed in Emacs, with the go--apply-rcs-patch
function.
This fixes undocumented issues with the old implementation such as
skipping over hunks of changes, and it fixes the documented issue
of not being able to handle file names that include whitespace.
It can also apply the patch on a buffer that has no file name
attached at all.
Last but not least, it greatly simplifies the gofmt function
itself.
Fixes #4766.
Fixes #4475.
R=adonovan, cw, patrick.allen.higgins, sameer
CC=golang-dev
https://golang.org/cl/7516046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/77ddbf1ff0278f7399509014b7078a3364248f67
元コミット内容
このコミットの元の内容は、misc/emacs: Rewrite gofmt to use own function for applying patch instead of using diff-mode.
というタイトルで、gofmt
の出力をdiff-mode
で処理するのではなく、独自の関数でパッチを適用するようにgofmt
のEmacs実装を書き直したことを示しています。
主な変更点は以下の通りです。
gofmt
の統一差分出力に依存する代わりに、diff -n
を手動で呼び出してRCS形式の差分を生成し、go--apply-rcs-patch
関数でEmacs内で簡単に解析できるようにした。- これにより、古い実装における、変更のチャンクをスキップするなどの未文書化の問題や、ファイル名に空白が含まれるファイルを処理できないという文書化された問題が修正された。
- ファイル名が全く添付されていないバッファにもパッチを適用できるようになった。
gofmt
関数自体が大幅に簡素化された。
この変更は、Go issue #4766と#4475を修正します。
変更の背景
このコミットの背景には、Go言語のコードフォーマッタであるgofmt
をEmacsエディタ内で利用する際の既存の課題がありました。従来のgo-mode.el
におけるgofmt
の実装は、gofmt
コマンドが生成する統一差分(unified diff)の出力に依存し、それをEmacsのdiff-mode
を使って現在のバッファに適用していました。
しかし、このアプローチにはいくつかの問題がありました。
- 未文書化の問題(スキップされる変更):
diff-mode
がgofmt
の生成する差分を適切に解釈できない場合があり、結果として一部の変更が適用されない、つまり「変更のチャンクがスキップされる」という問題が発生していました。これは、ユーザーがgofmt
を実行しても期待通りのフォーマットが適用されないという、非常に厄介なバグでした。 - ファイル名に空白が含まれる問題:
diff-mode
は、ファイル名に空白が含まれる場合にパッチの適用に失敗するという既知の問題を抱えていました。これは、特にWindows環境など、ファイル名に空白が頻繁に使用される環境でGoコードを編集するユーザーにとって大きな障壁となっていました。 - ファイル名のないバッファへの適用: 新規ファイルなど、まだファイル名が保存されていないEmacsバッファに対して
gofmt
を適用しようとすると、既存の実装では問題が発生する可能性がありました。 - コードの複雑性: 既存の
gofmt
関数は、差分処理の複雑さに起因して、その内部ロジックが複雑になっていました。
これらの問題は、Go言語のEmacsユーザーの生産性を低下させ、gofmt
の利便性を損なっていました。特に、gofmt
はGo言語の公式なコードスタイルを強制するための重要なツールであるため、そのEmacs統合が不安定であることは、開発体験全体に悪影響を与えていました。
このコミットは、これらの問題を根本的に解決するために、gofmt
の出力を直接パースして適用するのではなく、より制御された方法で差分を生成し、Emacs内でその差分を適用する新しいメカニズムを導入することで、より堅牢で信頼性の高いgofmt
統合を目指しました。
前提知識の解説
このコミットを理解するためには、以下の技術的な概念について基本的な知識が必要です。
-
gofmt
:- Go言語の公式なコードフォーマッタです。Goのソースコードを標準的なスタイルに自動的に整形します。
- 開発者が手動でコードスタイルを調整する手間を省き、プロジェクト全体で一貫したコードスタイルを維持することを目的としています。
- 通常、コマンドラインから
gofmt [ファイル名]
のように実行されます。変更を直接ファイルに書き込むことも、差分を出力することも可能です。 - このコミットでは、
gofmt
が生成する差分形式(統一差分)と、diff -n
コマンドが生成するRCS形式の差分が重要な役割を果たします。
-
Emacs:
- 高機能なテキストエディタであり、プログラミングIDEとしても広く使われています。
- Lisp方言であるEmacs Lisp(Elisp)で拡張可能であり、ユーザーは独自の関数やモードを記述して機能をカスタマイズできます。
go-mode.el
は、EmacsでGo言語のコードを編集するための主要なモードであり、シンタックスハイライト、インデント、gofmt
との統合などの機能を提供します。
-
差分(Diff):
- 2つのファイルまたはテキストのバージョン間の違いを示す情報です。
- 統一差分(Unified Diff):
diff -u
コマンドによって生成される一般的な差分形式で、変更された行の前後数行のコンテキストを含み、追加行は+
、削除行は-
で示されます。gofmt
が差分を出力する際に使用する形式です。 - RCS形式差分(RCS format diff):
diff -n
コマンドによって生成される差分形式で、RCS (Revision Control System) で使用される形式です。これは、変更の種類(追加a
または削除d
)、開始行番号、および変更された行数を示す簡潔な形式です。例えば、a10 5
は10行目から5行追加されたことを意味し、d20 3
は20行目から3行削除されたことを意味します。このコミットでは、このRCS形式の差分をEmacs内で解析しやすくするために採用しています。
-
diff-mode
(Emacs):- Emacsの組み込みモードの一つで、差分ファイルを閲覧したり、差分を現在のバッファに適用したりする機能を提供します。
- 従来の
go-mode.el
のgofmt
実装では、gofmt
の統一差分出力をdiff-mode
に渡してパッチを適用していました。しかし、このアプローチには前述の問題がありました。
-
Emacs Lisp (Elisp):
- Emacsの拡張言語です。Emacsのほとんどの機能はElispで書かれており、ユーザーはElispを使ってEmacsをカスタマイズしたり、新しい機能を追加したりできます。
- このコミットで追加された
go--apply-rcs-patch
関数はElispで書かれており、RCS形式の差分を解析し、現在のバッファに手動で適用するロジックを含んでいます。
これらの概念を理解することで、なぜこのコミットが重要であり、どのようにして既存の問題を解決しているのかが明確になります。特に、統一差分とRCS形式差分の違い、そしてEmacs Lispで差分を「手動で」適用するロジックが、この変更の核心部分となります。
技術的詳細
このコミットの技術的な核心は、gofmt
の出力を処理し、Emacsバッファに適用するメカニズムを根本的に変更した点にあります。
従来のgofmt
統合の問題点とアプローチ
従来のgo-mode.el
のgofmt
関数は、以下の手順で動作していました。
- 現在のEmacsバッファの内容を
gofmt
コマンドの標準入力にパイプします。 gofmt
コマンドには-d
フラグ(差分出力)を付けて実行し、整形前と整形後の差分を統一差分形式で標準出力に出力させます。shell-command-on-region
関数を使って、gofmt
の出力を一時的なバッファ(*Gofmt patch*
)にキャプチャします。- キャプチャされた統一差分をEmacsの
diff-mode
の機能(diff-apply-hunk
など)を使って現在のバッファに適用します。
このアプローチは、diff-mode
が差分解析と適用を抽象化してくれるため、一見するとシンプルに見えます。しかし、前述の通り、diff-mode
が特定の統一差分形式やファイル名(特に空白を含む場合)を適切に処理できないという問題がありました。また、新規ファイルのようにファイル名がないバッファの場合、diff-mode
はファイルベースの差分適用を前提としているため、直接適用が困難でした。
新しいgofmt
統合のアプローチ
このコミットでは、これらの問題を解決するために、以下の新しいアプローチを採用しています。
-
一時ファイルの利用:
- 現在のEmacsバッファの内容を一時ファイルに書き込みます。これは
write-region nil nil tmpfile
で行われます。一時ファイルはmake-temp-file
で作成され、.go
拡張子が付けられます。 - これにより、
gofmt
やdiff
コマンドが実際のファイルとして操作できるようになり、ファイル名がないバッファの問題が解消されます。
- 現在のEmacsバッファの内容を一時ファイルに書き込みます。これは
-
gofmt -w
の利用:gofmt
コマンドを-w
フラグ付きで実行し、一時ファイルの内容を直接整形して上書きします。call-process "gofmt" nil errbuf nil "-w" tmpfile
- このステップでは、
gofmt
は整形後の内容を標準出力に出力せず、直接ファイルに書き込むため、gofmt
の出力形式に依存する必要がなくなります。エラーが発生した場合のみ、errbuf
にエラーメッセージが出力されます。
-
diff -n
によるRCS形式差分の生成:- 整形前(現在のEmacsバッファの内容)と整形後(
gofmt -w
で整形された一時ファイルの内容)の差分を、diff -n
コマンドを使ってRCS形式で生成します。 call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile
diff -n
は、RCS形式の差分を出力します。この形式は、追加(a
)または削除(d
)の操作、開始行番号、および行数という非常に簡潔な構造を持っています。例えば、a10 5
は10行目から5行追加、d20 3
は20行目から3行削除を意味します。
- 整形前(現在のEmacsバッファの内容)と整形後(
-
go--apply-rcs-patch
による独自パッチ適用:- 生成されたRCS形式の差分を、新しく導入されたEmacs Lisp関数
go--apply-rcs-patch
が解析し、現在のEmacsバッファに手動で適用します。 - この関数は、RCS形式の各「チャンク」(追加または削除の指示)をループで処理します。
action
(a
またはd
)、from
(開始行番号)、len
(行数)を抽出し、それに基づいて現在のバッファのテキストを挿入または削除します。line-offset
の管理: パッチ適用中にバッファの行番号が変化するため、line-offset
という変数を導入して、パッチ内の行番号と実際のバッファの行番号との相対的なずれを追跡します。行の追加はオフセットを減らし(負の方向に)、行の削除はオフセットを増やします。これにより、後続のパッチチャンクが正しい位置に適用されるようにします。go--kill-whole-line
ヘルパー関数が、指定された行数を削除するために使用されます。
- 生成されたRCS形式の差分を、新しく導入されたEmacs Lisp関数
利点
この新しいアプローチにより、以下の利点がもたらされます。
- 堅牢性の向上:
diff-mode
の特定の挙動に依存しないため、未文書化の問題やファイル名に空白が含まれる問題が解消されます。RCS形式の差分は非常にシンプルで予測可能なため、Emacs Lispでの解析と適用が容易になります。 - 柔軟性: ファイル名がないバッファにも
gofmt
を適用できるようになります。 - 簡素化:
gofmt
関数自体のロジックが大幅に簡素化されます。差分生成と適用ロジックが分離され、特にgo--apply-rcs-patch
が差分適用の中核を担うことで、gofmt
関数はより高レベルなオーケストレーションに集中できます。 - パフォーマンス:
diff -n
は統一差分よりも簡潔な出力を生成するため、解析が高速になる可能性があります。
エラー処理の改善
エラー処理も改善されています。gofmt
やdiff
コマンドが失敗した場合、errbuf
にエラーメッセージがキャプチャされ、gofmt--process-errors
関数によってEmacsのコンパイルモードで表示されるようになります。これにより、ユーザーはgofmt
が失敗した理由を簡単に確認できます。特に、tmpfile
のパスが実際のファイル名に置換されることで、エラーメッセージがより分かりやすくなっています。
このコミットは、Emacsと外部ツール(gofmt
、diff
)との連携において、より低レベルで制御されたアプローチを採用することで、既存の統合の不安定性を解消し、より信頼性の高い開発体験を提供することに成功しています。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は、主にmisc/emacs/go-mode.el
ファイルに集中しています。
削除されたコード
(require 'diff-mode)
:diff-mode
への依存が削除されました。これは、パッチ適用にdiff-mode
を使用しなくなったためです。(defconst gofmt-stdin-tag "<standard input>")
:gofmt
が標準入力から読み込む際に使用するタグが削除されました。これは、一時ファイルを使用するようになったため不要になりました。gofmt--replace-buffer
関数: 新規ファイルの場合にバッファ全体を置き換えるためのヘルパー関数が削除されました。新しいアプローチでは、ファイル名のないバッファもRCSパッチで処理できるため不要です。gofmt--apply-patch
関数:diff-mode
を使ってパッチを適用するための主要なヘルパー関数が削除されました。これは、独自のパッチ適用関数に置き換えられたためです。gofmt
関数内の複雑なロジック: 従来のgofmt
関数内にあった、diff-mode
の呼び出し、新規ファイルかどうかの判定、diff-mode
が処理しやすいようにファイルの最後に改行を追加するロジックなどが削除され、大幅に簡素化されました。
追加されたコード
-
go--apply-rcs-patch
関数:- この関数は、RCS形式の差分を解析し、現在のバッファに適用するための新しい中核となるロジックです。
patch-buffer
からRCS形式の差分(a
またはd
、開始行、行数)を読み込みます。line-offset
という変数を導入し、パッチ適用中にバッファの行番号が変化するのを考慮して、正確な位置にパッチを適用します。forward-line
、insert
、decf
、incf
、go--kill-whole-line
などのEmacs Lisp関数を組み合わせて、テキストの追加や削除を直接行います。
-
gofmt
関数の再実装:gofmt
関数は大幅に簡素化され、新しいアプローチを採用しています。make-temp-file
で一時ファイルを作成し、現在のバッファの内容をそこに書き込みます。call-process
を使ってgofmt -w
を実行し、一時ファイルを直接整形します。call-process-region
を使ってdiff -n
を実行し、整形前と整形後の一時ファイルの差分をRCS形式でpatchbuf
に生成します。go--apply-rcs-patch
を呼び出して、生成されたRCSパッチを現在のバッファに適用します。- エラー処理のために
gofmt--process-errors
を呼び出し、一時ファイルとパッチバッファをクリーンアップします。
-
gofmt--process-errors
関数の修正:- エラーメッセージ内の
gofmt-stdin-tag
をファイル名に置換するロジックが、一時ファイルのパスを実際のファイル名に置換するロジックに変更されました。これにより、エラーメッセージがより正確になります。
- エラーメッセージ内の
これらの変更により、gofmt
のEmacs統合は、外部ツール(gofmt
、diff
)との連携をより細かく制御し、Emacs Lisp内で差分適用ロジックを直接実装することで、堅牢性と柔軟性を大幅に向上させています。
コアとなるコードの解説
ここでは、このコミットで導入された主要な関数であるgo--apply-rcs-patch
と、再実装されたgofmt
関数のコアロジックについて詳しく解説します。
go--apply-rcs-patch
関数
この関数は、RCS形式の差分を解析し、現在のEmacsバッファに適用する役割を担います。
(defun go--apply-rcs-patch (patch-buffer)
"Apply an RCS-formatted diff from PATCH-BUFFER to the current
buffer."
(let ((target-buffer (current-buffer))
;; Relative offset between buffer line numbers and line numbers
;; in patch.
;;
;; Line numbers in the patch are based on the source file, so
;; we have to keep an offset when making changes to the
;; buffer.
;;
;; Appending lines decrements the offset (possibly making it
;; negative), deleting lines increments it. This order
;; simplifies the forward-line invocations.
(line-offset 0))
(save-excursion
(with-current-buffer patch-buffer
(goto-char (point-min))
(while (not (eobp))
(unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
(error "invalid rcs patch or internal error in go--apply-rcs-patch"))
(forward-line)
(let ((action (match-string 1))
(from (string-to-number (match-string 2)))
(len (string-to-number (match-string 3))))
(cond
((equal action "a")
(let ((start (point)))
(forward-line len)
(let ((text (buffer-substring start (point))))
(with-current-buffer target-buffer
(decf line-offset len)
(goto-char (point-min))
(forward-line (- from len line-offset))
(insert text))))))
((equal action "d")
(with-current-buffer target-buffer
(goto-char (point-min))
(forward-line (- from line-offset 1))
(incf line-offset len)
(go--kill-whole-line len))))
(t
(error "invalid rcs patch or internal error in go--apply-rcs-patch")))))))))
patch-buffer
: RCS形式の差分が格納されているバッファです。target-buffer
: パッチを適用する対象のバッファ(通常は現在のバッファ)です。line-offset
: この変数がこの関数の肝です。パッチ内の行番号は元のファイルに基づいているため、パッチ適用中にtarget-buffer
の行数が変化すると、後続のパッチの適用位置がずれてしまいます。- 行を追加(
a
)すると、target-buffer
の行数が増えるため、line-offset
をlen
(追加された行数)だけ減らします。これにより、パッチ内の行番号が指す位置が、実際のバッファではより後ろにずれることを補正します。 - 行を削除(
d
)すると、target-buffer
の行数が減るため、line-offset
をlen
(削除された行数)だけ増やします。これにより、パッチ内の行番号が指す位置が、実際のバッファではより前にずれることを補正します。
- 行を追加(
save-excursion
: このマクロは、内部のコードブロックが実行された後、ポイント(カーソル位置)とマーク(選択範囲の開始点)を元の位置に戻します。これにより、パッチ適用中にカーソル位置が移動しても、ユーザーの操作に影響を与えません。with-current-buffer patch-buffer
:patch-buffer
に一時的に切り替えて、差分を読み込みます。while (not (eobp))
:patch-buffer
の最後までループします。looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)"
: RCS形式の差分行(例:a10 5
やd20 3
)を正規表現でマッチさせます。\\([ad]\\)
:a
またはd
(アクション)をキャプチャグループ1に。\\([0-9]+\\)
: 行番号をキャプチャグループ2に。\\([0-9]+\\)
: 行数をキャプチャグループ3に。
forward-line
: 現在の行をスキップして次の行に進みます。match-string
: 正規表現でキャプチャしたグループの内容を取得します。cond
:action
の値に基づいて処理を分岐します。action "a"
(追加):patch-buffer
内で追加するテキストの開始位置をstart
に保存します。forward-line len
で、追加するテキストの行数分だけポイントを進めます。buffer-substring start (point)
で、追加するテキストを抽出します。with-current-buffer target-buffer
でtarget-buffer
に切り替えます。decf line-offset len
でline-offset
を更新します。goto-char (point-min)
でバッファの先頭に移動します。forward-line (- from len line-offset))
で、パッチを適用する正確な行に移動します。from
はパッチ内の開始行、len
は追加される行数、line-offset
はこれまでの変更によるずれを補正します。insert text
で、抽出したテキストを挿入します。
action "d"
(削除):with-current-buffer target-buffer
でtarget-buffer
に切り替えます。goto-char (point-min)
でバッファの先頭に移動します。forward-line (- from line-offset 1))
で、削除を開始する正確な行に移動します。from
はパッチ内の開始行、line-offset
はこれまでの変更によるずれを補正します。-1
は、行番号が1から始まるため、0ベースのインデックスに合わせるためです。incf line-offset len
でline-offset
を更新します。go--kill-whole-line len
で、指定された行数だけ行を削除します。
このgo--apply-rcs-patch
関数は、Emacs Lispの基本的なテキスト操作関数を組み合わせて、RCS形式の差分を非常に正確かつ堅牢に適用するカスタムパッチエンジンとして機能します。
gofmt
関数の再実装(主要部分)
再実装されたgofmt
関数は、go--apply-rcs-patch
を利用して、より簡潔で信頼性の高いフォーマット処理を実現しています。
(defun gofmt ()
"Formats the current buffer according to the gofmt tool."
(interactive)
(let ((tmpfile (make-temp-file "gofmt" nil ".go"))
(patchbuf (get-buffer-create "*Gofmt patch*"))
(errbuf (get-buffer-create "*Gofmt Errors*"))
(coding-system-for-read 'utf-8)
(coding-system-for-write 'utf-8)))
(with-current-buffer errbuf
(setq buffer-read-only nil)
(erase-buffer))
(with-current-buffer patchbuf
(erase-buffer))
(write-region nil nil tmpfile) ; 現在のバッファの内容を一時ファイルに書き込む
;; gofmt -w を実行し、一時ファイルを直接整形する
;; errbuf は stdout と stderr の両方を受け取るが、gofmt -w は成功時に stdout を出力しないため問題ない
(if (zerop (call-process "gofmt" nil errbuf nil "-w" tmpfile))
;; gofmt が成功した場合
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
;; 差分がない場合(既に gofmt されている)
(message "Buffer is already gofmted")
;; 差分がある場合、RCSパッチを適用
(go--apply-rcs-patch patchbuf)
(kill-buffer errbuf) ; エラーバッファをクリーンアップ
(message "Applied gofmt"))
;; gofmt が失敗した場合
(message "Could not apply gofmt. Check errors for details")
(gofmt--process-errors (buffer-file-name) tmpfile errbuf)))
(kill-buffer patchbuf) ; パッチバッファをクリーンアップ
(delete-file tmpfile))) ; 一時ファイルを削除
interactive
: この関数がEmacsのM-xコマンドとして呼び出せるようにします。let
: ローカル変数を定義します。tmpfile
: 一時ファイルのパス。patchbuf
: RCS差分を格納するバッファ。errbuf
:gofmt
やdiff
のエラー出力を格納するバッファ。coding-system-for-read
,coding-system-for-write
: UTF-8エンコーディングを指定します。
write-region nil nil tmpfile
: 現在のバッファ全体の内容をtmpfile
に書き込みます。nil nil
はバッファ全体を意味します。call-process "gofmt" nil errbuf nil "-w" tmpfile
:gofmt
コマンドを実行します。nil
: 標準入力はなし(ファイルから読み込むため)。errbuf
:gofmt
の標準出力と標準エラー出力をこのバッファにリダイレクトします。nil
: 標準入力はなし。"-w" tmpfile
:tmpfile
を直接整形して上書きするオプションです。zerop
: コマンドの終了コードが0(成功)かどうかをチェックします。
call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile
:diff
コマンドを実行してRCS形式の差分を生成します。(point-min) (point-max)
: 現在のバッファ全体をdiff
の最初の入力として使用します(これは整形前の内容)。"diff"
: 実行するコマンド。nil
: 標準入力はなし。patchbuf
:diff
の標準出力をこのバッファにリダイレクトします(RCS差分がここに入る)。nil
: 標準入力はなし。"-n"
: RCS形式の差分を出力するオプション。"-"
:diff
の最初の入力が標準入力から来ることを示します(この場合はcall-process-region
のリージョン)。tmpfile
:diff
の2番目の入力(整形後の内容)。
go--apply-rcs-patch patchbuf
:diff -n
で生成されたRCS差分をgo--apply-rcs-patch
関数に渡し、現在のバッファに適用します。gofmt--process-errors (buffer-file-name) tmpfile errbuf
:gofmt
が失敗した場合にエラーメッセージを処理し、表示します。kill-buffer patchbuf)
、delete-file tmpfile)
: 処理後に一時的なバッファとファイルをクリーンアップします。
この再実装により、gofmt
はより信頼性の高い方法で動作し、Emacsユーザーにとってより良い体験を提供できるようになりました。
関連リンク
- Go issue #4766: https://code.google.com/p/go/issues/detail?id=4766 (古いGo issueトラッカーのリンク。現在はGitHubに移行している可能性がありますが、当時の参照元です。)
- このissueは、
gofmt
がファイル名に空白を含むファイルを処理できない問題に関連している可能性があります。
- このissueは、
- Go issue #4475: https://code.google.com/p/go/issues/detail?id=4475 (古いGo issueトラッカーのリンク。)
- このissueは、
gofmt
のEmacs統合における、変更がスキップされるなどの未文書化の問題に関連している可能性があります。
- このissueは、
- Gerrit Change-Id
7516046
: https://golang.org/cl/7516046- これは、このコミットがGoプロジェクトのGerritコードレビューシステムでレビューされた際の変更リスト(Change-Id)へのリンクです。Gerritは、GoプロジェクトがGitHubに移行する前に使用していたコードレビューツールです。このリンクを辿ることで、当時のレビューコメントや議論、変更の経緯を詳細に確認できます。
これらのリンクは、このコミットが解決しようとした具体的な問題と、その変更がどのようにGoコミュニティ内で議論され、承認されたかについての追加情報を提供します。
参考にした情報源リンク
- Emacs Lisp Reference Manual: Emacs Lispの関数やマクロの公式ドキュメント。
defun
,let
,interactive
,save-excursion
,with-current-buffer
,goto-char
,point-min
,eobp
,looking-at
,forward-line
,match-string
,string-to-number
,cond
,equal
,decf
,incf
,buffer-substring
,insert
,call-process
,call-process-region
,make-temp-file
,write-region
,kill-buffer
,delete-file
などの関数の詳細な挙動を理解するために参照しました。 diff
コマンドのマニュアルページ:diff -n
オプションがRCS形式の差分を生成すること、およびその出力形式について理解するために参照しました。man diff
(Linux/Unixシステムでコマンドラインから参照可能)
gofmt
コマンドのドキュメント:gofmt -w
オプションがファイルを直接整形すること、およびgofmt
の一般的な使用法について理解するために参照しました。- RCS (Revision Control System): RCS形式の差分がどのように構成されているか、その歴史的背景と目的について理解するために参照しました。
- Unified Diff Format: 統一差分形式の構造と、それがどのように変更を示すかについて理解するために参照しました。
- Emacs
diff-mode
documentation: 従来のgofmt
統合がdiff-mode
にどのように依存していたか、そしてその限界について理解するために参照しました。- Emacs内で
C-h f diff-mode
などで参照可能。
- Emacs内で
これらの情報源は、このコミットの技術的な詳細、背景、および関連する概念を深く掘り下げる上で不可欠でした。