Version 2.0 — now on every desktop

Notes that can compute.

EEditor is a Markdown editor with a Lisp interpreter, an SQLite database and a Lotus Agenda-style organizer built in. Your notes stay plain files in a folder you choose. Nothing is uploaded, and there is no account to make.

Free and open source (MIT). Version 2.0.0 · an iPhone and iPad build is in testing.

A rewrite, not a re-skin

EEditor started as a Mac-only app in Swift. Version 2 is a ground-up rebuild: the language and database core moved into EELisp, a standalone Rust engine, and the app around it is TypeScript on CodeMirror 6 in a Tauri shell. One engine, one editor, five platforms — and the parts you can script are now the same everywhere.

What's inside

A real editor

CodeMirror 6 with Markdown highlighting, live preview, light and dark themes, multiple tabs and autosave. Export any note to PDF.

Find anything

Fuzzy quick-open on ⌘P, full-text search across the workspace on ⌘⇧F, and a #hashtag index that doubles as a filter.

Linked notes

[[Wiki links]] with autocomplete as you type, click-through in preview or -click in the editor, and a backlinks bar showing what points here.

An organizer, not a to-do list

Items with dates, priorities and notes; hierarchical categories; recurrence; a calendar you can drag things around in; and rules that file new items for you.

λ

A language in the box

The EELisp REPL sits under the editor. Query the database, script your notes, or run a ```eelisp block straight from a document with ⌘⇧↵.

Tables and forms, not text dumps

browse renders a real table widget and defform a real form — dBASE III's good idea, rebuilt on SQLite.

The part nobody else has

Your keybindings are a program

There is no shortcuts preference pane. There is a file — .eeditor/keybindings.eelisp in your workspace — and that file is the shortcut table. Open it with ⌘⇧K, save it with ⌘S, and it reloads immediately. Delete it and the defaults come back.

A binding's body is EELisp, evaluated when the key fires. It hands back editor commands as data, so a shortcut can compute what it inserts:

;; ⌘I — a new note stamped with the minute, and a heading to match
(bind "Mod-i"
  (ed-new (str *date* " " (str-replace *time* ":" "") ".md")
          (str "# " *date* " " *time* "\n\n")))

;; ⌘B — wrap whatever is selected in bold
(bind "Mod-b" (ed-replace (str "**" *selection* "**")))

;; What opens when EEditor launches — a note, today's note, or nothing at all
(on-start (ed-cmd "daily-note"))

The caret, the selection, the whole buffer, the date and the time are all bound as variables before your code runs. Anything the standard library defines is callable too. The full binding reference is in the manual.

Files you can still read in ten years

A workspace is a folder. Notes are Markdown files in it. Move them, back them up with git, open them in any other editor — EEditor holds no lock on your work and keeps no proprietary index you'd lose.

Files from outside the workspace open too: drag one onto the window, or use Open With from your file manager. EEditor asks once whether to copy it in or edit it where it lies, and in-place notes save straight back to the original.

On iPhone and iPad, the workspace is exposed in the Files app under On My iPhone → EEditor, so the same notes sync however you already sync files.

Get EEditor 2.0

Free, no account, nothing to sign up for.

Download