ハクソク

世界を動かす技術を、日本語で。

エマックスソロの2年間

概要

  • Emacs Soloは、外部パッケージに依存しないEmacs設定の2周年を迎えた
  • 最新のリファクタで「コア」と「自作モジュール」を明確に分離
  • init.elはEmacs組み込み機能のみを設定し、lisp/は自作の追加機能を格納
  • 35個の独立した自作Elispモジュールを紹介
  • 維持の理由・学び・今後の展望についても言及

Emacs Solo 2周年:リファクタと設計思想

  • Emacs Soloは、外部パッケージを一切使用しないEmacs設定
  • init.elはEmacs本体の機能だけを設定、**lisp/**以下に自作モジュールを配置
  • package-installstraight.eluse-package :ensure tは一切不使用
  • Emacs本体と自作コードのみで完結する設定環境
  • スクリーンショットや詳細はリポジトリ参照

Emacs Soloを維持する理由

  • Emacsの素の機能を徹底的に理解するため
  • Emacsリリース間の互換性や壊れにくさの追求
  • パッケージリポジトリ依存によるトラブル回避
  • 外部要因によるビルド失敗やデバッグ地獄からの解放
  • 自作・自己管理の楽しさ

リファクタの概要:コアとエクストラの分離

  • 以前は巨大なinit.el一つに全て詰め込んでいた
  • 分離前の問題点
    • 構成が見通しにくい
    • 一部機能だけ使いたい人に不親切
    • Emacs本体の設定と自作コードの境界が不明瞭
  • 解決策:2層構造
    • Layer 1: init.el(Emacsコア設定のみ。依存なし)
    • Layer 2: lisp/(自作Elispモジュール群。必要なものだけrequire)

init.elの構成と主な設定

  • 見出し付きセクションで整理(outline-mode対応)
  • 各セクションごとにEmacs組み込み機能をカスタマイズ
  • 主な内容
    • キーバインド再定義(例:M-oでother-window等)
    • window-layout系コマンド(Emacs 31新機能)
    • フレーム名の管理、C-z無効化
    • バックアップ/オートセーブ先をcache/に統一
    • **treesit(tree-sitter)**自動インストールと有効化
    • abbrev-modeの独自プレースホルダーシステム
    • auth-source設定(~/.authinfo.gpg利用)
    • auto-revertによるファイル自動リロード
    • compilation-modeでANSIカラー対応
    • window管理の強化
    • tab-barによるワークスペース管理
    • RCIRC/ ERC両IRCクライアントの設定
    • icomplete-vertical-modeでの補完強化
    • dired/wdiredのカスタマイズ(システム連携、詳細非表示等)
    • eshellの高度な設定(履歴共有、プロンプト切替等)
    • isearchの拡張
    • vc(バージョン管理)の徹底活用と独自拡張
    • smerge/diff/ediffの見やすいウィンドウ分割
    • eldoc/eglotによるLSP・ドキュメント表示
    • flymake/flyspell/whitespace等の診断・可視化
    • gnus(メール/ニュース)
    • man/minibuffer/newsticker(RSS/ATOM)等
    • electric-pair/proced/org/speedbar/time/uniquify/which-key/webjump
    • 各言語モードのtree-sitter/非tree-sitter両対応

lisp/ディレクトリ:35個の自作Elispモジュール

  • 各モジュールは独立したElispファイル
  • MELPA等の外部パッケージの代替を小型・自作で実装
  • provide/requireで簡単に使い回し可能
  • hacky reimplementation」の精神:シンプル・理解しやすい・日常利用に十分
  • 例:emacs-solo-themes(独自カラーテーマ)など

Emacs Soloを通じて得た知見

  • Emacs本体の進化(Emacs 31等)で自作polyfillが不要になる場面が増加
  • 自作コードの可搬性・保守性が大幅向上
  • 壊れにくい・再現性の高い開発環境の実現
  • 自分で実装することでEmacsの深い理解を獲得
  • 外部依存ゼロの快適さと安心感

今後もEmacs Soloは「最小限の依存・最大の理解・日常利用に最適化」を目指して進化予定。興味があればリポジトリをぜひ参照。

Hackerたちの意見

> それは、コードが時々怪しいってことだけど、俺のコントロール下にあるんだ。自分で書いたし、理解してるし、壊れたときにはどこを見ればいいかもわかる。これ、めっちゃ共感できる。俺は「外部パッケージは使わない」みたいな純粋主義者じゃないけど、自分が欲しい機能がなかったから、自分用にいくつかの機能を作ったんだ。例えば、選択範囲を自分が定義したペア区切り文字に拡張する関数を作ったんだ(括弧、引用符、ブラケット、またはカスタムの左/右の正規表現を使える)。それから、その関数を実行すると、マッチングペアのために定義したトリガーキーを待って、適用可能な区切り文字に達するまで左と右に選択範囲を拡張する。キーを繰り返し押すと、左と右の区切り文字自体を選択できて、さらに繰り返すと次のマッチング区切り文字にまで拡張される。treesitterベースのexpand-regionプラグインを使ってるけど、自分のカスタム関数は、validなtreesitterオブジェクトの拡張を飛ばしたいときや、特定のテキストオブジェクトがtreesitterで定義されてないときに、すごく役立つ。自分が定義した便利なカスタム拡張には、こんなのがあるよ:「w」はVimが小文字のwを単語と見なすものを選択する「Space」はVimが大文字のWを単語と見なすものを選択する「$」は${...}-スタイルの式を選択する「/」はスラッシュの間のすべてを選択する「*」はアスタリスクの間を選択する(markdown編集のときに便利)これ、個人的には本当に貴重な機能なんだけど、いろいろな落とし穴や制限があるから、オープンソースにしようとはいつも思わないんだ。使う人全員を満足させる責任を負いたくないから。
> 「w」はVimが小文字のwを単語と見なすってどういうこと!?何それ、viはどうやって考えたんだ?
「なぜ」ってのはちょっと怪しいね。Emacsに入ってるものとELPAにあるものの違いは、なんか恣意的な感じがする。実際、ELPAでアップデートされる多くの組み込みパッケージがあって、ELPAを使ってないと、組み込みパッケージに未修正のバグがあるかもしれない。自分で全部書かなきゃいけない理由もないしね。オープンソースライセンスのパッケージを見つけて、理解するために読んで、それを自分の設定にコピーすることもできる。全部ゼロからやるのは時間の無駄だよ、プロセスを楽しむなら別だけど(その場合は思いっきりやって)。これは、科学的知識をゼロから自分で発見しようとするのと、先人たちが発見した知識を「当然」として受け入れるのと同じくらいのことだよ。そんなことをするのに恥ずかしさや不利はない。あと、重要な反論として:> 自分のパッケージを書くことがElispを学ぶ最良の方法だなんて、絶対に違う。言語を読むことが重要だよ。書くだけだと、変なやり方に陥って、全然成長できない。人が書いたものを読むことで、他の人が何を正しくて何を間違っているかを知ることができる。もちろん、自分のパッケージを書くことも必要だけど、それだけじゃ不十分だよ。
> 自分で全部書かなきゃいけない理由もないしね。 > これは、科学的知識をゼロから自分で発見しようとするのと、先人たちが発見した知識を「当然」として受け入れるのと同じくらいのことだよ。著者は、すべての機能が揃った別の設定を持っているけど、Emacsにはたくさんのパッケージがあって、それを調整するのは、Helmのようなフルスイートを構築するのに比べれば、そんなに大変じゃないよ。特に素晴らしいドキュメントシステムがあるからね。v0.xの何かを手に入れるのは数分の問題だし、ある日目が覚めたら、自分のワークフローのためにOSを一つ作ってしまっているってこともある。
> 絶対に違う。言語を読むことが重要だよ。この投稿は、パッケージを書く活動が書くだけで、読むことや学ぶことが厳禁だとは示唆してないと思う。 > オープンソースライセンスのパッケージを見つけて、理解するために読んで、それを自分の設定にコピーすることもできる。ゼロから全部やるのは時間の無駄だよ、プロセスを楽しむなら別だけど(その場合は思いっきりやって)。この投稿は、彼らが自分のパッケージを作る前に見て理解した比較的大きなオープンソースパッケージのセットを明確に示している。著者は、彼らの影響を認めていて、こう言ってるよ:「Emacs Soloは外部パッケージをインストールしないが、深く影響を受けている。diff-hl、ace-window、olivetti、doom-modeline、exec-path-from-shell、eldoc-box、rainbow-delimiters、sudo-edit、そして他にも多くが、何が可能かを示してくれて、良いEmacs体験の基準を設定してくれた。具体的なクレジットが必要な場合は、ソースコード自体に記載されている。」
すべてを再発見するなんてことはないよ。Emacsだけじゃなくて、人々が使いやすくするために設計されているんだから。自分が作るものは、結局自分にとって役立つものであればいいんだ。レゴで何も見ずに作るような感じだね。
どうして見逃したのか分からないけど、「なぜ」は明らかにEmacsをよりよく学び、理解するための挑戦だったんだよね。それに、楽しかったからでもあるし。
> 「なぜ」はちょっと怪しいよね。「なぜ」は「そこにあるから」っていうのが明らかだと思う。
Emacs自体に貢献するには、FSFのCLAにサインして、雇用主と貢献内容を確認する必要があるよ。ELPAに別のパッケージを出すのには、これをする必要はないけどね。
これ、めっちゃ美しいし、すごく理にかなってるし、参考になる資料だね。3500行のinit.elやほとんどの追加機能は使わないけど、ここにある良い部分は、いつかデフォルトの動作を大きく変更するのが合理的だと考えるなら、上流に持っていくべきだと思う。
> 「壊れたときにはどこを見ればいいかもわかる」って部分、すごく共感できる。これは、確定的なシステムが確率的なものより好きな理由と同じだね。自分のツールの実行グラフを全部把握していることで得られる特定のプロフェッショナルな安心感があるんだ。テキストエディタの設定でも、AIエージェントのセキュリティミドルウェアでも、関係ない。純粋主義者になることじゃなくて、自分のスタックのマスターになることが大事なんだ。
もしEmacsを再実装するなら、Lispじゃないな。テキスト編集においてLispが他の一般的なプログラミング言語より優れている理由ってあるの?僕はちょっと懐疑的なんだけど、EmacsがLispで書かれた唯一の主要なテキストエディタだと思うから。
これは時代の産物だよ。70年代中頃にEmacsが作られたとき、MITのLispマシンプロジェクトはすでに数年進んでいて、LispはMITのAIラボでかなり重要な存在だったんだ。スタールマンが85年頃にGNU Emacsを始めたとき、彼はLispやそのシステムからたくさんインスピレーションを受けたんだよ。Emacsは編集に重点を置いたソフトウェアLispマシンの一種だと思ってもいい。ただ、そのアナロジーはLispマシンについてあまり知らないか、目を細めて見るときだけうまく機能するけどね。Emacs Lispを通じて初めてLispを学んだ僕としては、楽しくて、ドキュメントも充実していて、パワフルだと思った。システムがどのように動的に組み合わさっているか、無限にハック可能で自己文書化されているかの基本を理解すると、ちょっと驚きだよ。
EmacsではLispがCを呼び出すんだ。もっと良い言語ってあるのかな?コードをデータとして扱い、データをコードとして扱うパラダイムは、すべてがバッファであるという考え方とすごく合ってると思う。グローバル名前空間やフック、defadviceみたいなものは他のインタプリタではすごく違和感があるけど、elispではしっくりくるんだよね。
でも、1976年に実装していたら、そうなっていたかもしれないね。
良い理由は、Lispにはほとんど構文がないから。だから、他の言語から来た開発者にとって学びやすい中立的な言語として機能するんだ。
Lispコードを生成するのがすごく簡単だから。メタプログラミング用に作られてるんだ。
>「Lispがテキスト編集のために他の汎用プログラミング言語より優れている理由はあるの?」 テキスト編集だけに関しては? いや、そうじゃない。でも、それがEmacsを特徴づけるものではないし、実際、テキスト編集に関してはあまり優れてないよ。Emacsのポイントは、完全に透明で、検査可能で、ダイナミックで、変更可能な環境であること。PharoのようなSmalltalkシステムに似た精神を持ってる。それに対してLispは唯一の選択肢ではないけど、非常に良い選択肢なんだ。どんな場所にも飛び込んで、変更を加えて、コードのブロックをコンパイルしたり評価したり、データとして扱ってシームレスに続けられる言語や環境はほとんどないからね。
この記事は、Emacsが最初に作られてから数十年経った今でも美しく、関連性のあるプロジェクトであり続けていることを示している。コアのデザインと実装が、今でも役立つものに進化し、現代のツールと競争できる能力は素晴らしい成果だよ。それに、現在の開発の多くがLLMによって進められているから、Emacsは現代のIDEに対してさらに競争力があるかもしれない。開発は、コマンドラインからClaude Codeのようなエージェントによって主に進められ、その後Emacsでコードをナビゲートしたり調整したり、Gitのコミットを処理したりすることができると思う。LLMはEmacsの強力なコア機能を活用して、Emacsを自分の思い通りに動かすためのElispを書くのが得意だと思う。この著者は手作業でそれを実現したけど、今LLMを使って始める人はもっと早くそこに到達できるんじゃないかな。
ハードコアなEmacsやVimの開発者にはいつも感心するよ、彼らのセットアップはすごいから。僕はGUI派なんだけど、ちょっと掘り下げようとすると、「c-C dingle bobをタイプすればxのことができる」みたいなことを見て、すぐに諦めちゃうんだ。こういう人たちが自分の脳に合うものを見つけたのは嬉しいけど、僕は彼らが使っているようなGUIが欲しいだけなんだ。最近、AI関連の機能を取り除いたZedのフォークを見たけど、まだバイナリは出てないみたい(コンパイルしてAppleの開発者アカウントを取得しないといけないし、そこまで気にしてない)。ZedとSublime Textは僕のスタイルに一番近いけど、もっと良いものを常に探しているよ。もしGUIも好きなEmacsフリークがいたら、君のアプリに参加させて!
Zedフォーク、面白そうだね!AppleのDevアカウントは何のために必要だったんだろう?前はアプリをApp Storeに提出するためだけに必要だった気がするけど、ローカルでDevビルドを動かすのには要らなかったよね。
> 「私は彼らが使っているようなGUIが欲しいだけなんだ。これが本当に可能だとは思えない。特別なのは、やりたいことのためのキー割り当てが何百もあるからなんだよね。だから、楽器を演奏するみたいに、キーを考えるんじゃなくて、筋肉の記憶を使う感じになる。もしメニューやボタンをたくさん作ったら、ぐちゃぐちゃになって使いにくくなると思う。Emacsには多くの機能のためのボタンやGUIコントロールがあるけど、ああいう使い方はちょっと面倒だよね。こういう設定がすごいのは、クリエイターが自分のエディタを使いこなすために時間と努力を注いだからなんだ。スキル開発に対する受け手の投資なしで、そのまま他の人に渡すことはできないよ。」
> 「私はGUI派なんだ。ちょっとでも深く掘り下げようとすると、“c-C dingle bobをタイプしてxをする”みたいなことを見ると、すぐにやめちゃう。こういう人たちが自分の脳に合ったものを見つけたのは嬉しいけど、私は彼らが使っているようなGUIが欲しいだけなんだ。ある程度は、キーを押すたびにオプションのメニューを表示してくれるwhich-keyみたいなパッケージがあるけどね。そうすると、よく使うキー割り当てを覚えられる。名前で検索して、VS Codeみたいにキー割り当ても見ることができるよ。これがdoom-emacsで、スペースを押してからスペース-tを押したときの画面だよ:https://files.catbox.moe/szfcif.png https://files.catbox.moe/2kgrai.png」
> 「— 理にかなったファイル処理:バックアップとキャッシュディレクトリでの自動保存、最近のファイル用のrecentf、ユニークな名前付けでクリーンなバッファ名。/etc/nginx/sites-enabled/fooでnginxファイルを編集すると、foo~という別のファイルが作成されて、nginxがそれも読み込もうとするのが信じられない。Emacsのredditコミュニティに聞いてみたら、私だけが必要としていて、みんなにぴったり合うデフォルトを変えたことで攻撃され始めた。あのデフォルトが信じられないほど悪いって思ってるのは私だけだなんて、まだ信じられない。」
私の.DS_storeを持っていくよ。
80年代からgnu emacsを使ってるけど、それが最初に変えたことの一つだよ。解決できた?もしできなかったら、明日答えを探してあげるよ。
これは10年以上前に私の設定に追加した最初のことの一つだよ:(setq backup-directory-alist '(("." . ".~")))
使うエディタでは、自動バックアップファイルの機能はいつも無効にしてる。なんでそんなのがデフォルトでオンになってるのか、全然理解できない。
(setq backup-directory-alist '(("." . "~/.emacs.d/backups/"))) Emacsをインストールするたびに最初にやること。これをやるとtrampが文句言うけど、ちゃんと動くよ。
新しいEmacsの機能、めっちゃいいね!(ついにネイティブなウィンドウ管理が実装された) いつかxrefでも編集できるようになったらいいなぁ。wgrepがEmacs 30に入ったし、project.elのgrepがデフォルトでxrefに行くから特にそう思う。ところで、最新のEmacsでグラフィカルブラウザを動かすための作業について知ってる人いる?webkit xwidgetsがEmacs 30以降で使えなくなったからさ。(EAF試したけど、Macではめっちゃバグってる)