diff --git a/CHANGELOG.md b/CHANGELOG.md index f9c612954..dee8f7d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ ### Changes +- Bump the default `cider-repl-history-size` from 500 to 5000. - Rename the REPL history browser from `cider-repl-history` to `cider-history` (command, mode and options), so its names no longer clash with the REPL's unrelated input-history settings (`cider-repl-history-file`, `cider-repl-history-size`); the old names keep working as obsolete aliases. - Color the nREPL messages buffer with theme-aware faces (`nrepl-message-faces`, eight faces inheriting from standard font-lock faces) instead of a hardcoded color list; `nrepl-message-colors` is now obsolete, but still takes precedence when customized. - Consolidate the per-buffer auto-select options into a single `cider-auto-select-buffer`, which can be `t`, `nil` or a list of the popup buffers to select (e.g. `'(error inspector)`); the old options (`cider-auto-select-error-buffer`, `cider-auto-select-test-report-buffer`, `cider-doc-auto-select-buffer`, `cider-inspector-auto-select-buffer`, `cider-cheatsheet-auto-select-buffer` and `cider-log-auto-select-frameworks-buffer`) are now obsolete, but still take precedence when customized. diff --git a/Eldev b/Eldev index 1655f8f04..fff7367ae 100644 --- a/Eldev +++ b/Eldev @@ -22,6 +22,10 @@ ;; allow commas to indicate that the first sentence continues, which enables longer first sentences (setq checkdoc-permit-comma-termination-flag t) +;; the experimental third-person-verb check misfires on nouns like "tests" +;; and "highlights", which a Clojure IDE can hardly avoid in docstrings +(setq checkdoc-verb-check-experimental-flag nil) + (defvar cider-test-type 'main) (setf eldev-standard-excludes `(:or ,eldev-standard-excludes ;; Exclude flycheck temporary files diff --git a/doc/modules/ROOT/pages/debugging/macroexpansion.adoc b/doc/modules/ROOT/pages/debugging/macroexpansion.adoc index 0e6acafae..c38f12641 100644 --- a/doc/modules/ROOT/pages/debugging/macroexpansion.adoc +++ b/doc/modules/ROOT/pages/debugging/macroexpansion.adoc @@ -220,5 +220,5 @@ in one step. further-expandable sub-forms (on by default). * `cider-macrostep-color-gensyms` - colorize the gensyms introduced by an expansion (on by default). -* `cider-macrostep-gensym-colors` - the palette cycled through when coloring - gensyms. +* `cider-macrostep-gensym-faces` - the face palette cycled through when + coloring gensyms (theme-aware, inheriting from font-lock faces). diff --git a/lisp/cider-client.el b/lisp/cider-client.el index 56a7947a8..0a4ecb49f 100644 --- a/lisp/cider-client.el +++ b/lisp/cider-client.el @@ -490,9 +490,8 @@ Set to nil for no limit." (defcustom cider-print-buffer-size (* 4 1024) "The size in bytes of each value/output chunk when using print streaming. -Smaller values mean smaller data chunks and faster feedback, but they also mean -smaller results that can be font-locked as Clojure in the REPL buffers, as only -a single chunk result can be font-locked. +Smaller values mean faster first feedback, but also more messages for large +results, with the associated decoding overhead. The default value in nREPL is 1024." :type 'integer diff --git a/lisp/cider-eval.el b/lisp/cider-eval.el index 9767c267f..7a723d365 100644 --- a/lisp/cider-eval.el +++ b/lisp/cider-eval.el @@ -226,8 +226,9 @@ additionally: `cider-default-err-handler' with BUFFER. BUFFER is the editor buffer the response is associated with (typically -the one that issued the eval). All other slots have the same semantics -as in `nrepl-make-eval-handler'." +the one that issued the eval). The other slots (ON-VALUE, ON-STDOUT, +ON-STDERR, ON-DONE, ON-EVAL-ERROR, ON-CONTENT-TYPE and ON-TRUNCATED) +have the same semantics as in `nrepl-make-eval-handler'." (nrepl-make-eval-handler :on-value on-value :on-stdout on-stdout @@ -329,8 +330,8 @@ REPL buffer. This is controlled via "Mark BUFFER's content as loaded into the REPL and in sync. Refreshes the evaluation fringe indicators across BUFFER and runs `cider-file-loaded-hook' (which the namespace load-state indicator hooks -into). BUFFER defaults to the current buffer. Used by the load-file flow -and by the namespace reloading commands once they finish." +into). BUFFER defaults to the current buffer. Used by the file-loading +flow and by the namespace reloading commands once they finish." (with-current-buffer (or buffer (current-buffer)) (cider--make-fringe-overlays-for-region (point-min) (point-max)) (run-hooks 'cider-file-loaded-hook))) diff --git a/lisp/cider-jack-in.el b/lisp/cider-jack-in.el index ab0ce8827..38bdecca2 100644 --- a/lisp/cider-jack-in.el +++ b/lisp/cider-jack-in.el @@ -744,7 +744,7 @@ with its nREPL middleware and dependencies." ;;; Command resolution (defun cider--resolve-command (command) - "Find COMMAND in `exec-path', or on the remote host's PATH over TRAMP. + "Find COMMAND in the variable `exec-path', or on a remote PATH over TRAMP. Return the (shell-quoted) absolute path if found, otherwise nil. When `default-directory' is remote, `executable-find' is asked to search on that host instead of the local one." diff --git a/lisp/cider-macrostep.el b/lisp/cider-macrostep.el index 60b55140a..e1a7721aa 100644 --- a/lisp/cider-macrostep.el +++ b/lisp/cider-macrostep.el @@ -58,18 +58,58 @@ silently skipped." (defcustom cider-macrostep-color-gensyms t "Whether to colorize the gensyms introduced by a macro expansion. When non-nil, each distinct gensym (e.g. `x__42__auto__') in an inline -expansion gets its own color from `cider-macrostep-gensym-colors', so a +expansion gets its own face from `cider-macrostep-gensym-faces', so a binding introduced by the macro can be tracked through the expansion." :type 'boolean :group 'cider :package-version '(cider . "2.0.0")) -(defcustom cider-macrostep-gensym-colors - '("#d33682" "#268bd2" "#859900" "#b58900" "#6c71c4" "#2aa198" "#cb4b16") - "Colors cycled through when coloring gensyms. -Each distinct gensym in an expansion is assigned the next color in this -list, wrapping around when an expansion has more gensyms than colors." - :type '(repeat color) +(defface cider-macrostep-gensym-1-face '((t :inherit font-lock-keyword-face)) + "Face 1 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defface cider-macrostep-gensym-2-face '((t :inherit font-lock-string-face)) + "Face 2 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defface cider-macrostep-gensym-3-face '((t :inherit font-lock-function-name-face)) + "Face 3 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defface cider-macrostep-gensym-4-face '((t :inherit font-lock-variable-name-face)) + "Face 4 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defface cider-macrostep-gensym-5-face '((t :inherit font-lock-type-face)) + "Face 5 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defface cider-macrostep-gensym-6-face '((t :inherit font-lock-constant-face)) + "Face 6 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defface cider-macrostep-gensym-7-face '((t :inherit font-lock-builtin-face)) + "Face 7 of the palette cycled through when coloring gensyms." + :group 'cider + :package-version '(cider . "2.0.0")) + +(defcustom cider-macrostep-gensym-faces + '(cider-macrostep-gensym-1-face cider-macrostep-gensym-2-face + cider-macrostep-gensym-3-face cider-macrostep-gensym-4-face + cider-macrostep-gensym-5-face cider-macrostep-gensym-6-face + cider-macrostep-gensym-7-face) + "Faces cycled through when coloring gensyms. +Each distinct gensym in an expansion is assigned the next face in this +list, wrapping around when an expansion has more gensyms than faces. +The defaults inherit from standard font-lock faces, so they follow your +theme." + :type '(repeat face) :group 'cider :package-version '(cider . "2.0.0")) @@ -288,11 +328,11 @@ symbols and are left uncolored.") (defun cider-macrostep--refresh-gensyms () "Color each distinct gensym in the active expansions. -All occurrences of a gensym share one color; different gensyms get different -colors from `cider-macrostep-gensym-colors'. A no-op when disabled." +All occurrences of a gensym share one face; different gensyms get different +faces from `cider-macrostep-gensym-faces'. A no-op when disabled." (cider-macrostep--clear-gensym-overlays) - (when (and cider-macrostep-color-gensyms cider-macrostep-gensym-colors) - (let ((colors (vconcat cider-macrostep-gensym-colors)) + (when (and cider-macrostep-color-gensyms cider-macrostep-gensym-faces) + (let ((faces (vconcat cider-macrostep-gensym-faces)) (assigned (make-hash-table :test 'equal)) (next 0) ;; Nested expansions overlap (the outer overlay still spans the inner @@ -302,13 +342,13 @@ colors from `cider-macrostep-gensym-colors'. A no-op when disabled." cider-macrostep--overlays)))) (dolist (match matches) (pcase-let ((`(,name ,beg ,end) match)) - (let ((color (or (gethash name assigned) - (let ((c (aref colors (mod next (length colors))))) - (puthash name c assigned) - (setq next (1+ next)) - c))) + (let ((face (or (gethash name assigned) + (let ((f (aref faces (mod next (length faces))))) + (puthash name f assigned) + (setq next (1+ next)) + f))) (gov (make-overlay beg end))) - (overlay-put gov 'face (list :foreground color)) + (overlay-put gov 'face face) (overlay-put gov 'priority 90) (push gov cider-macrostep--gensym-overlays))))))) diff --git a/lisp/cider-ns.el b/lisp/cider-ns.el index f9f84b339..bb2d77bdd 100644 --- a/lisp/cider-ns.el +++ b/lisp/cider-ns.el @@ -383,7 +383,11 @@ inhibit-fns)), which is how `cider-ns-menu' passes its arguments." nil t)) (when clear? - (cider-nrepl-sync-request `("op" ,(cider-ns--reload-op "reload-clear")) :connection conn)) + ;; The clear op is fast by itself, but it serializes behind any + ;; refresh already in flight, which on large projects can hold + ;; the lock well past the default timeout (#3652). + (let ((nrepl-sync-request-timeout 60)) + (cider-nrepl-sync-request `("op" ,(cider-ns--reload-op "reload-clear")) :connection conn))) (let ((reloading (list nil))) (cider-nrepl-send-request `("op" ,(cider-ns--reload-op (if all? "reload-all" "reload")) diff --git a/lisp/cider-overlays.el b/lisp/cider-overlays.el index 26d6a7e73..150094fe9 100644 --- a/lisp/cider-overlays.el +++ b/lisp/cider-overlays.el @@ -328,6 +328,12 @@ overlay." ;; Maximum value width at which we truncate it. (truncation-threshold (* 3 (window-width))) (o nil)) + ;; Huge results get truncated to the threshold below anyway; cut + ;; them down early so the face and width bookkeeping doesn't have + ;; to walk the full text. + (when (> (length display-string) (* 2 truncation-threshold)) + (setq display-string + (substring display-string 0 (* 2 truncation-threshold)))) ;; Remove any overlay at the position we're creating a new one, if it ;; exists. (remove-overlays beg end 'category type) diff --git a/lisp/cider-repl.el b/lisp/cider-repl.el index 9dc4e6e7e..f9cdb522c 100644 --- a/lisp/cider-repl.el +++ b/lisp/cider-repl.el @@ -424,7 +424,7 @@ The full getting-started help now lives in `cider-repl-help'." \\{cider-repl-help-mode-map}") (defun cider-repl--help-key (command keymap) - "Return a display key for COMMAND in KEYMAP, or an \"M-x\" form if unbound. + "Return a display key for COMMAND in KEYMAP, or an extended-command form. KEYMAP is a symbol whose value is a keymap. Only that keymap is searched (not its parents), since the refcard sections list commands bound directly in it." (if-let* ((km (and (boundp keymap) (symbol-value keymap))) @@ -1775,7 +1775,7 @@ If USE-CURRENT-INPUT is non-nil, use the current input." (t nil))) ;;; persistent history -(defcustom cider-repl-history-size 500 +(defcustom cider-repl-history-size 5000 "The maximum number of items to keep in the REPL history." :type 'integer :safe #'integerp) diff --git a/lisp/cider-scratch.el b/lisp/cider-scratch.el index df26a4b8e..4cfcc961f 100644 --- a/lisp/cider-scratch.el +++ b/lisp/cider-scratch.el @@ -104,8 +104,9 @@ Per-session scratch buffers are named `*cider-scratch: SESSION*'.") "Go to the scratch buffer attached to the current session. Each session gets its own scratch buffer, permanently attached to it, so evaluations always target a known session. When the current context has -no clear session (or with a prefix ARG to force it), prompt for one. With -no connections at all, fall back to a single session-less scratch buffer." +no clear session (or when ASK is non-nil - interactively, a prefix +argument), prompt for one. With no connections at all, fall back to a +single session-less scratch buffer." (interactive "P") (let ((repl (or (and (not ask) (cider-current-repl)) (cider-scratch--ask-for-repl)))) diff --git a/lisp/nrepl-client.el b/lisp/nrepl-client.el index f22b7562c..e1bbb24bd 100644 --- a/lisp/nrepl-client.el +++ b/lisp/nrepl-client.el @@ -787,7 +787,8 @@ sub-handlers has been provided. All UI concerns (namespace tracking, default error handling, need-input prompting, status messages) live in higher layers -- see `cider-make-eval-handler' for the editor wrapper. -Sub-handlers, all optional: +Sub-handlers (ON-VALUE, ON-STDOUT, ON-STDERR, ON-DONE, ON-NS, ON-STATUS, +ON-EVAL-ERROR, ON-CONTENT-TYPE and ON-TRUNCATED), all optional: :on-value called with VALUE when the response carries one. :on-stdout called with the OUT string for stdout chunks. @@ -854,7 +855,7 @@ level `cider-make-eval-handler' which layers UI concerns on top. The shim adapts the (BUFFER VALUE)-style sub-handlers expected here to the simpler (VALUE)-style sub-handlers of `nrepl-make-eval-handler', and additionally wires up the global handler hooks -(`nrepl-namespace-handler-function', `nrepl-err-handler-function', +\\(`nrepl-namespace-handler-function', `nrepl-err-handler-function', `nrepl-need-input-handler-function') and the legacy status messages that used to live inside `nrepl-make-eval-handler' itself. Anything that was visible behavior of the original 7-positional-arg API stays diff --git a/refcard/cider-refcard.pdf b/refcard/cider-refcard.pdf index 37d15f273..cc62da5ff 100644 Binary files a/refcard/cider-refcard.pdf and b/refcard/cider-refcard.pdf differ diff --git a/refcard/cider-refcard.tex b/refcard/cider-refcard.tex index 17277685c..1e00c1e1e 100644 --- a/refcard/cider-refcard.tex +++ b/refcard/cider-refcard.tex @@ -86,11 +86,14 @@ \subsection{Navigation} \item[C-c M-.] cider-find-resource \item[C-c C-? r] \ns{cider-xref-fn}-refs \item[C-c C-? d] \ns -deps + \item[C-c C-? s] \ns -refs-in-source + \item[C-c C-w c] cider-who-calls + \item[C-c C-w i] cider-who-implements \item[C-c M-s] cider-selector \end{keylist} \subsection{Evaluation} -\begin{keylist}[labelwidth=\widthof{\keyify{C-c C-M-l}}] +\begin{keylist}[labelwidth=\widthof{\keyify{C-c M-m a}}] \item[C-x C-e] \ns{cider-eval-last-sexp} \item[C-c M-e] \ns -to-repl \item[C-M-x] cider-eval-defun-at-point @@ -100,8 +103,9 @@ \subsection{Evaluation} \item[C-c M-;] cider-eval-defun-to-comment \item[C-c M-:] cider-read-and-eval \item[C-c M-i] cider-inspect - \item[C-c RET] \ns{cider-macroexpand}-1 - \item[C-c M-m] \ns -all + \item[C-c C-m] \ns{cider-macroexpand}-1 + \item[C-c M-m a] \ns -all + \item[C-c M-m e] cider-macrostep-expand \end{keylist} \columnbreak @@ -118,6 +122,7 @@ \section{Namespace} \item[C-c M-n n] cider-repl-set-ns \item[C-c M-n e] cider-eval-ns-form \item[C-c M-n r] cider-ns-refresh + \item[C-c M-n l] cider-ns-reload \item[C-c M-n b] cider-browse-ns \end{keylist} diff --git a/test/cider-macrostep-tests.el b/test/cider-macrostep-tests.el index b53630bb9..516841cc6 100644 --- a/test/cider-macrostep-tests.el +++ b/test/cider-macrostep-tests.el @@ -187,24 +187,24 @@ (push (match-string-no-properties 0) matches)) (expect (nreverse matches) :to-equal '("x__1__auto__" "G__42"))))) - (it "gives each distinct gensym its own color, shared across occurrences" + (it "gives each distinct gensym its own face, shared across occurrences" (with-temp-buffer (clojure-mode) (insert "(let* [x__1__auto__ 1 y__2__auto__ 2] (list x__1__auto__ y__2__auto__))") (setq cider-macrostep--overlays (list (make-overlay (point-min) (point-max)))) - (let ((cider-macrostep-gensym-colors '("red" "blue"))) + (let ((cider-macrostep-gensym-faces '(bold italic))) (cider-macrostep--refresh-gensyms)) ;; four occurrences -> four overlays (expect (length cider-macrostep--gensym-overlays) :to-equal 4) - ;; same gensym -> same color, distinct gensyms -> distinct colors - (let ((color-of (lambda (name) - (seq-some (lambda (o) - (when (string= name (buffer-substring-no-properties - (overlay-start o) (overlay-end o))) - (overlay-get o 'face))) - cider-macrostep--gensym-overlays)))) - (expect (funcall color-of "x__1__auto__") :to-equal '(:foreground "red")) - (expect (funcall color-of "y__2__auto__") :to-equal '(:foreground "blue"))))) + ;; same gensym -> same face, distinct gensyms -> distinct faces + (let ((face-of (lambda (name) + (seq-some (lambda (o) + (when (string= name (buffer-substring-no-properties + (overlay-start o) (overlay-end o))) + (overlay-get o 'face))) + cider-macrostep--gensym-overlays)))) + (expect (funcall face-of "x__1__auto__") :to-equal 'bold) + (expect (funcall face-of "y__2__auto__") :to-equal 'italic)))) (it "does not double-color gensyms in nested (overlapping) expansions" (with-temp-buffer