From 22ffacd4178e4aa50d1293097eb24842b23a1103 Mon Sep 17 00:00:00 2001 From: dan sutton Date: Sat, 20 Mar 2021 02:12:52 -0500 Subject: [PATCH 1/4] Function to select repls as the current active connection very simple: if in a repl, use that. if not in a repl, display a list of inf-clojure process buffers. If given a prefix, always show a list. Makes running simultaneous repls far easier --- CHANGELOG.md | 4 ++++ README.md | 11 +++++++++++ inf-clojure.el | 23 +++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aaafd4..56dc45a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### New features + +* [#190](https://github.com/clojure-emacs/inf-clojure/pull/190): Helper function `inf-clojure-set-repl` to select inf-clojure process buffer. + ### Bugs fixed * [#152](https://github.com/clojure-emacs/inf-clojure/issues/152): Sanitize should only remove whitespace at the end of a command. diff --git a/README.md b/README.md index d9c38aa..6bf9fca 100644 --- a/README.md +++ b/README.md @@ -316,6 +316,17 @@ one process, this does the right thing. If you run multiple processes, you might need to change `inf-clojure-buffer` to whichever process buffer you want to use. +You can use the helpful function `inf-clojure-set-repl`. If called in +an inf-clojure repl buffer, it will assign that buffer as the current +connection (`(setq inf-clojure-buffer (current-buffer)`). If you are +not in an inf-clojure repl buffer, it will offer a choice of +acceptable buffers to set as the repl buffer. If called with a prefix, +it will always give the list even if you are currently in an +acceptable repl buffer. Renaming buffers will greatly improve the +functionality of this list; the list "project-1: clojure repl", +"project-2: cljs repl" is far more understandable than "inf-clojure", +"inf-clojure<2>". + #### REPL Type An `inf-clojure` REPL has an associated type. The available types can be diff --git a/inf-clojure.el b/inf-clojure.el index 3832799..25457b5 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -199,6 +199,29 @@ has been found. See also variable `inf-clojure-buffer'." (unless no-error (error "No Clojure subprocess; see variable `inf-clojure-buffer'")))) +(defun inf-clojure-set-repl (always-ask) + "Set an inf clojure buffer as the active repl. +If in a repl already, use that unless a prefix is used (or +ALWAYS-ASK). Otherwise get a list of all active inf-clojure +repls and offer a choice. Recommended to rename buffers as they +are created with `rename-buffer`." + (interactive "P") + (cl-flet ((inf-clojure-repl-p () (and (derived-mode-p 'inf-clojure-mode) + (get-buffer-process (current-buffer)) + (process-live-p (get-buffer-process (current-buffer)))))) + (if (and (not always-ask) + (inf-clojure-repl-p)) + (setq inf-clojure-buffer (current-buffer)) + (let (repl-buffers) + (dolist (b (buffer-list)) + (with-current-buffer b + (when (inf-clojure-repl-p) + (push (buffer-name b) repl-buffers)))) + (if (> (length repl-buffers) 0) + (when-let ((repl-buffer (completing-read "Use for repl: " repl-buffers nil t))) + (setq inf-clojure-buffer (get-buffer repl-buffer))) + (user-error "No buffers have an inf-clojure process")))))) + (defvar-local inf-clojure-repl-type nil "Symbol to define your REPL type. Its root binding is nil and it can be further customized using From 64292c436429b22d17980f9b76f6d2895ea4ab3a Mon Sep 17 00:00:00 2001 From: dan sutton Date: Sat, 20 Mar 2021 09:46:11 -0500 Subject: [PATCH 2/4] Extract useful functions --- inf-clojure.el | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 25457b5..1ec3db8 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -199,6 +199,22 @@ has been found. See also variable `inf-clojure-buffer'." (unless no-error (error "No Clojure subprocess; see variable `inf-clojure-buffer'")))) +(defun inf-clojure-repl-p () + "Indicates if current buffer is an inf-clojure repl. +Checks the mode and that there is a live process." + (and (derived-mode-p 'inf-clojure-mode) + (get-buffer-process (current-buffer)) + (process-live-p (get-buffer-process (current-buffer))))) + +(defun inf-clojure-repls-list () + "Return a list of all known inf-clojure repls." + (let (repl-buffers) + (dolist (b (buffer-list)) + (with-current-buffer b + (when (inf-clojure-repl-p) + (push (buffer-name b) repl-buffers)))) + repl-buffers)) + (defun inf-clojure-set-repl (always-ask) "Set an inf clojure buffer as the active repl. If in a repl already, use that unless a prefix is used (or @@ -206,21 +222,14 @@ ALWAYS-ASK). Otherwise get a list of all active inf-clojure repls and offer a choice. Recommended to rename buffers as they are created with `rename-buffer`." (interactive "P") - (cl-flet ((inf-clojure-repl-p () (and (derived-mode-p 'inf-clojure-mode) - (get-buffer-process (current-buffer)) - (process-live-p (get-buffer-process (current-buffer)))))) - (if (and (not always-ask) - (inf-clojure-repl-p)) - (setq inf-clojure-buffer (current-buffer)) - (let (repl-buffers) - (dolist (b (buffer-list)) - (with-current-buffer b - (when (inf-clojure-repl-p) - (push (buffer-name b) repl-buffers)))) - (if (> (length repl-buffers) 0) - (when-let ((repl-buffer (completing-read "Use for repl: " repl-buffers nil t))) - (setq inf-clojure-buffer (get-buffer repl-buffer))) - (user-error "No buffers have an inf-clojure process")))))) + (if (and (not always-ask) + (inf-clojure-repl-p)) + (setq inf-clojure-buffer (current-buffer)) + (let ((repl-buffers (inf-clojure-repls-list))) + (if (> (length repl-buffers) 0) + (when-let ((repl-buffer (completing-read "Use for repl: " repl-buffers nil t))) + (setq inf-clojure-buffer (get-buffer repl-buffer))) + (user-error "No buffers have an inf-clojure process"))))) (defvar-local inf-clojure-repl-type nil "Symbol to define your REPL type. From 99279f6ee024733520956aeba0a0c189e82c735f Mon Sep 17 00:00:00 2001 From: dan sutton Date: Sat, 20 Mar 2021 14:02:08 -0500 Subject: [PATCH 3/4] Modeline with connected info note this changes the `inf-clojure-buffer` to always be a _buffer_ and not the name of a buffer. Seems like renaming can be quite risky since it was just a name of the buffer rather than the buffer. --- inf-clojure.el | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 1ec3db8..ac7951e 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -274,6 +274,14 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword \(as in :a, :c, etc.)" :type 'regexp) +(defun inf-clojure--modeline-info () + "Return modeline info. +Either \"not connected\" or \"repl-type: buffer-name\"" + (if (bufferp inf-clojure-buffer) + (with-current-buffer inf-clojure-buffer + (format "%s: %s" inf-clojure-repl-type (buffer-name (current-buffer)))) + "not connected")) + (defvar inf-clojure-mode-map (let ((map (copy-keymap comint-mode-map))) (define-key map (kbd "C-x C-e") #'inf-clojure-eval-last-sexp) @@ -358,6 +366,22 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword ["Quit REPL" inf-clojure-quit])) map)) +;;;###autoload +(defcustom inf-clojure-mode-line + '(:eval (format " inf-clojure[%s]" (inf-clojure--modeline-info))) + "Mode line lighter for cider mode. + +The value of this variable is a mode line template as in +`mode-line-format'. See Info Node `(elisp)Mode Line Format' for details +about mode line templates. + +Customize this variable to change how inf-clojure-minor-mode +displays its status in the mode line. The default value displays +the current connection. Set this variable to nil to disable the +mode line entirely." + :type 'sexp + :risky t) + ;;;###autoload (define-minor-mode inf-clojure-minor-mode "Minor mode for interacting with the inferior Clojure process buffer. @@ -365,7 +389,8 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword The following commands are available: \\{inf-clojure-minor-mode-map}" - :lighter "" :keymap inf-clojure-minor-mode-map + :lighter inf-clojure-mode-line + :keymap inf-clojure-minor-mode-map (setq-local comint-input-sender 'inf-clojure--send-string) (inf-clojure-eldoc-setup) (make-local-variable 'completion-at-point-functions) @@ -703,7 +728,7 @@ process buffer for a list of commands.)" (inf-clojure-mode) (setq-local inf-clojure-repl-type repl-type) (hack-dir-local-variables-non-file-buffer)))) - (setq inf-clojure-buffer "*inf-clojure*") + (setq inf-clojure-buffer (get-buffer "*inf-clojure*")) (if inf-clojure-repl-use-same-window (pop-to-buffer-same-window "*inf-clojure*") (pop-to-buffer "*inf-clojure*"))) From 4acc32eb3a394aae5d515ed30b06663d23f7bf13 Mon Sep 17 00:00:00 2001 From: dan sutton Date: Sat, 20 Mar 2021 14:28:44 -0500 Subject: [PATCH 4/4] Don't try to select a dead buffer --- inf-clojure.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index ac7951e..062f925 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -277,7 +277,8 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword (defun inf-clojure--modeline-info () "Return modeline info. Either \"not connected\" or \"repl-type: buffer-name\"" - (if (bufferp inf-clojure-buffer) + (if (and (bufferp inf-clojure-buffer) + (buffer-live-p inf-clojure-buffer)) (with-current-buffer inf-clojure-buffer (format "%s: %s" inf-clojure-repl-type (buffer-name (current-buffer)))) "not connected"))