Releases: clojure-emacs/port
v0.3.0
New features
- Wire-level message log for debugging:
M-x port-toggle-message-log(orport-log-messages t) mirrors every outgoing form and incoming parsed message to*port-messages*, timestamped to the millisecond and labelleduser/tool. Off by default. - Eldoc highlights the active argument and shows a short docstring preview alongside the arglist. Multi-arity arglists are parsed and the arity matching the current position picked automatically. Customisable via
port-eldoc-arg-index-functionandport-eldoc-arglist-formatter.
Bugs fixed
- Fix Emacs hang when a large prepl response (e.g. the completion warm-up against a namespace with thousands of vars) arrived in many TCP chunks. The process filter used to re-parse the accumulated buffer from byte 0 on every chunk; it now defers parsing until a real newline arrives, at most one parse per inbound message. ~10x speedup on 100KB responses.
Changes
- REPL input-completeness check rewritten on top of
parse-partial-sexp+ the newport-repl-input-syntax-tabledefvar. Same observable behaviour, override-friendly for dialect variants.
v0.2.0
-
Optional inline result overlays. Set
port-eval-overlay' tot' and each interactive eval (C-c C-e' on a sexp,C-c C-c'
on a defun, etc.) places a=> VALUE' overlay at the end of the form, dismissed by the next command. Composes withport-eval-display': you can keep your minibuffer / REPL
output and add the overlay on top. Errors get the
port-eval-overlay-error-face'; long values are truncated to the first line (full text still lands in the REPL whenport-eval-display' is `both'). Off by default, so the
existing minibuffer-or-REPL UX is unchanged. -
xref-find-definitionsnow offers tab-completion at its prompt,
drawing from the same per-namespace cache `completion-at-point'
uses. Falls back to free-form input when the cache is cold so
the prompt always works. -
M-x portjacks in to babashka projects (bb.edn). The
spawned command isbb -e <server-form>, identical to the
tools-deps / Leiningen invocations modulo the program name and
the dropped-Sdepsstep (bb resolves classpath viabb.edn).
Pretty-print:valfworks in bb too, so taps and eval results
arrive multi-line.port-jack-in-babashka-programoverrides
thebbbinary;port-jack-in-extra-depsis ignored for bb. -
completion-at-pointno longer blocks Emacs on every keystroke.
Port now fetches the full symbol list for the buffer's namespace
once and filters Elisp-side on subsequent capf calls; corfu /
company-mode auto-popup feels instant after the first hit. The
cache is warmed asynchronously whenport-mode' is enabled with a session live, expires afterport-completion-cache-ttlseconds (default 10), and gets cleared eagerly whenport-load-file' or
port-set-ns' runs.M-x port-completion-clear-cache' forces a
refresh. Setport-completion-use-cacheto nil for the previous
one-query-per-keystroke behaviour. -
Trace-frame jumps in
*port-stacktrace*now reach jar-only
frames.RETon a frame whose:filedoesn't resolve under
default-directoryor a project source root now asks the JVM
viaclojure.java.io/resourceover the tool socket; jar URLs
open the slurped source in the same*port-jar: ...*buffer
cacheM-.uses,file:URLs visit the path directly. Two
new defcustoms:port-stacktrace-frame-form(the lookup
template) andport-stacktrace-frame-timeout. -
Breaking:
port-find-definitionis gone; replaced by a real
xref-backend-functionsentry installed byport-mode. The
defaultM-./M-,bindings now route through Port whenever
a session is live, andxref-find-apropos(C-M-.by default)
returns matching symbols across all loaded namespaces, each
resolved to its file:line. Two new defcustoms:
port-xref-apropos-form(the apropos query template, mirroring
port-xref-form) andport-xref-apropos-timeout(default 5
seconds, since walkingall-nsisn't free). References aren't
implemented; for that, layer clojure-lsp via eglot or lsp-mode. -
clojure.testrunner with a structured report buffer. Four
commands underC-c C-t:truns the deftest at point,nthe
current namespace,pevery loaded test-bearing namespace, and
rre-runs whatever failed or errored last. Results land in
*port-test-report*with per-failure sections showing
expected/actual and afile:linelink to the source;RETon a
link jumps,n/pwalk failures,gre-runs the same
selection. Errors carry the capturedThrowable->map, soRET
on(RET to show stacktrace)pops the existing structured
stacktrace buffer. The Clojure-side machinery is held in
port-test-bootstrap-form; the four entry-point templates are
individual defcustoms (port-test-run-ns-formetc.) for dialect
or library overrides. -
Optional Orchard and
Compliment
integration viaport-orchard.el.M-x port-enable-orchard' probes the running prepl fororchard.info' andcompliment.core' and swaps in richer form templates for doc, eldoc, apropos, find-definition, and completion — independently per library. Orsetq' the
port-orchard-*' /port-compliment-*' defconsts persistently in
your init. -
port-enable-orchard-on-connectdefcustom: when non-nil,
port-enable-orchard' runs automatically after every successful jack-in /port-connect'. Paired with `port-jack-in-extra-deps' it
gets Orchard from "opt-in" to "always on" in two settings lines. -
port-after-connect-hook: a hook run at the end ofport-connect' once the tool-socket bootstrap has been installed. Used internally byport-orchard.el' for the auto-enable wiring; available for any
user-side extension that needs to fire helper-command requests
immediately after connect. -
Dedicated
*port-taps*history buffer for values published via
tap>. Each tap is appended with a timestamp header and rendered
inclojure-mode(orclojure-ts-mode) for syntax highlighting.
port-show-taps/port-clear-tapsare bound toC-c C-t v/
C-c C-t cinport-mode; the buffer is capped at
port-tap-max-entries(default 100). -
port-jack-in-extra-depsdefcustom: alist of(DEP . VERSION)
pairs that get spliced into the JVM start command at jack-in
(clojure -Sdeps {...}for tools-deps, chained
lein update-in :dependencies conjfor Leiningen). Combined with
the new `port-jack-in-orchard-deps' preset, opting into Orchard +
Compliment is now a one-liner:(setq port-jack-in-extra-deps port-jack-in-orchard-deps) -
port-jack-inis now an alias forport' — discoverable under the CIDER-style name for users withcider-jack-in' muscle memory. -
Jack-in now configures
io-preplwith aclojure.pprint-based
:valfby default, so:retand:tapvalues on the user socket
arrive pretty-printed (bounded byport-print-length/
port-print-level). Setport-jack-in-pretty-printto nil for
the old single-linepr-strbehaviour. -
Every Clojure form Port sends to the prepl is now held in a
defcustom—port-doc-form,port-source-form,
port-apropos-form,port-macroexpand-1-form,
port-macroexpand-all-form,port-load-file-form,
port-set-ns-form,port-eldoc-form,port-completion-form,
andport-xref-form. Each defaults to a JVMclojure.repl/*-style
form; override to target a different dialect (ClojureScript's
cljs.repl/*, a Compliment-based completion variant, etc.) without
having to fork Port.
v0.1.0
Initial release.
- TCP prepl client with a small EDN-ish reader (handles maps, vectors, and lists with simple leaf values).
- Two-socket session model: a user socket drives the REPL with raw streaming output, and a separate tool socket carries helper-command requests with reliable request/response correlation via a small
port.tooling/-evalbootstrap. M-x portjacks in: detectsdeps.edn/project.clj/bb.edn, picks a free port, spawns a JVM running a prepl server, polls until reachable, and connects. If a session is already active it just pops to the REPL, SLIME-style.- Single-buffer REPL that renders
:ret,:out,:err, and:tapmessages. Eldoc, completion-at-point, and persistent input history are wired into the prompt; killing the REPL buffer disconnects the session. - Persistent REPL input history. Each REPL buffer reads/writes
<project-root>/.port-history(configurable viaport-repl-history-file);M-p/M-nwalk the history across sessions. Capacity isport-repl-history-size(default 1000) and adjacent duplicates are dropped. - Interactive eval commands: last-sexp, defun-at-point, region, buffer. Values returned through the tool-socket path are pretty-printed via
clojure.pprint, capped byport-print-length(default 50) andport-print-level(default 5). Multi-line results are truncated to the first line in the minibuffer; the full text appears in the REPL whenport-eval-displayisboth. - Helper commands powered by Clojure evaluation: doc, source, apropos, macroexpand-1, macroexpand, load-file, set-ns.
- Eldoc support: arglists for the function whose call surrounds point, resolved on the tool socket and delivered asynchronously via
eldoc-documentation-functions. completion-at-pointfor symbols visible in the buffer's namespace, driven by a synchronous tool-socket request that walksns-map.port-find-definition(bound toM-.) jumps to the source of the symbol at point using:file/:linefrom var metadata. When the source lives inside a jar, the file's contents are slurped over the tool socket and shown in a read-only*port-jar: ...*buffer.- Structured stacktrace buffer (
*port-stacktrace*): on:exception true(and on:tag :errfrom the tool socket) Port renders a concise one-line summary inline and pops a navigable buffer with the cause chain, ex-data, and a filtered trace.RETon a frame jumps to the source when the file resolves locally. port-modeminor mode for Clojure source buffers. No hard dependency onclojure-mode; hook it onto whichever Clojure mode you use (clojure-mode,clojure-ts-mode, or both).