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..062f925 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -199,6 +199,38 @@ 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 +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") + (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. Its root binding is nil and it can be further customized using @@ -242,6 +274,15 @@ 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 (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")) + (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) @@ -326,6 +367,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. @@ -333,7 +390,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) @@ -671,7 +729,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*")))