About Clojure Elisp
Clojure Elisp is an MCP server in the Other category: a Clojure dialect that compiles to Emacs Lisp.
Install
git clone https://github.com/BuddhiLW/clojure-elispThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Clojure Elisp
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
ClojureElisp
A Clojure dialect that compiles to Emacs Lisp — like ClojureScript targets JavaScript, ClojureElisp targets Emacs.
Write .cljel files using Clojure syntax, compile them to .el files that run natively in Emacs 28.1+.
Quick Start
(require '[clojure-elisp.core :as clel])
;; Compile a single form
(clel/emit '(defn greet [name] (str "Hello, " name "!")))
;; => "(defun greet (name)\n (clel-str \"Hello, \" name \"!\"))"
;; Compile a string of code
(clel/compile-string "(defn inc2 [x] (+ x 2))")
;; => "(defun inc2 (x)\n (+ x 2))"
;; Compile a .cljel file to .el
(clel/compile-file "src/my_package.cljel" "out/my-package.el")
;; Compile an entire project in dependency order
(clel/compile-project ["src"] "out")
Example
;; my-package.cljel
(ns my.package
(:require [clojure.string :as str]))
(defn greet [name]
(let [msg (str "Hello, " name "!")]
(message msg)))
(defn process-buffer []
(-> (buffer-string)
str/upper-case
insert))
Compiles to:
;;; my-package.el --- -*- lexical-binding: t; -*-
;; Generated by ClojureElisp
(require 'clojure-elisp-runtime)
;;; Code:
(defun my-package-greet (name)
(let* ((msg (clel-str "Hello, " name "!")))
(message msg)))
(defun my-package-process-buffer ()
(insert (upcase (buffer-string))))
(provide 'my-package)
;;; my-package.el ends here
Features
Language
- Functions:
defn,fn(lambda), multi-arity, variadic (& rest), destructuring in params - Bindings:
letwith sequential bindings, vector/map destructuring,:keys,:as,:or - Control flow:
if,when,cond,case,do,and,or - Looping:
loop/recur,letfnwith mutual recursion - Macros:
defmacro(compile-time only), syntax-quote/unquote,macroexpand-1,macroexpand - Error handling:
try/catch/finally,throw,ex-info - Namespaces:
nswith:require,:as,:refer; namespace-prefixed definitions - Protocols & types:
defprotocol,defrecord,deftypewith^:mutablefields,set! - Multimethods:
defmulti/defmethodviacl-defgeneric/cl-defmethod - Lazy sequences:
lazy-seq,realized?,doall,dorun - Atoms:
atom,deref/@,reset!,swap!,add-watch,remove-watch - Elisp interop:
.methoddot-notation,elisp/fnnamespace,.-propertyaccess
Core Functions (100+)
Clojure core functions mapped to Elisp equivalents:
| Category | Functions |
|---|---|
| Arithmetic | +, -, *, /, mod, inc, dec |
| Comparison | =, <, >, <=, >=, not= |
| Predicates | nil?, string?, number?, zero?, pos?, neg?, even?, odd?, coll?, some? |
| Collections | first, rest, next, cons, conj, count, nth, get, assoc, dissoc, keys, vals, into, seq, empty? |
| Sequences | map, filter, remove, reduce, take, drop, concat, mapcat, sort, group-by, frequencies |
| Seq predicates | every?, some, not-every?, not-any? |
| Strings | str, subs, format, pr-str, println |
| Higher-order | apply, identity, constantly, partial, comp |
Compiler
- 3-stage pipeline: Reader (Clojure's) → Analyzer (AST + env) → Emitter (codegen)
- Source location tracking with optional
;;; L<line>:C<col>comments - Incremental compilation with mtime tracking (
.clel-cache/manifest.edn) - Cross-file symbol table with compile-time warnings for missing symbols
- Dependency-aware project compilation with topological sort
- Name mangling:
valid?→valid-p,reset!→reset-bang,my.ns/foo→my-ns-foo
Architecture
┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ Reader │───▶│ Analyzer │───▶│ Emitter │───▶│ Elisp Code │
│ (Clojure's) │ │ (AST + env) │ │ (codegen) │ │ (.el) │
└─────────────┘ └──────────────┘ └─────────────┘ └──────────────┘
| Component | File | Role |
|---|---|---|
| Analyzer | src/clojure_elisp/analyzer.clj |
Parse forms → AST nodes, macro expansion, destructuring, env tracking |
| Emitter | src/clojure_elisp/emitter.clj |
AST nodes → Elisp source strings |
| Core | src/clojure_elisp/core.clj |
Public API, file/project compilation, dependency resolution |
| Runtime | resources/clojure-elisp/clojure-elisp-runtime.el |
55+ Elisp functions implementing Clojure semantics |
| MCP Server | src/clojure_elisp/mcp.clj |
MCP stdio server exposing compiler as AI tools |
| CLI | src/clojure_elisp/cli.clj |
JVM uberjar entry point (compile, mcp, version) |
| BB CLI | bb/clel/main.clj |
Babashka CLI frontend (delegates to uberjar) |
| Emacs mode | resources/clojure-elisp/clojure-elisp-mode.el |
Major mode for .cljel files |
| CIDER | resources/clojure-elisp/cider-clojure-elisp.el |
nREPL middleware for CIDER integration |
Installation
Via bbin (recommended)
Install the clel CLI with bbin:
bbin install io.github.BuddhiLW/clojure-elisp
This gives you the clel command globally. Requires Babashka and the uberjar (see below).
Uberjar
The CLI delegates compilation to a JVM uberjar. Download from GitHub Releases or build from source:
# Build and install
make build install
# => ~/.local/lib/clel.jar
The CLI auto-detects the jar at ~/.local/lib/clel.jar or via $CLEL_JAR. If no jar is found, it falls back to clojure -M -e.
CLI Usage
clel compile # Compile project from clel.edn
clel compile src/my_app.cljel -o out/ # Compile a single file
clel compile src/ -o out/ # Compile a directory
clel watch src/ -o out/ # Watch and recompile on changes
clel mcp # Start MCP stdio server
clel version # Print version
Runtime (Emacs Package)
Compiled .el files require the ClojureElisp runtime. Install via MELPA (once available):
(package-install 'clojure-elisp)
Or manually copy from the repo:
cp resources/clojure-elisp/clojure-elisp-runtime.el ~/.emacs.d/site-lisp/
Building from Source
# Build uberjar
clojure -T:build uber
# => target/clel-<version>.jar
Development
# Start REPL with dev dependencies (nREPL, CIDER)
clojure -M:dev
# Run tests (Kaocha — 500 tests, 2588 assertions)
clojure -M:test
# Build uberjar
clojure -T:build uber
Requirements
- Clojure 1.12+
- Java 21+ (for building/running the uberjar)
- Emacs 28.1+ (for compiled output)
License
MIT
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.