📝

VSCode 使いが DoomEmacs に移行してみた

2025/03/05に公開

0. Emacs を再起動せず反映する方法

このブロック以降はさまざまな変更を設定ファイルに加えることになりますが、毎回変更 -> Emacs 再起動は面倒なので、起動したまま変更を反映させる方法を調べました。

SPC h r r : doom のリロード
SPC h r f : フォントのリロード
M-x eval-buffer : 開いているバッファのみを更新、config.el で一部だけ更新した時などに便利

また設定が反映されなかったり、動作がおかしい時には doom sync --rebuild でキャッシュをクリアすると直ることがありました。

1. ファイルを指定して起動方法がわからない

code main.tsvi main.c のようにコマンド名 + ファイル名で Doom Emacs がデスクトップアプリで起動させたいが emacs コマンドだと CU 版が起動する。stack overflow にまさにの回答があったので試すと成功。

alias eapp="open -a /opt/homebrew/opt/emacs-mac/Emacs.app $1"

2. アイコンの文字化け

起動時のダッシュボードでもアイコンが文字化けしているので Emacs を起動して以下のコマンドで解消する。

M-x nerd-icons-install-fonts

また文字化けではないが、terminal 上だと問題ないがデスクトップ版だと git の差分にアイコンが表示されなかった。

3. VSCode のファイル検索・コマンドパレット

今までは VSCode を使っていて cmd + p, cmd + shift + p のファイル検索、コマンドパレットが便利でした。同じようなことをするには以下のコマンドが利用できます。

ファイル検索

SPC SPC : プロジェクト内の全てのファイルからあいまい検索(基本的にこれを使えばいい)
SPC , : 開いている全てのファイルからあいまい検索
SPC > : 開いている全てのバッファをあいまい検索する (これは機能しなかった)

コマンドパレット

M-x : meta key (macOS だと cmd) と x キーでコマンドを検索して実行できる

プロジェクト内検索

SPC / : VSCode の cmd + shfit + f のようにプロジェクトのファイル内にヒットする文字列があるか調べる

最近使ったファイル

SPC f r

4. フォントの変更

