2023年4月16日
dumb-jumpはプログラムの変数や関数、クラスの定義へジャンプするパッケージであり、50以上のプログラミング言語をサポートしています。
dumb-jumpの利用シーンをイメージするとこのようになります。ReactもPythonもあらゆるプログラムは多くの自作モジュール、グローバル変数が至る所で使われています。
コードリーディングをしていて、使われている関数の中身がどのようなものかを把握しようとするのは骨が折れます。
- 使われている関数名をコピーする
- ファイルの上部を見て、どこからインポートされてるか確認
- 参照先のファイルを開き、関数名で検索
この手間を考えると、関数はブラックボックスでも良いかと思ってしまいます。
一方で、dumb-jumpを使えば、その問題は一発で解決します。
関数にカーソルを当てて、関数の定義場所へジャンプするコマンドを入力すれば、別のファイルにあろうが、同一ファイル上にあろうが、即座にジャンプできます。元いたところに戻る時も一瞬です
これが完成済みのコードです。
(use-package dumb-jump
:ensure t
:bind(
("C-c g" . dumb-jump-go) ;; クラスや関数、変数の定義されている場所へ飛ぶ
("C-c b" . dumb-jump-back) ;; 飛んできたら、元の場所に戻る
("C-M-q" . dumb-jump-quick-look) ;; 飛ぶ前にジャンプ先の候補を表示
)
:init
;; dumb-jumpを起動
(dumb-jump-mode)
:config
(add-hook 'xref-backend-functions #'dumb-jump-xref-activate) ;; xrefを使うらしいので起動させる
(setq dumb-jump-force-searcher 'rg). ;; デフォルトだとgit grepが使われてエラーが出たのでrgコマンドを強制利用する
(setq dumb-jump-prefer-searcher 'rg) ;; rgコマンドを優先的に利用する
(setq dumb-jump-default-project "") ;; ホームディレクトリ以下が検索対象になるのを回避
(setq dumb-jump-disable-obsolete-warnings t) ;; レガシーコマンドの警告を非表示
)
定義されたものへジャンプとバック
サンプルコードはこちらを利用してみましょう。
def get_integer(prompt):
while True:
try:
value = int(input(prompt))
break
except ValueError:
print("Please enter an integer.")
return value
def add_numbers():
num_values = get_integer("How many numbers do you want to add? ")
total = 0
for i in range(num_values):
num = get_integer("Enter a number: ")
total += num
print("The total is:", total)
if __name__ == '__main__':
add_numbers()
get_integer
関数は2箇所で利用されています。
get_integer("How many...")
にカーソルを合わせて、定義された場所にジャンプしてみます。("C-c g" dumb-jump-go)
を実行します。同じファイルの近いところにジャンプしているので、ありがたみは無いのですが、dumb-jumpは別のファイルに書かれていたとしても同様にジャンプできます。
元の場所に戻る時は、
("C-c b" dumb-jump-back)
でバックできます。dumb-jumpの使い方はこれだけです。
検索コマンドについて
dumb-jumpのリポジトリのREADMEを読むと、関数、変数のジャンプ先を探すコマンドはlispで書かれているのではなく、linuxコマンドを利用しています。Macの場合はわざわざコマンドをインストールしなくてもgrepが入っているので、それが使われます。
公式がお薦めしているのは
ag
とrg
コマンドです。2つのコマンドはデフォルトでMacに入っているわけでは無いので、dumb-jumpの検索コマンドとして使いたい場合はインストールが必要です。READMEのここに書かれているように、最適なパフォーマンスは
ag
かrg
を使った方が良いとあります。私は試しに
rg
コマンドを入れてみました。brew install ripgrep
もしも、agコマンドを利用する場合はbrewでインストールした後、emacsのdump-jumpのlispの設定を変更してください。
(setq dumb-jump-force-searcher 'ag). ;; デフォルトだとgit grepが使われてエラーが出たのでagコマンドを強制利用する
(setq dumb-jump-prefer-searcher 'ag) ;; agコマンドを優先的に利用する
レガシーコマンド警告について
config:
に記述した(setq dumb-jump-disable-obsolete-warnings t)
はdumb-jump-go
がレガシーコマンドになるから使うなという警告を非表示にする設定です。関数にジャンプするコマンドである
dumb-jump-go
はどうやら2020年くらいからレガシーになるとあるのですが、なぜか代わりに提案されているコマンドxref-find-definitions
は全く別の挙動をするので謎です。なので、
dumb-jump-go
を使うのですが、使うたびにメッセージに警告が表示されるのが邪魔なので、その警告を非表示にしています。何かこの辺りのことが分かる方教えてください。
まとめ
短いサンプルコードだとありがたみがさほど感じられませんが、これが膨大なアプリケーションになると、途端にスーパヒーローになります。dumb-jumpがないと、もはやコーディングなど無理なのでは、と思うくらいには素晴らしいパッケージなのでぜひ利用してみてください。
Ted
大学でコンセンサスアルゴリズムを研究。卒業後ベンチャー企業に入社してフルスタックでWebサービスを開発。現在は大手IT企業に転職し、プログラミングを行っている。AIにプログラマーの仕事を奪って欲しいと願っている。