Skip to content

Commit

Permalink
Merge branch 'clojure-emacs:master' into fix-remote-enrich-classpath-…
Browse files Browse the repository at this point in the history
…init
  • Loading branch information
caadr authored Jan 2, 2025
2 parents 9808235 + 356c2bd commit efe3b84
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 86 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

## master (unreleased)

### New features
- CIDER [History](https://docs.cider.mx/cider/repl/history.html): Add a command to delete history item at point.

### Changes

- Bump the injected nREPL version to [1.3.1](https://github.com/nrepl/nrepl/blob/master/CHANGELOG.md#131-2025-01-01).
- Bump the injected `cider-nrepl` to [0.51.0](https://github.com/clojure-emacs/cider-nrepl/blob/master/CHANGELOG.md#0510-2025-01-01).
- [#3574](https://github.com/clojure-emacs/cider/issues/3574): New value `per-project` for `cider-repl-history-file` to save the history on a per-project basis.

### Bugs fixed

- [#3763](https://github.com/clojure-emacs/cider/issues/3763): Fix `cider-docview-render` completion popup error when symbol being completed does not have a docstring.

## 1.16.1 (2024-12-03)

### Changes
Expand Down
9 changes: 5 additions & 4 deletions cider-doc.el
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,11 @@ in a COMPACT format is specified, FOR-TOOLTIP if specified."
"doc-first-sentence-fragments" (nrepl-dict-get info "doc-first-sentence-fragments"))))
(fetched-doc (nrepl-dict-get info "doc"))
(doc (or rendered-fragments
(if compact
(cider-docstring--trim
(cider-docstring--format fetched-doc))
fetched-doc)
(when fetched-doc
(if compact
(cider-docstring--trim
(cider-docstring--format fetched-doc))
fetched-doc))
(unless compact
"Not documented.")))
(url (nrepl-dict-get info "url"))
Expand Down
23 changes: 17 additions & 6 deletions cider-repl-history.el
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ call `cider-repl-history' again.")
(defvar cider-repl-history-previous-overlay nil
"Previous overlay within *cider-repl-history* buffer.")


(defun cider-repl-history-get-history ()
"Function to retrieve history from the REPL buffer."
(if cider-repl-history-repl-buffer
Expand Down Expand Up @@ -576,6 +575,16 @@ text from the *cider-repl-history* buffer."
(with-current-buffer cider-repl-history-repl-buffer
(undo)))

(defun cider-repl-history-delete-entry-at-point ()
"Delete history entry (at point)."
(interactive)
(let* ((orig (point))
(str (cider-repl-history-current-string orig)))
(with-current-buffer cider-repl-history-repl-buffer
(delete str cider-repl-input-history))
(cider-repl-history-update)
(goto-char orig)))

(defun cider-repl-history-setup (repl-win repl-buf history-buf &optional regexp)
"Setup.
REPL-WIN and REPL-BUF are where to insert commands;
Expand Down Expand Up @@ -637,16 +646,17 @@ HISTORY-BUF is the history, and optional arg REGEXP is a filter."
#'cider-repl-history-update-highlighted-entry
nil t))
(message
(let ((entry (if (= 1 (length cider-command-history))
"entry"
"entries")))
(let* ((history-length (length cider-command-history))
(entry (if (= 1 history-length)
"entry"
"entries")))
(concat
(if (and (not regexp)
cider-repl-history-display-duplicates)
(format "%s %s in the command history."
(length cider-command-history) entry)
history-length entry)
(format "%s (of %s) %s in the command history shown."
(length items) (length cider-command-history) entry))
(length items) history-length entry))
(substitute-command-keys
(concat " Type \\[cider-repl-history-quit] to quit. "
"\\[describe-mode] for help.")))))
Expand Down Expand Up @@ -693,6 +703,7 @@ HISTORY-BUF is the history, and optional arg REGEXP is a filter."
(define-key map (kbd "g") #'cider-repl-history-update)
(define-key map (kbd "q") #'cider-repl-history-quit)
(define-key map (kbd "U") #'cider-repl-history-undo-other-window)
(define-key map (kbd "D") #'cider-repl-history-delete-entry-at-point)
(define-key map (kbd "?") #'describe-mode)
(define-key map (kbd "h") #'describe-mode)
map))
Expand Down
81 changes: 45 additions & 36 deletions cider-repl.el
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,6 @@ CIDER 1.7."
This property value must be unique to avoid having adjacent inputs be
joined together.")

(defvar-local cider-repl-input-history '()
"History list of strings read from the REPL buffer.")

(defvar-local cider-repl-input-history-items-added 0
"Variable counting the items added in the current session.")

(defvar-local cider-repl-output-start nil
"Marker for the start of output.
Currently its only purpose is to facilitate `cider-repl-clear-buffer'.")
Expand Down Expand Up @@ -1468,13 +1462,15 @@ WIN, BUFFER and POS are the window, buffer and point under mouse position."
(defvar cider-repl-history-pattern nil
"The regexp most recently used for finding input history.")

(defvar cider-repl-input-history '()
"History list of strings read from the REPL buffer.")

(defun cider-repl--add-to-input-history (string)
"Add STRING to the input history.
Empty strings and duplicates are ignored."
(unless (or (equal string "")
(equal string (car cider-repl-input-history)))
(push string cider-repl-input-history)
(cl-incf cider-repl-input-history-items-added)))
(push string cider-repl-input-history)))

