Skip to content
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

Add cider-reload-ns and cider-ns-reload-all interactive command #2314

Merged
merged 1 commit into from
Aug 2, 2018

Conversation

arichiardi
Copy link
Contributor

@arichiardi arichiardi commented Jun 8, 2018

In order to send (require 'ns :reload/:reload-all) more easily.


Before submitting the PR make sure the following things have been done (and denote this
by checking the relevant checkboxes):

  • The commits are consistent with our [contribution guidelines][1]

  • You've updated the [changelog][3] (if adding/changing user-visible functionality)

  • You've updated the [user manual][4] (if adding/changing user-visible functionality)

@vspinu
Copy link
Contributor

vspinu commented Jun 8, 2018

I think cider-eval-ns-form could do this instead of adding a new command.

@arichiardi
Copy link
Contributor Author

I would be fine with this, however however this command can also ask if you want to reload something explicitly. Very handy when you don't need to evaluate the whole ns form but only part of it.

We could add this as well to cider-eval-ns-form actually...so...well I am open to both approaches.

(defun cider-reload (arg)
"Send a require :reload/:reload-all to the REPL.

The prefix argument ARG can change the behavior of the command:
Copy link
Member

Choose a reason for hiding this comment

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

I'd be useful to explain here why would users want to prefer this over cider-refresh.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adressed

@arichiardi
Copy link
Contributor Author

@bbatsov what is you opinion on using cider-eval-ns-form for this?

@bbatsov
Copy link
Member

bbatsov commented Jun 10, 2018

I'm fine with this idea.

@arichiardi arichiardi force-pushed the require-reload branch 2 times, most recently from da2c2fc to 6890f13 Compare June 12, 2018 23:42

The prefix argument ARG can change the behavior of the command:

- (4) \\[cider-reload]: prompts for a namespace name.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there is a better way to show this, without havin a C-u embedded in docstring warning, I am eager to know.

Copy link
Member

Choose a reason for hiding this comment

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

There must be - as I can't understand your notation at all. :D

Seems to me that probably 3 prefix arguments are a bit too much. Perhaps you don't really need to be able to operate on other namespaces and you could just have one prefix arg for reload-all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually maybe you are right and we should tune it for the most common cases - say I am working on ns A and I need to change it B:

Flow 1)

  • open ns B
  • modify
  • save
  • reload the I am in - B

Flow 2)

  • open B
  • modify
  • save
  • go to A
  • reload all in A

The ability of inputting a namespace stems from the fact that I am not a master of reload-all sometimes and I need to reload ad hoc a namespace that threw an error (was still stale), handy because I do need to open its buffer.

@arichiardi arichiardi force-pushed the require-reload branch 2 times, most recently from d0e8642 to ee87cb0 Compare June 13, 2018 00:12
cider-mode.el Outdated
@@ -273,6 +273,8 @@ Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for yo
["Clear latest output" cider-find-and-clear-repl-output]
["Clear all output" (cider-find-and-clear-repl-output t)
:keys "\\[universal-argument] \\[cider-find-and-clear-repl-output]"]
["Require and reload ns" (cider-reload t)
:keys "\\[universal-argument] \\[cider-reload]"]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also need some advice on this one.

:reload forces loading of all the identified libs even if they are already
loaded
:reload-all implies :reload and also forces loading of all libs that the
identified libs directly or indirectly load via require [...]"
Copy link
Member

Choose a reason for hiding this comment

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

This should definitely be mentioned, though - https://github.com/clojure/tools.namespace#reloading-code-motivation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean mention tools.namespace as alternative to reload?

