branch: elpa/cider
commit 1fa3f7c736ee0236b154c9897f37c226fae0e3ae
Author: Baptiste Strazzulla <baptiste.strazzu...@protonmail.com>
Commit: Bozhidar Batsov <bozhi...@batsov.dev>

    New value `per-project` for `cider-repl-history-file`
    
    To save the history on a per-project basis.
---
 CHANGELOG.md                                   |  4 ++
 cider-repl-history.el                          |  1 -
 cider-repl.el                                  | 55 +++++++++++++++++---------
 doc/modules/ROOT/pages/repl/configuration.adoc | 15 +++++--
 4 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6417918f10..4faa571e0d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 ## master (unreleased)
 
+### Changes
+
+- [#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.
diff --git a/cider-repl-history.el b/cider-repl-history.el
index ec19298ad2..e64c773af8 100644
--- a/cider-repl-history.el
+++ b/cider-repl-history.el
@@ -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
diff --git a/cider-repl.el b/cider-repl.el
index 9fd17c4f6d..7d967da294 100644
--- a/cider-repl.el
+++ b/cider-repl.el
@@ -194,9 +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.")
 
@@ -1468,6 +1465,9 @@ 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."
@@ -1593,9 +1593,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'."
@@ -1619,11 +1621,27 @@ 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 (clojure-project-dir)))
+      (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.
@@ -1658,6 +1676,13 @@ This function is meant to be used in hooks to avoid 
lambda
 constructs."
   (cider-repl-history-save cider-repl-history-file))
 
+(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)))))
+
 ;; 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
@@ -2051,13 +2076,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))
diff --git a/doc/modules/ROOT/pages/repl/configuration.adoc 
b/doc/modules/ROOT/pages/repl/configuration.adoc
index 774abc8891..39458d4749 100644
--- a/doc/modules/ROOT/pages/repl/configuration.adoc
+++ b/doc/modules/ROOT/pages/repl/configuration.adoc
@@ -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.

Reply via email to