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

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

このコミットは、EmacsのGo言語モード(go-mode.el)において、godef-jumpコマンドの挙動を改善し、find-tagコマンドと同様にpop-tag-mark(タグマークをポップする)機能に対応させるための変更です。これにより、godef-jumpで定義元にジャンプした後、簡単に元の位置に戻れるようになります。

コミット

commit 9c6fecc2da35d3d4ee685cc7f56c69f4671e8888
Author: Dominik Honnef <dominik.honnef@gmail.com>
Date:   Wed Jul 24 11:20:53 2013 -0400

    misc/emacs: Make godef-jump behave more like find-tag by supporting pop-tag-mark
    
    Push point to the find-tag marker ring to support pop-tag-mark.
    
    Fixes #5804.
    
    R=adonovan
    CC=golang-dev
    https://golang.org/cl/11457044

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

https://github.com/golang/go/commit/9c6fecc2da35d3d4ee685cc7f56c69f4671e8888

元コミット内容

misc/emacs: Make godef-jump behave more like find-tag by supporting pop-tag-mark

Push point to the find-tag marker ring to support pop-tag-mark.

Fixes #5804.

R=adonovan
CC=golang-dev
https://golang.org/cl/11457044

変更の背景

この変更は、Go言語のEmacsモード(go-mode.el)におけるgodef-jumpコマンドのユーザビリティを向上させるために行われました。godef-jumpは、Goのシンボル定義にジャンプするための便利な機能ですが、従来のEmacsのタグジャンプ機能であるfind-tagとは異なり、ジャンプ元の位置を記憶する「タグマーカーリング」に現在の位置をプッシュしていませんでした。

その結果、godef-jumpで定義に飛んだ後、pop-tag-mark(通常 M-* にバインドされている)を使って元の位置に戻ることができませんでした。これは、開発者がコードを探索する際のワークフローを妨げるものであり、Issue #5804として報告されていました。

このコミットの目的は、godef-jumpfind-tagと同様に、ジャンプ元の位置をfind-tag-marker-ringに記録するようにすることで、pop-tag-markによるスムーズなナビゲーションを可能にすることです。

前提知識の解説

このコミットを理解するためには、Emacsの以下の概念を理解しておく必要があります。

Emacsのタグシステム (find-tag, pop-tag-mark, タグマーカーリング)

Emacsには、ソースコード内の定義(関数、変数など)に素早くジャンプするための「タグシステム」があります。

  • find-tag (M-.): このコマンドは、etagsなどのツールで生成されたタグテーブル(シンボル名とその定義場所のマッピング)を使用して、指定されたシンボルの定義にジャンプします。例えば、関数名の上でM-.を実行すると、その関数の定義箇所に移動します。
  • pop-tag-mark (M-*): find-tagや関連するタグ検索コマンドでジャンプした後、このコマンドを使用すると、ジャンプする前の元の位置に戻ることができます。これは、Emacsがジャンプ元の位置を「タグマーカーリング」という特別なリングバッファに記録しているためです。
  • タグマーカーリング (find-tag-marker-ring): find-tagなどのコマンドが実行されると、ジャンプ元のカーソル位置がマーカーとしてこのリングバッファにプッシュされます。pop-tag-markはこのリングからマーカーをポップし、その位置にカーソルを戻します。これにより、コードの定義を辿っていった後でも、簡単に元の探索経路を逆戻りできます。

godef-jump

godef-jumpは、Go言語のEmacsモード(go-mode.el)で提供されるコマンドで、Goのシンボル定義にジャンプするために使用されます。これは、Goのgodefツール(Goのソースコードを解析して定義情報を提供するツール)と連携して動作します。find-tagが汎用的なタグシステムであるのに対し、godef-jumpはGo言語に特化した、より正確な定義ジャンプを提供します。