ここまで来ればもう少しでコードが書き始められる。あとは好みのフォントとフォントサイズの設定。

  1. config.el を開いて (setq doom-font (font-spec :family ブロックのコメントアウトを解除
  2. 行の末尾に移動して C-x C-e で setq を実行
  3. SPC h r f でフォントをリロード

5. ファイラー

init.eltreemacs を有効化する。lsp や git 連携ができるらしい。

SPC o p : treemacs をオープン
o h : treemacs のファイルにフォーカスが当たっている状態で入力すると、カーソル下のファイルを水平分割で表示する

6. ヤンクしてもクリップボードに共有されない

デスクトップ版は問題ないが emacsclient -t でターミナル版を使うとヤンクしてもクリップボードに共有されない。init.el:os tty を有効化する必要がある。ただし、OSC クリップボードをサポートしたターミナルが必要。
自分は WezTerm を使っていて OSC はサポートしているはずなのにコピーが共有されない。普段使っている tmux を解除すると共有されることを確認。tmux.conf に以下を追加することで修正。

set -s set-clipboard on

7. Local History

VSCode の LocalHistory を再現したかったが、時間がかかりそうなので Emacs に元から備わっている auto backup を活用する。config.el に以下を追記。

(setq make-backup-files t) ; enable auto backup
(setq version-control t) ; バックアップを複数生成
(setq kept-old-versions 10) ; 削除せず残す一番古い番号
(setq kept-new-versions 10) ; 削除せず残す一番新しい番号
(setq delete-old-versions t) ; 上記範囲外の古いバックアップは自動で削除

まだ使い方を十分には理解していないが M-x diff-backup で最新のバックアップとの差分を確認できる。

8. コメントのトグル

evil-commentary がデフォルトで有効化されている。使い方は M-;。他にもブロックコメントや行コメントなどの機能もある。

9. GitHub Copilot

copilot-emacs/copilot.el を使う。事前に v18 以上の Node のインストールが必要。

pacakge.el

(package! copilot
  :recipe (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")))
;; こっちは copilot chat
(package! copilot-chat
  :recipe (:host github :repo "chep/copilot-chat.el" :files ("*.el")))

config.el

(use-package! copilot
  :hook (prog-mode . copilot-mode)
  :bind (:map copilot-completion-map
              ("<tab>" . 'copilot-accept-completion)
              ("TAB" . 'copilot-accept-completion)
              ("C-TAB" . 'copilot-accept-completion-by-word)
              ("C-<tab>" . 'copilot-accept-completion-by-word))
  :config
  (add-to-list 'copilot-indentation-alist '(prog-mode 2))
  (add-to-list 'copilot-indentation-alist '(org-mode 2))
  (add-to-list 'copilot-indentation-alist '(text-mode 2))
  (add-to-list 'copilot-indentation-alist '(closure-mode 2))
  (add-to-list 'copilot-indentation-alist '(emacs-lisp-mode 2)))

記述できたら copilot の認証を行う

M-x copilot-install-server
M-x copilot-login
M-x copilot-diagnose

Copilot Chat を使う場合はそちらでも login が必要

10. git diff が更新されない

Doom Emacs ではデフォルトで (vc-gutter +pretty) が有効になっているので、git で管理されたプロジェクトだと差分が強調表示されます。しかし、terminal で commit しても Emacs では差分が強調表示されたままという状態だったので、保存で git diff が更新されるように。

config.el

(after! git-gutter
  (add-hook 'after-save-hook #'git-gutter:update-all-windows)) ; 保存時に更新

11. スペルチェック

VSCode では Code Spell Checker を使うことで typo をチェックしています。Doom Emacs でも同じような体験を得られるように aspell を使う。

homebrew で aspell をインストール

brew install 

init.el で以下を有効化

:checkers (spell +aspell)

+everywhere も有効化するとリアルタイムでコメントや文字列をチェックしてくれるようになるが、エラーが出すぎてうっとおしいので、必要なタイミングで M-x flyspell-buffer とするとカレンとバッファのスペルチェックを行える。

12. Emacs 内でターミナルを使う

elisp で作られ拡張性の高い eshell、C 言語で書かれ高速に動作する vterm のいずれかが良さそう。eshell だと環境変数とか alias の設定が面倒なのでひとまず vterm を使い始めることに。

SPC o t : ターミナルのトグル

13. タブ文字や全角空白の可視化

config.el

(setq whitespace-style '(face ; face による可視化を有効化(これがないと *-mark 以外が有効にならない)
                         trailing ; 行末の空白
                         tabs ; タブ
                         spaces ; スペース
                         empty ; バッファの前後の空行
                         space-mark ; 空白文字を置き換え
                         tab-mark ; タブ文字を置き換え
                         ))
(setq whitespace-display-mappings
      '((space-mark ?\x3000 [?\u25a1]) ; 全角空白を「□」で表示
        (tab-mark ?\t [?\u00BB ?\t] [?\\ ?\t]))) ; タブを「»」で表示
(setq whitespace-action '(auto-cleanup)) ; 自動クリーンアップを有効化
(global-whitespace-mode 1)  ; 全バッファで有効化

14. タイトルバーが大きすぎる

ツールバーのアイコンが原因と思われる現象で、タイトルバーが無題余白が多く縦長な状態になっている。issue もあり修正済みと書かれているが2025/02/04現在も発生しているので、修正コードを config.el に追記しておく

;; タイトルバーが大きいバグ対応 https://github.com/doomemacs/doomemacs/issues/7532
(add-hook 'doom-after-init-hook
          (lambda () (tool-bar-mode 1) (tool-bar-mode 0)))

15. ワークスペース

VSCode だとフォルダやファイルを開いていてアプリを閉じて開き直すと、開いていたファイルなどが復元されます。Doom Emacs でも同じようなことは可能で標準の workspace 機能を使います。

SPC TAB r : workspace の rename
SPC TAB TAB : workspace 一覧の表示
SPC TAB s : workspace の保存(これが重要)
SPC TAB l : 保存されている workspace の読み込み

16. Go の開発環境を整える

事前に Go をインストール

brew install go

いよいよ仕事で Emacs を利用できるようにしたいと思います。普段は主に Go で開発しているのでinit.el で以下を有効化

:tools lsp               ; lsp
:lang (go +lsp)          ; go のシンタックスや構文チェック、format など
:editor (format +onsave) ; 保存時にフォーマット

補完パッケージの corfu はデフォルトで有効になっているので、後は go.mod がある Go プロジェクトを開けば、補完や format、lint が機能するようになる。
+lookup/definition+loopup/references コマンドが用意されているので、定義元や参照元へのジャンプも簡単にできる。

以下を追加しておけば保存時にフォーマットと import が自動で整理されるようになる。
config.el

(add-hook 'before-save-hook #'lsp-organize-imports)
(add-hook 'before-save-hook #'lsp-format-buffer)

16. Rust の開発環境を整える

事前に Rust とコンポーネントのインストール

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup component add rust-analyzer clippy rustfmt

Doom Emacs のモジュールを有効化
init.el

:tools lsp        ; LSP の有効か
:lang (rust +lsp) ; Rust のサポートと LSP の有効か
:editor (format +onsave) ; 保存時にフォーマット

17. キーボードショートカット

細かいキーボードショートカットです

config.el

(map! :n "s-d" #'evil-mc-make-and-goto-next-match) ; vscode のマルチカーソル
(map! :n "s-p" #'projectile-find-file-other-window) ; cmd p でファイルを選択して cmd enter するのと同じ

最後に

ここまでやってみて、セットアップ大変だなと思いつつも10年近く前に Emacs に入門しよとした時よりも遥かに簡単に設定できました。また Native Compile のおかげで速度も全く気になりません。VSCode から移行してみて一番に感じたメリットは全ての操作をキーボードで済ませられることです。VSCode でも頑張ればファイラーやターミナルの操作も全てキーボードでできましたが、キーバインドにどこか違和感を感じたりしていました。Emacs を使うことでコーディング速度が上がりそうだとワクワクしています。

VSCode の全ての機能が Emacs で再現できたわけではありませんが、最低限開発できる状態になったので一旦これで区切りたいと思います。

Discussion