Emacsではすべてがサービスのように見える
(yummymelon.com)- Emacsはオペレーティングシステムそのものというより、カーネル上のアプリケーションやユーティリティを調整し、ファイルシステム・ネットワーク・外部プログラムを活用して、さまざまなサービスのクライアントになる
- クライアントに必要なUI・通信レイヤー・ローカルデータストアは、ミニバッファ、バッファ、URL、TCP/UDP、JSON、SQLiteなどの組み込みライブラリで構成できる
- 動的言語である**Emacs Lisp(Elisp)**は、実行中にElisp関数とシェルコマンドを組み合わせ、Emacsがアクセスできる機能を柔軟に調整する
- 例の
wttrコマンドは位置情報の入力を受け取り、wttr.inへHTTPリクエストを送り、JSONから地域・気温・天気を抽出してミニバッファに表示したうえでkill ringにも保存する - 完全な
wttr.elはcloc基準で67行であり、ネットワークリクエストとJSON処理をPythonのようなコマンドラインツールに任せれば、シェルコマンド自体をサービスとして扱う、より短いElispクライアントも作れる
オペレーティングシステム上でサービスを調整するEmacs
- Emacsをオペレーティングシステムと呼ぶ表現は正確ではないが、OSカーネル上でアプリケーションやユーティリティを調整する能力があるため、このような比較が生まれる
- ファイルシステムやネットワークといったOSサービスに組み込み機能でアクセスでき、ほかのプログラムも実行できるため、Emacs内でクライアントの動作をその場で組み立てやすい
- 複数のクライアントモードで多くのコンピューティング作業を処理できるため、ユーザーが「Emacsの中だけで生活する」という発想も成り立つ
リクエストとレスポンスで見るクライアントサーバーモデル
- クライアントサーバーモデルは、リソースを提供するサービスと、それを要求するクライアントが作業を分担する相互作用パターンである
- クライアントがリクエストを送る
- サーバーがリクエストを処理した後、レスポンスを返す
- リクエストとレスポンスで構成されるトランザクションは、ネットワーク経由でも、1つのシステム内でローカルにでも実行できる
- ネットワークベースのモデルは、RESTスタイルのソフトウェアアーキテクチャで広く発展した
Emacsクライアントを構成する3つの領域
- 一般的なクライアントは次の3領域を担当する
- UI: 必要に応じてユーザー入力と出力を処理する
- クライアントエッジ(Client Edge): サービスと通信し、ネットワーククライアントではネットワークサブシステムがこの役割を担う
- ローカルデータベース: サーバーと交換または同期するデータを表現し、具体的な管理方法は実装要件によって異なる
-
ユーザーインターフェースの構成
- EmacsはクライアントUIを作るための複数の組み込み機能を提供する
- Minibuffers
- Buffers
- Completion
- Tabulated List Mode
- Variable Pitch Table(vtable)
- Transient
-
サービス通信とデータ変換
- サービスにつながるクライアントエッジには、次の機能を活用できる
- シリアライズとデシリアライズには組み込みパーサーを利用する
-
ローカルデータ管理
- サーバーデータのローカル表現にはElispコレクションを活用できる
- 永続的なローカルストレージが必要ならSQLiteを使用できる
- 実際のクライアントの複雑さは要件によって変わり、重い処理を担う既存のコマンドラインユーティリティがあるなら、シェル呼び出しでアクセスするサービスとして再構成できる
Elispで機能を組み合わせる方法
- 前述のライブラリはすべてEmacs Lisp(Elisp)からアクセスできる
- Elispは、実行中に高いレベルの即興的な構成を可能にする動的プログラミング言語である
- Elisp関数からシェルコマンドまで、Emacsが利用できる動作を組み合わせ、複雑なフローを調整できる
wttr.in天気クライアントの実装
- wttr.inはコンソール中心の天気予報Webサービスで、JSON出力をサポートしている
- Emacs用の
wttrコマンドは次の順序で動作する- ユーザーから位置情報を受け取る
- wttr.inのリクエストURLを生成する
- HTTPリクエストを送信する
- JSONレスポンスを処理する
- 結果をミニバッファに表示し、kill ringに保存する
- 処理中にエラーが発生した場合は、ミニバッファにエラーメッセージを表示する
-
リクエストURLを作る
wttr--request-urlはhttps://wttr.inをベースURLとして使う- 入力された位置情報の空白を
+に置き換え、/<location>?0&format=j1形式のクエリを生成する - 完成したURLはその後、JSON取得関数に渡される
-
HTTPリクエストとJSONパース
fetch-json-as-hash-tableはurl-retrieve-synchronouslyでURLを同期的に取得する- データを取得できなければ、
Failed to fetch data from <URL>エラーを発生させる - レスポンスバッファでHTTPメタデータヘッダーの後ろへ移動した後、
json-parse-bufferで残りの内容をElispの**hash-table**に変換する - 処理が終わると、ダウンロードしたネットワークバッファを必ず削除し、メモリリークを防ぐ
-
天気メッセージの組み立て
wttr--report-messageはJSONデータから次の値を抽出する- 最も近い地域の名前
- 地域
- 国
- 現在の摂氏気温
temp_C - 現在の華氏気温
temp_F - 天気の説明
weatherDesc
- 空でない位置要素をカンマで連結し、
位置: 摂氏, 華氏 天気の説明形式の結果を作る - 完全な実装はwttr.elソースで確認できる
コマンドラインツールもサービスとして活用する
- Emacs APIは高レベルの抽象化を提供し、HTTPリクエストとJSON処理を直接実装した
wttr.elもcloc測定基準で67行である - より単純な代替案は、実際のネットワークリクエストとJSON処理を
weatherというPythonスクリプトに任せる方法である- Elispの
weatherコマンドがユーザーから位置情報を受け取る - 位置情報を引数として付け、
weatherシェルコマンドを構成する shell-command-to-stringでコマンドを実行する- 返された結果をkill ringに保存し、ミニバッファに表示する
- Elispの
- この構成では、シェルコマンドがリクエストを受けるサービスとなり、Elisp関数がクライアントの役割を担う
- Elispの動的な性質により、Elispライブラリとコマンドラインユーティリティを必要に応じて組み合わせられ、この統合可能性によってEmacs内であらゆるものをサービスのように扱えるようになる
1件のコメント
Hacker Newsのコメント
Lisp Machine 系が主流になれなかったために、Emacsがオペレーティングシステムのように見えているだけ
“Symbolics Lisp Machine demo”
https://www.youtube.com/watch?v=o4-YnLpLgtk
“Emacs and Lisp”
https://funcall.blogspot.com/2025/04/emacs-and-lisp.html
Lucidは初期のLSP構想の一つを実装しようとして、EmacsをXEmacsとしてフォークした。当時の機能の大半は今ではEmacsに再統合されている
https://dreamsongs.com/Cadillac.html
“Lucid Energize Demo”
https://www.youtube.com/watch?v=pQQTScuApWk
client、server、requestを十分広く定義すれば、何でもクライアント/サーバー構造に当てはめられる。LISP関数が一つのことをうまくこなすというだけで、EmacsがUnix哲学に従っていると無理に主張していたのと似ているEmacsがLISPマシンの発想に従っていることには大半の人が同意できるし、その上では実質的に望むものを何でも実装できる。CLIツールとは非常によく連携するが、それをクライアント/サーバーと定義して何が得られるのかは不明だ
何十年もの間、さまざまな流行を経ながら機能を取り込んできており、内部には今ではほとんど使われていないCEDET意味解析エンジンもある。その後LSPが登場し、今ではエージェントの時代だが、Emacsはエージェント向けフロントエンドとしてもかなり優れている
Emacsを25年以上使ってきたが、昨年転職した会社では、Emacsが特に向いている作業にさえ使わせてもらえなかった。チーム全員が同じツールを使うべきだという理由で、他の人たちをEmacsへ移行させることにも失敗した
今では作業ごとに別々の単一目的ツールをはるかに非効率に使いながら、新しいUIやキーマッピングまで覚え続けている
管理者は新しいプロジェクトでは全員Visual Studio Codeを使おうと言うだろうが、使っている消費モデルはVSCodeでもサポートされていない。Gitとデプロイ手順さえ合わせれば、エディタは各自が使い慣れたものを選べばいいはずなのに、Microsoftがサポートしていないオープンソースなので危険で、会社が検証していないソフトウェアだという答えが返ってきそうだ
Emacsは毎日使う中核ツールなので、禁止されるなら退職するつもりだ。管理者は理解したり論理的に判断したりしようとしているのではなく、別のIT部門の指示に従っているだけだ
会社が汎用テキストエディタを指定しているなら、Notepadを起動しても問題になるのか、個人用のToDo管理ツールまで指定しているのか確認してみる価値はある。Emacsで実行でき、まだ会社がツールを指定していないカテゴリを見つけ、その用途でインストールすればよい
Emacsはプラットフォームであり、オペレーティングシステムもまた複数あるプラットフォームの一つだ。プラットフォームとは、その上に新しいものを作れるよう設計されたソフトウェア層なので、作りたいYに対してどのプラットフォームXが適しているかを問うべきだ
私にとってXはEmacsであることが多いが、RacketやRustの場合もある。アプリケーションでありながら優れたプラットフォームでもあるツールなら、単なるアプリケーションより多くの学習投資をする価値がある
Emacsを十分に使い込み、「Emacsはオペレーティングシステムだ」という言葉を冗談ではなく、実際に信じられる概念として理解した瞬間が、キャリア上の重要な転換点になった
org modeを試そうとして数年前にEmacsを使い始め、極端に高い柔軟性のために使い続けることになった
init.elを自分で構成してみるつもりだEmacsは、テキストエディタを内蔵したプログラミング環境に近い。一部のSmalltalkイメージに似たものだと考えると、かなり興味深いツールだ
Emacsはオペレーティングシステムではなくシェルに近いが、シェルという概念自体が広く理解されているわけではない
viのほうがむしろシェルに近い。多くの機能を:.!で他の標準Unixプログラムに任せる必要があるからだ一方Emacsは、オペレーティングシステムのようにあらゆる機能を一つの巨大なディストリビューションに含めている
Emacsを使っていない人に見せるのに良い短い入門動画を最近見つけた
https://www.youtube.com/watch?v=mJZDmO5yOxE
init.elが本当に気になるEmacs自体をクライアントとサーバーとして実行できる。
emacs --daemonでサーバーを起動し、emacsclientで接続すると、ターミナルとGUIのすべてのインスタンスが同じサーバーを使い、開いているファイルとバッファを共有する残念ながらローカルでしか動作せず、Emacsサーバーのソケットをsshで転送してリモートクライアントから接続しようとしたが失敗した
emacsclientという名前はよくなかった。2026年に初めてEmacsに触れる人は、RESTクライアントのようにネットワーク越しにクライアントとサーバーの実行状態を同期するものだと期待しがちだここでのクライアントとサーバーは、Unixローカルドメイン、つまりファイルシステムソケットを通じてクライアントが簡単な制御コマンドを送る構造を指す。その後ネットワークソケットにも対応したが、クライアントが送るのは今でも単純な制御コマンドだけだ
ssh -XでリモートEmacsのフレームをローカルXサーバーに表示できる。ただし、非PGTK GTKビルドでは新しいフレームを閉じるときにリモートEmacsがクラッシュすることがあるので注意が必要だ