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

[インデックス 12814] ファイルの概要

このコミットは、Go言語のEmacsメジャーモードであるgo-mode.elにおける構文テーブルと空白文字の扱いの修正に関するものです。具体的には、コメント文字の認識と改行文字の扱いを改善し、Emacs上でのGoコード編集体験を向上させることを目的としています。

コミット

commit b0f4d805f27fc8b24ced42fdce39b859d90ce101
Author: Sameer Ajmani <sameer@golang.org>
Date:   Mon Apr 2 12:59:37 2012 -0400

    misc/emacs: fix go-mode syntax table and whitespace handling.
    - flag * and / as comment characters
    - mark newline as a comment-ender
    - include newline in go-mode-whitespace-p
    
    Thanks Jonathan Amsterdam and Steve Yegge for the patch!
    
    R=golang-dev, rsc
    CC=golang-dev, jba, stevey
    https://golang.org/cl/5938056

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/b0f4d805f27fc8b24ced42fdce39b859d90ce101

元コミット内容

misc/emacs: fix go-mode syntax table and whitespace handling.
- flag * and / as comment characters
- mark newline as a comment-ender
- include newline in go-mode-whitespace-p

Thanks Jonathan Amsterdam and Steve Yegge for the patch!

R=golang-dev, rsc
CC=golang-dev, jba, stevey
https://golang.org/cl/5938056

変更の背景

Emacsは、その高度なカスタマイズ性と拡張性から、多くのプログラマーに愛用されているテキストエディタです。各プログラミング言語には、その言語の構文をEmacsが正しく解釈し、ハイライト表示、インデント、コメントの自動挿入などを適切に行うための「メジャーモード」が存在します。Go言語の場合、「go-mode」がその役割を担っています。

