From 3d31beeb8d9236afad29aa2b15c46e10b93c706b Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Wed, 11 Aug 2021 09:45:33 +0300 Subject: [PATCH 01/61] Update my email --- inf-clojure.el | 2 +- test/inf-clojure-tests.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index f3f6665..790660b 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -2,7 +2,7 @@ ;; Copyright © 2014-2021 Bozhidar Batsov -;; Authors: Bozhidar Batsov +;; Authors: Bozhidar Batsov ;; Olin Shivers ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, clojure diff --git a/test/inf-clojure-tests.el b/test/inf-clojure-tests.el index 635ac2c..6023338 100644 --- a/test/inf-clojure-tests.el +++ b/test/inf-clojure-tests.el @@ -2,7 +2,7 @@ ;; ;; Copyright © 2014-2021 Bozhidar Batsov -;; Authors: Bozhidar Batsov +;; Authors: Bozhidar Batsov ;; Andrea Richiardi ;; This file is not part of GNU Emacs. From 38e7dc1829646b93473c31d704bda0dee6644a38 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 19 Aug 2021 14:46:47 +0300 Subject: [PATCH 02/61] Shuffle around the README badges --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 135945b..dc314a8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -[![License GPL 3][badge-license]][copying] +[![Circle CI][circleci-badge]][circleci] [![MELPA][melpa-badge]][melpa-package] [![MELPA Stable][melpa-stable-badge]][melpa-stable-package] -[![Circle CI][circleci-badge]][circleci] +[![NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.svg)](https://elpa.nongnu.org/nongnu/inf-clojure.html) [![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.com/invite/nFPpynQPME) +[![License GPL 3][badge-license]][copying] # inf-clojure From 765653dc23dc2a2c1520a1e24332ab9d4b49dd47 Mon Sep 17 00:00:00 2001 From: dpsutton Date: Wed, 27 Oct 2021 11:11:35 -0500 Subject: [PATCH 03/61] Set clojure-mode syntax table in repl buffer (#193) --- CHANGELOG.md | 1 + inf-clojure.el | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5c87a3..ec5e0c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Bugs fixed +* [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in repl buffer * [#152](https://github.com/clojure-emacs/inf-clojure/issues/152): Sanitize should only remove whitespace at the end of a command. * [#188](https://github.com/clojure-emacs/inf-clojure/pull/188): Handle newlines between forms for `inf-clojure-eval-buffer`. * [#189](https://github.com/clojure-emacs/inf-clojure/pull/189): Font-lock code inserted in the REPL from a source buffer. diff --git a/inf-clojure.el b/inf-clojure.el index 790660b..bbcb0c1 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -770,6 +770,7 @@ process buffer for a list of commands.)" (with-current-buffer (apply #'make-comint process-buffer-name (car cmdlist) nil (cdr cmdlist)) (inf-clojure-mode) + (set-syntax-table clojure-mode-syntax-table) (setq-local inf-clojure-repl-type repl-type) (hack-dir-local-variables-non-file-buffer)))) ;; update the default comint buffer and switch to it From dca9f1957237214a0bb6155c68163efd6783e445 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 8 Feb 2022 15:40:27 +0900 Subject: [PATCH 04/61] Remove a noise character --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index bbcb0c1..bb38c7d 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1450,7 +1450,7 @@ Useful for commands that can invoked outside of an ‘inf-clojure’ buffer "Send FORM and apply MATCH-P on the result of sending it to PROC. Note that this function will add a \n to the end of the string for evaluation, therefore FORM should not include it." -p (funcall match-p (inf-clojure--process-response form proc nil))) + (funcall match-p (inf-clojure--process-response form proc nil))) (provide 'inf-clojure) From 59194187dfd289b77d927fcc17675555d5a78f38 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 8 Feb 2022 18:59:37 +0900 Subject: [PATCH 05/61] Declare global variable before referenced --- inf-clojure.el | 108 ++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index bb38c7d..2a3cfd1 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -154,6 +154,47 @@ (macroexpand . "(clojure.core/macroexpand '%s)") (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))))) +(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 +either `setq-local` or an entry in `.dir-locals.el`." ) + +(defvar inf-clojure-buffer nil + "The current `inf-clojure' process buffer. + +MULTIPLE PROCESS SUPPORT +=========================================================================== +To run multiple Clojure processes, you start the first up +with \\[inf-clojure]. It will be in a buffer named `*inf-clojure*'. +Rename this buffer with \\[rename-buffer]. You may now start up a new +process with another \\[inf-clojure]. It will be in a new buffer, +named `*inf-clojure*'. You can switch between the different process +buffers with \\[switch-to-buffer]. + +Commands that send text from source buffers to Clojure processes -- +like `inf-clojure-eval-defun' or `inf-clojure-show-arglists' -- have to choose a +process to send to, when you have more than one Clojure process around. This +is determined by the global variable `inf-clojure-buffer'. Suppose you +have three inferior Clojures running: + Buffer Process + foo inf-clojure + bar inf-clojure<2> + *inf-clojure* inf-clojure<3> +If you do a \\[inf-clojure-eval-defun] command on some Clojure source code, +what process do you send it to? + +- If you're in a process buffer (foo, bar, or *inf-clojure*), + you send it to that process. +- If you're in some other buffer (e.g., a source file), you + send it to the process attached to buffer `inf-clojure-buffer'. +This process selection is performed by function `inf-clojure-proc'. + +Whenever \\[inf-clojure] fires up a new process, it resets +`inf-clojure-buffer' to be the new process's buffer. If you only run +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.") + (defun inf-clojure--get-feature (repl-type feature no-error) "Get FEATURE for REPL-TYPE from repl-features. If no-error is truthy don't error if feature is not present." @@ -232,11 +273,6 @@ buffers after they are created with `rename-buffer'." (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 -either `setq-local` or an entry in `.dir-locals.el`." ) - (defvar inf-clojure--repl-type-lock nil "Global lock for protecting against proc filter race conditions. See http://blog.jorgenschaefer.de/2014/05/race-conditions-in-emacs-process-filter.html") @@ -544,42 +580,6 @@ See command `inf-clojure-minor-mode'." (with-current-buffer buffer (inf-clojure-minor-mode -1)))) -(defvar inf-clojure-buffer nil - "The current `inf-clojure' process buffer. - -MULTIPLE PROCESS SUPPORT -=========================================================================== -To run multiple Clojure processes, you start the first up -with \\[inf-clojure]. It will be in a buffer named `*inf-clojure*'. -Rename this buffer with \\[rename-buffer]. You may now start up a new -process with another \\[inf-clojure]. It will be in a new buffer, -named `*inf-clojure*'. You can switch between the different process -buffers with \\[switch-to-buffer]. - -Commands that send text from source buffers to Clojure processes -- -like `inf-clojure-eval-defun' or `inf-clojure-show-arglists' -- have to choose a -process to send to, when you have more than one Clojure process around. This -is determined by the global variable `inf-clojure-buffer'. Suppose you -have three inferior Clojures running: - Buffer Process - foo inf-clojure - bar inf-clojure<2> - *inf-clojure* inf-clojure<3> -If you do a \\[inf-clojure-eval-defun] command on some Clojure source code, -what process do you send it to? - -- If you're in a process buffer (foo, bar, or *inf-clojure*), - you send it to that process. -- If you're in some other buffer (e.g., a source file), you - send it to the process attached to buffer `inf-clojure-buffer'. -This process selection is performed by function `inf-clojure-proc'. - -Whenever \\[inf-clojure] fires up a new process, it resets -`inf-clojure-buffer' to be the new process's buffer. If you only run -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.") - (define-derived-mode inf-clojure-mode comint-mode "Inferior Clojure" "Major mode for interacting with an inferior Clojure process. Runs a Clojure interpreter as a subprocess of Emacs, with Clojure @@ -1253,19 +1253,6 @@ every other EXPR will be discarded and nil will be returned." (inf-clojure--read-or-nil) (inf-clojure--list-or-nil))) -(defun inf-clojure-completions (expr) - "Return completions for the Clojure expression starting with EXPR. - -Under the hood it calls the function -\\[inf-clojure-completions-fn] passing in the result of -evaluating \\[inf-clojure-completion-form] at the REPL." - (let* ((proc (inf-clojure-proc 'no-error)) - (completion-form (inf-clojure-get-feature proc 'completion t))) - (when (and proc completion-form (not (string-blank-p expr))) - (let ((completion-expr (format completion-form (substring-no-properties expr)))) - (funcall inf-clojure-completions-fn - (inf-clojure--process-response completion-expr proc "(" ")")))))) - (defcustom inf-clojure-completions-fn 'inf-clojure-list-completions "The function that parses completion results. @@ -1290,6 +1277,19 @@ you might want to use in your customization." :type 'function :package-version '(inf-clojure . "2.1.0")) +(defun inf-clojure-completions (expr) + "Return completions for the Clojure expression starting with EXPR. + +Under the hood it calls the function +\\[inf-clojure-completions-fn] passing in the result of +evaluating \\[inf-clojure-completion-form] at the REPL." + (let* ((proc (inf-clojure-proc 'no-error)) + (completion-form (inf-clojure-get-feature proc 'completion t))) + (when (and proc completion-form (not (string-blank-p expr))) + (let ((completion-expr (format completion-form (substring-no-properties expr)))) + (funcall inf-clojure-completions-fn + (inf-clojure--process-response completion-expr proc "(" ")")))))) + (defconst inf-clojure-clojure-expr-break-chars "^[] \"'`><,;|&{()[@\\^]" "Regexp are hard. From a5108373680fc9b3b1eecc247d66f0bbeecc2537 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 8 Feb 2022 19:01:54 +0900 Subject: [PATCH 06/61] Fix byte-compile warnings of unused variables --- inf-clojure.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 2a3cfd1..34a6fee 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -507,7 +507,7 @@ Clojure to load that file." ;; :reload-all implies :reload and also forces loading of all libs that the ;; identified libs directly or indirectly load via require or use -(defun inf-clojure-reload-form (proc) +(defun inf-clojure-reload-form (_proc) "Return the form to query the Inf-Clojure PROC for reloading a namespace. If you are using REPL types, it will pickup the most appropriate `inf-clojure-reload-form` variant." @@ -525,7 +525,7 @@ Clojure to load that file." :safe #'stringp :package-version '(inf-clojure . "2.2.0")) -(defun inf-clojure-reload-all-form (proc) +(defun inf-clojure-reload-all-form (_proc) "Return the form to query the Inf-Clojure PROC for :reload-all of a namespace. If you are using REPL types, it will pickup the most appropriate `inf-clojure-reload-all-form` variant." From edbdd09569cac829f824a1f52dd15829de6f8904 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 8 Feb 2022 19:04:38 +0900 Subject: [PATCH 07/61] Specify customize variable :type attribute --- inf-clojure.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 34a6fee..4534766 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -450,7 +450,8 @@ number (e.g. (\"localhost\" . 5555))." "Form to be used to start `inf-clojure'. Can be a cons pair of (host . port) where host is a string and port is an integer, or a string to startup an interpreter like -\"planck\".") +\"planck\"." + :type '(choice (cons string integer) (const nil))) (defcustom inf-clojure-custom-repl-type nil From 975ed78919ff50ddc290a0630502c42cee3e9a81 Mon Sep 17 00:00:00 2001 From: Shohei YOSHIDA Date: Tue, 8 Feb 2022 22:38:56 +0900 Subject: [PATCH 08/61] Put a space after prompt --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 4534766..2008939 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -282,7 +282,7 @@ See http://blog.jorgenschaefer.de/2014/05/race-conditions-in-emacs-process-filte (interactive) (let ((types (mapcar #'car inf-clojure-repl-features))) (intern - (completing-read "Set REPL type:" + (completing-read "Set REPL type: " (sort (mapcar #'symbol-name types) #'string-lessp))))) (defgroup inf-clojure nil From d89ad48a5b61ccf1c7417f63b006493cec4063f7 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Tue, 8 Feb 2022 18:27:52 +0200 Subject: [PATCH 09/61] Bump copyright --- README.md | 2 +- inf-clojure.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc314a8..971854d 100644 --- a/README.md +++ b/README.md @@ -476,7 +476,7 @@ This creates `.inf-clojure.log` in the project directory so that you can `tail - ## License -Copyright © 2014-2021 Bozhidar Batsov and [contributors][]. +Copyright © 2014-2022 Bozhidar Batsov and [contributors][]. Distributed under the GNU General Public License; type C-h C-c to view it. diff --git a/inf-clojure.el b/inf-clojure.el index 2008939..1ad0bbb 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1,6 +1,6 @@ ;;; inf-clojure.el --- Run an external Clojure process in an Emacs buffer -*- lexical-binding: t; -*- -;; Copyright © 2014-2021 Bozhidar Batsov +;; Copyright © 2014-2022 Bozhidar Batsov ;; Authors: Bozhidar Batsov ;; Olin Shivers From e47684de78da1ee470d42ae2a411909b2cf61d50 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Tue, 8 Feb 2022 18:28:24 +0200 Subject: [PATCH 10/61] Tweak a changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec5e0c1..01a558a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ ### Bugs fixed -* [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in repl buffer +* [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in REPL buffer. * [#152](https://github.com/clojure-emacs/inf-clojure/issues/152): Sanitize should only remove whitespace at the end of a command. * [#188](https://github.com/clojure-emacs/inf-clojure/pull/188): Handle newlines between forms for `inf-clojure-eval-buffer`. * [#189](https://github.com/clojure-emacs/inf-clojure/pull/189): Font-lock code inserted in the REPL from a source buffer. From de59e5c416c242f77e3744ece3597843278191e5 Mon Sep 17 00:00:00 2001 From: dpsutton Date: Tue, 15 Mar 2022 05:58:11 -0500 Subject: [PATCH 11/61] Adds an option to disable eldoc (#197) Eldoc is quite nice and puts the function signatures in the minibuffer. But it does this at a cost. Since inf-clojure only uses a single connection (currently at least) the commands interrupt the values of `*1`, `*2`, etc. Further, this can lead to multiple prompts appearing in the repl buffer. ```clojure user=> user=> (map inc (range 4)) (1 2 3 4) user=> user=> *1 nil user=> ``` `user` appears multiple times, and then `*1` has been bound to the result of getting arglists. ```clojure user=> (+ 1 1) 2 user=> *1 ([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) ``` The multiple prompts is quite annoying when inserting forms into the repl. --- CHANGELOG.md | 4 ++++ README.md | 18 ++++++++++-------- inf-clojure.el | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01a558a..daccb36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### New features + +* [#187](https://github.com/clojure-emacs/inf-clojure/pull/197): Defcustom `inf-clojure-enable-eldoc` to disable eldoc interaction. + ## 3.1.0 (2021-07-23) ### New features diff --git a/README.md b/README.md index 971854d..fe08189 100644 --- a/README.md +++ b/README.md @@ -356,18 +356,20 @@ startup when using the `inf-clojure` command or is specified manually when using #### ElDoc -**Note:** You can skip this section if you're using Emacs 26.1+, as `eldoc-mode` -is enabled by default there. - `eldoc-mode` is supported in Clojure source buffers and `*inferior-clojure*` buffers which are running a Clojure REPL. -When ElDoc is enabled and there is an active REPL, it will show the -argument list of the function call you are currently editing in the -echo area. +When ElDoc is enabled and there is an active REPL, it will show the argument +list of the function call you are currently editing in the echo area. It +accomplishes this by evaluating forms to get the metadata for the vars under +your cursor. One side effect of this is that it can mess with repl vars like +`*1` and `*2`. You can disable inf-clojure's Eldoc functionality with `(setq +inf-clojure-enable-eldoc nil)`. + -You can activate ElDoc with `M-x eldoc-mode` or by adding the -following to you Emacs config: +ElDoc should be enabled by default in Emacs 26.1+. If it is not active by +default, you can activate ElDoc with `M-x eldoc-mode` or by adding the following +to you Emacs config: ```emacs-lisp (add-hook 'clojure-mode-hook #'eldoc-mode) diff --git a/inf-clojure.el b/inf-clojure.el index 1ad0bbb..1e588fd 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -420,6 +420,13 @@ mode line entirely." :type 'sexp :risky t) +(defcustom inf-clojure-enable-eldoc t + "Var that allows disabling `eldoc-mode` in `inf-clojure`. + +Set to `nil` to disable eldoc. Eldoc can be quite useful by +displaying function signatures in the modeline, but can also +cause multiple prompts to appear and mess with `*1`, `*2`, etc.") + ;;;###autoload (define-minor-mode inf-clojure-minor-mode "Minor mode for interacting with the inferior Clojure process buffer. @@ -430,7 +437,8 @@ The following commands are available: :lighter inf-clojure-mode-line :keymap inf-clojure-minor-mode-map (setq-local comint-input-sender 'inf-clojure--send-string) - (inf-clojure-eldoc-setup) + (when inf-clojure-enable-eldoc + (inf-clojure-eldoc-setup)) (make-local-variable 'completion-at-point-functions) (add-to-list 'completion-at-point-functions #'inf-clojure-completion-at-point)) @@ -632,7 +640,8 @@ to continue it." (setq mode-line-process '(":%s")) (clojure-mode-variables) (clojure-font-lock-setup) - (inf-clojure-eldoc-setup) + (when inf-clojure-enable-eldoc + (inf-clojure-eldoc-setup)) (setq comint-get-old-input #'inf-clojure-get-old-input) (setq comint-input-filter #'inf-clojure-input-filter) (setq-local comint-prompt-read-only inf-clojure-prompt-read-only) @@ -1408,6 +1417,7 @@ Return the number of nested sexp the point was over or after." "Backend function for eldoc to show argument list in the echo area." ;; todo: this never gets unset once connected and is a lie (when (and (inf-clojure-connected-p) + inf-clojure-enable-eldoc ;; don't clobber an error message in the minibuffer (not (member last-command '(next-error previous-error)))) (let* ((info (inf-clojure-eldoc-info-in-current-sexp)) From 6dcf449dea3f68ec532d034bd3ac50773a2b3e9a Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Tue, 15 Mar 2022 12:58:48 +0200 Subject: [PATCH 12/61] Bump the development version --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 1e588fd..6808409 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -6,7 +6,7 @@ ;; Olin Shivers ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, clojure -;; Version: 3.1.0 +;; Version: 3.2.0-snapshot ;; Package-Requires: ((emacs "25.1") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. From e6ae253326d5f508872ef494f77001ce6be88769 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Tue, 15 Mar 2022 12:59:58 +0200 Subject: [PATCH 13/61] Add missing metadata --- inf-clojure.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 6808409..ffe20e4 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -425,7 +425,10 @@ mode line entirely." Set to `nil` to disable eldoc. Eldoc can be quite useful by displaying function signatures in the modeline, but can also -cause multiple prompts to appear and mess with `*1`, `*2`, etc.") +cause multiple prompts to appear and mess with `*1`, `*2`, etc." + :type 'boolean + :safe 'booleanp + :package-version '(inf-clojure . "3.2.0")) ;;;###autoload (define-minor-mode inf-clojure-minor-mode From f511dcad0e0684c9609c7526930e88d11da989ab Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Tue, 15 Mar 2022 13:02:48 +0200 Subject: [PATCH 14/61] Tweak docstring --- inf-clojure.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index ffe20e4..b5b1388 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -421,11 +421,12 @@ mode line entirely." :risky t) (defcustom inf-clojure-enable-eldoc t - "Var that allows disabling `eldoc-mode` in `inf-clojure`. + "Var that allows disabling `eldoc-mode' in `inf-clojure'. -Set to `nil` to disable eldoc. Eldoc can be quite useful by +Set to nil to disable eldoc. Eldoc can be quite useful by displaying function signatures in the modeline, but can also -cause multiple prompts to appear and mess with `*1`, `*2`, etc." +cause multiple prompts to appear in the REPL and mess with *1, +*2, etc." :type 'boolean :safe 'booleanp :package-version '(inf-clojure . "3.2.0")) From abeab8d6d4cb3bdded5e9083776aab0c06cbdf57 Mon Sep 17 00:00:00 2001 From: winterbeardo <103951470+winterbeardo@users.noreply.github.com> Date: Thu, 21 Apr 2022 00:59:57 -0500 Subject: [PATCH 15/61] [Fix #185] Improve cmd string splitting (#198) The following now works: (inf-clojure "clojure -Sdeps \"{:deps {insn/insn {:mvn/version \\\"0.5.4\\\"}}}\"") --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index b5b1388..bb07c34 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -775,7 +775,7 @@ process buffer for a list of commands.)" (let ((default-directory (or project-dir default-directory)) (cmdlist (if (consp cmd) (list cmd) - (split-string cmd))) + (split-string-and-unquote cmd))) (repl-type (or (unless prefix-arg inf-clojure-custom-repl-type) (car (rassoc cmd inf-clojure-startup-forms)) From 8f295050a856b03d6ec14f0fd5e782e7acde6e2d Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 3 Jun 2022 11:23:50 -0400 Subject: [PATCH 16/61] Added function for switching back from an inf-clojure buffer (#200) * Added function for switching back from an inf-clojure buffer * set inf-clojure--recent-buffer on inf-clojure-connect * use most recent buffer instead of 'last swapped from' buffer * provide display-buffer-reuse-window one day I'll learn how to read and pass args in emacs --- CHANGELOG.md | 1 + inf-clojure.el | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daccb36..4880f36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### New features +* [#168](https://github.com/clojure-emacs/inf-clojure/pull/197): Helper function `inf-clojure-switch-to-recent-buffer` to select the last buffer an inf-clojure process buffer was swapped to from. * [#187](https://github.com/clojure-emacs/inf-clojure/pull/197): Defcustom `inf-clojure-enable-eldoc` to disable eldoc interaction. ## 3.1.0 (2021-07-23) diff --git a/inf-clojure.el b/inf-clojure.el index bb07c34..484e211 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -330,6 +330,7 @@ Either \"no process\" or \"buffer-name(repl-type)\"" (define-key map (kbd "C-c C-S-a") #'inf-clojure-apropos) (define-key map (kbd "C-c M-o") #'inf-clojure-clear-repl-buffer) (define-key map (kbd "C-c C-q") #'inf-clojure-quit) + (define-key map (kbd "C-c C-z") #'inf-clojure-switch-to-recent-buffer) (easy-menu-define inf-clojure-mode-menu map "Inferior Clojure REPL Menu" '("Inf-Clojure REPL" @@ -694,22 +695,36 @@ to continue it." (let ((comint-buffer-maximum-size 0)) (comint-truncate-buffer)))) +(defun inf-clojure--swap-to-buffer-window (to-buffer) + "Switch to `TO-BUFFER''s window." + (let ((pop-up-frames + ;; Be willing to use another frame + ;; that already has the window in it. + (or pop-up-frames + (get-buffer-window to-buffer t)))) + (pop-to-buffer to-buffer '(display-buffer-reuse-window . ())))) + (defun inf-clojure-switch-to-repl (eob-p) "Switch to the inferior Clojure process buffer. With prefix argument EOB-P, positions cursor at end of buffer." (interactive "P") (if (get-buffer-process inf-clojure-buffer) - (let ((pop-up-frames - ;; Be willing to use another frame - ;; that already has the window in it. - (or pop-up-frames - (get-buffer-window inf-clojure-buffer t)))) - (pop-to-buffer inf-clojure-buffer)) + (inf-clojure--swap-to-buffer-window inf-clojure-buffer) (call-interactively #'inf-clojure)) (when eob-p (push-mark) (goto-char (point-max)))) +(defun inf-clojure-switch-to-recent-buffer () + "Switch to the most recently used `inf-clojure-minor-mode' buffer." + (interactive) + (let ((recent-inf-clojure-minor-mode-buffer (seq-find (lambda (buf) + (with-current-buffer buf (bound-and-true-p inf-clojure-minor-mode))) + (buffer-list)))) + (if recent-inf-clojure-minor-mode-buffer + (inf-clojure--swap-to-buffer-window recent-inf-clojure-minor-mode-buffer) + (message "inf-clojure: No recent buffer known.")))) + (defun inf-clojure-quit (&optional buffer) "Kill the REPL buffer and its underlying process. From 64c9af8531afcb3c03ed990b4f6ea101a0b4d577 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Mon, 11 Jul 2022 08:50:28 +0300 Subject: [PATCH 17/61] Tweak the README a bit --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fe08189..d919ba2 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This package provides basic interaction with a Clojure subprocess (REPL). It's based on ideas from the popular `inferior-lisp` package. -`inf-clojure` has two components - a nice REPL buffer (`inf-clojure`) and a REPL +`inf-clojure` has two components - a nice REPL buffer (`inf-clojure-mode`) and a REPL interaction minor mode (`inf-clojure-minor-mode`), which extends `clojure-mode` with commands to evaluate forms directly in the REPL. @@ -70,18 +70,18 @@ the right code for each REPL type. **Note:** `inf-clojure` requires Emacs 25 or newer. -`inf-clojure` is available on the community-maintained `package.el` repos - +`inf-clojure` is available on the official [NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.html) `package.el` repo and on the community-maintained [MELPA Stable][] and [MELPA][] repos. -MELPA Stable is recommended as it has the latest stable version. +NonGNU ELPA and MELPA Stable are recommended as they have the latest stable version. MELPA has a development snapshot for users who don't mind breakage but -don't want to run from a git checkout. +don't want to run `inf-clojure` from a git checkout. You can install `inf-clojure` using the following command: M-x package-install [RET] inf-clojure [RET] -or if you'd rather keep it in your dotfiles: +or if you'd rather keep it in your Emacs config: ```emacs-lisp (unless (package-installed-p 'inf-clojure) @@ -122,11 +122,11 @@ and enter its host and port numbers. Inf-clojure aims to be very simple and offer tooling that the REPL itself exposes. A few commands are: -- eval last sexp `C-x C-e` -- show arglists for function `C-c C-a` -- show var documentation `C-c C-v` -- show source `C-c C-s` -- insert top level form into REPL `C-c C-j d` +- eval last sexp (`C-x C-e`) +- show arglists for function (`C-c C-a`) +- show var documentation (`C-c C-v`) +- show source (`C-c C-s`) +- insert top level form into REPL (`C-c C-j d`) For a list of all available commands in `inf-clojure-mode` (a.k.a. the REPL) and `inf-clojure-minor-mode` you can either invoke `C-h f RET From f3c1de4a43f8cb6dbd6caf919665057db04321a4 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Mon, 11 Jul 2022 08:54:30 +0300 Subject: [PATCH 18/61] Replace mentions of clojure-complete with incomplete --- README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d919ba2..391c0a5 100644 --- a/README.md +++ b/README.md @@ -385,13 +385,13 @@ Code completion is a tricky aspect if you are trying to be as close to a generic REPL as possible. Planck and lumo REPL implementations explicitly provide completion functions in their REPL namespaces. For clojure, you will need to have a library on your classpath. If you are -using lein, you already have -[clojure-complete](https://github.com/ninjudd/clojure-complete). You +using a recent version of Leiningen, you already have +[incomplete](https://github.com/nrepl/incomplete). You could alternatively use `compliment {:mvn/version "0.3.10"}`. ```emacs-lisp -;; for clojure-complete -(inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")") +;; for incomplete +(inf-clojure-update-feature 'clojure 'completion "(incomplete.core/completions \"%s\")") ;; or ;; for compliment @@ -401,17 +401,14 @@ could alternatively use `compliment {:mvn/version "0.3.10"}`. If you give a form for the completion form, it is your responsibility to ensure that this namespace is on the classpath and required. If -using lein, this is done for you with clojure-complete. If adding -compliment, the following sample deps.edn can conveniently add the dep -to your program. - -Sample deps.edn: +using Leiningen, this is done for you with `incomplete`. If adding +`compliment`, the following sample `deps.edn` can conveniently add the dep +to your program: ```clojure {:aliases {:compliment {:extra-deps {compliment {:mvn/version "0.3.10"}}}}} ``` - Use the startup command: `clojure -A:compliment`. Then require the ns once so that the completion machinery will work: `(require 'compliment.core)`. Now tab completion should work. @@ -422,7 +419,7 @@ to customization. Not only you can `setq` the customary `inf-clojure-completion-form-planck` and `inf-clojure-completion-form-joker` - the form to send to the REPL - but you can also use `inf-clojure-completions-fn` for specifying a -function that given the REPL response should return elisp data +function that given the REPL response should return Elisp data compatible with [`completion-at-point-functions`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion-in-Buffers.html). For more info run `M-x describe-variable RET @@ -434,7 +431,7 @@ it](https://github.com/clojure-emacs/cider/blob/3e9ed12e8cfbad04d7618e649322765d For an optimal Lumo experience the `-d` needs to be passed to Lumo when launched from the command line. This disable `readline` support -in order to play nicely with emacs. +in order to play nicely with Emacs. ## Troubleshooting From 771cf6da1df65e1fccfcd0d0a9fc911b100e4bed Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Mon, 11 Jul 2022 08:55:53 +0300 Subject: [PATCH 19/61] Update one more reference to clojure-complete --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 391c0a5..6e8d53e 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,7 @@ If you want to update a specific form there is a function `inf-clojure-update-repl-feature` which can be used like so: ```emacs-lisp -(inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")") +(inf-clojure-update-feature 'clojure 'completion "(incomplete.core/completions \"%s\")") ``` #### Caveats From 0bef87ca08f131867cdd5d7d4a22b211c3dc9557 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 15 Jul 2022 11:56:49 +0300 Subject: [PATCH 20/61] Tweak keywords --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 484e211..cec2a45 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -5,7 +5,7 @@ ;; Authors: Bozhidar Batsov ;; Olin Shivers ;; URL: http://github.com/clojure-emacs/inf-clojure -;; Keywords: processes, clojure +;; Keywords: processes, comint, clojure ;; Version: 3.2.0-snapshot ;; Package-Requires: ((emacs "25.1") (clojure-mode "5.11")) From 8ac47af1083c640ef558ece8556de9caf3f9f4ea Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 15 Jul 2022 11:59:33 +0300 Subject: [PATCH 21/61] Fix package version extraction logic --- inf-clojure.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index cec2a45..643b75e 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -293,8 +293,9 @@ See http://blog.jorgenschaefer.de/2014/05/race-conditions-in-emacs-process-filte :link '(emacs-commentary-link :tag "Commentary" "inf-clojure")) (defconst inf-clojure-version - (eval-when-compile - (lm-version (or load-file-name buffer-file-name))) + (or (if (fboundp 'package-get-version) + (package-get-version)) + "3.2.0") "The current version of `inf-clojure'.") (defcustom inf-clojure-prompt-read-only t From 67b0403aa183d521e36545266100f1f62a34e783 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 15 Jul 2022 12:05:27 +0300 Subject: [PATCH 22/61] Release 3.2.0 --- CHANGELOG.md | 13 ++++++++++--- inf-clojure.el | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4880f36..c752aca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,18 @@ ## master (unreleased) +## 3.2.0 (2022-07-15) + ### New features -* [#168](https://github.com/clojure-emacs/inf-clojure/pull/197): Helper function `inf-clojure-switch-to-recent-buffer` to select the last buffer an inf-clojure process buffer was swapped to from. -* [#187](https://github.com/clojure-emacs/inf-clojure/pull/197): Defcustom `inf-clojure-enable-eldoc` to disable eldoc interaction. +* [#168](https://github.com/clojure-emacs/inf-clojure/pull/197): New helper function `inf-clojure-switch-to-recent-buffer` to select the last buffer an inf-clojure process buffer was swapped to from. +* [#187](https://github.com/clojure-emacs/inf-clojure/pull/197): New defcustom `inf-clojure-enable-eldoc` to disable eldoc interaction. + +### Bugs fixed + +* [#185](https://github.com/clojure-emacs/inf-clojure/issues/185): Improve cmd string splitting. +* [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in REPL buffer. +* Fix `inf-clojure-display-version` (it wasn't extracting properly the package version). ## 3.1.0 (2021-07-23) @@ -17,7 +25,6 @@ ### Bugs fixed -* [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in REPL buffer. * [#152](https://github.com/clojure-emacs/inf-clojure/issues/152): Sanitize should only remove whitespace at the end of a command. * [#188](https://github.com/clojure-emacs/inf-clojure/pull/188): Handle newlines between forms for `inf-clojure-eval-buffer`. * [#189](https://github.com/clojure-emacs/inf-clojure/pull/189): Font-lock code inserted in the REPL from a source buffer. diff --git a/inf-clojure.el b/inf-clojure.el index 643b75e..6e871ff 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -6,7 +6,7 @@ ;; Olin Shivers ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure -;; Version: 3.2.0-snapshot +;; Version: 3.2.0 ;; Package-Requires: ((emacs "25.1") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. From 7de63df35fd912fb04fde56a1c07862e0e22bfe4 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sat, 16 Jul 2022 19:51:15 +0300 Subject: [PATCH 23/61] Small fixes to make NonGNU ELPA happier Thanks @monnier! --- .gitignore | 4 ++++ inf-clojure.el | 25 +++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index c724233..22372af 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ TAGS dist .vagrant/ .dir-locals?.el + +# ELPA-generated files +/inf-clojure-autoloads.el +/inf-clojure-pkg.el diff --git a/inf-clojure.el b/inf-clojure.el index 6e871ff..9cc217d 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -4,6 +4,7 @@ ;; Authors: Bozhidar Batsov ;; Olin Shivers +;; Maintainer: Bozhidar Batsov ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure ;; Version: 3.2.0 @@ -212,8 +213,8 @@ If no-error is truthy don't error if feature is not present." (defun inf-clojure--update-feature (repl-type feature form) "Return a copy of the datastructure containing the repl features. -Given a REPL-TYPE ('clojure, 'lumo, ...) and a FEATURE ('doc, -'apropos, ...) and a FORM this will return a new datastructure +Given a REPL-TYPE (`clojure', `lumo', ...) and a FEATURE (`doc', +`apropos', ...) and a FORM this will return a new datastructure that can be set as `inf-clojure-repl-features'." (let ((original (alist-get repl-type inf-clojure-repl-features))) (if original @@ -225,8 +226,8 @@ that can be set as `inf-clojure-repl-features'." (defun inf-clojure-update-feature (repl-type feature form) "Mutate the repl features to the new FORM. -Given a REPL-TYPE ('clojure, 'lumo, ...) and a FEATURE ('doc, -'apropos, ...) and a FORM this will set +Given a REPL-TYPE (`clojure', `lumo', ...) and a FEATURE (`doc', +`apropos', ...) and a FORM this will set `inf-clojure-repl-features' with these new values." (setq inf-clojure-repl-features (inf-clojure--update-feature repl-type feature form))) @@ -352,7 +353,7 @@ Either \"no process\" or \"buffer-name(repl-type)\"" map)) (defvar inf-clojure-insert-commands-map - (let ((map (define-prefix-command 'inf-clojure-insert-commands-map))) + (let ((map (make-sparse-keymap))) (define-key map (kbd "d") #'inf-clojure-insert-defun) (define-key map (kbd "C-d") #'inf-clojure-insert-defun) (define-key map (kbd "e") #'inf-clojure-insert-last-sexp) @@ -369,7 +370,7 @@ Either \"no process\" or \"buffer-name(repl-type)\"" (define-key map (kbd "C-c C-r") #'inf-clojure-eval-region) (define-key map (kbd "C-c M-r") #'inf-clojure-reload) (define-key map (kbd "C-c C-n") #'inf-clojure-eval-form-and-next) - (define-key map (kbd "C-c C-j") 'inf-clojure-insert-commands-map) + (define-key map (kbd "C-c C-j") inf-clojure-insert-commands-map) (define-key map (kbd "C-c C-z") #'inf-clojure-switch-to-repl) (define-key map (kbd "C-c C-i") #'inf-clojure-show-ns-vars) (define-key map (kbd "C-c C-S-a") #'inf-clojure-apropos) @@ -430,7 +431,7 @@ displaying function signatures in the modeline, but can also cause multiple prompts to appear in the REPL and mess with *1, *2, etc." :type 'boolean - :safe 'booleanp + :safe #'booleanp :package-version '(inf-clojure . "3.2.0")) ;;;###autoload @@ -926,10 +927,10 @@ Indent FORM. FORM is expected to have been trimmed." (buffer-substring-no-properties (save-excursion (backward-sexp) (point)) (point)))) -;;; Now that inf-clojure-eval-/defun/region takes an optional prefix arg, -;;; these commands are redundant. But they are kept around for the user -;;; to bind if he wishes, for backwards functionality, and because it's -;;; easier to type C-c e than C-u C-c C-e. +;; Now that inf-clojure-eval-/defun/region takes an optional prefix arg, +;; these commands are redundant. But they are kept around for the user +;; to bind if he wishes, for backwards functionality, and because it's +;; easier to type C-c e than C-u C-c C-e. (defun inf-clojure-eval-region-and-go (start end) "Send the current region to the inferior Clojure, and switch to its buffer. @@ -1017,7 +1018,7 @@ display." (if (zerop (length ans)) default ans)))) -;;; Adapted from function-called-at-point in help.el. +;; Adapted from function-called-at-point in help.el. (defun inf-clojure-fn-called-at-pt () "Return the name of the function called in the current call. The value is nil if it can't find one." From 151b20ba9d3ae39b88f91aecbab98bd5a5215f1a Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 22 Jul 2022 09:28:14 +0300 Subject: [PATCH 24/61] Release 3.2.1 --- CHANGELOG.md | 6 ++++++ inf-clojure.el | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c752aca..139613a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## master (unreleased) +## 3.2.1 (2022-07-22) + +### Bugs fixed + +* Address some small issues with NonGNU ELPA (e.g. missing maintainer metadata). + ## 3.2.0 (2022-07-15) ### New features diff --git a/inf-clojure.el b/inf-clojure.el index 9cc217d..1297cb5 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -7,7 +7,7 @@ ;; Maintainer: Bozhidar Batsov ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure -;; Version: 3.2.0 +;; Version: 3.2.1 ;; Package-Requires: ((emacs "25.1") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. @@ -296,7 +296,7 @@ See http://blog.jorgenschaefer.de/2014/05/race-conditions-in-emacs-process-filte (defconst inf-clojure-version (or (if (fboundp 'package-get-version) (package-get-version)) - "3.2.0") + "3.2.1") "The current version of `inf-clojure'.") (defcustom inf-clojure-prompt-read-only t From f436760489cd95400b5a5449158161031beac7ba Mon Sep 17 00:00:00 2001 From: Emma Griffin <53583563+E-A-Griffin@users.noreply.github.com> Date: Sat, 23 Jul 2022 11:36:04 -0400 Subject: [PATCH 25/61] Add ClojureCLR support (#203) --- CHANGELOG.md | 1 + README.md | 3 ++- inf-clojure.el | 20 ++++++++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 139613a..a0fa722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## master (unreleased) +* [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. ## 3.2.1 (2022-07-22) diff --git a/README.md b/README.md index 6e8d53e..a0ec0dd 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,14 @@ It supports the following REPLs: - Clojure - ClojureScript +- ClojureCLR (via [lein-clr](https://github.com/kumarshantanu/lein-clr)) - [Planck](http://planck-repl.org/) - [Lumo](https://github.com/anmonteiro/lumo) - [Joker](https://joker-lang.org/) - [babashka](https://github.com/borkdude/babashka) `inf-clojure` provides a set of essential features for interactive -Clojure(Script) development: +Clojure/ClojureScript/ClojureCLR development: * Enhanced REPL * Interactive code evaluation diff --git a/inf-clojure.el b/inf-clojure.el index 1297cb5..a213a55 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -36,7 +36,7 @@ ;; REPL. ;; ;; `inf-clojure` provides a set of essential features for interactive -;; Clojure(Script) development: +;; Clojure/ClojureScript/ClojureCLR development: ;; ;; * REPL ;; * Interactive code evaluation @@ -75,6 +75,7 @@ (boot . "boot repl") (clojure . "clojure") (cljs . "clojure -m cljs.main -r") + (lein-clr . "lein clr repl") (planck . "planck -d") (babashka . "bb") (lumo . "lumo -d") @@ -153,7 +154,22 @@ (ns-vars . "(clojure.repl/dir %s)") (set-ns . "(clojure.core/in-ns '%s)") (macroexpand . "(clojure.core/macroexpand '%s)") - (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))))) + (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))) + (lein-clr . ((load . "(clojure.core/load-file \"%s\")") + (doc . "(clojure.repl/doc %s)") + (source . "(clojure.repl/source %s)") + (arglists . + "(try + (:arglists + (clojure.core/meta + (clojure.core/resolve + (clojure.core/read-string \"%s\")))) + (catch Exception e nil))") + (apropos . "(doseq [var (sort (clojure.repl/apropos \"%s\"))] (println (str var)))") + (ns-vars . "(clojure.repl/dir %s)") + (set-ns . "(clojure.core/in-ns '%s)") + (macroexpand . "(clojure.core/macroexpand '%s)") + (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))))) (defvar-local inf-clojure-repl-type nil "Symbol to define your REPL type. From 59a9f0695f3d97a593f8d5ea04b51ea5dcb2718a Mon Sep 17 00:00:00 2001 From: dpsutton Date: Sun, 7 Aug 2022 16:13:04 -0500 Subject: [PATCH 26/61] Ensure repl scrolls on insert (#204) When inserting forms into the repl, the buffer doesn't always scroll to show the new input and result. This has been fixed in CIDER in a similar way, so now I'm bringing the same trick here. See https://github.com/clojure-emacs/cider/pull/2590 for more details. --- CHANGELOG.md | 2 ++ inf-clojure.el | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0fa722..6bf9e4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) * [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. +* [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands + ## 3.2.1 (2022-07-22) diff --git a/inf-clojure.el b/inf-clojure.el index a213a55..3b7f8dc 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -920,16 +920,21 @@ Prefix argument AND-GO means switch to the Clojure buffer afterwards." "Insert FORM into process and evaluate. Indent FORM. FORM is expected to have been trimmed." (let ((clojure-process (inf-clojure-proc))) - (with-current-buffer (process-buffer clojure-process) - (comint-goto-process-mark) - (let ((beginning (point))) - (insert (format "%s" form)) - (let ((end (point))) - (goto-char beginning) - (indent-sexp end) - ;; font-lock the inserted code - (font-lock-ensure beginning end))) - (comint-send-input t t)))) + ;; ensure the repl buffer scrolls. See similar fix in CIDER: + ;; https://github.com/clojure-emacs/cider/pull/2590 + (with-selected-window (or (get-buffer-window inf-clojure-buffer) + (selected-window)) + (with-current-buffer (process-buffer clojure-process) + (comint-goto-process-mark) + (let ((beginning (point))) + (insert form) + (let ((end (point))) + (goto-char beginning) + (indent-sexp end) + ;; font-lock the inserted code + (font-lock-ensure beginning end) + (goto-char end))) + (comint-send-input t t))))) (defun inf-clojure-insert-defun () "Send current defun to process." From e5ce3839835b9b561fca5810f43f413c96c197d9 Mon Sep 17 00:00:00 2001 From: Danny Date: Sun, 13 Nov 2022 13:54:16 +0000 Subject: [PATCH 27/61] Use comint-mode-map as parent map instead Whilst playing with inf-clojure-mode-map, some previous binds are overriden, because copy-keymap is used instead of set-parent-map. This will help for that. --- inf-clojure.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 3b7f8dc..b439722 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -339,7 +339,8 @@ Either \"no process\" or \"buffer-name(repl-type)\"" "no process")) (defvar inf-clojure-mode-map - (let ((map (copy-keymap comint-mode-map))) + (let ((map (make-sparse-keymap))) + (set-keymap-parent map comint-mode-map) (define-key map (kbd "C-x C-e") #'inf-clojure-eval-last-sexp) (define-key map (kbd "C-c C-l") #'inf-clojure-load-file) (define-key map (kbd "C-c C-a") #'inf-clojure-show-arglists) From 4ab78518c881dc3653e4f071eb4865c1c51f91c2 Mon Sep 17 00:00:00 2001 From: Justin Tirrell Date: Fri, 24 Feb 2023 11:45:14 -0500 Subject: [PATCH 28/61] Display message after setting repl --- CHANGELOG.md | 1 + inf-clojure.el | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bf9e4c..a77b1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## master (unreleased) * [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. * [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands +* [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting repl. ## 3.2.1 (2022-07-22) diff --git a/inf-clojure.el b/inf-clojure.el index b439722..0dbc7f6 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -281,14 +281,17 @@ ALWAYS-ASK). Otherwise get a list of all active inf-clojure REPLS and offer a choice. It's recommended to rename REPL buffers after 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))) - (if (> (length repl-buffers) 0) - (when-let ((repl-buffer (completing-read "Select default REPL: " repl-buffers nil t))) - (setq inf-clojure-buffer (get-buffer repl-buffer))) - (user-error "No buffers have an inf-clojure process"))))) + (let ((new-repl-buffer + (if (and (not always-ask) + (inf-clojure-repl-p)) + (setq inf-clojure-buffer (current-buffer)) + (let ((repl-buffers (inf-clojure-repls))) + (if (> (length repl-buffers) 0) + (when-let ((repl-buffer (completing-read "Select default REPL: " repl-buffers nil t))) + (setq inf-clojure-buffer (get-buffer repl-buffer))) + (user-error "No buffers have an inf-clojure process")))))) + (when new-repl-buffer + (message "Current inf-clojure REPL set to %s" new-repl-buffer)))) (defvar inf-clojure--repl-type-lock nil "Global lock for protecting against proc filter race conditions. From 3cfc4f0bd598146b4ca664b8a3da2e5410681a36 Mon Sep 17 00:00:00 2001 From: Justin Tirrell Date: Fri, 24 Feb 2023 18:37:49 -0500 Subject: [PATCH 29/61] Don't use outer let --- inf-clojure.el | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 0dbc7f6..01d6f1b 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -281,17 +281,17 @@ ALWAYS-ASK). Otherwise get a list of all active inf-clojure REPLS and offer a choice. It's recommended to rename REPL buffers after they are created with `rename-buffer'." (interactive "P") - (let ((new-repl-buffer - (if (and (not always-ask) - (inf-clojure-repl-p)) - (setq inf-clojure-buffer (current-buffer)) - (let ((repl-buffers (inf-clojure-repls))) - (if (> (length repl-buffers) 0) - (when-let ((repl-buffer (completing-read "Select default REPL: " repl-buffers nil t))) - (setq inf-clojure-buffer (get-buffer repl-buffer))) - (user-error "No buffers have an inf-clojure process")))))) - (when new-repl-buffer - (message "Current inf-clojure REPL set to %s" new-repl-buffer)))) + (if (and (not always-ask) + (inf-clojure-repl-p)) + (progn + (setq inf-clojure-buffer (current-buffer)) + (message "Current inf-clojure REPL set to %s" inf-clojure-buffer)) + (let ((repl-buffers (inf-clojure-repls))) + (if (> (length repl-buffers) 0) + (when-let ((repl-buffer (completing-read "Select default REPL: " repl-buffers nil t))) + (setq inf-clojure-buffer (get-buffer repl-buffer)) + (message "Current inf-clojure REPL set to %s" inf-clojure-buffer)) + (user-error "No buffers have an inf-clojure process"))))) (defvar inf-clojure--repl-type-lock nil "Global lock for protecting against proc filter race conditions. From fb9b5ea55f9ef02be32660cc29df15023968fb78 Mon Sep 17 00:00:00 2001 From: Justin Tirrell Date: Sat, 25 Feb 2023 12:39:49 -0500 Subject: [PATCH 30/61] Extract function to prompt for repl buffer --- inf-clojure.el | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 01d6f1b..3e86834 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -274,6 +274,16 @@ Checks the mode and that there is a live process." (push (buffer-name b) repl-buffers))) repl-buffers)) +(defun inf-clojure--prompt-repl-buffer (prompt) + "Prompt the user to select an inf-clojure repl buffer. +PROMPT is a string to prompt the user. +Returns nil when no buffer is selected." + (let ((repl-buffers (inf-clojure-repls))) + (if (> (length repl-buffers) 0) + (when-let ((repl-buffer (completing-read prompt repl-buffers nil t))) + (get-buffer repl-buffer)) + (user-error "No buffers have an inf-clojure process")))) + (defun inf-clojure-set-repl (always-ask) "Set an inf-clojure buffer as the active (default) REPL. If in a REPL buffer already, use that unless a prefix is used (or @@ -281,17 +291,13 @@ ALWAYS-ASK). Otherwise get a list of all active inf-clojure REPLS and offer a choice. It's recommended to rename REPL buffers after they are created with `rename-buffer'." (interactive "P") - (if (and (not always-ask) - (inf-clojure-repl-p)) - (progn - (setq inf-clojure-buffer (current-buffer)) - (message "Current inf-clojure REPL set to %s" inf-clojure-buffer)) - (let ((repl-buffers (inf-clojure-repls))) - (if (> (length repl-buffers) 0) - (when-let ((repl-buffer (completing-read "Select default REPL: " repl-buffers nil t))) - (setq inf-clojure-buffer (get-buffer repl-buffer)) - (message "Current inf-clojure REPL set to %s" inf-clojure-buffer)) - (user-error "No buffers have an inf-clojure process"))))) + (when-let ((new-repl-buffer + (if (or always-ask + (not (inf-clojure-repl-p))) + (inf-clojure--prompt-repl-buffer "Select default REPL: ") + (current-buffer)))) + (setq inf-clojure-buffer new-repl-buffer) + (message "Current inf-clojure REPL set to %s" new-repl-buffer))) (defvar inf-clojure--repl-type-lock nil "Global lock for protecting against proc filter race conditions. From 05bf92ffbd6cf613eab4edaa07865f219c6d10dd Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 24 Mar 2023 10:22:10 +0200 Subject: [PATCH 31/61] Update the CI setup to match that of CIDER --- .circleci/config.yml | 120 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 31918ba..d2a8cef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,36 +1,120 @@ version: 2.1 +orbs: + win: circleci/windows@2.2.0 + # Default actions to perform on each Emacs version -default: &default-steps - steps: - - checkout - - run: apt-get update && apt-get install make - - run: make test +commands: + setup: + steps: + - checkout + - run: + name: Install Eldev + command: curl -fsSL https://raw.github.com/doublep/eldev/master/webinstall/circle-eldev > x.sh && source ./x.sh + + macos-setup: + steps: + - checkout + - run: + name: Install Emacs latest + command: | + echo "HOMEBREW_NO_AUTO_UPDATE=1" >> $BASH_ENV + brew install homebrew/cask/emacs + - run: + name: Install Eldev + command: curl -fsSL https://raw.github.com/doublep/eldev/master/webinstall/circle-eldev > x.sh && source ./x.sh + + setup-windows: + steps: + - checkout + - run: + name: Install Eldev + command: | + # Remove expired DST Root CA X3 certificate. Workaround + # for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=51038 + # bug on Emacs 27.2. + gci cert:\LocalMachine\Root\DAC9024F54D8F6DF94935FB1732638CA6AD77C13 + gci cert:\LocalMachine\Root\DAC9024F54D8F6DF94935FB1732638CA6AD77C13 | Remove-Item + (iwr https://raw.github.com/doublep/eldev/master/webinstall/circle-eldev.ps1).Content | powershell -command - + test: + steps: + - run: + name: Run regression tests + command: eldev -dtT -p test + lint: + steps: + - run: + name: Run Elisp-lint + command: eldev lint + - run: + name: Byte-compile `.el' files + command: eldev -dtT compile --warnings-as-errors -# Enumerated list of Emacs versions jobs: - test-emacs-26: + test-ubuntu-emacs-26: + docker: + - image: silex/emacs:26-ci + entrypoint: bash + steps: + - setup + - test + + test-ubuntu-emacs-27: docker: - - image: silex/emacs:26-ci-cask + - image: silex/emacs:27-ci entrypoint: bash - <<: *default-steps + steps: + - setup + - test - test-emacs-27: + test-ubuntu-emacs-28: docker: - - image: silex/emacs:27-ci-cask + - image: silex/emacs:28-ci entrypoint: bash - <<: *default-steps + steps: + - setup + - test - test-emacs-master: + test-ubuntu-emacs-master: docker: - - image: silex/emacs:master-ci-cask + - image: silex/emacs:master-ci entrypoint: bash - <<: *default-steps + steps: + - setup + - test + + test-macos-emacs-latest: + macos: + xcode: "14.0.0" + steps: + - macos-setup + - test + + test-windows-emacs-latest: + executor: win/default + steps: + - run: + name: Install Emacs latest + command: | + choco install emacs + - setup-windows + - test + + test-lint: + docker: + - image: silex/emacs:28-ci + steps: + - setup + - lint workflows: version: 2 ci-test-matrix: jobs: - - test-emacs-26 - - test-emacs-27 - - test-emacs-master + - test-ubuntu-emacs-26 + - test-ubuntu-emacs-27 + - test-ubuntu-emacs-28 + - test-ubuntu-emacs-master + - test-lint + - test-macos-emacs-latest + - test-windows-emacs-latest From 2fd4873025be00ddc092a664b482048e06c5aa47 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 24 Mar 2023 11:12:32 +0200 Subject: [PATCH 32/61] Replace Cask with Eldev --- Cask | 11 ----------- Eldev | 7 +++++++ Makefile | 19 ------------------- 3 files changed, 7 insertions(+), 30 deletions(-) delete mode 100644 Cask create mode 100644 Eldev delete mode 100644 Makefile diff --git a/Cask b/Cask deleted file mode 100644 index d2a5667..0000000 --- a/Cask +++ /dev/null @@ -1,11 +0,0 @@ -(source gnu) -(source melpa) - -(package-file "inf-clojure.el") - -(files "*.el" (:exclude ".dir-locals.el")) - -(development - (depends-on "clojure-mode") - (depends-on "buttercup") - (depends-on "assess")) diff --git a/Eldev b/Eldev new file mode 100644 index 0000000..8581b45 --- /dev/null +++ b/Eldev @@ -0,0 +1,7 @@ +; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- + +(eldev-use-package-archive 'gnu) +(eldev-use-package-archive 'nongnu) +(eldev-use-package-archive 'melpa-stable) + +(eldev-use-plugin 'autoloads) diff --git a/Makefile b/Makefile deleted file mode 100644 index d002f72..0000000 --- a/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -.PHONY: clean version test - -all: build - -clean: - rm -rf .cask - -.cask: - cask install - cask update - -version: - emacs --version - -build: version .cask - cask build - -test: version .cask - cask exec buttercup -L . From 836d7a31735bd77340fe5fc772cda2cb8f1a2c00 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 24 Mar 2023 11:13:08 +0200 Subject: [PATCH 33/61] Ignore .eldev --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 22372af..9e62e23 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ elpa* TAGS .DS_STORE dist +.eldev .vagrant/ .dir-locals?.el From e555702f87ea2d20109c15766652b6f3d004976a Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 24 Mar 2023 11:22:58 +0200 Subject: [PATCH 34/61] Add the missing assess dep for the tests --- Eldev | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Eldev b/Eldev index 8581b45..80ae7b1 100644 --- a/Eldev +++ b/Eldev @@ -4,4 +4,7 @@ (eldev-use-package-archive 'nongnu) (eldev-use-package-archive 'melpa-stable) +;; the tests depend on the assess library +(eldev-add-extra-dependencies 'test 'assess) + (eldev-use-plugin 'autoloads) From 8ad2242b75ea1a06fad391deb8f858a392408a94 Mon Sep 17 00:00:00 2001 From: Michael Bruce Date: Sun, 26 Mar 2023 20:46:52 +0100 Subject: [PATCH 35/61] [#209] Implement a command that starts a socket REPL (inf-clojure-socket-repl) (#210) --- CHANGELOG.md | 1 + README.md | 3 + inf-clojure.el | 178 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 156 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a77b1e5..836cd49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. * [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands * [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting repl. +* [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. ## 3.2.1 (2022-07-22) diff --git a/README.md b/README.md index a0ec0dd..7a022aa 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,9 @@ common startup forms. You can select one of these or type in your own custom startup. This will start a REPL process for the current project and you can start interacting with it. +If you want to use a socket REPL server, use `M-x inf-clojure-socket-repl` +which will start a socket server and connect to it for you. + If you've already started a socket REPL server, use `M-x inf-clojure-connect` and enter its host and port numbers. diff --git a/inf-clojure.el b/inf-clojure.el index 3e86834..6f8d216 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -8,7 +8,7 @@ ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure ;; Version: 3.2.1 -;; Package-Requires: ((emacs "25.1") (clojure-mode "5.11")) +;; Package-Requires: ((emacs "26.2") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. @@ -74,7 +74,7 @@ (defvar inf-clojure-startup-forms '((lein . "lein repl") (boot . "boot repl") (clojure . "clojure") - (cljs . "clojure -m cljs.main -r") + (cljs . "clojure -M -m cljs.main -r") (lein-clr . "lein clr repl") (planck . "planck -d") (babashka . "bb") @@ -140,6 +140,17 @@ (set-ns . "(clojure.core/in-ns '%s)") (macroexpand . "(clojure.core/macroexpand '%s)") (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))) + (node-babashka . ((load . "(clojure.core/load-file \"%s\")") + (doc . "(clojure.repl/doc %s)") + (source . "(clojure.repl/source %s)") + (arglists . + "(try (-> '%s clojure.core/resolve clojure.core/meta :arglists) + (catch Throwable e nil))") + (apropos . "(doseq [var (sort (clojure.repl/apropos \"%s\"))] (println (str var)))") + (ns-vars . "(clojure.repl/dir %s)") + (set-ns . "(clojure.core/in-ns '%s)") + (macroexpand . "(clojure.core/macroexpand '%s)") + (macroexpand-1 . "(clojure.core/macroexpand-1 '%s)"))) (clojure . ((load . "(clojure.core/load-file \"%s\")") (doc . "(clojure.repl/doc %s)") (source . "(clojure.repl/source %s)") @@ -641,33 +652,34 @@ Customization: Entry to this mode runs the hooks on `comint-mode-hook' and You can send text to the inferior Clojure process from other buffers containing Clojure source. - `inf-clojure-switch-to-repl' switches the current buffer to the Clojure process buffer. + `inf-clojure-switch-to-repl' switches the current buffer to the Clojure + process buffer. `inf-clojure-eval-defun' sends the current defun to the Clojure process. `inf-clojure-eval-region' sends the current region to the Clojure process. Prefixing the inf-clojure-eval/defun/region commands with - a \\[universal-argument] causes a switch to the Clojure process buffer after sending - the text. + a \\[universal-argument] causes a switch to the Clojure process buffer after + sending the text. Commands:\\ -\\[comint-send-input] after the end of the process' output sends the text from the - end of process to point. -\\[comint-send-input] before the end of the process' output copies the sexp ending at point - to the end of the process' output, and sends it. -\\[comint-copy-old-input] copies the sexp ending at point to the end of the process' output, - allowing you to edit it before sending it. -If `comint-use-prompt-regexp' is nil (the default), \\[comint-insert-input] on old input - copies the entire old input to the end of the process' output, allowing - you to edit it before sending it. When not used on old input, or if - `comint-use-prompt-regexp' is non-nil, \\[comint-insert-input] behaves according to - its global binding. +\\[comint-send-input] after the end of the process' output sends the text from + the end of process to point. +\\[comint-send-input] before the end of the process' output copies the sexp + ending at point to the end of the process' output, and sends it. +\\[comint-copy-old-input] copies the sexp ending at point to the end of the + process' output,allowing you to edit it before sending it. +If `comint-use-prompt-regexp' is nil (the default), \\[comint-insert-input] on + old input copies the entire old input to the end of the process' output, + allowing you to edit it before sending it. When not used on old input, or if + `comint-use-prompt-regexp' is non-nil, \\[comint-insert-input] behaves + according to its global binding. \\[backward-delete-char-untabify] converts tabs to spaces as it moves back. \\[clojure-indent-line] indents for Clojure; with argument, shifts rest of expression rigidly with the current line. -\\[indent-sexp] does \\[clojure-indent-line] on each line starting within following expression. -Paragraphs are separated only by blank lines. Semicolons start comments. -If you accidentally suspend your process, use \\[comint-continue-subjob] -to continue it." +\\[indent-sexp] does \\[clojure-indent-line] on each line starting within + following expression. Paragraphs are separated only by blank lines. + Semicolons start comments. If you accidentally suspend your process, + use \\[comint-continue-subjob] to continue it." (setq comint-input-sender 'inf-clojure--send-string) (setq comint-prompt-regexp inf-clojure-comint-prompt-regexp) (setq mode-line-process '(":%s")) @@ -807,9 +819,11 @@ process buffer for a list of commands.)" nil 'confirm-after-completion)))) (let* ((project-dir (clojure-project-dir)) - (process-buffer-name (if project-dir - (format "inf-clojure %s" (inf-clojure--project-name project-dir)) - "inf-clojure")) + (process-buffer-name (or + inf-clojure-custom-repl-name + (if project-dir + (format "inf-clojure %s" (inf-clojure--project-name project-dir)) + "inf-clojure"))) ;; comint adds the asterisks to both sides (repl-buffer-name (format "*%s*" process-buffer-name))) ;; Create a new comint buffer if needed @@ -819,10 +833,11 @@ process buffer for a list of commands.)" (cmdlist (if (consp cmd) (list cmd) (split-string-and-unquote cmd))) - (repl-type (or (unless prefix-arg + (repl-type (or inf-clojure-socket-repl-type + (unless prefix-arg inf-clojure-custom-repl-type) - (car (rassoc cmd inf-clojure-startup-forms)) - (inf-clojure--prompt-repl-type)))) + (car (rassoc cmd inf-clojure-startup-forms)) + (inf-clojure--prompt-repl-type)))) (message "Starting Clojure REPL via `%s'..." cmd) (with-current-buffer (apply #'make-comint process-buffer-name (car cmdlist) nil (cdr cmdlist)) @@ -843,6 +858,117 @@ HOST is the host the process is running on, PORT is where it's listening." (interactive "shost: \nnport: ") (inf-clojure (cons host port))) +(defvar-local inf-clojure-socket-callback nil + "Used to transfer state between the socket process buffer & REPL buffer.") + +(defvar-local inf-clojure-socket-buffer nil + "Used to kill the associated socket buffer when it's REPL buffer is killed.") + +(defun inf-clojure-socket-filter (process output) + "A filter that gets triggered each time the socket receives new OUTPUT. +This function prints out the output received but also +watches for a prompt using the `inf-clojure-prompt' regexp, once +this happens a callback is triggered if available. The callback +is intended to be used to trigger a `inf-clojure-connect' once we +can determine that a socket REPL is ready to receive a +connection. + +PROCESS is the process object that is being filtered. + +OUTPUT is the latest data received from the process" + (let ((server-buffer (process-buffer process))) + (when (buffer-live-p server-buffer) + (with-current-buffer server-buffer + (insert output))) + (let ((prompt-displayed (string-match inf-clojure-prompt output))) + (when prompt-displayed + (message (format "Socket REPL startup detected for %s" (process-name process))) + (with-current-buffer server-buffer + (when inf-clojure-socket-callback + (funcall inf-clojure-socket-callback))))))) + +(defun inf-clojure-socket-repl-sentinel (process event) + "Ensures socket REPL are cleaned up when the REPL buffer is closed. + +PROCESS is the process object that is connected to a socket REPL. + +EVENT is the event that triggered this function to be called." + (when (not (process-live-p process)) + (let ((repl-buffer (process-buffer process))) + (with-current-buffer repl-buffer + (when inf-clojure-socket-buffer + (kill-buffer inf-clojure-socket-buffer)))))) + +(defvar inf-clojure-socket-repl-startup-forms + '((lein . "JVM_OPTS='-Dclojure.server.repl={:port %d :accept clojure.core.server/repl}' lein repl") + (boot . "export BOOT_JVM_OPTIONS='-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\"' boot repl") + (clojure . "clojure -J-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\"") + (cljs . "clojure -J-Dclojure.server.repl=\"{:port %d :accept cljs.server.browser/repl}\"") + (lein-clr . "JVM_OPTS='-Dclojure.server.repl={:port %d :accept clojure.core.server/repl}' lein clr repl") + (planck . "planck -n %d") + (babashka . "bb socket-repl %d"))) + +(defcustom inf-clojure-socket-repl-port + nil + "Port to be used when creating a socket REPL via `inf-clojure-socket-repl'. +If left as nil a random port will be selected between 5500-6000." + :type '(choice integer (const nil)) + :package-version '(inf-clojure . "3.3")) + +;;;###autoload +(defun inf-clojure-socket-repl (cmd) + "Start a socket REPL server and connect to it via `inf-clojure'. +CMD is the command line used to start the socket REPL, if this +isn't provided you will be prompted to select from the defaults +provided in `inf-clojure-socket-repl-startup-forms' or +`inf-clojure-custom-startup' if this is defined." + (interactive (list (or (unless current-prefix-arg + inf-clojure-custom-startup) + (completing-read "Select Clojure socket REPL startup command: " + (mapcar #'cdr inf-clojure-socket-repl-startup-forms) + nil + 'confirm-after-completion)))) + (let* ((host "localhost") + (port (or inf-clojure-socket-repl-port (+ 5500 (random 500)))) + (project-dir (clojure-project-dir)) + (repl-type (or (unless prefix-arg + inf-clojure-custom-repl-type) + (car (rassoc cmd inf-clojure-socket-repl-startup-forms)) + (inf-clojure--prompt-repl-type))) + (project-name (inf-clojure--project-name (or project-dir "standalone"))) + (socket-process-name (format "*%s-%s-socket-server*" project-name repl-type)) + (socket-buffer-name (format "*%s-%s-socket*" project-name repl-type)) + (socket-buffer (get-buffer-create socket-buffer-name)) + (repl-buffer-name (format "%s-%s-repl" project-name repl-type)) + (socket-form (or cmd + (cdr (assoc repl-type inf-clojure-socket-repl-startup-forms)) + inf-clojure-custom-startup)) + (socket-cmd (format socket-form port)) + (sock (let ((default-directory (or project-dir default-directory))) + (start-file-process-shell-command + socket-process-name socket-buffer + socket-cmd)))) + (with-current-buffer socket-buffer + (setq-local + inf-clojure-socket-callback + (lambda () + (let ((with-process-repl-buffer-name (concat "*" repl-buffer-name "*"))) + (setq inf-clojure-socket-repl-type + repl-type + inf-clojure-custom-repl-name + repl-buffer-name + repl-buffer + (get-buffer-create with-process-repl-buffer-name)) + (inf-clojure-connect host port) + (with-current-buffer with-process-repl-buffer-name + (setq inf-clojure-socket-buffer socket-buffer)) + (set-process-sentinel + (get-buffer-process (get-buffer with-process-repl-buffer-name)) + #'inf-clojure-socket-repl-sentinel))))) + (set-process-filter sock #'inf-clojure-socket-filter) + (message "Starting %s socket REPL server at %s:%d with %s" repl-type host port socket-cmd))) + + (defun inf-clojure--forms-without-newlines (str) "Remove newlines between toplevel forms. STR is a string of contents to be evaluated. When sending From b153e5126419910c38691088aab569b7c281068c Mon Sep 17 00:00:00 2001 From: dpsutton Date: Sat, 8 Apr 2023 04:52:51 -0500 Subject: [PATCH 36/61] Cleanup socket repl startup (#212) This simplifies the socket repl startup code and addresses some lint warnings. --- inf-clojure.el | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 6f8d216..4c5e018 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -518,6 +518,9 @@ Should be a symbol that is a key in `inf-clojure-repl-features'." (const :tag "babashka" babashka) (const :tag "determine at startup" nil))) +(defvar inf-clojure-custom-repl-name nil + "A string to be used as the repl buffer name.") + (defun inf-clojure--whole-comment-line-p (string) "Return non-nil iff STRING is a whole line semicolon comment." (string-match-p "^\s*;" string)) @@ -606,7 +609,9 @@ This should usually be a combination of `inf-clojure-prompt' and :package-version '(inf-clojure . "2.0.0")) (defcustom inf-clojure-auto-mode t - "When non-nil, automatically enable inf-clojure-minor-mode for all Clojure buffers." + "Automatically enable inf-clojure-minor-mode. +All buffers in `clojure-mode' will automatically be in +`inf-clojure-minor-mode' unless set to nil." :type 'boolean :safe #'booleanp :package-version '(inf-clojure . "3.1.0")) @@ -795,7 +800,7 @@ The name is simply the final segment of the path." (file-name-nondirectory (directory-file-name dir))) ;;;###autoload -(defun inf-clojure (cmd) +(defun inf-clojure (cmd &optional suppress-message) "Run an inferior Clojure process, input and output via buffer `*inf-clojure*'. If there is a process already running in `*inf-clojure*', just switch to that buffer. @@ -809,6 +814,9 @@ and `inf-clojure-custom-startup' if those are set. Use a prefix to prevent using these when they are set. +Prints a message that it has connected to the host and port +unless SUPPRESS-MESSAGE is truthy. + Runs the hooks from `inf-clojure-mode-hook' (after the `comint-mode-hook' is run). \(Type \\[describe-mode] in the process buffer for a list of commands.)" @@ -833,12 +841,12 @@ process buffer for a list of commands.)" (cmdlist (if (consp cmd) (list cmd) (split-string-and-unquote cmd))) - (repl-type (or inf-clojure-socket-repl-type - (unless prefix-arg + (repl-type (or (unless prefix-arg inf-clojure-custom-repl-type) - (car (rassoc cmd inf-clojure-startup-forms)) - (inf-clojure--prompt-repl-type)))) - (message "Starting Clojure REPL via `%s'..." cmd) + (car (rassoc cmd inf-clojure-startup-forms)) + (inf-clojure--prompt-repl-type)))) + (unless suppress-message + (message "Starting Clojure REPL via `%s'..." cmd)) (with-current-buffer (apply #'make-comint process-buffer-name (car cmdlist) nil (cdr cmdlist)) (inf-clojure-mode) @@ -849,14 +857,17 @@ process buffer for a list of commands.)" (setq inf-clojure-buffer (get-buffer repl-buffer-name)) (if inf-clojure-repl-use-same-window (pop-to-buffer-same-window repl-buffer-name) - (pop-to-buffer repl-buffer-name)))) + (pop-to-buffer repl-buffer-name)) + repl-buffer-name)) -;;;###autoload -(defun inf-clojure-connect (host port) +;;;###autol +(defun inf-clojure-connect (host port &optional suppress-message) "Connect to a running socket REPL server via `inf-clojure'. -HOST is the host the process is running on, PORT is where it's listening." +HOST is the host the process is running on, PORT is where it's +listening. SUPPRESS-MESSAGE is optional and if truthy will +prevent showing the startup message." (interactive "shost: \nnport: ") - (inf-clojure (cons host port))) + (inf-clojure (cons host port) suppress-message)) (defvar-local inf-clojure-socket-callback nil "Used to transfer state between the socket process buffer & REPL buffer.") @@ -882,12 +893,11 @@ OUTPUT is the latest data received from the process" (insert output))) (let ((prompt-displayed (string-match inf-clojure-prompt output))) (when prompt-displayed - (message (format "Socket REPL startup detected for %s" (process-name process))) (with-current-buffer server-buffer (when inf-clojure-socket-callback (funcall inf-clojure-socket-callback))))))) -(defun inf-clojure-socket-repl-sentinel (process event) +(defun inf-clojure-socket-repl-sentinel (process _event) "Ensures socket REPL are cleaned up when the REPL buffer is closed. PROCESS is the process object that is connected to a socket REPL. @@ -917,11 +927,11 @@ If left as nil a random port will be selected between 5500-6000." ;;;###autoload (defun inf-clojure-socket-repl (cmd) - "Start a socket REPL server and connect to it via `inf-clojure'. -CMD is the command line used to start the socket REPL, if this -isn't provided you will be prompted to select from the defaults -provided in `inf-clojure-socket-repl-startup-forms' or -`inf-clojure-custom-startup' if this is defined." + "Start a socket REPL server and connects to it via `inf-clojure-connect'. +CMD is the command line instruction used to start the socket +REPL. It should be a string with \"%d\" in it to take a random +port. Set `inf-clojure-custom-startup' or choose from the +defaults provided in `inf-clojure-socket-repl-startup-forms'." (interactive (list (or (unless current-prefix-arg inf-clojure-custom-startup) (completing-read "Select Clojure socket REPL startup command: " @@ -937,13 +947,9 @@ provided in `inf-clojure-socket-repl-startup-forms' or (inf-clojure--prompt-repl-type))) (project-name (inf-clojure--project-name (or project-dir "standalone"))) (socket-process-name (format "*%s-%s-socket-server*" project-name repl-type)) - (socket-buffer-name (format "*%s-%s-socket*" project-name repl-type)) - (socket-buffer (get-buffer-create socket-buffer-name)) - (repl-buffer-name (format "%s-%s-repl" project-name repl-type)) - (socket-form (or cmd - (cdr (assoc repl-type inf-clojure-socket-repl-startup-forms)) - inf-clojure-custom-startup)) - (socket-cmd (format socket-form port)) + (socket-buffer (get-buffer-create + (format "*%s-%s-socket*" project-name repl-type))) + (socket-cmd (format cmd port)) (sock (let ((default-directory (or project-dir default-directory))) (start-file-process-shell-command socket-process-name socket-buffer @@ -952,19 +958,13 @@ provided in `inf-clojure-socket-repl-startup-forms' or (setq-local inf-clojure-socket-callback (lambda () - (let ((with-process-repl-buffer-name (concat "*" repl-buffer-name "*"))) - (setq inf-clojure-socket-repl-type - repl-type - inf-clojure-custom-repl-name - repl-buffer-name - repl-buffer - (get-buffer-create with-process-repl-buffer-name)) - (inf-clojure-connect host port) - (with-current-buffer with-process-repl-buffer-name - (setq inf-clojure-socket-buffer socket-buffer)) - (set-process-sentinel - (get-buffer-process (get-buffer with-process-repl-buffer-name)) - #'inf-clojure-socket-repl-sentinel))))) + (let* ((inf-clojure-custom-repl-type repl-type) + (created-repl-buffer (inf-clojure-connect host port :suppress-message))) + (with-current-buffer (get-buffer created-repl-buffer) + (setq-local inf-clojure-socket-buffer socket-buffer) + (set-process-sentinel + (get-buffer-process (current-buffer)) + #'inf-clojure-socket-repl-sentinel)))))) (set-process-filter sock #'inf-clojure-socket-filter) (message "Starting %s socket REPL server at %s:%d with %s" repl-type host port socket-cmd))) From 9aea5012bf9047781a21a3b62cea134b126f7709 Mon Sep 17 00:00:00 2001 From: p4v4n Date: Sat, 9 Sep 2023 04:56:00 +0530 Subject: [PATCH 37/61] Replace `beginning-of-defun` fn --- CHANGELOG.md | 1 + inf-clojure.el | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 836cd49..c7e8a9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## master (unreleased) +* Improve support for multiple forms in the same line by replacing beginning-of-defun fn. * [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. * [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands * [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting repl. diff --git a/inf-clojure.el b/inf-clojure.el index 4c5e018..9efe1de 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1018,7 +1018,7 @@ current defun else return the string.." (let ((end (point)) (case-fold-search t) (func (if bounds #'cons #'buffer-substring-no-properties))) - (beginning-of-defun) + (beginning-of-defun-raw) (funcall func (point) end)))) (defun inf-clojure-eval-defun (&optional and-go) From ece16ffeefc5ab23a31012d10765c34197510220 Mon Sep 17 00:00:00 2001 From: Roman Rudakov Date: Sat, 24 May 2025 18:32:24 +0200 Subject: [PATCH 38/61] Add clojure-ts-mode support --- CHANGELOG.md | 5 +- README.md | 16 ++++++ inf-clojure.el | 148 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 115 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e8a9b..e824df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,13 @@ # Changelog ## master (unreleased) + * Improve support for multiple forms in the same line by replacing beginning-of-defun fn. * [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. * [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands * [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting repl. -* [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. - +* [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. +- [#217](https://github.com/clojure-emacs/inf-clojure/pull/217): Add `clojure-ts-mode` support. ## 3.2.1 (2022-07-22) diff --git a/README.md b/README.md index 7a022aa..fb81008 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,10 @@ You can also add the following to your Emacs config to enable ```emacs-lisp (add-hook 'clojure-mode-hook #'inf-clojure-minor-mode) + +;; or if you're a `clojure-ts-mode' user: + +(add-hook 'clojure-ts-mode-hook #'inf-clojure-minor-mode) ``` **Warning:** Don't enable `inf-clojure-minor-mode` and `cider-mode` at the same time. They @@ -217,6 +221,18 @@ If you want to update a specific form there is a function (inf-clojure-update-feature 'clojure 'completion "(incomplete.core/completions \"%s\")") ``` +### `clojure-ts-mode` support + +`inf-clojure` will try to use `clojure-ts-mode` by default if it's +available with fallback to `clojure-mode`. + +If you want to use `inf-clojure` with `clojure-mode` exclusively, you +can set it to: + +```emacs-lisp +(setopt inf-clojure-source-modes '(clojure-mode)) +``` + #### Caveats As `inf-clojure` is built on top of `comint` it has all the usual comint limitations - diff --git a/inf-clojure.el b/inf-clojure.el index 9efe1de..5634f9a 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -65,11 +65,13 @@ (require 'comint) (require 'clojure-mode) +(require 'clojure-ts-mode nil :no-error) (require 'eldoc) (require 'thingatpt) (require 'ansi-color) (require 'cl-lib) (require 'subr-x) +(require 'project) (defvar inf-clojure-startup-forms '((lein . "lein repl") (boot . "boot repl") @@ -193,10 +195,10 @@ either `setq-local` or an entry in `.dir-locals.el`." ) MULTIPLE PROCESS SUPPORT =========================================================================== To run multiple Clojure processes, you start the first up -with \\[inf-clojure]. It will be in a buffer named `*inf-clojure*'. +with \\[inf-clojure]. It will be in a buffer named *inf-clojure*. Rename this buffer with \\[rename-buffer]. You may now start up a new process with another \\[inf-clojure]. It will be in a new buffer, -named `*inf-clojure*'. You can switch between the different process +named *inf-clojure*. You can switch between the different process buffers with \\[switch-to-buffer]. Commands that send text from source buffers to Clojure processes -- @@ -205,7 +207,7 @@ process to send to, when you have more than one Clojure process around. This is determined by the global variable `inf-clojure-buffer'. Suppose you have three inferior Clojures running: Buffer Process - foo inf-clojure + foo `inf-clojure' bar inf-clojure<2> *inf-clojure* inf-clojure<3> If you do a \\[inf-clojure-eval-defun] command on some Clojure source code, @@ -269,7 +271,7 @@ has been found. See also variable `inf-clojure-buffer'." (error "No Clojure subprocess; see variable `inf-clojure-buffer'")))) (defun inf-clojure-repl-p (&optional buf) - "Indicates if BUF is an inf-clojure REPL. + "Indicates if BUF is an `inf-clojure' REPL. If BUF is nil then defaults to the current buffer. Checks the mode and that there is a live process." (let ((buf (or buf (current-buffer)))) @@ -278,7 +280,7 @@ Checks the mode and that there is a live process." (process-live-p (get-buffer-process buf))))) (defun inf-clojure-repls () - "Return a list of all inf-clojure REPL buffers." + "Return a list of all `inf-clojure' REPL buffers." (let (repl-buffers) (dolist (b (buffer-list)) (when (inf-clojure-repl-p b) @@ -286,27 +288,27 @@ Checks the mode and that there is a live process." repl-buffers)) (defun inf-clojure--prompt-repl-buffer (prompt) - "Prompt the user to select an inf-clojure repl buffer. + "Prompt the user to select an `inf-clojure' repl buffer. PROMPT is a string to prompt the user. Returns nil when no buffer is selected." (let ((repl-buffers (inf-clojure-repls))) (if (> (length repl-buffers) 0) - (when-let ((repl-buffer (completing-read prompt repl-buffers nil t))) + (when-let* ((repl-buffer (completing-read prompt repl-buffers nil t))) (get-buffer repl-buffer)) (user-error "No buffers have an inf-clojure process")))) (defun inf-clojure-set-repl (always-ask) - "Set an inf-clojure buffer as the active (default) REPL. + "Set an `inf-clojure' buffer as the active (default) REPL. If in a REPL buffer already, use that unless a prefix is used (or -ALWAYS-ASK). Otherwise get a list of all active inf-clojure +ALWAYS-ASK). Otherwise get a list of all active `inf-clojure' REPLS and offer a choice. It's recommended to rename REPL buffers after they are created with `rename-buffer'." (interactive "P") - (when-let ((new-repl-buffer - (if (or always-ask - (not (inf-clojure-repl-p))) - (inf-clojure--prompt-repl-buffer "Select default REPL: ") - (current-buffer)))) + (when-let* ((new-repl-buffer + (if (or always-ask + (not (inf-clojure-repl-p))) + (inf-clojure--prompt-repl-buffer "Select default REPL: ") + (current-buffer)))) (setq inf-clojure-buffer new-repl-buffer) (message "Current inf-clojure REPL set to %s" new-repl-buffer))) @@ -349,6 +351,14 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword \(as in :a, :c, etc.)" :type 'regexp) +(defcustom inf-clojure-source-modes '(clojure-ts-mode clojure-mode) + "Used to determine if a buffer contains Clojure source code. + +Any buffer with one of these major modes, it's considered a Clojure +source file by all `inf-clojure' commands." + :type '(repeat symbol) + :safe #'symbolp) + (defun inf-clojure--modeline-info () "Return modeline info for `inf-clojure-minor-mode'. Either \"no process\" or \"buffer-name(repl-type)\"" @@ -453,7 +463,7 @@ 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 +Customize this variable to change how `inf-clojure-minor-mode' displays its status in the mode line. The default value displays the current REPL. Set this variable to nil to disable the mode line entirely." @@ -609,24 +619,35 @@ This should usually be a combination of `inf-clojure-prompt' and :package-version '(inf-clojure . "2.0.0")) (defcustom inf-clojure-auto-mode t - "Automatically enable inf-clojure-minor-mode. + "Automatically enable `inf-clojure-minor-mode'. All buffers in `clojure-mode' will automatically be in `inf-clojure-minor-mode' unless set to nil." :type 'boolean :safe #'booleanp :package-version '(inf-clojure . "3.1.0")) +(defun inf-clojure--get-preferred-major-modes () + "Return list of preferred major modes that are actually available." + (cl-remove-if-not (lambda (mode) (featurep mode)) + inf-clojure-source-modes)) + +(defun inf-clojure--clojure-buffer-p () + "Return TRUE if the current buffer is a Clojure buffer." + (derived-mode-p (inf-clojure--get-preferred-major-modes))) + (defun inf-clojure--clojure-buffers () "Return a list of all existing `clojure-mode' buffers." - (cl-remove-if-not - (lambda (buffer) (with-current-buffer buffer (derived-mode-p 'clojure-mode))) - (buffer-list))) + (cl-remove-if-not (lambda (buffer) + (with-current-buffer buffer + (inf-clojure--clojure-buffer-p))) + (buffer-list))) (defun inf-clojure-enable-on-existing-clojure-buffers () "Enable inf-clojure's minor mode on existing Clojure buffers. See command `inf-clojure-minor-mode'." (interactive) - (add-hook 'clojure-mode-hook #'inf-clojure-minor-mode) + (dolist (mode (inf-clojure--get-preferred-major-modes)) + (add-hook (derived-mode-hook-name mode) #'inf-clojure-minor-mode)) (dolist (buffer (inf-clojure--clojure-buffers)) (with-current-buffer buffer (inf-clojure-minor-mode +1)))) @@ -688,6 +709,8 @@ If `comint-use-prompt-regexp' is nil (the default), \\[comint-insert-input] on (setq comint-input-sender 'inf-clojure--send-string) (setq comint-prompt-regexp inf-clojure-comint-prompt-regexp) (setq mode-line-process '(":%s")) + ;; NOTE: Using Tree-sitter based syntax highlighting in comint + ;; buffer is currently not possible. (clojure-mode-variables) (clojure-font-lock-setup) (when inf-clojure-enable-eldoc @@ -799,10 +822,24 @@ to suppress the usage of the target buffer discovery logic." The name is simply the final segment of the path." (file-name-nondirectory (directory-file-name dir))) +(defun inf-clojure--project-dir () + "Return current Clojure project root." + (let ((project-vc-extra-root-markers '("project.clj" ; Leiningen + "build.boot" ; Boot + "build.gradle" ; Gradle + "build.gradle.kts" ; Gradle + "deps.edn" ; Clojure CLI (a.k.a. tools.deps) + "shadow-cljs.edn" ; shadow-cljs + "bb.edn" ; babashka + "nbb.edn" ; nbb + "basilisp.edn" ; Basilisp (Python) + ))) + (project-root (project-current)))) + ;;;###autoload (defun inf-clojure (cmd &optional suppress-message) - "Run an inferior Clojure process, input and output via buffer `*inf-clojure*'. -If there is a process already running in `*inf-clojure*', just + "Run an inferior Clojure process, input and output via buffer *inf-clojure*. +If there is a process already running in *inf-clojure*, just switch to that buffer. CMD is a string which serves as the startup command or a cons of @@ -826,7 +863,7 @@ process buffer for a list of commands.)" (mapcar #'cdr inf-clojure-startup-forms) nil 'confirm-after-completion)))) - (let* ((project-dir (clojure-project-dir)) + (let* ((project-dir (inf-clojure--project-dir)) (process-buffer-name (or inf-clojure-custom-repl-name (if project-dir @@ -850,7 +887,9 @@ process buffer for a list of commands.)" (with-current-buffer (apply #'make-comint process-buffer-name (car cmdlist) nil (cdr cmdlist)) (inf-clojure-mode) - (set-syntax-table clojure-mode-syntax-table) + (set-syntax-table (pcase (car (inf-clojure--get-preferred-major-modes)) + ('clojure-ts-mode clojure-ts-mode-syntax-table) + (_ clojure-mode-syntax-table))) (setq-local inf-clojure-repl-type repl-type) (hack-dir-local-variables-non-file-buffer)))) ;; update the default comint buffer and switch to it @@ -940,7 +979,7 @@ defaults provided in `inf-clojure-socket-repl-startup-forms'." 'confirm-after-completion)))) (let* ((host "localhost") (port (or inf-clojure-socket-repl-port (+ 5500 (random 500)))) - (project-dir (clojure-project-dir)) + (project-dir (inf-clojure--project-dir)) (repl-type (or (unless prefix-arg inf-clojure-custom-repl-type) (car (rassoc cmd inf-clojure-socket-repl-startup-forms)) @@ -978,7 +1017,8 @@ of forms." (condition-case nil (with-temp-buffer (progn - (clojurec-mode) + ;; Activate preferred major mode. + (funcall (car (inf-clojure--get-preferred-major-modes))) (insert str) (whitespace-cleanup) (goto-char (point-min)) @@ -986,8 +1026,10 @@ of forms." (while (looking-at "\n") (delete-char 1)) (unless (eobp) - (clojure-forward-logical-sexp)) - (unless (eobp) + ;; NOTE: There is no special API for that in + ;; `clojure-ts-mode', so probably for now lets keep this + ;; `clojure-mode' function. + (clojure-forward-logical-sexp) (forward-char))) (buffer-substring-no-properties (point-min) (point-max)))) (scan-error str))) @@ -1105,13 +1147,6 @@ START and END are the beginning and end positions in the buffer to send." This holds a cons cell of the form `(DIRECTORY . FILE)' describing the last `inf-clojure-load-file' command.") -(defcustom inf-clojure-source-modes '(clojure-mode) - "Used to determine if a buffer contains Clojure source code. -If it's loaded into a buffer that is in one of these major modes, it's -considered a Clojure source file by `inf-clojure-load-file'. -Used by this command to determine defaults." - :type '(repeat symbol)) - (defun inf-clojure-load-file (&optional switch-to-repl file-name) "Load a Clojure file into the inferior Clojure process. @@ -1123,7 +1158,7 @@ is present it will be used instead of the current file." (file-name (or file-name (car (comint-get-source "Load Clojure file: " inf-clojure-prev-l/c-dir/file ;; nil because doesn't need an exact name - inf-clojure-source-modes nil)))) + (inf-clojure--get-preferred-major-modes) nil)))) (load-form (inf-clojure-get-feature proc 'load))) (comint-check-source file-name) ; Check to see if buffer needs saved. (setq inf-clojure-prev-l/c-dir/file (cons (file-name-directory file-name) @@ -1132,23 +1167,32 @@ is present it will be used instead of the current file." (when switch-to-repl (inf-clojure-switch-to-repl t)))) +(defun inf-clojure--find-ns () + "Return the namespace of the current Clojure buffer. + +This function delegates its job to an appropritate function, considering +`inf-clojure-source-modes'." + (pcase (car (inf-clojure--get-preferred-major-modes)) + ('clojure-ts-mode (clojure-ts-find-ns)) + (_ (clojure-find-ns)))) + (defun inf-clojure-reload (arg) "Send a query to the inferior Clojure for reloading the namespace. -See variable `inf-clojure-reload-form' and +See variable `inf-clojure-reload-form' and variable `inf-clojure-reload-all-form'. The prefix argument ARG can change the behavior of the command: - - C-u M-x `inf-clojure-reload': prompts for a namespace name. - - M-- M-x `inf-clojure-reload': executes (require ... :reload-all). - - M-- C-u M-x `inf-clojure-reload': reloads all AND prompts." + - \\`C-u' \\[inf-clojure-reload]: prompts for a namespace name. + - \\`M--' \\[inf-clojure-reload]: executes (require ... :reload-all). + - \\`M--' \\`C-u' \\[inf-clojure-reload]: reloads all AND prompts." (interactive "P") (let* ((proc (inf-clojure-proc)) (reload-all-p (or (equal arg '-) (equal arg '(-4)))) (prompt-p (or (equal arg '(4)) (equal arg '(-4)))) (ns (if prompt-p - (car (inf-clojure-symprompt "Namespace" (clojure-find-ns))) - (clojure-find-ns))) + (car (inf-clojure-symprompt "Namespace" (inf-clojure--find-ns))) + (inf-clojure--find-ns))) (form (if (not reload-all-p) (inf-clojure-reload-form proc) (inf-clojure-reload-all-form proc)))) @@ -1249,7 +1293,7 @@ STRING if present." (prin1-to-string (substring-no-properties string)))) nil (expand-file-name inf-clojure--log-file-name - (clojure-project-dir)) + (inf-clojure--project-dir)) 'append 'no-annoying-write-file-in-minibuffer))) @@ -1357,11 +1401,11 @@ for evaluation, therefore FORM should not include it." (defun inf-clojure-arglists (fn) "Send a query to the inferior Clojure for the arglists for function FN. See variable `inf-clojure-arglists-form'." - (when-let ((proc (inf-clojure-proc 'no-error))) - (when-let ((arglists-form (inf-clojure-get-feature proc 'arglists))) - (thread-first (format arglists-form fn) - (inf-clojure--process-response proc "(" ")") - (inf-clojure--some))))) + (when-let* ((proc (inf-clojure-proc 'no-error)) + (arglists-form (inf-clojure-get-feature proc 'arglists))) + (thread-first (format arglists-form fn) + (inf-clojure--process-response proc "(" ")") + (inf-clojure--some)))) (defun inf-clojure-show-arglists (prompt-for-symbol) "Show the arglists for function FN in the mini-buffer. @@ -1383,8 +1427,8 @@ prefix argument PROMPT-FOR-NS, it prompts for a namespace name." (interactive "P") (let* ((proc (inf-clojure-proc)) (ns (if prompt-for-ns - (car (inf-clojure-symprompt "Ns vars" (clojure-find-ns))) - (clojure-find-ns))) + (car (inf-clojure-symprompt "Ns vars" (inf-clojure--find-ns))) + (inf-clojure--find-ns))) (ns-vars-form (inf-clojure-get-feature proc 'ns-vars))) (inf-clojure--send-string proc (format ns-vars-form ns)))) @@ -1396,8 +1440,8 @@ PROMPT-FOR-NS, it prompts for a namespace name." (interactive "P") (let* ((proc (inf-clojure-proc)) (ns (if prompt-for-ns - (car (inf-clojure-symprompt "Set ns to" (clojure-find-ns))) - (clojure-find-ns))) + (car (inf-clojure-symprompt "Set ns to" (inf-clojure--find-ns))) + (inf-clojure--find-ns))) (set-ns-form (inf-clojure-get-feature proc 'set-ns))) (when (or (not ns) (equal ns "")) (user-error "No namespace selected")) From aff7407a7571c184a9f9c553498f0ce420ee35a5 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 11:44:10 +0300 Subject: [PATCH 39/61] Bump the copyright years --- README.md | 2 +- inf-clojure.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fb81008..8b0a969 100644 --- a/README.md +++ b/README.md @@ -495,7 +495,7 @@ This creates `.inf-clojure.log` in the project directory so that you can `tail - ## License -Copyright © 2014-2022 Bozhidar Batsov and [contributors][]. +Copyright © 2014-2025 Bozhidar Batsov and [contributors][]. Distributed under the GNU General Public License; type C-h C-c to view it. diff --git a/inf-clojure.el b/inf-clojure.el index 5634f9a..f0c7ea5 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1,6 +1,6 @@ ;;; inf-clojure.el --- Run an external Clojure process in an Emacs buffer -*- lexical-binding: t; -*- -;; Copyright © 2014-2022 Bozhidar Batsov +;; Copyright © 2014-2025 Bozhidar Batsov ;; Authors: Bozhidar Batsov ;; Olin Shivers From 9c06132cd31249d1078d8954e59cbfb9e1b562df Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 11:45:30 +0300 Subject: [PATCH 40/61] Bump the dev version --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index f0c7ea5..ebb3511 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -7,7 +7,7 @@ ;; Maintainer: Bozhidar Batsov ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure -;; Version: 3.2.1 +;; Version: 3.3.0-snapshot ;; Package-Requires: ((emacs "26.2") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. From 6833bb81fafeabb48a4f3ee5b89a5ae0bfb45889 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 11:48:19 +0300 Subject: [PATCH 41/61] Require Emacs 27 --- .circleci/config.yml | 9 --------- CHANGELOG.md | 3 ++- inf-clojure.el | 6 ++---- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d2a8cef..30583b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,14 +51,6 @@ commands: command: eldev -dtT compile --warnings-as-errors jobs: - test-ubuntu-emacs-26: - docker: - - image: silex/emacs:26-ci - entrypoint: bash - steps: - - setup - - test - test-ubuntu-emacs-27: docker: - image: silex/emacs:27-ci @@ -111,7 +103,6 @@ workflows: version: 2 ci-test-matrix: jobs: - - test-ubuntu-emacs-26 - test-ubuntu-emacs-27 - test-ubuntu-emacs-28 - test-ubuntu-emacs-master diff --git a/CHANGELOG.md b/CHANGELOG.md index e824df5..8149bd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ * [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands * [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting repl. * [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. -- [#217](https://github.com/clojure-emacs/inf-clojure/pull/217): Add `clojure-ts-mode` support. +* [#217](https://github.com/clojure-emacs/inf-clojure/pull/217): Add `clojure-ts-mode` support. +* Require Emacs 27. ## 3.2.1 (2022-07-22) diff --git a/inf-clojure.el b/inf-clojure.el index ebb3511..d70848c 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -8,7 +8,7 @@ ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure ;; Version: 3.3.0-snapshot -;; Package-Requires: ((emacs "26.2") (clojure-mode "5.11")) +;; Package-Requires: ((emacs "27") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. @@ -332,9 +332,7 @@ See http://blog.jorgenschaefer.de/2014/05/race-conditions-in-emacs-process-filte :link '(emacs-commentary-link :tag "Commentary" "inf-clojure")) (defconst inf-clojure-version - (or (if (fboundp 'package-get-version) - (package-get-version)) - "3.2.1") + (package-get-version) "The current version of `inf-clojure'.") (defcustom inf-clojure-prompt-read-only t From 6bf42957aa53cb68a355f48bab4166b085ae5cea Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 11:53:17 +0300 Subject: [PATCH 42/61] Tweak the README markup a bit --- README.md | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 8b0a969..91801df 100644 --- a/README.md +++ b/README.md @@ -40,18 +40,18 @@ It supports the following REPLs: `inf-clojure` provides a set of essential features for interactive Clojure/ClojureScript/ClojureCLR development: -* Enhanced REPL -* Interactive code evaluation -* Code completion -* Definition lookup -* Documentation lookup -* ElDoc -* Apropos -* Macroexpansion -* Reloading a namespace (via `require :reload`/`require :reload-all`) -* Connecting to socket REPLs - -For a more powerful/full-featured solution see [CIDER](https://github.com/clojure-emacs/cider). +- Enhanced REPL +- Interactive code evaluation +- Code completion +- Definition lookup +- Documentation lookup +- ElDoc +- Apropos +- Macroexpansion +- Reloading a namespace (via `require :reload`/`require :reload-all`) +- Connecting to socket REPLs + +For a more powerful/full-featured solution see [CIDER][]. ## Rationale @@ -156,7 +156,7 @@ configurable. You can set custom values to `inf-clojure` variables on a per-project basis using [directory variables](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html) -or by setting them in in your init file. +or by setting them in in your [init file][Emacs init file]. You can see all the configuration options available using the command `M-x customize-group RET inf-clojure`. @@ -245,7 +245,7 @@ If you decide _not_ to use the socket REPL, it is highly recommended you disable output coloring and/or `readline` facilities: `inf-clojure` does not filter out ASCII escape characters at the moment and will not behave correctly. -For Leiningen, there are no command-line switches and you need to add +For [Leiningen][], there are no command-line switches and you need to add a custom [`project.clj` option](https://github.com/technomancy/leiningen/blob/master/sample.project.clj): @@ -261,8 +261,8 @@ If you have the new [Clojure CLI tools][] installed you can use the `clojure` co _do not use `clj` because it adds readline support_ -``` shellsession -$ clojure -J-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}" +``` shell +clojure -J-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}" ``` Then either `C-c M-c RET localhost RET 5555` from within Emacs or add the following to your `.dir-locals.el`: @@ -270,6 +270,7 @@ Then either `C-c M-c RET localhost RET 5555` from within Emacs or add the follow ```emacs-lisp ((nil . ((inf-clojure-custom-startup . ("localhost" . 5555))))) ``` + #### Leiningen Socket REPL For Leiningen, add the following option to your `~/.lein/profiles.clj` or your `project.clj`: @@ -386,7 +387,6 @@ your cursor. One side effect of this is that it can mess with repl vars like `*1` and `*2`. You can disable inf-clojure's Eldoc functionality with `(setq inf-clojure-enable-eldoc nil)`. - ElDoc should be enabled by default in Emacs 26.1+. If it is not active by default, you can activate ElDoc with `M-x eldoc-mode` or by adding the following to you Emacs config: @@ -416,7 +416,6 @@ could alternatively use `compliment {:mvn/version "0.3.10"}`. ;; or ;; for compliment (inf-clojure-update-feature 'clojure 'completion "(compliment.core/completions \"%s\")") - ``` If you give a form for the completion form, it is your responsibility @@ -479,7 +478,7 @@ The explanation of this problem and solution can be found [here](https://groups. The solution is to create a file named `.jline.rc` in your `$HOME` directory and add this line to that file: -``` +```ini jline.terminal=unsupported ``` @@ -514,4 +513,3 @@ Distributed under the GNU General Public License; type C-h C-c to vie [melpa stable]: http://stable.melpa.org [Emacs init file]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html [Clojure cli tools]: https://clojure.org/guides/getting_started -[Boot]: http://boot-clj.com From 616c40f9e4c7d18e96ebbe303edca14e0e90a090 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 11:59:38 +0300 Subject: [PATCH 43/61] Drop support for Lumo It has been abandoned a few years ago. --- CHANGELOG.md | 12 +++++++++--- README.md | 29 +++++------------------------ inf-clojure.el | 24 ++---------------------- 3 files changed, 16 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8149bd2..52823a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,19 @@ ## master (unreleased) -* Improve support for multiple forms in the same line by replacing beginning-of-defun fn. +### New features + * [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. -* [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands -* [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting repl. * [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. * [#217](https://github.com/clojure-emacs/inf-clojure/pull/217): Add `clojure-ts-mode` support. + +### Changes + +* Improve support for multiple forms in the same line by replacing `beginning-of-defun` fn. +* [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands +* [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting REPL. * Require Emacs 27. +* Drop support for Lumo. ## 3.2.1 (2022-07-22) diff --git a/README.md b/README.md index 91801df..92fd6bd 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,6 @@ It supports the following REPLs: - ClojureScript - ClojureCLR (via [lein-clr](https://github.com/kumarshantanu/lein-clr)) - [Planck](http://planck-repl.org/) -- [Lumo](https://github.com/anmonteiro/lumo) - [Joker](https://joker-lang.org/) - [babashka](https://github.com/borkdude/babashka) @@ -181,7 +180,7 @@ There are two important configuration variables here: 1. `inf-clojure-custom-startup`: Which startup command to use so inf-clojure can run the inferior Clojure process (REPL). -2. `inf-clojure-custom-repl-type`: The type of the REPL started by the above command (e.g. `lumo`). +2. `inf-clojure-custom-repl-type`: The type of the REPL started by the above command (e.g. `planck`). If these are set and you wish to prevent inf-clojure from using them, use a prefix arg when invoking `inf-clojure` (`C-u M-x inf-clojure`). @@ -290,18 +289,6 @@ information on how connect: The socket server REPL configuration options are described [here](https://clojure.org/reference/repl_and_main#_launching_a_socket_server). -#### Lumo Socket REPL - -Lumo is decoupled from `inf-clojure-project-type` and therefore the command used depends on what you are using for dependency resolution. - -For example if a `project.clj` is present in the project root folder, `inf-clojure-lein-cmd` will be used. - -After you launch `lumo ... -n 5555`, as customary, either `C-c M-c RET localhost RET 5555` from within Emacs or add the following to your `.dir-locals.el`: - -```emacs-lisp -((nil (inf-clojure-custom-startup "localhost" . 5555))) -``` - #### Multiple Process Support To run multiple Clojure processes, you start the first up @@ -365,7 +352,7 @@ obtained from `inf-clojure-repl-features`: ```emacs-lisp (mapcar 'car inf-clojure-repl-features) -;; => (cljs lumo planck joker clojure babashka) +;; => (cljs planck joker clojure babashka) ``` What does it mean that a REPL type is supported? Well, it means that @@ -402,7 +389,7 @@ You can leave it enabled, it just won't show anything in the echo area. #### Code Completion Code completion is a tricky aspect if you are trying to be as close to -a generic REPL as possible. Planck and lumo REPL implementations +a generic REPL as possible. Some runtimes (e.g. Planck) explicitly provide completion functions in their REPL namespaces. For clojure, you will need to have a library on your classpath. If you are using a recent version of Leiningen, you already have @@ -434,7 +421,7 @@ once so that the completion machinery will work: `(require For more advanced customization, code completion is particularly open to customization. Not only you can `setq` the customary -`inf-clojure-completion-form`, `inf-clojure-completion-form-lumo`, +`inf-clojure-completion-form`, `inf-clojure-completion-form-planck` and `inf-clojure-completion-form-joker` - the form to send to the REPL - but you can also use `inf-clojure-completions-fn` for specifying a @@ -446,12 +433,6 @@ inf-clojure-completions-fn`. Another option is to have a look at [how cider does it](https://github.com/clojure-emacs/cider/blob/3e9ed12e8cfbad04d7618e649322765dc9bff5d6/cider-interaction.el#L595). -#### Lumo Setup - -For an optimal Lumo experience the `-d` needs to be passed to Lumo -when launched from the command line. This disable `readline` support -in order to play nicely with Emacs. - ## Troubleshooting ### Things seem broken @@ -459,7 +440,7 @@ in order to play nicely with Emacs. Inf-clojure is intentionally quite simple and just sends commands to a REPL on your behalf to provide features. In order to do this inf-clojure largely needs to know the REPL type so it can format the -correct calls. Most end up in `(lumo.repl/doc [symbol])` or +correct calls. Most end up in `(planck.repl/doc [symbol])` or `(cljs.repl/doc ...)` so its important that the REPL type is set correctly. This REPL type exists in the process buffer (REPL) and the source buffers as a cache. If you have problems, run `m-x diff --git a/inf-clojure.el b/inf-clojure.el index d70848c..3e81d9f 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -47,7 +47,6 @@ ;; * Apropos ;; * Macroexpansion ;; * Support connecting to socket REPLs -;; * Support for Lumo ;; * Support for Planck ;; * Support for Joker ;; @@ -80,7 +79,6 @@ (lein-clr . "lein clr repl") (planck . "planck -d") (babashka . "bb") - (lumo . "lumo -d") (joker . "joker"))) (defvar inf-clojure-repl-features @@ -92,23 +90,6 @@ (set-ns . "(in-ns '%s)") (macroexpand . "(cljs.core/macroexpand '%s)") (macroexpand-1 . "(cljs.core/macroexpand-1 '%s)"))) - (lumo . ((load . "(clojure.core/load-file \"%s\")") - (doc . "(lumo.repl/doc %s)") - (source . "(lumo.repl/source %s)") - (arglists . - "(let [old-value lumo.repl/*pprint-results*] - (set! lumo.repl/*pprint-results* false) - (js/setTimeout #(set! lumo.repl/*pprint-results* old-value) 0) - (lumo.repl/get-arglists \"%s\"))") - (apropos . "(lumo.repl/apropos \"%s\")") - (ns-vars . "(lumo.repl/dir %s)") - (set-ns . "(in-ns '%s)") - (macroexpand . "(macroexpand-1 '%s)") - (macroexpand-1 . "(macroexpand-1 '%s)") - (completion . - "(let [ret (atom nil)] - (lumo.repl/get-completions \"%s\" (fn [res] (reset! ret (map str res)))) - @ret)"))) (planck . ((load . "(load-file \"%s\")") (doc . "(planck.repl/doc %s)") (source . "(planck.repl/source %s)") @@ -242,7 +223,7 @@ If no-error is truthy don't error if feature is not present." (defun inf-clojure--update-feature (repl-type feature form) "Return a copy of the datastructure containing the repl features. -Given a REPL-TYPE (`clojure', `lumo', ...) and a FEATURE (`doc', +Given a REPL-TYPE (`clojure', `planck', ...) and a FEATURE (`doc', `apropos', ...) and a FORM this will return a new datastructure that can be set as `inf-clojure-repl-features'." (let ((original (alist-get repl-type inf-clojure-repl-features))) @@ -255,7 +236,7 @@ that can be set as `inf-clojure-repl-features'." (defun inf-clojure-update-feature (repl-type feature form) "Mutate the repl features to the new FORM. -Given a REPL-TYPE (`clojure', `lumo', ...) and a FEATURE (`doc', +Given a REPL-TYPE (`clojure', `planck', ...) and a FEATURE (`doc', `apropos', ...) and a FORM this will set `inf-clojure-repl-features' with these new values." (setq inf-clojure-repl-features (inf-clojure--update-feature repl-type feature form))) @@ -520,7 +501,6 @@ Should be a symbol that is a key in `inf-clojure-repl-features'." :package-version '(inf-clojure . "3.0.0") :type '(choice (const :tag "clojure" clojure) (const :tag "cljs" cljs) - (const :tag "lumo" lumo) (const :tag "planck" planck) (const :tag "joker" joker) (const :tag "babashka" babashka) From 53efc1aa6e03a594aad185adf11e533a11207e88 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 12:01:09 +0300 Subject: [PATCH 44/61] Update the required Emacs version in the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92fd6bd..3b91a80 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ the right code for each REPL type. ## Installation -**Note:** `inf-clojure` requires Emacs 25 or newer. +**Note:** `inf-clojure` requires Emacs 27 or newer. `inf-clojure` is available on the official [NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.html) `package.el` repo and on the community-maintained [MELPA Stable][] and [MELPA][] repos. From 4dc2b36223bb6d4063b9c2b6e56875af9c944061 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 12:07:36 +0300 Subject: [PATCH 45/61] Use real callouts --- README.md | 70 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3b91a80..4e729cb 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,13 @@ It's based on ideas from the popular `inferior-lisp` package. interaction minor mode (`inf-clojure-minor-mode`), which extends `clojure-mode` with commands to evaluate forms directly in the REPL. ------------ - -**This documentation tracks the `master` branch of `inf-clojure`. Some of -the features and settings discussed here might not be available in -older releases (including the current stable release). Please, consult -the relevant git tag (e.g. 2.2.0) if you need documentation for a -specific `inf-clojure` release.** -*** +> [!IMPORTANT] +> +> This documentation tracks the `master` branch of `inf-clojure`. Some of +> the features and settings discussed here might not be available in +> older releases (including the current stable release). Please, consult +> the relevant git tag (e.g. 2.2.0) if you need documentation for a +> specific `inf-clojure` release. ## Overview @@ -54,21 +53,31 @@ For a more powerful/full-featured solution see [CIDER][]. ## Rationale -`inf-clojure`'s goal is to provide the simplest possible way to interact with a Clojure REPL. -In Emacs terminology "inferior" process is a subprocess started by Emacs (it being the "superior" process, of course). +`inf-clojure`'s goal is to provide the simplest possible way to interact with a +Clojure REPL. In Emacs terminology "inferior" process is a subprocess started +by Emacs (it being the "superior" process, of course). -`inf-clojure` doesn't require much of setup, as at its core it simply runs a terminal REPL process, pipes input to it, and -processes its output. As the Clojure socket REPL works in exactly the same manner `inf-clojure` can also interact with it. +`inf-clojure` doesn't require much of setup, as at its core it simply runs a +terminal REPL process, pipes input to it, and processes its output. As the +Clojure socket REPL works in exactly the same manner `inf-clojure` can also +interact with it. -Functionality like code completion and eldoc is powered by evaluation of predefined code snippets that provide the necessary results. -As different Clojure REPLs have different capabilities, `inf-clojure` tracks the type of a REPL and invokes -the right code for each REPL type. +Functionality like code completion and eldoc is powered by evaluation of +predefined code snippets that provide the necessary results. As different +Clojure REPLs have different capabilities, `inf-clojure` tracks the type of a +REPL and invokes the right code for each REPL type. -`inf-clojure` is built on top of Emacs's [comint](https://github.com/emacs-mirror/emacs/blob/master/lisp/comint.el). Unfortunately `comint` is pretty light on official documentation, but there is a good overview/tutorial [here](https://www.masteringemacs.org/article/comint-writing-command-interpreter). +`inf-clojure` is built on top of Emacs's +[comint](https://github.com/emacs-mirror/emacs/blob/master/lisp/comint.el). Unfortunately +`comint` is pretty light on official documentation, but there is a good +overview/tutorial +[here](https://www.masteringemacs.org/article/comint-writing-command-interpreter). ## Installation -**Note:** `inf-clojure` requires Emacs 27 or newer. +> [!IMPORTANT] +> +> `inf-clojure` requires Emacs 27 or newer. `inf-clojure` is available on the official [NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.html) `package.el` repo and on the community-maintained [MELPA Stable][] and [MELPA][] repos. @@ -98,7 +107,8 @@ If the installation doesn't work try refreshing the package list: `nil`. You can also add the following to your Emacs config to enable -`inf-clojure-minor-mode` for Clojure source buffers, regardless of whether there's an `inf-clojure` REPL running: +`inf-clojure-minor-mode` for Clojure source buffers, regardless of whether +there's an `inf-clojure` REPL running: ```emacs-lisp (add-hook 'clojure-mode-hook #'inf-clojure-minor-mode) @@ -108,9 +118,11 @@ You can also add the following to your Emacs config to enable (add-hook 'clojure-ts-mode-hook #'inf-clojure-minor-mode) ``` -**Warning:** Don't enable `inf-clojure-minor-mode` and `cider-mode` at the same time. They -have overlapping functionality and keybindings and the result will be nothing -short of havoc. +> [!WARNING] +> +> Don't enable `inf-clojure-minor-mode` and `cider-mode` at the same time. They +> have overlapping functionality and keybindings and the result will be nothing +> short of havoc. ## Basic Usage @@ -147,8 +159,6 @@ for the symbol you want to show the docstring for. ## Configuration -**Note:** The configuration options were changed massively in `inf-clojure` 3.0. - In the time-honoured Emacs tradition `inf-clojure`'s behaviour is extremely configurable. @@ -173,8 +183,10 @@ that goes with it. This is most easily achieved with the following `.dir-locals. (inf-clojure-custom-repl-type . clojure))) ``` -**Note:** This file has to be in the directory in which you're invoking `inf-clojure` or a parent -directory. +> [!IMPORTANT] +> +> This file has to be in the directory in which you're invoking +> `inf-clojure` or a parent directory. There are two important configuration variables here: @@ -298,9 +310,11 @@ process with another `inf-clojure`. It will be in a new buffer, named `*inf-clojure*`. You can switch between the different process buffers with `switch-to-buffer`. -**Note:** If you're starting `inf-clojure` within a Clojure project directory -the name of the project will be incorporated into the name of the REPL buffer -- e.g. `*inf-clojure my-project*`. +> [!NOTE] +> +> If you're starting `inf-clojure` within a Clojure project directory +> the name of the project will be incorporated into the name of the REPL buffer +> - e.g. `*inf-clojure my-project*`. Commands that send text from source buffers to Clojure processes (like `inf-clojure-eval-defun` or `inf-clojure-show-arglists`) have to choose a process to send to, when you have more than From 847d7057f6e7e8077c718bdd11d20c9e60c60cd8 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 12:11:17 +0300 Subject: [PATCH 46/61] Tweak a warning --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e729cb..a937c08 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,9 @@ option](https://github.com/technomancy/leiningen/blob/master/sample.project.clj) If you have the new [Clojure CLI tools][] installed you can use the `clojure` command: -_do not use `clj` because it adds readline support_ +> [!IMPORTANT] +> +> Do not use `clj` because it adds readline support. ``` shell clojure -J-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}" From c103f2a5463001620c3c7489e3581aa0914c37db Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 12:12:06 +0300 Subject: [PATCH 47/61] m-x -> M-x --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a937c08..7c7a357 100644 --- a/README.md +++ b/README.md @@ -459,7 +459,7 @@ inf-clojure largely needs to know the REPL type so it can format the correct calls. Most end up in `(planck.repl/doc [symbol])` or `(cljs.repl/doc ...)` so its important that the REPL type is set correctly. This REPL type exists in the process buffer (REPL) and the -source buffers as a cache. If you have problems, run `m-x +source buffers as a cache. If you have problems, run `M-x inf-clojure-set-repl-type` from the source buffer to set the REPL type in both buffers. To see how simple inf-clojure is, look at `inf-clojure-repl-features` to see largely how things are laid out. From 0743744608c89fb1a0f0b8799a28e98b2b8c8a5f Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 12:27:39 +0300 Subject: [PATCH 48/61] More README improvements --- README.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7c7a357..6d6978e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![MELPA][melpa-badge]][melpa-package] [![MELPA Stable][melpa-stable-badge]][melpa-stable-package] [![NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.svg)](https://elpa.nongnu.org/nongnu/inf-clojure.html) -[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.com/invite/nFPpynQPME) [![License GPL 3][badge-license]][copying] # inf-clojure @@ -301,7 +300,8 @@ information on how connect: ((nil (inf-clojure-custom-startup "localhost" . 5555))) ``` -The socket server REPL configuration options are described [here](https://clojure.org/reference/repl_and_main#_launching_a_socket_server). +The socket server REPL configuration options are described +[here](https://clojure.org/reference/repl_and_main#_launching_a_socket_server). #### Multiple Process Support @@ -314,9 +314,9 @@ buffers with `switch-to-buffer`. > [!NOTE] > -> If you're starting `inf-clojure` within a Clojure project directory -> the name of the project will be incorporated into the name of the REPL buffer -> - e.g. `*inf-clojure my-project*`. +> If you're starting `inf-clojure` within a Clojure project directory the name +> of the project will be incorporated into the name of the REPL buffer - +> e.g. `*inf-clojure my-project*`. Commands that send text from source buffers to Clojure processes (like `inf-clojure-eval-defun` or `inf-clojure-show-arglists`) have to choose a process to send to, when you have more than @@ -355,10 +355,12 @@ 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. -**Tip:** 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>". +> [!TIP] +> +> 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 @@ -444,9 +446,10 @@ but you can also use `inf-clojure-completions-fn` for specifying a function that given the REPL response should return Elisp data compatible with [`completion-at-point-functions`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion-in-Buffers.html). + For more info run `M-x describe-variable RET inf-clojure-completions-fn`. Another option is to have a look at [how -cider does +CIDER does it](https://github.com/clojure-emacs/cider/blob/3e9ed12e8cfbad04d7618e649322765dc9bff5d6/cider-interaction.el#L595). ## Troubleshooting From 8735dcea9cfb4bd7c8b81bd7f52aef9853995f24 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 12:28:49 +0300 Subject: [PATCH 49/61] Tweak the changelog markup --- CHANGELOG.md | 134 +++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52823a2..3109832 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,142 +4,142 @@ ### New features -* [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. -* [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. -* [#217](https://github.com/clojure-emacs/inf-clojure/pull/217): Add `clojure-ts-mode` support. +- [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. +- [#210](https://github.com/clojure-emacs/inf-clojure/pull/210) Include `inf-clojure-socket-repl` to create a socket REPL and connect to it from inside Emacs. +- [#217](https://github.com/clojure-emacs/inf-clojure/pull/217): Add `clojure-ts-mode` support. ### Changes -* Improve support for multiple forms in the same line by replacing `beginning-of-defun` fn. -* [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands -* [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting REPL. -* Require Emacs 27. -* Drop support for Lumo. +- Improve support for multiple forms in the same line by replacing `beginning-of-defun` fn. +- [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands +- [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting REPL. +- Require Emacs 27. +- Drop support for Lumo. ## 3.2.1 (2022-07-22) ### Bugs fixed -* Address some small issues with NonGNU ELPA (e.g. missing maintainer metadata). +- Address some small issues with NonGNU ELPA (e.g. missing maintainer metadata). ## 3.2.0 (2022-07-15) ### New features -* [#168](https://github.com/clojure-emacs/inf-clojure/pull/197): New helper function `inf-clojure-switch-to-recent-buffer` to select the last buffer an inf-clojure process buffer was swapped to from. -* [#187](https://github.com/clojure-emacs/inf-clojure/pull/197): New defcustom `inf-clojure-enable-eldoc` to disable eldoc interaction. +- [#168](https://github.com/clojure-emacs/inf-clojure/pull/197): New helper function `inf-clojure-switch-to-recent-buffer` to select the last buffer an inf-clojure process buffer was swapped to from. +- [#187](https://github.com/clojure-emacs/inf-clojure/pull/197): New defcustom `inf-clojure-enable-eldoc` to disable eldoc interaction. ### Bugs fixed -* [#185](https://github.com/clojure-emacs/inf-clojure/issues/185): Improve cmd string splitting. -* [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in REPL buffer. -* Fix `inf-clojure-display-version` (it wasn't extracting properly the package version). +- [#185](https://github.com/clojure-emacs/inf-clojure/issues/185): Improve cmd string splitting. +- [#193](https://github.com/clojure-emacs/inf-clojure/pull/193): Set syntax table in REPL buffer. +- Fix `inf-clojure-display-version` (it wasn't extracting properly the package version). ## 3.1.0 (2021-07-23) ### New features -* [#190](https://github.com/clojure-emacs/inf-clojure/pull/190): Helper function `inf-clojure-set-repl` to select inf-clojure process buffer. -* Auto-enable `inf-clojure-minor-mode` after invoking `inf-clojure`. This behaviour is controlled via `inf-clojure-auto-mode`. -* Include the project name automatically in the REPL buffer name. +- [#190](https://github.com/clojure-emacs/inf-clojure/pull/190): Helper function `inf-clojure-set-repl` to select inf-clojure process buffer. +- Auto-enable `inf-clojure-minor-mode` after invoking `inf-clojure`. This behaviour is controlled via `inf-clojure-auto-mode`. +- Include the project name automatically in the REPL buffer name. ### Bugs fixed -* [#152](https://github.com/clojure-emacs/inf-clojure/issues/152): Sanitize should only remove whitespace at the end of a command. -* [#188](https://github.com/clojure-emacs/inf-clojure/pull/188): Handle newlines between forms for `inf-clojure-eval-buffer`. -* [#189](https://github.com/clojure-emacs/inf-clojure/pull/189): Font-lock code inserted in the REPL from a source buffer. +- [#152](https://github.com/clojure-emacs/inf-clojure/issues/152): Sanitize should only remove whitespace at the end of a command. +- [#188](https://github.com/clojure-emacs/inf-clojure/pull/188): Handle newlines between forms for `inf-clojure-eval-buffer`. +- [#189](https://github.com/clojure-emacs/inf-clojure/pull/189): Font-lock code inserted in the REPL from a source buffer. ## 3.0.0 (2020-08-01) ### New features -* [#174](https://github.com/clojure-emacs/inf-clojure/pull/174): Invoke `inf-clojure` with a prefix argument to prevent using `inf-clojure-custom-startup` and `inf-clojure-custom-repl-type`. -* Made it possible to add user-defined REPL types (by modifying `inf-clojure-repl-features`). +- [#174](https://github.com/clojure-emacs/inf-clojure/pull/174): Invoke `inf-clojure` with a prefix argument to prevent using `inf-clojure-custom-startup` and `inf-clojure-custom-repl-type`. +- Made it possible to add user-defined REPL types (by modifying `inf-clojure-repl-features`). ### Changes -* **(Breaking)** Restructure massively the configuration. See `inf-clojure-repl-features` for details. -* [#174](https://github.com/clojure-emacs/inf-clojure/pull/174): Set REPL type from startup form or prompt at startup, introduce `inf-clojure-custom-repl-type` defcustom. -* [#173](https://github.com/clojure-emacs/inf-clojure/issues/173): Use clojure-mode's project detection instead of duplicate version in inf-clojure. +- **(Breaking)*- Restructure massively the configuration. See `inf-clojure-repl-features` for details. +- [#174](https://github.com/clojure-emacs/inf-clojure/pull/174): Set REPL type from startup form or prompt at startup, introduce `inf-clojure-custom-repl-type` defcustom. +- [#173](https://github.com/clojure-emacs/inf-clojure/issues/173): Use clojure-mode's project detection instead of duplicate version in inf-clojure. ### Bugs fixed -* [#178](https://github.com/clojure-emacs/inf-clojure/issues/178): Ensure a valid directory is used when starting process. +- [#178](https://github.com/clojure-emacs/inf-clojure/issues/178): Ensure a valid directory is used when starting process. ## 2.2.0 (2020-04-15) ### New features -* [#170](https://github.com/clojure-emacs/inf-clojure/pull/170): Add insert defun and last sexp commands. -* [#160](https://github.com/clojure-emacs/inf-clojure/pull/160): Support [Joker](https://joker-lang.org/). +- [#170](https://github.com/clojure-emacs/inf-clojure/pull/170): Add insert defun and last sexp commands. +- [#160](https://github.com/clojure-emacs/inf-clojure/pull/160): Support [Joker](https://joker-lang.org/). ### Bugs fixed -* [#164](https://github.com/clojure-emacs/inf-clojure/pull/164): Fix for eldoc-mode on ClojureCLR. -* [#135](https://github.com/clojure-emacs/inf-clojure/pull/135): Improve command sanitation code. -* Fix `info-clojure-apropos`. +- [#164](https://github.com/clojure-emacs/inf-clojure/pull/164): Fix for eldoc-mode on ClojureCLR. +- [#135](https://github.com/clojure-emacs/inf-clojure/pull/135): Improve command sanitation code. +- Fix `info-clojure-apropos`. ## 2.1.0 (2018-01-02) ### New Features -* [#114](https://github.com/clojure-emacs/inf-clojure/pull/114): Introduce `inf-clojure-project-type` defcustom. -* [#117](https://github.com/clojure-emacs/inf-clojure/pull/117): Introduce `tools.deps` project type and `inf-clojure-tools-deps-cmd`. -* [#122](https://github.com/clojure-emacs/inf-clojure/pull/122): Introduce `inf-clojure-completions-fn` defcustom. -* [#128](https://github.com/clojure-emacs/inf-clojure/pull/128): Expose `inf-clojure-apropos` as `C-c C-S-a` in `inf-clojure-mode` (the REPL). -* [#125](https://github.com/clojure-emacs/inf-clojure/pull/125): Avoid throwing an error for frequent operations like completion. -* [#130](https://github.com/clojure-emacs/inf-clojure/pull/130): Support loading directory locals in our buffers. -* [#129](https://github.com/clojure-emacs/inf-clojure/pull/129): Improve the completion bounds detection (now with keywords). -* [#132](https://github.com/clojure-emacs/inf-clojure/pull/132): Introduce inf-clojure-reload. +- [#114](https://github.com/clojure-emacs/inf-clojure/pull/114): Introduce `inf-clojure-project-type` defcustom. +- [#117](https://github.com/clojure-emacs/inf-clojure/pull/117): Introduce `tools.deps` project type and `inf-clojure-tools-deps-cmd`. +- [#122](https://github.com/clojure-emacs/inf-clojure/pull/122): Introduce `inf-clojure-completions-fn` defcustom. +- [#128](https://github.com/clojure-emacs/inf-clojure/pull/128): Expose `inf-clojure-apropos` as `C-c C-S-a` in `inf-clojure-mode` (the REPL). +- [#125](https://github.com/clojure-emacs/inf-clojure/pull/125): Avoid throwing an error for frequent operations like completion. +- [#130](https://github.com/clojure-emacs/inf-clojure/pull/130): Support loading directory locals in our buffers. +- [#129](https://github.com/clojure-emacs/inf-clojure/pull/129): Improve the completion bounds detection (now with keywords). +- [#132](https://github.com/clojure-emacs/inf-clojure/pull/132): Introduce inf-clojure-reload. ### Bugs Fixed -* [#79](https://github.com/clojure-emacs/inf-clojure/pull/82): Eldoc error when running boot repl. -* [#83](https://github.com/clojure-emacs/inf-clojure/pull/85): No such namespace: complete.core in lumo REPL. -* [#93](https://github.com/clojure-emacs/inf-clojure/pull/93): Slow response from inf-clojure (completions, arglists, ...). -* [#101](https://github.com/clojure-emacs/inf-clojure/pull/101): `inf-clojure-set-ns` hangs Emacs. -* [#119](https://github.com/clojure-emacs/inf-clojure/pull/119): Set inf-clojure-buffer REPL type on detect. -* [#120](https://github.com/clojure-emacs/inf-clojure/pull/120): Send REPL string always, even if empty. -* [#128](https://github.com/clojure-emacs/inf-clojure/pull/128): Fix inf-clojure-apropos. -* [#131](https://github.com/clojure-emacs/inf-clojure/pull/131): Add macroexpand forms for Lumo. +- [#79](https://github.com/clojure-emacs/inf-clojure/pull/82): Eldoc error when running boot repl. +- [#83](https://github.com/clojure-emacs/inf-clojure/pull/85): No such namespace: complete.core in lumo REPL. +- [#93](https://github.com/clojure-emacs/inf-clojure/pull/93): Slow response from inf-clojure (completions, arglists, ...). +- [#101](https://github.com/clojure-emacs/inf-clojure/pull/101): `inf-clojure-set-ns` hangs Emacs. +- [#119](https://github.com/clojure-emacs/inf-clojure/pull/119): Set inf-clojure-buffer REPL type on detect. +- [#120](https://github.com/clojure-emacs/inf-clojure/pull/120): Send REPL string always, even if empty. +- [#128](https://github.com/clojure-emacs/inf-clojure/pull/128): Fix inf-clojure-apropos. +- [#131](https://github.com/clojure-emacs/inf-clojure/pull/131): Add macroexpand forms for Lumo. ## 2.0.1 (2017-05-18) ### Bugs Fixed -* [#77](https://github.com/clojure-emacs/inf-clojure/pull/77): Fix request "Eval expression:" if arglists return is `nil`. +- [#77](https://github.com/clojure-emacs/inf-clojure/pull/77): Fix request "Eval expression:" if arglists return is `nil`. ## 2.0.0 (2017-05-01) ### New Features -* [#63](https://github.com/clojure-emacs/inf-clojure/pull/69): Fix spurious process output on init. -* [#57](https://github.com/clojure-emacs/inf-clojure/pull/68): Add `inf-clojure-connect`. -* [#66](https://github.com/clojure-emacs/inf-clojure/pull/56): Add Planck support. -* [#51](https://github.com/clojure-emacs/inf-clojure/pull/51): Commands do not prompt by default anymore, unless they receive a non-nil prefix argument. -* [#44](https://github.com/clojure-emacs/inf-clojure/pull/44): Add REPL types and Lumo support. -* [#50](https://github.com/clojure-emacs/inf-clojure/pull/50): Rename defcustoms to `inf-clojure-*-form` where appropriate. -* [#34](https://github.com/clojure-emacs/inf-clojure/pull/34): Add support for socket REPL connections. -* New interactive command `inf-clojure-display-version`. -* [#42](https://github.com/clojure-emacs/inf-clojure/issues/42): Add a defcustom controlling the window in which the REPL buffer is displayed (`inf-clojure-repl-use-same-window`). -* Font-lock the code in the REPL. -* Handle properly ANSI color escape sequences in the REPL. -* [#41](https://github.com/clojure-emacs/inf-clojure/issues/41): Add a command to quit the REPL (it's bound to `C-c C-q`). -* [#29](https://github.com/clojure-emacs/inf-clojure/issues/29): Add a command to restart the REPL. -* [#31](https://github.com/clojure-emacs/inf-clojure/issues/31): Invoke different init command based on the project type (boot, lein or generic). +- [#63](https://github.com/clojure-emacs/inf-clojure/pull/69): Fix spurious process output on init. +- [#57](https://github.com/clojure-emacs/inf-clojure/pull/68): Add `inf-clojure-connect`. +- [#66](https://github.com/clojure-emacs/inf-clojure/pull/56): Add Planck support. +- [#51](https://github.com/clojure-emacs/inf-clojure/pull/51): Commands do not prompt by default anymore, unless they receive a non-nil prefix argument. +- [#44](https://github.com/clojure-emacs/inf-clojure/pull/44): Add REPL types and Lumo support. +- [#50](https://github.com/clojure-emacs/inf-clojure/pull/50): Rename defcustoms to `inf-clojure-*-form` where appropriate. +- [#34](https://github.com/clojure-emacs/inf-clojure/pull/34): Add support for socket REPL connections. +- New interactive command `inf-clojure-display-version`. +- [#42](https://github.com/clojure-emacs/inf-clojure/issues/42): Add a defcustom controlling the window in which the REPL buffer is displayed (`inf-clojure-repl-use-same-window`). +- Font-lock the code in the REPL. +- Handle properly ANSI color escape sequences in the REPL. +- [#41](https://github.com/clojure-emacs/inf-clojure/issues/41): Add a command to quit the REPL (it's bound to `C-c C-q`). +- [#29](https://github.com/clojure-emacs/inf-clojure/issues/29): Add a command to restart the REPL. +- [#31](https://github.com/clojure-emacs/inf-clojure/issues/31): Invoke different init command based on the project type (boot, lein or generic). ### Changes -* Display the REPL in a different window by default (it used to be displayed in the current window). -* [#26](https://github.com/clojure-emacs/inf-clojure/issues/26): Make switching to the REPL optional on `inf-clojure-load-file` (it's now controlled via a prefix argument). -* Removed the `inf-clojure` alias `run-clojure`. +- Display the REPL in a different window by default (it used to be displayed in the current window). +- [#26](https://github.com/clojure-emacs/inf-clojure/issues/26): Make switching to the REPL optional on `inf-clojure-load-file` (it's now controlled via a prefix argument). +- Removed the `inf-clojure` alias `run-clojure`. ### Bugs Fixed -* [#35](https://github.com/clojure-emacs/inf-clojure/issues/35): Fix prompt being included in input history. +- [#35](https://github.com/clojure-emacs/inf-clojure/issues/35): Fix prompt being included in input history. ## 1.4.0 (2016-01-17) ### New Features -* [#22](https://github.com/clojure-emacs/inf-clojure/pull/22): Add ElDoc support. +- [#22](https://github.com/clojure-emacs/inf-clojure/pull/22): Add ElDoc support. From 782bcd9ec89533d7a78dc087e42cc5f27bb5e70b Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 13:01:08 +0300 Subject: [PATCH 50/61] Add Emacs 29 and 30 to the CI matrix --- .circleci/config.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 30583b1..6527b13 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -67,6 +67,22 @@ jobs: - setup - test + test-ubuntu-emacs-29: + docker: + - image: silex/emacs:29-ci + entrypoint: bash + steps: + - setup + - test + + test-ubuntu-emacs-30: + docker: + - image: silex/emacs:30-ci + entrypoint: bash + steps: + - setup + - test + test-ubuntu-emacs-master: docker: - image: silex/emacs:master-ci @@ -94,7 +110,7 @@ jobs: test-lint: docker: - - image: silex/emacs:28-ci + - image: silex/emacs:30-ci steps: - setup - lint @@ -105,6 +121,8 @@ workflows: jobs: - test-ubuntu-emacs-27 - test-ubuntu-emacs-28 + - test-ubuntu-emacs-29 + - test-ubuntu-emacs-30 - test-ubuntu-emacs-master - test-lint - test-macos-emacs-latest From d285b62ecb74e47f7422e72754a5500f4ad86f7d Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:05:53 +0300 Subject: [PATCH 51/61] Address a couple of lint issues --- inf-clojure.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 3e81d9f..cd77498 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1,4 +1,4 @@ -;;; inf-clojure.el --- Run an external Clojure process in an Emacs buffer -*- lexical-binding: t; -*- +;;; inf-clojure.el --- Basic interaction with a Clojure REPL -*- lexical-binding: t; -*- ;; Copyright © 2014-2025 Bozhidar Batsov @@ -8,7 +8,7 @@ ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure ;; Version: 3.3.0-snapshot -;; Package-Requires: ((emacs "27") (clojure-mode "5.11")) +;; Package-Requires: ((emacs "27.1") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. From 1b817dca59c763e96162b1d7d9b87f5108a1975f Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:10:51 +0300 Subject: [PATCH 52/61] Tweak the name of a variable --- inf-clojure.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index cd77498..d29e5bd 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1120,7 +1120,7 @@ START and END are the beginning and end positions in the buffer to send." (interactive) (inf-clojure-eval-defun t)) -(defvar inf-clojure-prev-l/c-dir/file nil +(defvar inf-clojure-prev-loaded-dir-and-file nil "Record last directory and file used in loading or compiling. This holds a cons cell of the form `(DIRECTORY . FILE)' describing the last `inf-clojure-load-file' command.") @@ -1134,12 +1134,12 @@ is present it will be used instead of the current file." (interactive "P") (let* ((proc (inf-clojure-proc)) (file-name (or file-name - (car (comint-get-source "Load Clojure file: " inf-clojure-prev-l/c-dir/file + (car (comint-get-source "Load Clojure file: " inf-clojure-prev-loaded-dir-and-file ;; nil because doesn't need an exact name (inf-clojure--get-preferred-major-modes) nil)))) (load-form (inf-clojure-get-feature proc 'load))) (comint-check-source file-name) ; Check to see if buffer needs saved. - (setq inf-clojure-prev-l/c-dir/file (cons (file-name-directory file-name) + (setq inf-clojure-prev-loaded-dir-and-file (cons (file-name-directory file-name) (file-name-nondirectory file-name))) (inf-clojure--send-string proc (format load-form file-name)) (when switch-to-repl From ac073957ababe266863d66e1b9dd9ada4629e3cd Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:15:48 +0300 Subject: [PATCH 53/61] Address a couple of byte-compilation issues --- inf-clojure.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inf-clojure.el b/inf-clojure.el index d29e5bd..56bf0ec 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -814,6 +814,8 @@ The name is simply the final segment of the path." ))) (project-root (project-current)))) +(defvar clojure-ts-mode-syntax-table) + ;;;###autoload (defun inf-clojure (cmd &optional suppress-message) "Run an inferior Clojure process, input and output via buffer *inf-clojure*. @@ -1145,6 +1147,8 @@ is present it will be used instead of the current file." (when switch-to-repl (inf-clojure-switch-to-repl t)))) +(declare-function clojure-ts-find-ns "clojure-ts-mode") + (defun inf-clojure--find-ns () "Return the namespace of the current Clojure buffer. From 43c436f93da45cdf487ed6bee243006884d8845d Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:19:33 +0300 Subject: [PATCH 54/61] Remove duplicated [] characters from a regexp --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 56bf0ec..c275108 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1504,7 +1504,7 @@ evaluating \\[inf-clojure-completion-form] at the REPL." (funcall inf-clojure-completions-fn (inf-clojure--process-response completion-expr proc "(" ")")))))) -(defconst inf-clojure-clojure-expr-break-chars "^[] \"'`><,;|&{()[@\\^]" +(defconst inf-clojure-clojure-expr-break-chars "^[] \"'`><,;|&{()@\\^" "Regexp are hard. This regex has been built in order to match the first of the From fd9a8fe3bae6e2a64244f8f1ca866bc56447a625 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:23:08 +0300 Subject: [PATCH 55/61] Remove boot project detection Boot is dead. --- inf-clojure.el | 1 - 1 file changed, 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index c275108..d2e56c2 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -803,7 +803,6 @@ The name is simply the final segment of the path." (defun inf-clojure--project-dir () "Return current Clojure project root." (let ((project-vc-extra-root-markers '("project.clj" ; Leiningen - "build.boot" ; Boot "build.gradle" ; Gradle "build.gradle.kts" ; Gradle "deps.edn" ; Clojure CLI (a.k.a. tools.deps) From 89d8874a19c84e3a737a3f3696bfad540b74f117 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:24:52 +0300 Subject: [PATCH 56/61] Revert "Remove duplicated [] characters from a regexp" The previous change resulted in some other lint error. Regular expressions are hard! This reverts commit 43c436f93da45cdf487ed6bee243006884d8845d. --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index d2e56c2..83f640c 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1503,7 +1503,7 @@ evaluating \\[inf-clojure-completion-form] at the REPL." (funcall inf-clojure-completions-fn (inf-clojure--process-response completion-expr proc "(" ")")))))) -(defconst inf-clojure-clojure-expr-break-chars "^[] \"'`><,;|&{()@\\^" +(defconst inf-clojure-clojure-expr-break-chars "^[] \"'`><,;|&{()[@\\^]" "Regexp are hard. This regex has been built in order to match the first of the From b6268430a357b34a10fe9412df507bed77e28fa4 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 16:26:58 +0300 Subject: [PATCH 57/61] Tweak a docstring --- inf-clojure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inf-clojure.el b/inf-clojure.el index 83f640c..77336a2 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -824,7 +824,7 @@ switch to that buffer. CMD is a string which serves as the startup command or a cons of host and port. - Prompts user for repl startup command and repl type if not + Prompts user for REPL startup command and REPL type if not inferrable from startup command. Uses `inf-clojure-custom-repl-type' and `inf-clojure-custom-startup' if those are set. Use a prefix to prevent using these when they From c86e4a1947707818795d99eabbb5af9549c9960f Mon Sep 17 00:00:00 2001 From: Roman Rudakov Date: Sun, 25 May 2025 17:14:45 +0200 Subject: [PATCH 58/61] Fix CI failures --- .circleci/config.yml | 9 --------- inf-clojure.el | 18 +++++++++++------- test/inf-clojure-tests.el | 5 ++--- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6527b13..f03a87f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,14 +51,6 @@ commands: command: eldev -dtT compile --warnings-as-errors jobs: - test-ubuntu-emacs-27: - docker: - - image: silex/emacs:27-ci - entrypoint: bash - steps: - - setup - - test - test-ubuntu-emacs-28: docker: - image: silex/emacs:28-ci @@ -119,7 +111,6 @@ workflows: version: 2 ci-test-matrix: jobs: - - test-ubuntu-emacs-27 - test-ubuntu-emacs-28 - test-ubuntu-emacs-29 - test-ubuntu-emacs-30 diff --git a/inf-clojure.el b/inf-clojure.el index 77336a2..9122371 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -8,7 +8,7 @@ ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure ;; Version: 3.3.0-snapshot -;; Package-Requires: ((emacs "27.1") (clojure-mode "5.11")) +;; Package-Requires: ((emacs "28.1") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. @@ -1004,12 +1004,16 @@ of forms." (while (not (eobp)) (while (looking-at "\n") (delete-char 1)) + ;; NOTE: There is no special API for that in + ;; `clojure-ts-mode', so probably for now lets keep this + ;; `clojure-mode' function. (unless (eobp) - ;; NOTE: There is no special API for that in - ;; `clojure-ts-mode', so probably for now lets keep this - ;; `clojure-mode' function. - (clojure-forward-logical-sexp) - (forward-char))) + (clojure-forward-logical-sexp)) + (unless (eobp) + (forward-char) + ;; Remove an empty line at the end of the buffer. + (when (eobp) + (delete-char -1)))) (buffer-substring-no-properties (point-min) (point-max)))) (scan-error str))) @@ -1503,7 +1507,7 @@ evaluating \\[inf-clojure-completion-form] at the REPL." (funcall inf-clojure-completions-fn (inf-clojure--process-response completion-expr proc "(" ")")))))) -(defconst inf-clojure-clojure-expr-break-chars "^[] \"'`><,;|&{()[@\\^]" +(defconst inf-clojure-clojure-expr-break-chars "^][ \"'`><,;|&{()@\\^" "Regexp are hard. This regex has been built in order to match the first of the diff --git a/test/inf-clojure-tests.el b/test/inf-clojure-tests.el index 6023338..af6dea9 100644 --- a/test/inf-clojure-tests.el +++ b/test/inf-clojure-tests.el @@ -88,9 +88,8 @@ (ict-with-assess-buffers ((a (insert "@"))) (with-current-buffer a - (expect - (ict-bounds-string (inf-clojure-completion-bounds-of-expr-at-point)) - :not :to-be nil)))) + (expect (inf-clojure-completion-bounds-of-expr-at-point) + :to-be nil)))) (it "computes bounds for [symbol" (ict-with-assess-buffers From 7f5dd9cf897b6612d72b1f8daba49579b9b3488f Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 23:52:19 +0300 Subject: [PATCH 59/61] Tweak docstrings --- inf-clojure.el | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/inf-clojure.el b/inf-clojure.el index 9122371..610f7c5 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -1508,21 +1508,12 @@ evaluating \\[inf-clojure-completion-form] at the REPL." (inf-clojure--process-response completion-expr proc "(" ")")))))) (defconst inf-clojure-clojure-expr-break-chars "^][ \"'`><,;|&{()@\\^" - "Regexp are hard. + "A list of characters that serve as expression boundaries. -This regex has been built in order to match the first of the -listed chars. There are a couple of quirks to consider: - -- the ] is always a special in elisp regex so you have to put it - directly AFTER [ if you want to match it as literal. -- The ^ needs to be escaped with \\^. - -Tests and `re-builder' are your friends.") +See `inf-clojure-completion-bounds-of-expr-at-point'.") (defun inf-clojure--kw-to-symbol (kw) - "Convert the keyword KW to a symbol. - -This guy was taken from CIDER, thanks folks." + "Convert the keyword KW to a symbol." (when kw (replace-regexp-in-string "\\`:+" "" kw))) From bdef6110a3d051c08179503207eadc43b1dd4d09 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 23:54:00 +0300 Subject: [PATCH 60/61] Release 3.3 --- CHANGELOG.md | 2 ++ README.md | 2 +- inf-clojure.el | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3109832..d483b14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +## 3.3.0 (2025-05-25) + ### New features - [#202](https://github.com/clojure-emacs/inf-clojure/issues/202): Add ClojureCLR support. diff --git a/README.md b/README.md index 6d6978e..c6322c5 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ overview/tutorial > [!IMPORTANT] > -> `inf-clojure` requires Emacs 27 or newer. +> `inf-clojure` requires Emacs 28 or newer. `inf-clojure` is available on the official [NonGNU ELPA](https://elpa.nongnu.org/nongnu/inf-clojure.html) `package.el` repo and on the community-maintained [MELPA Stable][] and [MELPA][] repos. diff --git a/inf-clojure.el b/inf-clojure.el index 610f7c5..37f91ed 100644 --- a/inf-clojure.el +++ b/inf-clojure.el @@ -7,7 +7,7 @@ ;; Maintainer: Bozhidar Batsov ;; URL: http://github.com/clojure-emacs/inf-clojure ;; Keywords: processes, comint, clojure -;; Version: 3.3.0-snapshot +;; Version: 3.3.0 ;; Package-Requires: ((emacs "28.1") (clojure-mode "5.11")) ;; This file is not part of GNU Emacs. From 5decdb89d261247dec01879e763cec0d6b7d04f4 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Sun, 25 May 2025 23:55:32 +0300 Subject: [PATCH 61/61] Update changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d483b14..f3c3e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - Improve support for multiple forms in the same line by replacing `beginning-of-defun` fn. - [#204](https://github.com/clojure-emacs/inf-clojure/issues/204): Scroll repl buffer on insert commands - [#208](https://github.com/clojure-emacs/inf-clojure/pull/208) Display message after setting REPL. -- Require Emacs 27. +- Require Emacs 28. - Drop support for Lumo. ## 3.2.1 (2022-07-22) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy