概要
- EmacsのTRAMPを高速化するための設定と工夫を解説
- TRAMPの遅さの原因やボトルネックの分析方法を紹介
- MagitやLSPなど主要パッケージとTRAMPの相性・対策
- キャッシュ活用や非同期プロセス最適化による効率化手法
- 今後のTRAMP改善アイデアやディスカッションへの誘い
Emacs TRAMPを快適に使うための高速化ガイド
- TRAMP はEmacs用のリモートアクセスパッケージで、リモートマシンをローカルのように操作可能
- SCPやrsyncなど多様なプロトコル対応、VSCodeのRemote Development Extensionに類似
- デフォルト設定だと 動作が遅い ことが多く、特に既存設定との組み合わせで顕著
- emacs -Q (クリーン起動)ではTRAMPも軽快に動作する場合が多い
- 基本設定例:
- ロックファイルやオートセーブ抑制
(setq remote-file-name-inhibit-locks t tramp-use-scp-direct-remote-copying t remote-file-name-inhibit-auto-save-visited t)
- ロックファイルやオートセーブ抑制
- ファイル転送方式(inline/アウトオブバンド)の選択と閾値調整が重要
- デフォルト10KBだが、 2MB程度までinlineが高速 な場合が多い
- 例:
(setq tramp-copy-size-limit (* 1024 1024) ; 1MB tramp-verbose 2)
- rsyncはSCPより 既存ファイル更新が高速 だが、リモートシェルとの相性注意
Direct Async Processの活用
- 非同期プロセス は従来TRAMP経由だと非常に遅い
- TRAMP 2.7以降は direct async process 導入で大幅に改善
- 設定例:
(connection-local-set-profile-variables 'remote-direct-async-process '((tramp-direct-async-process . t))) (connection-local-set-profiles '(:application tramp :protocol "scp") 'remote-direct-async-process) (setq magit-tramp-pipe-stty-settings 'pty)
- 設定例:
- Magitやgit-gutterなどのパフォーマンス向上
コンパイル時のSSHコントロール維持
- 新しいTRAMPは SSHコネクション共有 で高速化
- compileコマンド実行時もコントロール維持推奨
- 設定例:
(with-eval-after-load 'tramp (with-eval-after-load 'compile (remove-hook 'compilation-mode-hook #'tramp-compile-disable-ssh-controlmaster-options)))
- 設定例:
パフォーマンス問題のデバッグ方法
- M-x profiler-start で遅い操作のプロファイリング
- tramp-wait-for-output が目立つ場合TRAMPがボトルネック
- debug-on-entry でtramp-send-command呼び出し元特定
- doom-modelineやforgeなど、 TRAMP非対応のパッケージ機能 を無効化推奨
- 例:
(remove-hook 'evil-insert-state-exit-hook #'doom-modeline-update-buffer-file-name) (remove-hook 'find-file-hook #'doom-modeline-update-buffer-file-name) (remove-hook 'find-file-hook 'forge-bug-reference-setup)
- 例:
MagitのTRAMP最適化
- Magit はEmacsの強力なgitインターフェースだが、TRAMP経由では極端に遅い
- magit-statusで10~20秒かかる場合も
- ステータスバッファ更新のたびに多くのシェルコマンド実行
- 対策:
- magit-dispatch や magit-file-dispatch の活用で必要最小限の操作
- ステータスバッファは全体状況把握や大量ファイル操作時のみ利用
- シェル直接実行(M-S-!)で部分的なgit操作
- 不要な自動リフレッシュやdiff表示の無効化
- 例:
(setq magit-commit-show-diff nil) (setq magit-branch-direct-configure nil) (setq magit-refresh-status-buffer nil)
- 例:
- キャッシュ機能の追加も有効(今後Magit本体での対応予定)
LSPとTRAMP
- LSP-mode はTRAMP経由でも動作するが、direct async processは非対応
- lsp-bridgeも選択肢だが、リモートPythonのFFI対応が必要
- リモート時は LSP自動有効化を回避 し、Eldocやcompletionも停止
- 例:
(defun $lsp-unless-remote () (if (file-remote-p buffer-file-name) (progn (eldoc-mode -1) (setq-local completion-at-point-functions nil)) (lsp)))
- 例:
キャッシュの徹底活用
- TRAMP経由の呼び出しは高コストのため キャッシュ利用が効果的
- project-current, magit-toplevel, vc-git-root, counsel-git-candsなどを memoize
- 例:
(defvar project-current-cache nil) (defun memoize-project-current (orig &optional prompt directory) (memoize-remote (or directory project-current-directory-override default-directory) 'project-current-cache orig prompt directory)) (advice-add 'project-current :around #'memoize-project-current)
- 例:
- キャッシュリセットは変数をnilに
今後の展望
- 現状の工夫でTRAMPは十分実用的に
- さらなる根本的な高速化には TRAMP本体の改良 が必要
- 今後の開発・議論への参加を呼びかけ