cider-mode.el Outdated
@@ -273,6 +273,8 @@ Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for yo
["Clear latest output" cider-find-and-clear-repl-output]
["Clear all output" (cider-find-and-clear-repl-output t)
:keys "\\[universal-argument] \\[cider-find-and-clear-repl-output]"]
["Require and reload ns" (cider-reload t)
Copy link
Member

Choose a reason for hiding this comment

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

Why did you put this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I saw the other pattern, should it go somewhere else? Or take it away completely?

Copy link
Member

Choose a reason for hiding this comment

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

I meant that the local of this is kind of arbitrary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I don't really get what this should be instead, can you dumb it down a bit 😄

Copy link
Member

Choose a reason for hiding this comment

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

Local -> location. I meant that it should be somewhere around cider-refresh.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh ok cool I will move it there no problem

@vspinu
Copy link
Contributor

vspinu commented Jun 18, 2018

BTW, I think cider-reload is not specific enough. It might be confused with cider-restart which does very different things.

@arichiardi
Copy link
Contributor Author

Clojure "reload" users should know the difference between the two I guess. There is not key binding for it at the moment so if you opt in probably you know the difference?

@bbatsov
Copy link
Member

bbatsov commented Jun 21, 2018

Both of you make valid points - the current names can probably be improved, although generally most people should know what to do. Naming is hard! Maybe cider-reload-ns/buffer might be a better name. I don't have any great ideas right now.

@arichiardi
Copy link
Contributor Author

arichiardi commented Jul 1, 2018

@bbatsov where should this go now? cider-eval.el? It is eval-ing something... cider-refresh.el?

@bbatsov
Copy link
Member

bbatsov commented Jul 1, 2018

I think it can go to cider-common.el if we plan to use this from repls, or to cider-mode.el otherwise.

@arichiardi
Copy link
Contributor Author

arichiardi commented Jul 1, 2018

Ok cool, yes it is a repl command, actually not unless there is way to find the current namespace at the repl..probably there is

@arichiardi
Copy link
Contributor Author

@bbatsov @vspinu I was thinking, what if the reload I have can be selected with a defcustom?

There are cases also when the cider-refresh would not work, one could be the absence of the middleware, the other is ClojureScript. Folks might want to disable it completely and use the (require ... :reload) instead.

@arichiardi
Copy link
Contributor Author

Well no, the functions have different arguments, completely different.

@arichiardi arichiardi force-pushed the require-reload branch 2 times, most recently from f26efb5 to 3f6a45e Compare July 1, 2018 16:50
@arichiardi arichiardi changed the title Add cider-reload interactive command Add cider-reload-ns interactive command Jul 1, 2018
cider-mode.el Outdated
@@ -416,6 +418,7 @@ If invoked with a prefix ARG eval the expression after inserting it."
(declare-function cider-toggle-trace-ns "cider-tracing")
(declare-function cider-toggle-trace-var "cider-tracing")
(declare-function cider-refresh "cider-refresh")
(declare-function cider-reload-ns "cider-reload-ns")
Copy link
Member

Choose a reason for hiding this comment

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

That's not exactly correct. ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh got it

cider-refresh.el Outdated
@@ -141,6 +171,37 @@ Its behavior is controlled by `cider-save-files-on-cider-refresh'."
(file-truename default-directory)
(eq system-type 'windows-nt))))))))

;;;###autoload
(defun cider-reload-ns (&optional arg)
Copy link
Member

Choose a reason for hiding this comment

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

Reload is different from refresh, so I wouldn't keep in the same source file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uhm why not? the two actually do the same thing. cider-refresh does it a bit better because of clojure.tools.namespace. I put the explanation in the commentary and it is evident from there that the end result is the same. That is why I opted for putting in here. If you feel very strong about moving, of course we will move it, please pick a file ;)

Copy link
Contributor

Choose a reason for hiding this comment

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

To be frank I am still not very clear about the difference. From the commentary which you added looks like refresh is uniformly better, right? Then why to bother with ns level reload? Does it have specific advantages besides small improvements in speed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is not speed the advantage, it is not using tools.namespace for something simple which is provided by Clojure natively. No middleware involved - less potential breakage

Copy link
Member

Choose a reason for hiding this comment

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

@arichiardi Noticed that everything in this file is about cider-refresh. Notice also that every function here has the cider-refresh prefix. cider-reload-ns simply looks out of place here. That's why I suggest cider-common.el or just putting this in cider-mode.el if you don't envision it to be used from the REPL much.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh ok yes that makes sense, unless we call it cider-refresh-native-reload

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or cider-refresh-require-reload

Copy link
Member

Choose a reason for hiding this comment

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

I actually have a better idea finally. We rename cider-refresh.el to cider-ns.el and we put there cider-refresh as cider-ns-refresh and cider-reload-ns, as cider-ns-reload. This will also make it a natural home for things like cider-ns-eval and cider-ns-cleanup, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh I like this will do it

@arichiardi arichiardi force-pushed the require-reload branch 3 times, most recently from 9036792 to 316da57 Compare July 1, 2018 21:59
cider-refresh.el Outdated
;; http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
;;
;; Note that refresh with clojure.tools.namespace.repl is a smarter way to
;; reload code.
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, here you mean that refresh is "smarter" compared to "traditional reload" which you describe below? Wouldn't it be clearer to first describe "traditional reload" and then list all those features below as "improvements" of the refresh and not "problems" of reload?

I think this is a good write up and could be even placed in the manual.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can do that - however I am not writing this myself but it is in the README of tools.namespace that Bohzidar linked. So kudos to the original writer.

cider-refresh.el Outdated
(form (concat "(require '%s " (if (not reload-all-p)
":reload)"
":reload-all)"))))
(cider-interactive-eval (format form ns))))
Copy link
Member

Choose a reason for hiding this comment

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

Btw, with the default handler users won't really get any specific feedback the ns being reloaded. They'll just see some form got evaluated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uhm that is not good, there should be at least the spinner going. Which handler would you recommend?

Copy link
Member

Choose a reason for hiding this comment

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

Leave this for now. I'll think of some more versatile handler later. Basically we just need something like the current handler that should be aware if it was invoked in a REPL and then print its out there.

bbatsov added a commit that referenced this pull request Jul 10, 2018
See #2314 for the rationale
behind this change. Basically we plan to put several ns manipulation
commands together in the same module.
@arichiardi
Copy link
Contributor Author

Oh ok didn't notice that you've already renamed. I will need to do a cleanup and rebase.

@bbatsov
Copy link
Member

bbatsov commented Jul 23, 2018

👍

@arichiardi arichiardi changed the title Add cider-reload-ns interactive command Add cider-reload-ns and cider-ns-reload-all interactive command Aug 1, 2018
@arichiardi
Copy link
Contributor Author

Revisited this, splitting in two commands and assigning them to C-c M-n l and C-c M-n M-l respectively.

cider-ns.el Outdated
(ns (if prompt-p
(string-remove-prefix "'" (read-from-minibuffer "Namespace: " (clojure-find-ns)))
(clojure-find-ns)))
(form (concat "(require '%s :reload)")))
Copy link
Member

Choose a reason for hiding this comment

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

What's this concat here for? :-) I think you could have used format here directly to add the ns instead of doing it a line done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep sorry will fix that, leftover from the previous impl

cider-ns.el Outdated
(ns (if prompt-p
(string-remove-prefix "'" (read-from-minibuffer "Namespace: " (clojure-find-ns)))
(clojure-find-ns)))
(form (concat "(require '%s :reload-all)")))
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

cider-ns.el Outdated
(defun cider-ns-reload (&optional arg)
"Send a (require current-ns :reload) to the REPL.

With the universal prefix ARG, prompts for a namespace name and then
Copy link
Contributor

Choose a reason for hiding this comment

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

"and then" what? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lol thanks, again did some poor job in splitting the original fn + comment yesterday

cider-ns.el Outdated
on org.clojure/tools.namespace. See Commentary of this file for a longer
list of differences. From the Clojure doc:

:reload forces loading of all the identified libs even if they are
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to avoid empty lines in the docs unless strictly necessary? Here you could simple quote like this: From the Clojure doc ":reload forces ...".

cider-ns.el Outdated
:reload forces loading of all the identified libs even if they are
already loaded"
(interactive "P")
(let* ((prompt-p (or (equal arg '(4)) (equal arg '(-4))))
Copy link
Contributor

Choose a reason for hiding this comment

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

arg has no other function right? So you could name your argument prompt-p directly. Alos -p prefix is reserved for functions (predicates). We use prompt and do-prompt elsewhere.

Copy link
Member

Choose a reason for hiding this comment

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

Good catch. I guess this is a leftover from the original implementation that had a different behavior for single and double prefix argument. I really dislike double prefix args, so I asked @arichiardi to split this in two commands.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool will do

;; Smart code refresh functionality based on ideas from:
;; http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
;;
;; Note that refresh with clojure.tools.namespace.repl is a smarter way to
Copy link
Contributor

Choose a reason for hiding this comment

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

Smarter compared to what? Now that this file contains loads of other ns functionality this comment should be more explicit regarding what it refers to.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

merged with the following line down there

cider-ns.el Outdated
(defun cider-ns-reload-all (&optional arg)
"Send a (require current-ns :reload-all) to the REPL.

With the universal prefix ARG, prompts for a namespace name and then
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

@vspinu
Copy link
Contributor

vspinu commented Aug 2, 2018

Are you sure about the keys? Usually base keys like l and M-l serve for the same command. In my experience when two similar commands are hooked on similar keys it's very easy to confuse them. But maybe it's not a problem in this case because one is a super-set of the other, right?

An alternative would be to have one command proposing *all* option along other namespaces when used with the prefix argument. *all* could be the default such that C-u C-c l RET would get us the :reload-all.

@bbatsov
Copy link
Member

bbatsov commented Aug 2, 2018

I think it's fine in this this case, although probably we can have M-l and l for reload and M-a and a for reload-all. I also comtemplated on whether to comment on this in light of how most of CIDER behaves, but I think l and M-l would be ok as well, as nothing really bad can come out from mixing those up.

@arichiardi
Copy link
Contributor Author

Btw why do we reserve two keys per command? In this case it felt better to change the pattern a bit but I am open to any solution you guys find better

The C-c M-n l has been assigned to cider-ns-reload while C-c M-n M-l has been
assigned to cider-ns-reload-all.
@bbatsov
Copy link
Member

bbatsov commented Aug 2, 2018

Common Emacs convention, as some people (like me) prefer not to lift their finger holding down some modifier key, and some don't. :-)

@arichiardi
Copy link
Contributor Author

Oh got it, I think now understand better your comment above about the behavior and yes, the worst you observe if you :reload-all instead of :reload is that it takes more time. Of course this method is not really optimal (that is why the tools.namespace method exists) so most of the times I personally do not rely on the exactness of it.

@bbatsov bbatsov merged commit 623a669 into clojure-emacs:master Aug 2, 2018
@arichiardi arichiardi deleted the require-reload branch August 3, 2018 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants