Skip to content

Set REPL type from startup form, prompt, or defcustom at startup #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## master (unreleased)

### New features

* [#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
* [#174](https://github.com/clojure-emacs/inf-clojure/pull/174): Prefix on `inf-clojure` to prevent using `inf-clojure-custom-startup` and `inf-clojure-custom-repl-type.

## 2.2.0 (2020-04-15)

### New features
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,27 @@ for the symbol you want to show the docstring for.

## Configuration

## Most Common Configuration

Most likely you will want to set the startup command and the repl
type. This is most easily set with the follow dir-locals

```emacs-lisp
((nil
(inf-clojure-custom-startup . "clojure -A:compliment")
(inf-clojure-custom-repl-type . clojure)))
```

There are two important commands here:
1. `inf-clojure-custom-startup`: Which startup command to use so
inf-clojure can run the inferior process and
2. `inf-clojure-custom-repl-type`: Which repl type it is so
inf-clojure knows how to format commands to the repl

If these are set and you wish to prevent inf-clojure from using them,
use a prefix arg when invoking `inf-clojure`.

### All 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
Expand Down
90 changes: 41 additions & 49 deletions inf-clojure.el
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,6 @@
(require 'subr-x)
(require 'seq)

(defvar inf-clojure-recognize-alist '((lumo . "lumo.repl")
(planck . "planck.repl")
;; cljs goes after the selfhosts
(cljs . "cljs.repl")
(joker . "joker.repl")
(babashka . "babashka.classpath")
(clojure . "clojure.core.server")))

(defvar inf-clojure-startup-forms '((lein . "lein repl")
(boot . "boot repl")
(clojure . "clojure")
Expand Down Expand Up @@ -217,37 +209,13 @@ either `setq-local` or an entry in `.dir-locals.el`." )
"Global lock for protecting against proc filter race conditions.
See http://blog.jorgenschaefer.de/2014/05/race-conditions-in-emacs-process-filter.html")

(defun inf-clojure--detect-repl-type (proc)
"Identifies the current REPL type for PROC."
(when (not inf-clojure--repl-type-lock)
(let ((inf-clojure--repl-type-lock t))
(or (seq-some (lambda (r)
(when (inf-clojure--some-response-p
proc (format "(find-ns '%s)" (cdr r)))
(car r)))
inf-clojure-recognize-alist)
'clojure))))

(defun inf-clojure-set-repl-type ()
(defun inf-clojure--prompt-repl-type ()
"Set the REPL type to one of the available implementations."
(interactive)
(let* ((proc (inf-clojure-proc))
(types (mapcar #'car inf-clojure-repl-features))
(type-to-set (intern
(completing-read "Set REPL type:"
(sort (mapcar #'symbol-name types) #'string-lessp)))))
(with-current-buffer (process-buffer proc)
(setq-local inf-clojure-repl-type type-to-set))))

(defun inf-clojure--set-repl-type (proc)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Farewell, it has served as well-ish 😁

"Set the REPL type if has not already been set.
It requires a REPL PROC for inspecting the correct type."
;; todo: don't like this happening so frequently
(with-current-buffer (process-buffer proc)
(if (not inf-clojure-repl-type)
(let ((repl-type (inf-clojure--detect-repl-type proc)))
(setq-local inf-clojure-repl-type repl-type))
inf-clojure-repl-type)))
(let ((types (mapcar #'car inf-clojure-repl-features)))
(intern
(completing-read "Set REPL type:"
(sort (mapcar #'symbol-name types) #'string-lessp)))))

(defgroup inf-clojure nil
"Run an external Clojure process (REPL) in an Emacs buffer."
Expand Down Expand Up @@ -390,6 +358,19 @@ 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\".")

(defcustom inf-clojure-custom-repl-type
nil
"REPL type to use for inf-clojure process buffer.
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)
(const :tag "determine at startup" nil)))

(defun inf-clojure--whole-comment-line-p (string)
"Return non-nil iff STRING is a whole line semicolon comment."
(string-match-p "^\s*;" string))
Expand Down Expand Up @@ -424,7 +405,6 @@ always be preferred over `comint-send-string`. It delegates to
`comint-simple-send` so it always appends a newline at the end of
the string for evaluation. Refer to `comint-simple-send` for
customizations."
(inf-clojure--set-repl-type proc)
(let ((sanitized (inf-clojure--sanitize-command string)))
(inf-clojure--log-string sanitized "----CMD->")
(comint-send-string proc sanitized)))
Expand All @@ -449,7 +429,6 @@ Clojure to load that file."
"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."
(inf-clojure--set-repl-type proc)
inf-clojure-reload-form)

(defcustom inf-clojure-reload-all-form "(require '%s :reload-all)"
Expand All @@ -468,7 +447,6 @@ Clojure to load that file."
"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."
(inf-clojure--set-repl-type proc)
inf-clojure-reload-all-form)

(defcustom inf-clojure-prompt "^[^=> \n]+=> *"
Expand Down Expand Up @@ -681,14 +659,23 @@ to suppress the usage of the target buffer discovery logic."
;;;###autoload
(defun inf-clojure (cmd)
"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.
With argument, allows you to edit the CMD used to launch
it (default is value of `inf-clojure-*-cmd'). 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.)"
(interactive (list (or inf-clojure-custom-startup
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
host and port.

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
are set.

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.)"
(interactive (list (or (unless current-prefix-arg
inf-clojure-custom-startup)
(completing-read "Select Clojure REPL startup command: "
(mapcar #'cdr inf-clojure-startup-forms)
nil
Expand All @@ -698,11 +685,16 @@ run).
(let ((default-directory (inf-clojure-project-root))
(cmdlist (if (consp cmd)
(list cmd)
(split-string cmd))))
(split-string cmd)))
(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)
(with-current-buffer (apply #'make-comint
"inf-clojure" (car cmdlist) nil (cdr cmdlist))
(inf-clojure-mode)
(setq-local inf-clojure-repl-type repl-type)
(hack-dir-local-variables-non-file-buffer))))
(setq inf-clojure-buffer "*inf-clojure*")
(if inf-clojure-repl-use-same-window
Expand Down
18 changes: 10 additions & 8 deletions todo.org
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
* Core

** TODO set repl type on connection not first command
** DONE set repl type on connection not first command
For some reason ~inf-clojure--set-repl-type~ is called in:
1. inf-clojure--send-string
2. inf-clojure-reload-form
Expand All @@ -11,13 +11,6 @@ Seems better to do this on the two different connection methods and then be done
** DONE do we need repl type in both source buffer and connection?
these can get out of sync and lead to confusing errors when closing a repl and opening a new one. It seems like we keep the repl-type in the source buffer to prevent a single ~(with-current-buffer (process-buffer proc) inf-clojure-repl-type)~

** TODO nice startup
There's some project detection but that's becoming less and less useful as time goes on. Shadow, lein, deps.edn can all easily be mixed in the same project. And then lumo, planck, or bb scripts could live side by side. Rather than trying to guess the project type, I think i'd like to mimic geiser's style of handling multiple scheme backends. Perhaps ~m-x inf-clojure-run-planck~ and similar could help out.

Some considerations:
- is this path aware? IE, don't show an option to run planck, lumo, etc, if they aren't visible or installed?
- should it have a rebuild function so that user registered implementations can show up in the ~m-x~ menu as well?

** DONE Better dispatch for the implementations
Right now the functions are kinda clunky cond statements:
#+BEGIN_SRC emacs-lisp
Expand Down Expand Up @@ -65,6 +58,9 @@ The source primitive is quite nice but we most likely need a way to navigate to

** TODO PREPL
Be nice to implement this now that we have parseedn in elisp to understand edn.

** DONE inhibit custom repl-type and startup form
its nice to have these in dir-locals to just start up. but if you normally have ~clojure -m cljs.main -r~ as the startup command but you want to crank up a clj repl there's no way without removing those dir locals.
* Nice-to-haves
** TODO Put repl type in modeline
Rather than just ~*inf-clojure*~ we could put the repl type. Make it easy to follow and makes it easy to see when it gets it wrong.
Expand All @@ -81,3 +77,9 @@ Seems a bit heavy handed but its working for me so far.

** TODO is disabling color still required?
in the readme it mentions that color should be turned off. in my usage I haven't run into this problem at all. perhaps no longer true?
** TODO nice startup
There's some project detection but that's becoming less and less useful as time goes on. Shadow, lein, deps.edn can all easily be mixed in the same project. And then lumo, planck, or bb scripts could live side by side. Rather than trying to guess the project type, I think i'd like to mimic geiser's style of handling multiple scheme backends. Perhaps ~m-x inf-clojure-run-planck~ and similar could help out.

Some considerations:
- is this path aware? IE, don't show an option to run planck, lumo, etc, if they aren't visible or installed?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imho to keep it simple not to have path inspection is a good start.

- should it have a rebuild function so that user registered implementations can show up in the ~m-x~ menu as well?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go for the classic defcustom as list approach and maybe a register function like lsp imho yes

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