|
1 | 1 | # Changelog |
2 | 2 |
|
3 | | -## 0.3.0-snapshot (unreleased) |
4 | | - |
5 | | -- **Fix** Emacs hang when receiving a large prepl response (e.g. the |
6 | | - completion warm-up against a namespace with thousands of vars). |
7 | | - The process filter re-parsed the entire accumulated buffer from |
8 | | - byte 0 on every TCP chunk, throwing `port-edn-incomplete` partway |
9 | | - through and walking the same prefix again on the next chunk — |
10 | | - O(M^2 / K) work plus a list of ~M cons cells discarded per |
11 | | - chunk. For a 100 KB response in ~90 chunks that was enough GC |
12 | | - churn to freeze the editor for seconds. We now defer the parse |
13 | | - attempt until the buffer contains a real newline (prepl's |
14 | | - per-message terminator; embedded newlines in printed strings are |
15 | | - escaped as `\\n'), so at most one parse runs per inbound message. |
16 | | - Microbenchmarks show ~10x speedup on 100 KB responses; the |
17 | | - reproducible recipe — typing `[:' in the REPL while the |
18 | | - completion warm-up is in flight — no longer hangs. |
19 | | -- REPL input-completeness check rewritten on top of |
20 | | - `parse-partial-sexp' against a new `port-repl-input-syntax-table' |
21 | | - defvar. Functionally identical to the previous hand-rolled |
22 | | - character walker (same balance, string, and `;'-comment |
23 | | - semantics), but ~20 lines shorter and override-friendly: drop in |
24 | | - a different syntax table to use Port's REPL with dialect variants |
25 | | - that have different bracket or comment conventions. |
26 | | -- Wire-level message log for debugging. Set `port-log-messages` to |
27 | | - `t` (or run `M-x port-toggle-message-log`) and every outgoing form |
28 | | - and incoming parsed message gets mirrored to `*port-messages*`, |
29 | | - timestamped to the millisecond and tagged with the socket label |
30 | | - (`user` / `tool`) plus host:port. Outgoing entries are the form |
31 | | - verbatim; incoming entries are `pp`'d. Off by default. |
32 | | -- Eldoc gained Neat-grade polish. The default server-side form now |
33 | | - returns a `{:name :arglists :doc}` map, and the Elisp side parses |
34 | | - the arglist (`[f coll]` / `([] [x] [x & rs])` shapes), picks the |
35 | | - arity matching the current argument position, and highlights the |
36 | | - active parameter with `eldoc-highlight-function-argument'. The |
37 | | - first line of `:doc' is appended to the display when present. |
38 | | - Target detection prefers the symbol at point, falling back to the |
39 | | - enclosing list head (so `(str |)' still shows `str''s arglist, |
40 | | - but `|str' shows `str''s directly). Two new customisation |
41 | | - seams: `port-eldoc-arg-index-function` (swap for non-Lisp argument |
42 | | - boundaries) and `port-eldoc-arglist-formatter` (swap for servers |
43 | | - reporting arglists in a different syntax). Form templates that |
44 | | - return a plain string still render verbatim, so 3rd-party overrides |
45 | | - stay backward compatible; the bundled Orchard variant has been |
46 | | - upgraded to return the new map shape too. |
| 3 | +## main (unreleased) |
| 4 | + |
| 5 | +### New features |
| 6 | + |
| 7 | +- Wire-level message log for debugging: `M-x port-toggle-message-log` (or `port-log-messages t`) mirrors every outgoing form and incoming parsed message to `*port-messages*`, timestamped to the millisecond and labelled `user` / `tool`. Off by default. |
| 8 | +- 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-function` and `port-eldoc-arglist-formatter`. |
| 9 | + |
| 10 | +### Bugs fixed |
| 11 | + |
| 12 | +- 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. |
| 13 | + |
| 14 | +### Changes |
| 15 | + |
| 16 | +- REPL input-completeness check rewritten on top of `parse-partial-sexp` + the new `port-repl-input-syntax-table` defvar. Same observable behaviour, override-friendly for dialect variants. |
47 | 17 |
|
48 | 18 | ## 0.2.0 (2026-05-14) |
49 | 19 |
|
50 | | -- Optional inline result overlays. Set `port-eval-overlay' to |
51 | | - `t' and each interactive eval (`C-c C-e' on a sexp, `C-c C-c' |
52 | | - on a defun, etc.) places a `=> VALUE' overlay at the end of |
53 | | - the form, dismissed by the next command. Composes with |
54 | | - `port-eval-display': you can keep your minibuffer / REPL |
55 | | - output and add the overlay on top. Errors get the |
56 | | - `port-eval-overlay-error-face'; long values are truncated to |
57 | | - the first line (full text still lands in the REPL when |
58 | | - `port-eval-display' is `both'). Off by default, so the |
59 | | - existing minibuffer-or-REPL UX is unchanged. |
60 | | -- `xref-find-definitions` now offers tab-completion at its prompt, |
61 | | - drawing from the same per-namespace cache `completion-at-point' |
62 | | - uses. Falls back to free-form input when the cache is cold so |
63 | | - the prompt always works. |
64 | | -- `M-x port` jacks in to babashka projects (`bb.edn`). The |
65 | | - spawned command is `bb -e <server-form>`, identical to the |
66 | | - tools-deps / Leiningen invocations modulo the program name and |
67 | | - the dropped `-Sdeps` step (bb resolves classpath via `bb.edn`). |
68 | | - Pretty-print `:valf` works in bb too, so taps and eval results |
69 | | - arrive multi-line. `port-jack-in-babashka-program` overrides |
70 | | - the `bb` binary; `port-jack-in-extra-deps` is ignored for bb. |
71 | | -- `completion-at-point` no longer blocks Emacs on every keystroke. |
72 | | - Port now fetches the full symbol list for the buffer's namespace |
73 | | - once and filters Elisp-side on subsequent capf calls; corfu / |
74 | | - company-mode auto-popup feels instant after the first hit. The |
75 | | - cache is warmed asynchronously when `port-mode' is enabled with a |
76 | | - session live, expires after `port-completion-cache-ttl` seconds |
77 | | - (default 10), and gets cleared eagerly when `port-load-file' or |
78 | | - `port-set-ns' runs. `M-x port-completion-clear-cache' forces a |
79 | | - refresh. Set `port-completion-use-cache` to nil for the previous |
80 | | - one-query-per-keystroke behaviour. |
81 | | -- Trace-frame jumps in `*port-stacktrace*` now reach jar-only |
82 | | - frames. `RET` on a frame whose `:file` doesn't resolve under |
83 | | - `default-directory` or a project source root now asks the JVM |
84 | | - via `clojure.java.io/resource` over the tool socket; jar URLs |
85 | | - open the slurped source in the same `*port-jar: ...*` buffer |
86 | | - cache `M-.` uses, `file:` URLs visit the path directly. Two |
87 | | - new defcustoms: `port-stacktrace-frame-form` (the lookup |
88 | | - template) and `port-stacktrace-frame-timeout`. |
89 | | -- **Breaking:** `port-find-definition` is gone; replaced by a real |
90 | | - `xref-backend-functions` entry installed by `port-mode`. The |
91 | | - default `M-.` / `M-,` bindings now route through Port whenever |
92 | | - a session is live, and `xref-find-apropos` (`C-M-.` by default) |
93 | | - returns matching symbols across all loaded namespaces, each |
94 | | - resolved to its file:line. Two new defcustoms: |
95 | | - `port-xref-apropos-form` (the apropos query template, mirroring |
96 | | - `port-xref-form`) and `port-xref-apropos-timeout` (default 5 |
97 | | - seconds, since walking `all-ns` isn't free). References aren't |
98 | | - implemented; for that, layer clojure-lsp via eglot or lsp-mode. |
99 | | -- `clojure.test` runner with a structured report buffer. Four |
100 | | - commands under `C-c C-t`: `t` runs the deftest at point, `n` the |
101 | | - current namespace, `p` every loaded test-bearing namespace, and |
102 | | - `r` re-runs whatever failed or errored last. Results land in |
103 | | - `*port-test-report*` with per-failure sections showing |
104 | | - expected/actual and a `file:line` link to the source; `RET` on a |
105 | | - link jumps, `n`/`p` walk failures, `g` re-runs the same |
106 | | - selection. Errors carry the captured `Throwable->map`, so `RET` |
107 | | - on `(RET to show stacktrace)` pops the existing structured |
108 | | - stacktrace buffer. The Clojure-side machinery is held in |
109 | | - `port-test-bootstrap-form`; the four entry-point templates are |
110 | | - individual defcustoms (`port-test-run-ns-form` etc.) for dialect |
111 | | - or library overrides. |
112 | | -- Optional [Orchard](https://github.com/clojure-emacs/orchard) and |
113 | | - [Compliment](https://github.com/alexander-yakushev/compliment) |
114 | | - integration via `port-orchard.el`. `M-x port-enable-orchard' probes |
115 | | - the running prepl for `orchard.info' and `compliment.core' and swaps |
116 | | - in richer form templates for doc, eldoc, apropos, find-definition, |
117 | | - and completion — independently per library. Or `setq' the |
118 | | - `port-orchard-*' / `port-compliment-*' defconsts persistently in |
119 | | - your init. |
120 | | -- `port-enable-orchard-on-connect` defcustom: when non-nil, |
121 | | - `port-enable-orchard' runs automatically after every successful |
122 | | - jack-in / `port-connect'. Paired with `port-jack-in-extra-deps' it |
123 | | - gets Orchard from "opt-in" to "always on" in two settings lines. |
124 | | -- `port-after-connect-hook`: a hook run at the end of `port-connect' |
125 | | - once the tool-socket bootstrap has been installed. Used internally |
126 | | - by `port-orchard.el' for the auto-enable wiring; available for any |
127 | | - user-side extension that needs to fire helper-command requests |
128 | | - immediately after connect. |
129 | | -- Dedicated `*port-taps*` history buffer for values published via |
130 | | - `tap>`. Each tap is appended with a timestamp header and rendered |
131 | | - in `clojure-mode` (or `clojure-ts-mode`) for syntax highlighting. |
132 | | - `port-show-taps` / `port-clear-taps` are bound to `C-c C-t v` / |
133 | | - `C-c C-t c` in `port-mode`; the buffer is capped at |
134 | | - `port-tap-max-entries` (default 100). |
135 | | -- `port-jack-in-extra-deps` defcustom: alist of `(DEP . VERSION)` |
136 | | - pairs that get spliced into the JVM start command at jack-in |
137 | | - (`clojure -Sdeps {...}` for tools-deps, chained |
138 | | - `lein update-in :dependencies conj` for Leiningen). Combined with |
139 | | - the new `port-jack-in-orchard-deps' preset, opting into Orchard + |
140 | | - Compliment is now a one-liner: |
141 | | - |
142 | | - (setq port-jack-in-extra-deps port-jack-in-orchard-deps) |
143 | | - |
144 | | -- `port-jack-in` is now an alias for `port' — discoverable under the |
145 | | - CIDER-style name for users with `cider-jack-in' muscle memory. |
146 | | -- Jack-in now configures `io-prepl` with a `clojure.pprint`-based |
147 | | - `:valf` by default, so `:ret` and `:tap` values on the user socket |
148 | | - arrive pretty-printed (bounded by `port-print-length` / |
149 | | - `port-print-level`). Set `port-jack-in-pretty-print` to nil for |
150 | | - the old single-line `pr-str` behaviour. |
151 | | -- Every Clojure form Port sends to the prepl is now held in a |
152 | | - `defcustom` — `port-doc-form`, `port-source-form`, |
153 | | - `port-apropos-form`, `port-macroexpand-1-form`, |
154 | | - `port-macroexpand-all-form`, `port-load-file-form`, |
155 | | - `port-set-ns-form`, `port-eldoc-form`, `port-completion-form`, |
156 | | - and `port-xref-form`. Each defaults to a JVM `clojure.repl/*`-style |
157 | | - form; override to target a different dialect (ClojureScript's |
158 | | - `cljs.repl/*`, a Compliment-based completion variant, etc.) without |
159 | | - having to fork Port. |
| 20 | +### New features |
| 21 | + |
| 22 | +- `clojure.test` runner with a navigable `*port-test-report*` buffer. `C-c C-t t` runs the deftest at point, `C-c C-t n` the current namespace, `C-c C-t p` every loaded test-bearing namespace, `C-c C-t r` re-runs the failures. `RET` on a failure jumps to source or pops the stacktrace; `n`/`p` walk failures, `g` re-runs the same selection. |
| 23 | +- Optional [Orchard](https://github.com/clojure-emacs/orchard) and [Compliment](https://github.com/alexander-yakushev/compliment) integration via `port-orchard.el`. `M-x port-enable-orchard` probes the running prepl and swaps in richer form templates for doc, eldoc, apropos, find-definition, and completion. |
| 24 | +- `port-enable-orchard-on-connect`: when non-nil, runs `port-enable-orchard` automatically after every successful jack-in / `port-connect`. |
| 25 | +- `port-after-connect-hook`: a hook run at the end of `port-connect` once the tool-socket bootstrap has been installed. |
| 26 | +- Dedicated `*port-taps*` history buffer for values published via `tap>`, bound to `C-c C-t v` (view) and `C-c C-t c` (clear). Capped at `port-tap-max-entries` (default 100). |
| 27 | +- `port-jack-in-extra-deps` splices extra Maven coords into the jack-in command (tools-deps via `-Sdeps`, Leiningen via chained `update-in :dependencies conj`). Ships with a `port-jack-in-orchard-deps` preset for one-line Orchard + Compliment opt-in. |
| 28 | +- `M-x port` jacks in to babashka projects (`bb.edn`). Override the binary via `port-jack-in-babashka-program`. |
| 29 | +- Optional inline eval-result overlays via `port-eval-overlay` (off by default). Composes with `port-eval-display`; errors get a distinct face. |
| 30 | + |
| 31 | +### Changes |
| 32 | + |
| 33 | +- **Breaking:** `port-find-definition` is gone; Port now installs an `xref-backend-functions` entry, so `M-.` / `M-,` route through the standard xref UI. `xref-find-apropos` is also wired up. |
| 34 | +- `xref-find-definitions` offers tab-completion at the prompt from the per-namespace symbol cache. |
| 35 | +- `completion-at-point` no longer blocks Emacs on every keystroke. Port pre-fetches the buffer's symbol list once per namespace and filters Elisp-side; the cache is warmed asynchronously and cleared by `port-load-file` / `port-set-ns`. Opt out via `port-completion-use-cache` nil. |
| 36 | +- Trace-frame jumps in `*port-stacktrace*` now reach jar-only frames. When local resolution misses, Port asks the JVM via `clojure.java.io/resource` and renders jar URLs in the shared `*port-jar: ...*` buffer cache. |
| 37 | +- Jack-in now configures `io-prepl` with a `clojure.pprint`-based `:valf` by default, so `:ret` and `:tap` values arrive pretty-printed. Opt out via `port-jack-in-pretty-print` nil. |
| 38 | +- `port-jack-in` is now an alias for `port`, matching `cider-jack-in` muscle memory. |
| 39 | +- Every Clojure form Port sends to the prepl is now held in a `defcustom` (`port-doc-form`, `port-source-form`, `port-apropos-form`, etc.), making it easy to swap in dialect- or library-specific variants without forking Port. |
160 | 40 |
|
161 | 41 | ## 0.1.0 (2026-05-11) |
162 | 42 |
|
163 | 43 | Initial release. |
164 | 44 |
|
165 | | -- TCP prepl client with a small EDN-ish reader (handles maps, |
166 | | - vectors, and lists with simple leaf values). |
167 | | -- Two-socket session model: a user socket drives the REPL with raw |
168 | | - streaming output, and a separate tool socket carries helper-command |
169 | | - requests with reliable request/response correlation via a small |
170 | | - `port.tooling/-eval` bootstrap. |
171 | | -- `M-x port` jacks in: detects `deps.edn` / `project.clj` / `bb.edn`, |
172 | | - picks a free port, spawns a JVM running a prepl server, polls until |
173 | | - reachable, and connects. If a session is already active it just |
174 | | - pops to the REPL, SLIME-style. |
175 | | -- Single-buffer REPL that renders `:ret`, `:out`, `:err`, and `:tap` |
176 | | - messages. Eldoc, completion-at-point, and persistent input history |
177 | | - are wired into the prompt; killing the REPL buffer disconnects the |
178 | | - session. |
179 | | -- Persistent REPL input history. Each REPL buffer reads/writes |
180 | | - `<project-root>/.port-history` (configurable via |
181 | | - `port-repl-history-file`); `M-p` / `M-n` walk the history across |
182 | | - sessions. Capacity is `port-repl-history-size` (default 1000) |
183 | | - and adjacent duplicates are dropped. |
184 | | -- Interactive eval commands: last-sexp, defun-at-point, region, buffer. |
185 | | - Values returned through the tool-socket path are pretty-printed |
186 | | - via `clojure.pprint`, capped by `port-print-length` (default 50) |
187 | | - and `port-print-level` (default 5). Multi-line results are |
188 | | - truncated to the first line in the minibuffer; the full text |
189 | | - appears in the REPL when `port-eval-display' is `both'. |
190 | | -- Helper commands powered by Clojure evaluation: doc, source, apropos, |
191 | | - macroexpand-1, macroexpand, load-file, set-ns. |
192 | | -- Eldoc support: arglists for the function whose call surrounds point, |
193 | | - resolved on the tool socket and delivered asynchronously via |
194 | | - `eldoc-documentation-functions`. |
195 | | -- `completion-at-point` for symbols visible in the buffer's namespace, |
196 | | - driven by a synchronous tool-socket request that walks `ns-map'. |
197 | | -- `port-find-definition` (bound to `M-.`) jumps to the source of the |
198 | | - symbol at point using `:file` / `:line` from var metadata. When |
199 | | - the source lives inside a jar, the file's contents are slurped |
200 | | - over the tool socket and shown in a read-only `*port-jar: ...*` |
201 | | - buffer. |
202 | | -- Structured stacktrace buffer (`*port-stacktrace*`): on `:exception |
203 | | - true` (and on `:tag :err` from the tool socket) Port renders a |
204 | | - concise one-line summary inline and pops a navigable buffer with |
205 | | - the cause chain, ex-data, and a filtered trace. `RET` on a frame |
206 | | - jumps to the source when the file resolves locally. |
207 | | -- `port-mode` minor mode for Clojure source buffers. No hard |
208 | | - dependency on `clojure-mode`; hook it onto whichever Clojure mode |
209 | | - you use (`clojure-mode`, `clojure-ts-mode`, or both). |
| 45 | +### New features |
| 46 | + |
| 47 | +- TCP prepl client with a small EDN-ish reader for the subset of values prepl emits. |
| 48 | +- Two-socket session model: a user socket drives the REPL with raw streaming output; a separate tool socket carries helper-command requests, correlated via a small `port.tooling/-eval` bootstrap. |
| 49 | +- `M-x port` jacks in: detects `deps.edn` / `project.clj` / `bb.edn`, picks a free port, spawns the JVM, polls until reachable, and connects. |
| 50 | +- Single-buffer REPL rendering `:ret`, `:out`, `:err`, and `:tap` messages. Eldoc, completion-at-point, and persistent input history wired into the prompt; killing the buffer disconnects the session. |
| 51 | +- Persistent REPL input history (`.port-history` under the project root by default), capped at `port-repl-history-size` and walkable via `M-p` / `M-n`. |
| 52 | +- Interactive eval commands (last-sexp, defun-at-point, region, buffer), pretty-printed via `clojure.pprint` and capped by `port-print-length` / `port-print-level`. |
| 53 | +- Helper commands: doc, source, apropos, macroexpand-1, macroexpand, load-file, set-ns. |
| 54 | +- Async eldoc: arglists for the function whose call surrounds point. |
| 55 | +- `completion-at-point` for symbols visible in the buffer's namespace. |
| 56 | +- `port-find-definition` (bound to `M-.`) jumps to the source of the symbol at point, slurping jar contents into a read-only `*port-jar: ...*` buffer when needed. |
| 57 | +- Structured stacktrace buffer (`*port-stacktrace*`) on `:exception true` or `:tag :err`, with the cause chain, ex-data, and a filtered trace with file:line jumps. |
| 58 | +- `port-mode` minor mode for Clojure source buffers; no hard dependency on `clojure-mode`. |
0 commit comments