サービスオーケストレーターとしてのEmacs: Elispによるクライアント構築

サービスオーケストレーターとしてのEmacs: Elispによるクライアント構築

サービスオーケストレーターとしてのEmacs

Emacsはオペレーティングシステムではありませんが、OSカーネルレベルより上のアプリケーションやユーティリティを管理できる高レベルなオーケストレーターとして機能します。システムサービスへの組み込みのアクセス権とEmacs Lisp (Elisp) の柔軟性を活用することで、ユーザーはネットワークAPIやローカルのコマンドラインツールといった、ほぼすべての外部リソースを、カスタムクライアントによって消費されるサービスとして扱うことができます。

Emacsにおけるクライアント・サーバーモデル

標準的なクライアント・サーバーモデルでは、タスクはサービス(リソース提供者)とクライアント(要求者)の間に分割されます。Emacsは、クライアントの3つの主要な関心事に対してネイティブライブラリを提供しているため、この相互作用のクライアント側を実装する上でユニークな立場にあります。

1. ユーザーインターフェース (UI)

Emacsは、データの表示や入力のキャプチャのために、以下のような幅広い組み込みUIコンポーネントを提供しています:

  • Minibuffers and Buffers: 基本的なテキスト操作とデータ表示用。
  • Completion and Transient: 効率的なユーザー入力とコマンドナビゲーション用。
  • Tabulated List Mode and vtable: 構造化データの提示用。

2. クライアント・エッジ (通信)

Emacsは、以下を通じて外部サービスと通信するための必要な仕組みを提供しています:

  • Network Protocols: URL (HTTP/HTTPS), Sockets (TCP/UDP), および SMTP の組み込みサポート。
  • Data Serialization: JSON および XML をパースして生成するためのネイティブライブラリ。

3. ローカルデータベース (データ管理)

交換されたデータの状態を管理するために、Emacsは以下を利用します:

  • Collections: Association lists, property lists, および hash tables。
  • Persistent Storage: より複雑なデータ要件のための組み込みの SQLite サポート。

サービスクライアントの実装: wttr.in の例

Elispは動的言語であるため、開発者はクライアントを迅速にプロトタイプできます。例えば、wttr.in 用の天気クライアントは、以下の手順に従うことで、約67行のコードで実装可能です:

  1. Request Construction: url-generic-parse-url を使用して wttr.in JSON API へのリクエストを構築します。
  2. Data Retrieval: url-retrieve-synchronously を使用してデータを取得し、json-parse-buffer を使用してレスポンスを Elisp の hash table に変換します。
  3. Data Extraction: hash table をパースして特定の値(例:温度や天気の詳細)を抽出し、人間が読みやすい文字列にフォーマットします。
  4. Display: 最終的な文字列を minibuffer に出力し、後で利用するために kill-ring に保存します。

CLIツールをサービスとして再定義する

専用の Elisp ライブラリが必要でない場合、あらゆるコマンドラインユーティリティを「サービス」として再定義できます。shell-command-to-string を使用することで、Emacsはローカルスクリプト(例:API呼び出しを処理する Python スクリプト)にリクエストを送信し、そのスクリプトの出力をサービスレスポンスとして扱うことができます。これにより、広範なボイラープレートコードを書くことなく、外部ツールの高度に即興的な統合が可能になります。

コミュニティの視点と技術的背景

「すべてはサービスである」というアプローチは強力ですが、コミュニティは Emacs の性質についていくつかの微妙な視点を提供しています:

  • Lisp Machine Heritage: 一部のユーザーは、Emacs は OS ではなく、Lisp Machine の概念の実現であると主張しています。つまり、テキストエディタが組み込まれたプログラミング環境であり、その逆ではありません。
  • Comparison to Modern Standards: Language Server Protocol (LSP) がエディタにおける多くのクライアント・サーバー相互作用を標準化しましたが、コントリビューターたちは、Emacs は LSP が存在するずっと前から、長時間実行されるサブプロセス、RPCのような相互作用、および TRAMP (Transparent Remote Access, Multiple Protocols) を備えていたと指摘しています。
  • The "Blob" Architecture: 一部の人は Emacs を「一様な Lisp の塊 (unvariegated blob of Lisp)」と表現しています。そこでは、コアシステムとプラグインの境界が曖昧であり、新しいサービスをシームレスに統合できるのです。

"Emacs は、テキストエディタが組み込まれたプログラミング環境のようなものです。ある種の SmallTalk イメージのようです。"

"Emacs は、長時間実行されるサブプロセス、RPC的な相互作用、TRAMP、GUD、REPL 統合などを備えていました。LSP は一つの重要なインターフェースを標準化しましたが、それはアーキテクチャの始まりではありません。"

Sources