(defun cider-repl-delete-current-input ()
"Delete all text after the prompt."
Expand Down Expand Up @@ -1593,9 +1589,11 @@ If USE-CURRENT-INPUT is non-nil, use the current input."
:safe #'integerp)

(defcustom cider-repl-history-file nil
"File to save the persistent REPL history to."
:type 'string
:safe #'stringp)
"File to save the persistent REPL history to.
If this is set to a path the history will be global to all projects. If this is
set to `per-project', the history will be stored in a file (.cider-history) at
the root of each project."
:type '(choice string symbol))

(defun cider-repl--history-read-filename ()
"Ask the user which file to use, defaulting `cider-repl-history-file'."
Expand All @@ -1612,28 +1610,48 @@ It does not yet set the input history."
(read (current-buffer))))
'()))

(defun cider-repl--find-dir-for-history ()
"Find the first suitable directory to store the project's history."
(seq-find
(lambda (dir) (and (not (null dir)) (not (tramp-tramp-file-p dir))))
(list nrepl-project-dir (clojure-project-dir) default-directory)))

(defun cider-repl-history-load (&optional filename)
"Load history from FILENAME into current session.
FILENAME defaults to the value of `cider-repl-history-file' but user
defined filenames can be used to read special history files.

The value of `cider-repl-input-history' is set by this function."
(interactive (list (cider-repl--history-read-filename)))
(let ((f (or filename cider-repl-history-file)))
;; TODO: probably need to set cider-repl-input-history-position as well.
;; in a fresh connection the newest item in the list is currently
;; not available. After sending one input, everything seems to work.
(setq cider-repl-input-history (cider-repl--history-read f))))
(cond
(filename (setq cider-repl-history-file filename))
((equal 'per-project cider-repl-history-file)
(make-local-variable 'cider-repl-input-history)
(when-let ((dir (cider-repl--find-dir-for-history)))
(setq-local
cider-repl-history-file (expand-file-name ".cider-history" dir)))))
(when cider-repl-history-file
(condition-case nil
;; TODO: probably need to set cider-repl-input-history-position as
;; well. In a fresh connection the newest item in the list is
;; currently not available. After sending one input, everything
;; seems to work.
(setq
cider-repl-input-history
(cider-repl--history-read cider-repl-history-file))
(error
(message
"Malformed cider-repl-history-file: %s" cider-repl-history-file)))
(add-hook 'kill-buffer-hook #'cider-repl-history-just-save t t)
(add-hook 'kill-emacs-hook #'cider-repl-history-save-all)))

(defun cider-repl--history-write (filename)
"Write history to FILENAME.
Currently coding system for writing the contents is hardwired to
utf-8-unix."
(let* ((mhist (cider-repl--histories-merge cider-repl-input-history
cider-repl-input-history-items-added
(cider-repl--history-read filename)))
(let* ((end (min (length cider-repl-input-history) cider-repl-history-size))
;; newest items are at the beginning of the list, thus 0
(hist (cl-subseq mhist 0 (min (length mhist) cider-repl-history-size))))
(hist (cl-subseq cider-repl-input-history 0 end)))
(unless (file-writable-p filename)
(error (format "History file not writable: %s" filename)))
(let ((print-length nil) (print-level nil))
Expand All @@ -1658,15 +1676,12 @@ This function is meant to be used in hooks to avoid lambda
constructs."
(cider-repl-history-save cider-repl-history-file))

;; SLIME has different semantics and will not save any duplicates.
;; we keep track of how many items were added to the history in the
;; current session in `cider-repl--add-to-input-history' and merge only the
;; new items with the current history found in the file, which may
;; have been changed in the meantime by another session.
(defun cider-repl--histories-merge (session-hist n-added-items file-hist)
"Merge histories from SESSION-HIST adding N-ADDED-ITEMS into FILE-HIST."
(append (cl-subseq session-hist 0 n-added-items)
file-hist))
(defun cider-repl-history-save-all ()
"Save all histories."
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when (equal major-mode 'cider-repl-mode)
(cider-repl-history-just-save)))))


;;; REPL shortcuts
Expand Down Expand Up @@ -2051,13 +2066,7 @@ in an unexpected place."
(setq-local prettify-symbols-alist clojure--prettify-symbols-alist)
;; apply dir-local variables to REPL buffers
(hack-dir-local-variables-non-file-buffer)
(when cider-repl-history-file
(condition-case nil
(cider-repl-history-load cider-repl-history-file)
(error
(message "Malformed cider-repl-history-file: %s" cider-repl-history-file)))
(add-hook 'kill-buffer-hook #'cider-repl-history-just-save t t)
(add-hook 'kill-emacs-hook #'cider-repl-history-just-save))
(cider-repl-history-load)
(add-hook 'completion-at-point-functions #'cider-complete-at-point nil t)
(add-hook 'paredit-mode-hook (lambda () (clojure-paredit-setup cider-repl-mode-map)))
(cider-repl-setup-paredit))
Expand Down
4 changes: 2 additions & 2 deletions cider.el
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ Throws an error if PROJECT-TYPE is unknown."
"List of dependencies where elements are lists of artifact name and version.")
(put 'cider-jack-in-dependencies 'risky-local-variable t)

(defcustom cider-injected-nrepl-version "1.3.0"
(defcustom cider-injected-nrepl-version "1.3.1"
"The version of nREPL injected on jack-in.
We inject the newest known version of nREPL just in case
your version of Boot or Leiningen is bundling an older one."
Expand Down Expand Up @@ -591,7 +591,7 @@ the artifact.")

Used when `cider-jack-in-auto-inject-clojure' is set to `latest'.")

(defconst cider-required-middleware-version "0.50.3"
(defconst cider-required-middleware-version "0.51.0"
"The CIDER nREPL version that's known to work properly with CIDER.")

(defcustom cider-injected-middleware-version cider-required-middleware-version
Expand Down
2 changes: 1 addition & 1 deletion dev/docker-sample-project/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
:dependencies [[org.clojure/clojure "1.11.1"]
[clj-http "3.12.3"]]
:source-paths ["src"]
:plugins [[cider/cider-nrepl "0.50.3"]])
:plugins [[cider/cider-nrepl "0.51.0"]])
2 changes: 1 addition & 1 deletion dev/tramp-sample-project/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
:dependencies [[org.clojure/clojure "1.11.1"]
[clj-http "3.12.3"]]
:source-paths ["src"]
:plugins [[cider/cider-nrepl "0.50.3"]
:plugins [[cider/cider-nrepl "0.51.0"]
[refactor-nrepl "3.9.0"]])
12 changes: 6 additions & 6 deletions doc/modules/ROOT/pages/basics/middleware_setup.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ Use the convenient plugin for defaults, either in your project's

[source,clojure]
----
:plugins [[cider/cider-nrepl "0.50.3"]]
:plugins [[cider/cider-nrepl "0.51.0"]]
----

A minimal `profiles.clj` for CIDER would be:

[source,clojure]
----
{:repl {:plugins [[cider/cider-nrepl "0.50.3"]]}}
{:repl {:plugins [[cider/cider-nrepl "0.51.0"]]}}
----

WARNING: Be careful not to place this in the `:user` profile, as this way CIDER's
Expand All @@ -59,7 +59,7 @@ all of their projects using a `~/.boot/profile.boot` file like so:
(require 'boot.repl)

(swap! boot.repl/*default-dependencies*
concat '[[cider/cider-nrepl "0.50.3"]])
concat '[[cider/cider-nrepl "0.51.0"]])

(swap! boot.repl/*default-middleware*
conj 'cider.nrepl/cider-middleware)
Expand All @@ -76,11 +76,11 @@ run `cider-connect` or `cider-connect-cljs`.

[source,clojure]
----
:cider-clj {:extra-deps {cider/cider-nrepl {:mvn/version "0.50.3"}}
:cider-clj {:extra-deps {cider/cider-nrepl {:mvn/version "0.51.0"}}
:main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]}

:cider-cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.10.339"}
cider/cider-nrepl {:mvn/version "0.50.3"}
cider/cider-nrepl {:mvn/version "0.51.0"}
cider/piggieback {:mvn/version "0.5.3"}}
:main-opts ["-m" "nrepl.cmdline" "--middleware"
"[cider.nrepl/cider-middleware,cider.piggieback/wrap-cljs-repl]"]}
Expand All @@ -99,7 +99,7 @@ NOTE: Make sure you're using https://github.com/clojurephant/clojurephant[Clojur
----
dependencies {
devImplementation 'nrepl:nrepl:0.9.0'
devImplementation 'cider:cider-nrepl:0.50.3'
devImplementation 'cider:cider-nrepl:0.51.0'
}

tasks.named('clojureRepl') {
Expand Down
4 changes: 2 additions & 2 deletions doc/modules/ROOT/pages/basics/up_and_running.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ simple - CIDER simply passes the extra dependencies and nREPL configuration to
your build tool in the command it runs to start the nREPL server. Here's how
this looks for `tools.deps`:

$ clojure -Sdeps '{:deps {nrepl {:mvn/version "1.3.0"} cider/cider-nrepl {:mvn/version "0.50.3"}}}' -m nrepl.cmdline --middleware '["cider.nrepl/cider-middleware"]'
$ clojure -Sdeps '{:deps {nrepl {:mvn/version "1.3.1"} cider/cider-nrepl {:mvn/version "0.51.0"}}}' -m nrepl.cmdline --middleware '["cider.nrepl/cider-middleware"]'

TIP: If you don't want `cider-jack-in` to inject dependencies automatically, set
`cider-inject-dependencies-at-jack-in` to `nil`. Note that you'll have to setup
Expand Down Expand Up @@ -350,7 +350,7 @@ It is also possible for plain `clj`, although the command is somewhat longer:

[source,sh]
----
$ clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.50.3"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]"
$ clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.51.0"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]"
----

Alternatively, you can start nREPL either manually or using the facilities
Expand Down
2 changes: 1 addition & 1 deletion doc/modules/ROOT/pages/cljs/shadow-cljs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ And connect to it with `cider-connect`.
...For that to work, `shadow-cljs.edn` contents like the following are assumed:

```clj
:dependencies [[cider/cider-nrepl "0.50.3"] ;; mandatory (unless it's inherited from deps.edn or otherwise present in the classpath of shadow-cljs's JVM process)
:dependencies [[cider/cider-nrepl "0.51.0"] ;; mandatory (unless it's inherited from deps.edn or otherwise present in the classpath of shadow-cljs's JVM process)
[refactor-nrepl/refactor-nrepl "3.9.0"]] ;; refactor-nrepl is optional

:nrepl {:middleware [cider.nrepl/cider-middleware ;; it's advisable to explicitly add this middleware. It's automatically added by shadow-cljs (if available in the classpath), unless `:nrepl {:cider false}`
Expand Down
4 changes: 2 additions & 2 deletions doc/modules/ROOT/pages/cljs/up_and_running.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ or in `build.gradle`:
[source, groovy]
----
dependencies {
devImplementation 'nrepl:nrepl:1.3.0'
devImplementation 'cider:cider-nrepl:0.50.3'
devImplementation 'nrepl:nrepl:1.3.1'
devImplementation 'cider:cider-nrepl:0.51.0'
devImplementation 'cider:cider-piggieback:0.5.3'
}

Expand Down
15 changes: 12 additions & 3 deletions doc/modules/ROOT/pages/repl/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,21 @@ reset automatically by the `track-state` middleware.
(setq cider-repl-history-size 1000) ; the default is 500
----

* To store the REPL history in a file:
* To store the REPL history of all projects in a single file:

[source,lisp]
----
(setq cider-repl-history-file "path/to/file")
----

Note that CIDER writes the history to the file when you kill the REPL
buffer, which includes invoking `cider-quit`, or when you quit Emacs.
* To store the REPL history per project (by creating a
`.cider-history` file at the root of each):

[source,lisp]
----
(setq cider-repl-history-file 'per-project)
----

Note that CIDER writes the history to the file(s) when you kill the
REPL buffer, which includes invoking `cider-quit`, or when you quit
Emacs.
3 changes: 3 additions & 0 deletions doc/modules/ROOT/pages/repl/history.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,7 @@ There are a number of important keybindings in history buffers.

| kbd:[U]
| Undo in the REPL buffer.

| kbd:[D]
| Delete history item (at point).
|===
Loading

0 comments on commit efe3b84

Please sign in to comment.