このコミットが行われた背景には、go-modeがGo言語のコメント(/* ... */// ...)を正しく認識できていなかったという問題がありました。具体的には、*(アスタリスク)と/(スラッシュ)がコメントの開始文字として適切にフラグ付けされておらず、また改行文字がコメントの終了を意味する文字として認識されていませんでした。これにより、Emacs上でのGoコードの編集時に、コメントのハイライトが途切れたり、インデントが崩れたり、コメント関連の操作が期待通りに機能しないといった不具合が発生していました。

また、go-mode-whitespace-pという関数が改行文字を空白文字として扱っていなかったため、空白文字のスキップや整形に関する処理が不正確になる可能性がありました。これらの問題を解決し、Emacsユーザーがより快適にGoコードを記述できるようにするために、この修正が導入されました。

前提知識の解説

Emacs Lisp (Elisp)

Emacs Lispは、Emacsエディタの拡張言語です。Emacsのほぼ全ての機能はEmacs Lispで記述されており、ユーザーはEmacs Lispを使って新しい機能を追加したり、既存の機能をカスタマイズしたりすることができます。go-mode.elもEmacs Lispで書かれたファイルであり、Go言語の編集に関するEmacsの振る舞いを定義しています。

構文テーブル (Syntax Table)

Emacsの構文テーブルは、各文字がどのような構文的な役割を持つかを定義するデータ構造です。例えば、文字が単語の一部なのか、空白文字なのか、コメントの開始文字なのか、文字列の区切り文字なのか、といった情報が格納されています。Emacsは構文テーブルを参照して、テキストのハイライト表示、単語単位の移動、コメントの自動挿入、インデントの調整など、様々な構文認識に基づく処理を行います。

構文テーブルのエントリは、modify-syntax-entry関数を使って変更できます。この関数は、文字、その文字の構文クラス、そしてオプションで構文フラグを受け取ります。

  • 構文クラス: 文字の基本的な種類を定義します。例えば、wは単語文字、 は空白文字、.は句読点などです。
  • 構文フラグ: 構文クラスをさらに詳細に定義します。例えば、コメントの開始文字、コメントの終了文字、文字列の開始文字などです。

このコミットでは、特に以下の構文フラグが重要です。

  • 1: コメントの開始文字(/**など)
  • 2: コメントの終了文字(*/*など)
  • 3: コメントの開始文字(///など)
  • 4: コメントの終了文字(\nなど、行コメントの終了)
  • b: バランスグループの開始文字(括弧など)
  • >: コメントの終了文字(行コメントの終了)

go-mode-whitespace-p 関数

この関数は、与えられた文字がgo-modeにおいて空白文字として扱われるべきかどうかを判定します。Emacsの構文テーブルでは、空白文字は通常、構文クラス32(スペース文字のASCIIコード)として定義されます。この関数は、インデントや空白文字の整形に関連するEmacsの内部処理で利用されます。

技術的詳細

このコミットの技術的な核心は、Emacsの構文テーブルの正確な設定と、空白文字判定関数の改善にあります。

構文テーブルの修正

Go言語では、ブロックコメントは/* ... */、行コメントは// ...で記述されます。Emacsがこれらのコメントを正しく認識するためには、*/がコメント関連の構文フラグを持つ必要があります。

元のコードでは、*/は単に句読点(.)として扱われていました。

    (modify-syntax-entry ?*  "." st)
    (modify-syntax-entry ?/  "." st)

修正後、これらの文字にはコメント関連の構文フラグが追加されました。

    (modify-syntax-entry ?*  ". 23" st)   ; also part of comments
    (modify-syntax-entry ?/  ". 124b" st) ; ditto
  • ?*: アスタリスク文字

    • .: 句読点クラス
    • 2: コメントの終了文字(*/*
    • 3: コメントの開始文字(/**
    • これにより、*がブロックコメントの開始と終了の両方に関与する文字として認識されます。
  • ?/: スラッシュ文字

    • .: 句読点クラス
    • 1: コメントの開始文字(/*/
    • 2: コメントの終了文字(*//
    • 4: コメントの終了文字(//の行コメントの終了)
    • b: バランスグループの開始文字(Go言語の正規表現などでの/の利用を考慮している可能性がありますが、コメントの文脈では主にコメント開始文字としての役割が強調されます)
    • これにより、/がブロックコメントと行コメントの開始文字として、また行コメントの終了文字としても認識されるようになります。

さらに、改行文字\nがコメントの終了文字として明示的にフラグ付けされました。

    ;; Newline is a comment-ender.
    (modify-syntax-entry ?\n "> b" st)
  • ?\n: 改行文字
    • >: コメントの終了文字(行コメントの終了)
    • b: バランスグループの開始文字(これは通常、括弧などに対して使われるフラグですが、ここでは改行が特定の構文要素の区切りとなることを示唆している可能性があります。行コメントの終了という文脈では>が主要な役割を果たします。)
    • この変更により、Emacsは行コメントが改行で終了することを正しく認識し、それ以降のテキストをコードとしてハイライトできるようになります。

go-mode-whitespace-p 関数の修正

元のgo-mode-whitespace-p関数は、文字の構文クラスが32(スペース)であるかどうかのみをチェックしていました。

(defun go-mode-whitespace-p (char)
  "Is char whitespace in the syntax table for go."
  (eq 32 (char-syntax char)))

修正後、この関数は改行文字?\nも空白文字として明示的に含めるようになりました。

(defun go-mode-whitespace-p (char)
  "Is newline, or char whitespace in the syntax table for go."
  (or (eq char ?\n)
      (eq 32 (char-syntax char))))

この変更により、go-modeが空白文字を扱う際に、スペースだけでなく改行も適切に考慮するようになり、インデントや整形処理の精度が向上します。

コアとなるコードの変更箇所

--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -33,8 +33,8 @@
      ;; Operators (punctuation)
      (modify-syntax-entry ?+  "." st)
      (modify-syntax-entry ?-  "." st)
-    (modify-syntax-entry ?*  "." st)
-    (modify-syntax-entry ?/  "." st)
+    (modify-syntax-entry ?*  ". 23" st)   ; also part of comments
+    (modify-syntax-entry ?/  ". 124b" st) ; ditto
      (modify-syntax-entry ?%  "." st)
      (modify-syntax-entry ?&  "." st)
      (modify-syntax-entry ?|  "." st)
@@ -50,6 +50,9 @@
      (modify-syntax-entry ?`  "." st)
      (modify-syntax-entry ?\\ "." st)
 
+    ;; Newline is a comment-ender.
+    (modify-syntax-entry ?\n "> b" st)
+
      st)
    "Syntax table for Go mode.")
 
@@ -545,8 +548,9 @@ token on the line."\n          (not (looking-at go-mode-non-terminating-keywords-regexp)))))))\n 
 (defun go-mode-whitespace-p (char)\n-  "Is char whitespace in the syntax table for go."\n-  (eq 32 (char-syntax char)))\n+  "Is newline, or char whitespace in the syntax table for go."\n+  (or (eq char ?\n)\n+      (eq 32 (char-syntax char))))\n 
 (defun go-mode-backward-skip-comments ()\n   "Skip backward over comments and whitespace."\n

コアとなるコードの解説

上記の差分は、go-mode.elファイル内の2つの主要な変更点を示しています。

  1. go-mode-syntax-table 関数の変更:

    • この関数は、Go言語の構文解析に使用されるEmacsの構文テーブルを構築します。
    • modify-syntax-entry関数が使用され、*/文字の構文定義が更新されています。
      • ?* (アスタリスク): 構文クラスは句読点 (.) のままで、構文フラグに 2 (コメント終了) と 3 (コメント開始) が追加されました。これにより、/* ... */形式のブロックコメントの開始と終了の両方で*が適切に認識されるようになります。
      • ?/ (スラッシュ): 構文クラスは句読点 (.) のままで、構文フラグに 1 (コメント開始), 2 (コメント終了), 4 (行コメント終了), b (バランスグループ開始) が追加されました。これにより、/* ... */形式のブロックコメントの開始と終了、および// ...形式の行コメントの開始と終了の両方で/が適切に認識されるようになります。特に4フラグは行コメントの終了を意味し、//コメントが改行で終わることをEmacsに伝えます。
    • 新たに、改行文字 ?\n の構文エントリが追加されました。構文クラスは不明ですが、構文フラグに > (コメント終了) と b (バランスグループ開始) が設定されています。これは、改行が行コメントの明確な終了点であることをEmacsに認識させるための重要な変更です。
  2. go-mode-whitespace-p 関数の変更:

    • この関数は、与えられた文字がGoモードにおいて空白文字として扱われるべきかを判定します。
    • 元の実装では、文字の構文クラスがスペース (32) であるかのみをチェックしていました。
    • 変更後、or条件が追加され、文字が改行文字 (?\n) であるか、または構文クラスがスペース (32) であるかのいずれかの場合に真を返すようになりました。これにより、改行も空白文字として適切に扱われるようになり、インデントや整形処理の精度が向上します。

これらの変更により、EmacsはGo言語のコメントをより正確に解析し、ハイライト表示、インデント、およびその他の構文認識に基づく機能を改善することができます。

関連リンク

参考にした情報源リンク

  • コミットメッセージと差分: /home/orange/Project/comemo/commit_data/12814.txt
  • GitHub上のコミットページ: https://github.com/golang/go/commit/b0f4d805f27fc8b24ced42fdce39b859d90ce101
  • Emacs Lispの構文テーブルに関する一般的な情報源(上記「関連リンク」と重複する可能性あり)
    • Emacs Lisp Reference Manual (Syntax Table Functions, Syntax Properties)
    • Stack OverflowやEmacs Wikiなどのコミュニティリソースで「emacs syntax table」や「emacs go-mode」を検索し、関連する議論や解説を参照しました。
  • Go言語のコメント構文に関する情報: https://go.dev/ref/spec#Comments
  • Go言語のgo-modeに関する情報(EmacsのパッケージリポジトリやGoの公式リポジトリ内のmisc/emacsディレクトリなど)```markdown

[インデックス 12814] ファイルの概要

このコミットは、Go言語のEmacsメジャーモードであるgo-mode.elにおける構文テーブルと空白文字の扱いの修正に関するものです。具体的には、コメント文字の認識と改行文字の扱いを改善し、Emacs上でのGoコード編集体験を向上させることを目的としています。

コミット

commit b0f4d805f27fc8b24ced42fdce39b859d90ce101
Author: Sameer Ajmani <sameer@golang.org>
Date:   Mon Apr 2 12:59:37 2012 -0400

    misc/emacs: fix go-mode syntax table and whitespace handling.
    - flag * and / as comment characters
    - mark newline as a comment-ender
    - include newline in go-mode-whitespace-p
    
    Thanks Jonathan Amsterdam and Steve Yegge for the patch!
    
    R=golang-dev, rsc
    CC=golang-dev, jba, stevey
    https://golang.org/cl/5938056

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/b0f4d805f27fc8b24ced42fdce39b859d90ce101

元コミット内容

misc/emacs: fix go-mode syntax table and whitespace handling.
- flag * and / as comment characters
- mark newline as a comment-ender
- include newline in go-mode-whitespace-p

Thanks Jonathan Amsterdam and Steve Yegge for the patch!

R=golang-dev, rsc
CC=golang-dev, jba, stevey
https://golang.org/cl/5938056

変更の背景

Emacsは、その高度なカスタマイズ性と拡張性から、多くのプログラマーに愛用されているテキストエディタです。各プログラミング言語には、その言語の構文をEmacsが正しく解釈し、ハイライト表示、インデント、コメントの自動挿入などを適切に行うための「メジャーモード」が存在します。Go言語の場合、「go-mode」がその役割を担っています。

このコミットが行われた背景には、go-modeがGo言語のコメント(/* ... */// ...)を正しく認識できていなかったという問題がありました。具体的には、*(アスタリスク)と/(スラッシュ)がコメントの開始文字として適切にフラグ付けされておらず、また改行文字がコメントの終了を意味する文字として認識されていませんでした。これにより、Emacs上でのGoコードの編集時に、コメントのハイライトが途切れたり、インデントが崩れたり、コメント関連の操作が期待通りに機能しないといった不具合が発生していました。

また、go-mode-whitespace-pという関数が改行文字を空白文字として扱っていなかったため、空白文字のスキップや整形に関する処理が不正確になる可能性がありました。これらの問題を解決し、Emacsユーザーがより快適にGoコードを記述できるようにするために、この修正が導入されました。

前提知識の解説

Emacs Lisp (Elisp)

Emacs Lispは、Emacsエディタの拡張言語です。Emacsのほぼ全ての機能はEmacs Lispで記述されており、ユーザーはEmacs Lispを使って新しい機能を追加したり、既存の機能をカスタマイズしたりすることができます。go-mode.elもEmacs Lispで書かれたファイルであり、Go言語の編集に関するEmacsの振る舞いを定義しています。

構文テーブル (Syntax Table)

Emacsの構文テーブルは、各文字がどのような構文的な役割を持つかを定義するデータ構造です。例えば、文字が単語の一部なのか、空白文字なのか、コメントの開始文字なのか、文字列の区切り文字なのか、といった情報が格納されています。Emacsは構文テーブルを参照して、テキストのハイライト表示、単語単位の移動、コメントの自動挿入、インデントの調整など、様々な構文認識に基づく処理を行います。

構文テーブルのエントリは、modify-syntax-entry関数を使って変更できます。この関数は、文字、その文字の構文クラス、そしてオプションで構文フラグを受け取ります。

  • 構文クラス: 文字の基本的な種類を定義します。例えば、wは単語文字、 は空白文字、.は句読点などです。
  • 構文フラグ: 構文クラスをさらに詳細に定義します。例えば、コメントの開始文字、コメントの終了文字、文字列の開始文字などです。

このコミットでは、特に以下の構文フラグが重要です。

  • 1: コメントの開始文字(/**など)
  • 2: コメントの終了文字(*/*など)
  • 3: コメントの開始文字(///など)
  • 4: コメントの終了文字(\nなど、行コメントの終了)
  • b: バランスグループの開始文字(括弧など)
  • >: コメントの終了文字(行コメントの終了)

go-mode-whitespace-p 関数

この関数は、与えられた文字がgo-modeにおいて空白文字として扱われるべきかどうかを判定します。Emacsの構文テーブルでは、空白文字は通常、構文クラス32(スペース文字のASCIIコード)として定義されます。この関数は、インデントや空白文字の整形に関連するEmacsの内部処理で利用されます。

技術的詳細

このコミットの技術的な核心は、Emacsの構文テーブルの正確な設定と、空白文字判定関数の改善にあります。

構文テーブルの修正

Go言語では、ブロックコメントは/* ... */、行コメントは// ...で記述されます。Emacsがこれらのコメントを正しく認識するためには、*/がコメント関連の構文フラグを持つ必要があります。

元のコードでは、*/は単に句読点(.)として扱われていました。

    (modify-syntax-entry ?*  "." st)
    (modify-syntax-entry ?/  "." st)

修正後、これらの文字にはコメント関連の構文フラグが追加されました。

    (modify-syntax-entry ?*  ". 23" st)   ; also part of comments
    (modify-syntax-entry ?/  ". 124b" st) ; ditto
  • ?*: アスタリスク文字

    • .: 句読点クラス
    • 2: コメントの終了文字(*/*
    • 3: コメントの開始文字(/**
    • これにより、*がブロックコメントの開始と終了の両方に関与する文字として認識されます。
  • ?/: スラッシュ文字

    • .: 句読点クラス
    • 1: コメントの開始文字(/*/
    • 2: コメントの終了文字(*//
    • 4: コメントの終了文字(//の行コメントの終了)
    • b: バランスグループの開始文字(Go言語の正規表現などでの/の利用を考慮している可能性がありますが、コメントの文脈では主にコメント開始文字としての役割が強調されます)
    • これにより、/がブロックコメントと行コメントの開始文字として、また行コメントの終了文字としても認識されるようになります。

さらに、改行文字\nがコメントの終了文字として明示的にフラグ付けされました。

    ;; Newline is a comment-ender.
    (modify-syntax-entry ?\n "> b" st)
  • ?\n: 改行文字
    • >: コメントの終了文字(行コメントの終了)
    • b: バランスグループの開始文字(これは通常、括弧などに対して使われるフラグですが、ここでは改行が特定の構文要素の区切りとなることを示唆している可能性があります。行コメントの終了という文脈では>が主要な役割を果たします。)
    • この変更により、Emacsは行コメントが改行で終了することを正しく認識し、それ以降のテキストをコードとしてハイライトできるようになります。

go-mode-whitespace-p 関数の修正

元のgo-mode-whitespace-p関数は、文字の構文クラスが32(スペース)であるかどうかのみをチェックしていました。

(defun go-mode-whitespace-p (char)
  "Is char whitespace in the syntax table for go."
  (eq 32 (char-syntax char)))

修正後、この関数は改行文字?\nも空白文字として明示的に含めるようになりました。

(defun go-mode-whitespace-p (char)
  "Is newline, or char whitespace in the syntax table for go."
  (or (eq char ?\n)
      (eq 32 (char-syntax char))))

この変更により、go-modeが空白文字を扱う際に、スペースだけでなく改行も適切に考慮するようになり、インデントや整形処理の精度が向上します。

コアとなるコードの変更箇所

--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -33,8 +33,8 @@
      ;; Operators (punctuation)
      (modify-syntax-entry ?+  "." st)
      (modify-syntax-entry ?-  "." st)
-    (modify-syntax-entry ?*  "." st)
-    (modify-syntax-entry ?/  "." st)
+    (modify-syntax-entry ?*  ". 23" st)   ; also part of comments
+    (modify-syntax-entry ?/  ". 124b" st) ; ditto
      (modify-syntax-entry ?%  "." st)
      (modify-syntax-entry ?&  "." st)
      (modify-syntax-entry ?|  "." st)
@@ -50,6 +50,9 @@
      (modify-syntax-entry ?`  "." st)
      (modify-syntax-entry ?\\ "." st)
 
+    ;; Newline is a comment-ender.
+    (modify-syntax-entry ?\n "> b" st)
+
      st)
    "Syntax table for Go mode.")
 
@@ -545,8 +548,9 @@ token on the line."\n          (not (looking-at go-mode-non-terminating-keywords-regexp)))))))\n 
 (defun go-mode-whitespace-p (char)\n-  "Is char whitespace in the syntax table for go."\n-  (eq 32 (char-syntax char)))\n+  "Is newline, or char whitespace in the syntax table for go."\n+  (or (eq char ?\n)\n+      (eq 32 (char-syntax char))))\n 
 (defun go-mode-backward-skip-comments ()\n   "Skip backward over comments and whitespace."\n

コアとなるコードの解説

上記の差分は、go-mode.elファイル内の2つの主要な変更点を示しています。

  1. go-mode-syntax-table 関数の変更:

    • この関数は、Go言語の構文解析に使用されるEmacsの構文テーブルを構築します。
    • modify-syntax-entry関数が使用され、*/文字の構文定義が更新されています。
      • ?* (アスタリスク): 構文クラスは句読点 (.) のままで、構文フラグに 2 (コメント終了) と 3 (コメント開始) が追加されました。これにより、/* ... */形式のブロックコメントの開始と終了の両方で*が適切に認識されるようになります。
      • ?/ (スラッシュ): 構文クラスは句読点 (.) のままで、構文フラグに 1 (コメント開始), 2 (コメント終了), 4 (行コメント終了), b (バランスグループ開始) が追加されました。これにより、/* ... */形式のブロックコメントの開始と終了、および// ...形式の行コメントの開始と終了の両方で/が適切に認識されるようになります。特に4フラグは行コメントの終了を意味し、//コメントが改行で終わることをEmacsに伝えます。
    • 新たに、改行文字 ?\n の構文エントリが追加されました。構文クラスは不明ですが、構文フラグに > (コメント終了) と b (バランスグループ開始) が設定されています。これは、改行が行コメントの明確な終了点であることをEmacsに認識させるための重要な変更です。
  2. go-mode-whitespace-p 関数の変更:

    • この関数は、与えられた文字がGoモードにおいて空白文字として扱われるべきかを判定します。
    • 元の実装では、文字の構文クラスがスペース (32) であるかのみをチェックしていました。
    • 変更後、or条件が追加され、文字が改行文字 (?\n) であるか、または構文クラスがスペース (32) であるかのいずれかの場合に真を返すようになりました。これにより、改行も空白文字として適切に扱われるようになり、インデントや整形処理の精度が向上します。

これらの変更により、EmacsはGo言語のコメントをより正確に解析し、ハイライト表示、インデント、およびその他の構文認識に基づく機能を改善することができます。

関連リンク

参考にした情報源リンク

  • コミットメッセージと差分: /home/orange/Project/comemo/commit_data/12814.txt
  • GitHub上のコミットページ: https://github.com/golang/go/commit/b0f4d805f27fc8b24ced42fdce39b859d90ce101
  • Emacs Lispの構文テーブルに関する一般的な情報源(上記「関連リンク」と重複する可能性あり)
    • Emacs Lisp Reference Manual (Syntax Table Functions, Syntax Properties)
    • Stack OverflowやEmacs Wikiなどのコミュニティリソースで「emacs syntax table」や「emacs go-mode」を検索し、関連する議論や解説を参照しました。
  • Go言語のコメント構文に関する情報: https://go.dev/ref/spec#Comments
  • Go言語のgo-modeに関する情報(EmacsのパッケージリポジトリやGoの公式リポジトリ内のmisc/emacsディレクトリなど)