Hammock Editor

A terminal text editor for deep thinking. Inspired by Rich Hickey's Hammock Driven Development. Minimal C kernel. Clojure scripting. Markdown-native.

scroll to explore

What It Is

Hammock is a Clojure-oriented terminal editor inspired by Emacs, but it's not Emacs. It's built for people who think in Clojure and write in GitHub-flavored Markdown.

The *scratch* buffer runs Clojure, evaluated by SCI (Small Clojure Interpreter) compiled as a native shared library via GraalVM. You can modify editor behavior live with C-j.

Architecture

Two layers: a functional core in Clojure and an imperative shell in C. Commands return effect vectors describing what C should do, rather than doing it directly.

C Kernel: src/

Performance-critical primitives: ncurses display, gap buffer text storage, key input, in-process SCI calls, and cursor movement.

Clojure Layer: clj/

Everything else: commands, keybindings, modes, editor state via atoms, git integration, markdown navigation, and buffer management.

Effect Vectors

Clojure commands return data like [:message "saved"] or [:point-forward 1]. C interprets and executes them.

Live Reload

Atom watches on keybindings, commands, and modes propagate changes instantly. swap! takes effect on the next loop iteration.

How It Works

1

Initialize the C kernel

ncurses terminal, input handling, gap buffers

2

Load Clojure modules via SCI

In-process evaluation of clj/*.clj through libsci

3

Fetch keybinding and mode tables

Clojure exports EDN, C parses it into its keymap

4

Enter the main loop

Each keystroke dispatches through the keymap. Hot-path commands run in C for zero latency. Everything else round-trips through Clojure.

Commands in Clojure

All editor commands are defined in Clojure using defcommand and return effect vectors:

;; clj/commands.clj
(defcommand "save-buffer"
  "Save the current buffer to disk"
  (fn []
    [(fx/save-buffer)
     (fx/message "Buffer saved.")]))

(defcommand "git-status"
  "Show git status in a buffer"
  (fn []
    (let [status (git/status)]
      [(fx/switch-to-buffer "*git-status*")
       (fx/insert status)])))

Features

Build

Requires a C11 compiler, ncurses, and GraalVM CE with native-image (provided by the Nix flake).

$ nix develop
$ make -C libsci
$ make

Built by Tobi Lehman