[インデックス 18842] ファイルの概要
このコミットは、Go言語のEmacsメジャーモードであるgo-mode.el
における、メソッドのシンタックスハイライト(fontification)に関するバグ修正です。具体的には、go-fontify-function-calls
変数がnil
(無効)に設定されている場合に、メソッド宣言の誤った部分がハイライトされてしまう問題を解決します。
コミット
- コミットハッシュ:
e9ba9470bc0c7042e2e5aac6838aa86f2f514ca3
- Author: Dominik Honnef dominik.honnef@gmail.com
- Date: Wed Mar 12 11:02:42 2014 -0400
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e9ba9470bc0c7042e2e5aac6838aa86f2f514ca3
元コミット内容
misc/emacs: correctly fontify methods when go-fontify-function-calls is nil
We were fontifying the wrong part of method declarations
LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/66120043
変更の背景
Emacsのgo-mode.el
では、Go言語のコードを適切にシンタックスハイライトするための設定が含まれています。go-fontify-function-calls
という変数は、関数呼び出しやメソッド呼び出しをハイライトするかどうかを制御します。この変数がnil
に設定されている場合、つまり関数呼び出しのハイライトが無効になっている場合でも、メソッド宣言自体は適切にハイライトされるべきです。
しかし、このコミット以前のgo-mode.el
の実装では、go-fontify-function-calls
がnil
の際に、メソッド宣言のハイライトにおいて正規表現のキャプチャグループの指定が誤っていました。これにより、メソッド名ではなく、メソッド宣言全体の別の部分(例えばレシーバの型など)が誤ってハイライトされてしまう問題が発生していました。このコミットは、この誤ったハイライトを修正し、メソッド名が正しくハイライトされるようにすることを目的としています。
前提知識の解説
Emacs font-lock-mode
font-lock-mode
は、Emacsにおける主要なシンタックスハイライト(構文強調)システムです。このモードは、バッファの内容を解析し、特定のパターン(通常は正規表現)に一致するテキストに異なるフォントフェイス(色、太字、斜体など)を適用することで、コードの可読性を向上させます。
font-lock-mode
は、各メジャーモード(例: go-mode
、python-mode
など)が定義するfont-lock-keywords
という変数に依存します。この変数には、ハイライトのルールを定義するリストが格納されています。
font-lock-keywords
の構造と正規表現グループ
font-lock-keywords
の各エントリは、通常、以下の形式を取ります。
(REGEXP (GROUP FACE) ...)
REGEXP
: ハイライトしたいテキストパターンを定義する正規表現です。この正規表現内で括弧()
を使用すると、キャプチャグループを定義できます。GROUP
:REGEXP
内で定義されたキャプチャグループの番号(整数)を指定します。0
は正規表現全体の一致を指し、1
は最初のキャプチャグループ、2
は2番目のキャプチャグループ、といった具合に続きます。FACE
:GROUP
で指定されたキャプチャグループに適用されるフォントフェイス(例:font-lock-function-name-face
、font-lock-type-face
など)です。
font-lock-mode
は、REGEXP
がバッファ内で一致するたびに、指定されたGROUP
の内容にFACE
を適用します。この仕組みを利用して、例えば関数定義全体ではなく、関数名だけをハイライトするといった細かい制御が可能になります。
このコミットの文脈では、go-func-meth-regexp
という正規表現がメソッド宣言全体を捕捉し、その正規表現内の特定のキャプチャグループがメソッド名に対応していると推測されます。
技術的詳細
このコミットの核心は、Emacs Lispのfont-lock-mode
における正規表現のキャプチャグループの指定ミスを修正することです。
go-mode.el
の関連するコードスニペットは、go-fontify-function-calls
変数の値に基づいて、異なるハイライトルールを適用しています。
元のコードでは、go-fontify-function-calls
がnil
の場合に適用されるルールが以下のようになっていました。
`((,go-func-meth-regexp 1 font-lock-function-name-face))) ;; method name
ここで、,go-func-meth-regexp
はメソッド宣言に一致する正規表現です。そして、1
は、この正規表現の最初のキャプチャグループにfont-lock-function-name-face
(関数名用のフォントフェイス)を適用することを意味しています。
しかし、実際にはgo-func-meth-regexp
という正規表現の構造上、メソッド名が格納されているのは2番目のキャプチャグループでした。そのため、1
を指定すると、メソッド名ではない別の部分(例えばレシーバの型など)が誤ってハイライトされてしまっていたのです。
このコミットでは、このGROUP
の指定を1
から2
に変更することで、go-func-meth-regexp
の2番目のキャプチャグループ、すなわちメソッド名に正しくfont-lock-function-name-face
が適用されるように修正しています。
コアとなるコードの変更箇所
変更はmisc/emacs/go-mode.el
ファイルの一箇所のみです。
--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -269,7 +269,7 @@ For mode=set, all covered lines will have this weight.\"\
(if go-fontify-function-calls
`((,(concat \"\\\\(\" go-identifier-regexp \"\\\\)[[:space:]]*(\") 1 font-lock-function-name-face) ;; function call/method name
(,(concat \"[^[:word:][:multibyte:]](\\\\(\" go-identifier-regexp \"\\\\))[[:space:]]*(\") 1 font-lock-function-name-face)) ;; bracketed function call
- `((,go-func-meth-regexp 1 font-lock-function-name-face))) ;; method name
+ `((,go-func-meth-regexp 2 font-lock-function-name-face))) ;; method name
`(\
(,(concat (go--regexp-enclose-in-symbol \"type\") \"[[:space:]]+\\\\([^[:space:]]+\\\\)\") 1 font-lock-type-face) ;; types
コアとなるコードの解説
変更された行は以下の部分です。
- `((,go-func-meth-regexp 1 font-lock-function-name-face))) ;; method name
+ `((,go-func-meth-regexp 2 font-lock-function-name-face))) ;; method name
このコードは、go-fontify-function-calls
がnil
の場合に適用されるfont-lock-keywords
のエントリを定義しています。
-
で始まる行は削除された元のコードです。+
で始まる行は追加された新しいコードです。
変更点は、正規表現go-func-meth-regexp
に続く数字が1
から2
に変更されたことです。
この変更により、go-func-meth-regexp
が一致した際に、font-lock-function-name-face
が適用される対象のキャプチャグループが、元の「1番目のキャプチャグループ」から「2番目のキャプチャグループ」へと変更されました。これにより、go-func-meth-regexp
がGo言語のメソッド宣言をパースする際に、メソッド名が正しく2番目のキャプチャグループに格納されるという前提に基づき、メソッド名のみが適切にハイライトされるようになりました。
この修正は、Emacsのシンタックスハイライトが、正規表現のキャプチャグループの正確な理解と指定にどれほど依存しているかを示す良い例です。
関連リンク
- Go CL (Code Review) ページ: https://golang.org/cl/66120043
参考にした情報源リンク
- Emacs Lisp
font-lock-mode
documentation (general understanding offont-lock-keywords
and regex groups): - Stack Overflow / Emacs Wiki discussions on
font-lock-mode
regex group numbering: