logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·01.11.26
← Back to news

In Emacs, Everything Looks Like a Service

Original article
yummymelon.com|137 points|73 comments|by kickingvegas|Jul 10, 2026

In Emacs, Everything Looks Like a Service

Notes based on the writing of Charles Choi (최민수) Date: 09 Jul 2026

It is a frequent claim that Emacs is an operating system (OS). While this is technically inaccurate, the comparison arises because Emacs possesses the unique ability to coordinate various utilities and applications sitting atop the OS kernel.

The following diagram illustrates the actual relationship between Emacs, the underlying OS, and its functional capabilities:

Because Emacs has native access to system services (such as the network and file system) and can execute external binaries, it is remarkably easy to build custom client behaviors directly within the editor. Consequently, users can satisfy a vast array of computing requirements through various "client modes," leading to the philosophy of “living exclusively in Emacs.”

This article explores how Emacs enables the construction of these clients, arguing that within this environment, everything is essentially a service.


Understanding the Client–Server Model

At its core, the client-server model is a design pattern that splits a task between two entities:

  1. The Service (Provider): The entity that holds the resource.
  2. The Client (Requester): The entity that asks for the resource.

Definition: A transaction consists of a request issued by the client and a subsequent response returned by the server.

These interactions can happen across a global network or locally on a single machine. The most prominent modern implementation of this is the REST-style architecture.

REST Interaction Flow

The sequence below depicts a standard RESTful communication pattern:


Emacs as a Client

To function as a client, Emacs must handle three primary concerns. We can view these as a checklist for implementation:

  • UI (User Interface): How the data is presented to the user.
  • Client Edge: The mechanism for communicating with the external service.
  • Local Database: How the exchanged data is stored or synchronized locally.

Emacs provides a wealth of built-in and community libraries to satisfy these needs.

Available Emacs Tooling

ConcernEmacs Libraries / Features
UIMinibuffers, Buffers, Completion, Tabulated List Mode, Variable Pitch Table (vtable), Transient
Client EdgeURL, Socket (TCP/UDP), SMTP, JSON, XML
Local DatabaseCollections, Association Lists (alists), Property Lists (plists), Hash Tables, SQLite

The level of complexity depends on the goal. If a command-line tool already exists to do the "heavy lifting," that tool can be treated as a service accessed via a shell call.

The Role of Elisp

All the aforementioned tools are orchestrated via Elisp (Emacs Lisp). Because Elisp is a dynamic programming language, it allows for extreme improvisation during runtime. This flexibility enables the complex coordination of everything from internal Lisp functions to external shell commands.


Practical Implementation: A wttr.in Client

To demonstrate, let's look at a client for wttr.in, a weather service designed for the console. Since it supports JSON, we can create a wttr command that prompts for a location, fetches the data, and displays it in the mini-buffer.

1. The Main Entry Point

The wttr function handles the user interaction and error catching.

(defun wttr (location)
  "Show weather conditions for LOCATION from `https://wttr.in' in mini-buffer."
  (interactive "sWhere (default: local): ")
  (condition-case err
      (let* ((url (wttr--request-url location))
             (jsondb (fetch-json-as-hash-table url))
             (msg (wttr--report-message jsondb)))
        (kill-new msg)
        (message "%s" msg))
    (error
     (message "ERROR: %s" (cdr err)))))

2. Constructing the Request

The URL must be formatted correctly to request JSON output (format=j1).

(defun wttr--request-url (location)
  "Construct wttr.in URL with LOCATION."
  (let* ((base-url (url-generic-parse-url "https://wttr.in"))
         (encoded-location (string-replace "+" location))
         (query (format "/%s?format=j1" encoded-location))
         (_dummy (setf (url-filename base-url) query)))
    (url-recreate-url base-url)))

3. Fetching and Parsing

This function handles the network request and converts the JSON response into an Elisp hash-table.

(defun fetch-json-as-hash-table (url)
  "Fetch URL with expected JSON response and return a `hash-table'."
  (let ((data-buffer (url-retrieve-synchronously url)))
    (if (not data-buffer)
        (error "Failed to fetch data from %s url" url)
      (unwind-protect
          (with-current-buffer data-buffer
            ;; Move point past the HTTP metadata headers
            (goto-char (url-http-end-of-headers))
            ;; Parse the remaining JSON buffer into a hash-table
            (json-parse-buffer :object-type 'hash-table))
        ;; Always kill the downloaded network buffer to prevent memory leaks
        (kill-buffer data-buffer)))))

4. Formatting the Output

Finally, we extract the specific values. For example, the service provides temperatures in both Celsius and Fahrenheit, related by the formula: T∘F=T∘C×95+32T_{^\circ\text{F}} = T_{^\circ\text{C}} \times \frac{9}{5} + 32T∘F​=T∘C​×59​+32

(defun wttr--report-message (jsondb)
  "Generate weather report message from JSONDB."
  (let* ((area-buflist ())
         (nearest-area (wttr--get-first jsondb 'nearest_area))
         (area-name (map-elt (wttr--get-first nearest-area 'areaName) 'value))
         (region (map-elt (wttr--get-first nearest-area 'region) 'value))
         (country (map-elt (wttr--get-first nearest-area 'country) 'value))
         (current-condition (wttr--get-first jsondb 'current_condition))
         (temp_c (map-elt current-condition 'temp_C))
         (temp_f (map-elt current-condition 'temp_F))
         (weather-description (map-elt (wttr--get-first current-condition 'weatherDesc) 'value)))
    (mapc (lambda (x)
            (if (and x (not (string-equal x "")))
                (push x area-buflist)))
          (list area-name region country))
    (format "%s: %s°C, %s°F %s" 
            (string-join area-buflist ", ") 
            temp_c temp_f weather-description)))

Emacs Workflow Placeholder

By leveraging these patterns, Emacs transforms from a mere text editor into a powerful orchestrator where any external data source or local utility is simply another service to be integrated.