Emacs Lispのpoint-markerring-insert

  • point-marker: Emacs Lispの関数で、現在のカーソル位置(point)に新しいマーカーオブジェクトを作成して返します。マーカーは、バッファ内の特定の位置を指すオブジェクトで、テキストの挿入や削除があっても、その論理的な位置を追跡し続けます。
  • ring-insert: Emacs Lispのringパッケージで提供される関数で、リングバッファに要素を挿入します。リングバッファは固定サイズのデータ構造で、新しい要素が追加されると、最も古い要素が自動的に削除されます。ring-insertは、指定されたリングにオブジェクトを挿入し、リングが満杯の場合は最も古い要素を削除します。

技術的詳細

このコミットの核心は、godef-jumpfind-tagのナビゲーション履歴メカニズムに統合されるようにすることです。

従来のgodef-jumpは、Goのシンボル定義にジャンプする際に、単に新しいファイルを開き、指定された行と列にカーソルを移動するだけでした。この動作は、Emacsの一般的なタグジャンプの慣習とは異なり、ジャンプ元の位置をfind-tag-marker-ringに記録していませんでした。そのため、ユーザーはpop-tag-markを使って元の位置に戻ることができず、手動でバッファ履歴を辿るなどの手間が必要でした。

このコミットでは、godef-jumpが定義にジャンプする直前に、現在のカーソル位置をfind-tag-marker-ringに明示的にプッシュする処理を追加します。これにより、godef-jumpによるジャンプもfind-tagによるジャンプと同様に履歴に記録され、pop-tag-markで元の位置に戻ることが可能になります。

具体的には、以下の手順が実行されます。

  1. godef-jumpが呼び出され、定義元へのジャンプが決定されます。
  2. ジャンプ先のファイルを開く前に、現在のバッファの現在のカーソル位置をpoint-markerでマーカーとして取得します。
  3. 取得したマーカーをring-insert関数を使ってfind-tag-marker-ringに挿入します。
  4. その後、godef--find-file-line-column関数が呼び出され、定義元のファイルが開き、カーソルが適切な位置に移動します。

この変更により、godef-jumpはEmacsの既存のナビゲーションワークフローにシームレスに統合され、Go開発者の生産性が向上します。

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

変更はmisc/emacs/go-mode.elファイルに集中しています。

--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -5,7 +5,9 @@
 ;; license that can be found in the LICENSE file.
 
 (require 'cl)
+(require 'etags)
 (require 'ffap)
+(require 'ring)
 (require 'url)
 
 ;; XEmacs compatibility guidelines
@@ -925,6 +927,7 @@ description at POINT."
           (message "%s" file))\n          (t
            (push-mark)
+          (ring-insert find-tag-marker-ring (point-marker))\n           (godef--find-file-line-column file other-window))))
     (file-error (message "Could not run godef binary"))))
 

コアとなるコードの解説

変更されたコードは以下の3行です。

  1. (require 'etags):
    • etagsライブラリをロードします。find-tag-marker-ringetagsライブラリによって提供されるため、これを使用する前にロードする必要があります。
  2. (require 'ring):
    • ringライブラリをロードします。ring-insert関数はこのライブラリの一部であるため、これを使用する前にロードする必要があります。
  3. (ring-insert find-tag-marker-ring (point-marker)):
    • この行が変更の核心です。
    • point-markerは、現在のカーソル位置(point)に新しいマーカーを作成します。
    • find-tag-marker-ringは、Emacsのタグジャンプ履歴を管理するリングバッファです。
    • ring-insertは、point-markerで作成された現在の位置のマーカーをfind-tag-marker-ringに挿入します。
    • これにより、godef-jumpで定義にジャンプする前に、ジャンプ元の位置がタグジャンプ履歴に記録されます。その結果、ユーザーはpop-tag-markM-*)を使って元の位置に簡単に戻れるようになります。

この変更は、godef-jumpfind-tagの既存のナビゲーション機能と連携するようにすることで、EmacsにおけるGo開発の体験をより一貫性のあるものにしています。

関連リンク

参考にした情報源リンク