syl20bnr / spacemacs

A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!
http://spacemacs.org
GNU General Public License v3.0
23.66k stars 4.89k forks source link

[Clojure] Add Cider connect and Session management keybindings to layer #12593

Closed practicalli-johnny closed 4 years ago

practicalli-johnny commented 5 years ago

We now have more cider-connect-* commands and recent session management commands via sesman that do not have keybindings in the Clojure layer.

Please suggest keybindings you would like to see, with respect to the mnemonic approach used by Spacemacs.

From docs.cider.mx we have the following connection commands available

C-c C-x c j to call cider-connect-clj C-c C-x c s to call cider-connect-cljs C-c C-x c m to call cider-connect-clj&cljs

Add new REPLs to the current session with

C-c C-x s j cider-connect-sibling-clj C-c C-x s s cider-connect-sibling-cljs

Session life-cycle management commands live on the Sesman map (C-c C-s)

C-c C-s s sesman-start C-c C-s r sesman-restart C-c C-s q sesman-quit

Discussion forked from the abandoned PR #12061

yuhan0 commented 5 years ago

Here are the sesman related bindings from my local config, never quite got around to making a PR:

+            "sI" 'sesman-info
+            "slb" 'sesman-link-with-buffer
+            "sld" 'sesman-link-with-directory
+            "slp" 'sesman-link-with-project
+            "slu" 'sesman-unlink
+            "sm" 'sesman-browser
+            "sQ" 'sesman-quit
+            "sS" 'sesman-start
-            "sX" 'cider-restart
+            "sX" 'sesman-restart

Rationale: sesman-start, -quit and -restart commands are like more general variants of the cider-* ones, hence the uppercase. E.g. for jacking-in / connecting / siblings I usually go for sesman-start and interactively choose from the dropdown, rather than memorize 8 different bindings. sesman-link-* commands are also very useful for evaluating forms in external libraries.

On a related note, why was the "f" in "sjf" chosen for cider-jack-in-clj&cljs? Cider defaults use "m" which seems equally arbitrary.

practicalli-johnny commented 5 years ago

@yuhan0 thanks, this keybindings are very useful for our discussions. I will add some and take them for a test drive myself this week

s j f was chosen as the mnemonic (s)cider (j)jack-in (f)fullstack - as fullstack is a fairly common term for combining front end (ClojureScript) and backend (Clojure). Although I appreciate that you can also do ClojureScript on the backend with node.js.

yuhan0 commented 5 years ago

I'd propose changing cider-jack-in-clj to sjj and using the mnemonic "c" for "common", by analogy with the file extensions:

.clj -> j .cljs -> s .cljc -> c

The corresponding cider-connect-* bindings would then be scj, scs and scc

practicalli-johnny commented 5 years ago

I would like to get more feedback on these keybindings before proceeding to make any change.

There also seems to be a few bugs with sesman, so I suggest postponing any change for a month or so whilst the maintainers carry out more bug fixing in CIDER (which is the focus of the next release)

practicalli-johnny commented 4 years ago

Reviewing the keybindings for the Clojure layer, it seems the keybindings in the ms menu are a mixture of repl connection management and using/sending code to the current repl buffer. There are no Spacemacs keybindings for session management

This looks like a big change, but its mostly additive in terms of keybindings

Proposal: [x] Add keybindings for sesman commands into "ms" menu, adding "msl" [x] Use sesman-start (wrapper around all jack-in and connect commands) [x] Refactor "mc" keybinding to "mRc" to clear the repl buffer and "mc" is now sub-menu for connect functions [x] Rename "ms" menu from "repl" to "repl connections" [x] Migrate keybindings from "ms" relating to using/sending code to REPL, to "mR" menu

13140 pull request will allow you to try out these changes for yourself.

Sesman repl session management

use ms for repl session management using sesman. This greatly simplifies the menu as sesman-start prompts you for the type of repl you want

Updates to Clojure major mode menu

      ("msc" . "connect to repl")     ;; new - added all connection types
      ("mR" . "use repl")                 ;; migrate using repl keybindings here
      ("msj" . "jack-in")                   ;; unchange
      ("ms" . "repl connections")    ;; renamed menu, adding sesman keybindings
      ("msl" . "sesman link")          ;; new - linking sessions with sesman
      ("mss" . "sibling sessions")   ;; adding a sibling session with sesman 

Working with the repl buffer

move the keybindings related to using a particular repl from "ms" to a new mR menu

The new "mR" menu would contain

"Rc" 'cider-repl-clear-buffer
"RC" 'cider-find-and-clear-repl-output
"Re" 'spacemacs/cider-send-last-sexp-to-repl
"RE" 'spacemacs/cider-send-last-sexp-to-repl-focus
"Rf" 'spacemacs/cider-send-function-to-repl
"RF" 'spacemacs/cider-send-function-to-repl-focus
"Rn" 'spacemacs/cider-send-ns-form-to-repl
"RN" 'spacemacs/cider-send-ns-form-to-repl-focus
"Ro" 'cider-repl-switch-to-other
"Rr" 'spacemacs/cider-send-region-to-repl
"RR" 'spacemacs/cider-send-region-to-repl-focus
"Rs" (if (eq m 'cider-repl-mode)
         'cider-switch-to-last-clojure-buffer
       'cider-switch-to-repl-buffer)
"Ru" 'cider-repl-require-repl-utils

Replacements

Keybindings replaced elsewhere

;; cider-eval-buffer is a more meaningful alias for cider-load-buffer function,
;; relocated to evaluate menu
"sb" 'cider-load-buffer
"sB" 'spacemacs/cider-send-buffer-in-repl-and-focus 

;; replaced "rc" 'cider-repl-clear-buffer and "rC" 'cider-find-and-clear-repl-output
;; and "sc" 
"sc" (if (eq m 'cider-repl-mode)
              'cider-repl-clear-buffer
            'cider-connect)

Removals sesman-start is a wrapper for both of these functions, they are still available under "sj" menu

"\"" 'cider-jack-in-cljs
"\&" 'cider-jack-in-clj&cljs
didibus commented 4 years ago

Hum... arguably, I need to manage repl connections way less then I want to clear repl buffer, find repl buffer, switch to repl namespace, etc.

So I find the move of these to uppercase R a bit of a downside.

I'll have to try it out. But that's my first instinctive reaction

practicalli-johnny commented 4 years ago

@didibus do you find benefit in having a separate REPL buffer open, rather than evaluating the code in the source buffer as you are working with it. It always felt strange to me (and a lot more keybindings) to jump back and forth between code and REPL buffers, just to see what the code does. Especially when you can do it all in the one source code buffer (leaving more desktop space for tests and other namespaces to be shown).

If its the capital leter in "mR" that is the issue then we could bump the refactor keybindings to "mR" and have the 'using the repl' keybindings under "mr". I dropped clj-refactor a while ago (its now optional in develop clojure layer) as clj-refactor and sayid have caused lots of issues over the last year or so. All the refactor commands can be done in Evil, so do not seem like prominent keybindings.

Other lower-case top level bindings available include, "ma", "mb", "mc", "mi" (would parallel "si" for cider-jack-in), "mj", "mk" (use for refactor to parallel lisp state keybiding), "ml", "mm", "mn", "mo", "mq", "mu", "mv", "mw", "mx" (meta-x), "my" and "mz".

Or move all the sesman and cider connection functions to "mc" and have the 'using REPL' functions under "ms" (but that doesn't fit mnemonically as repl starts with r - the argument that s stands for CIDER phonetically doest hold water, as the whole menu is about 95% CIDER and we cant have everything under "ms")

Another option would be to merge the cider-send-* functions into the evaluation menu, after all that is what you are doing with them. The send functions only add updating the REPL buffer . I guess its tricky as we have 3 almost identical functions for evaluation (cider-eval-*, cider-send-* and cider-send-*-focus that are then duplicated based on context (buffer, current top level function, last expression). If you did merge the cider-send-* functions into "me", then there are only "Rs" and "Ro" to put back under "ms" somewhere.

We could drop all the cider-send-*-to-repl-focus and use SPC u in front of all the cider-send-* functions to focus the repl. That would remove a lot of duplication. Are both versions used regularly?

Then we also have duplication through specialization. The send-ns-form-to-repl and send-ns-form-to-repl-focus are a versions of cider-send-last-sexp-to-repl and cider-send-function-to-repl (and their accompanying -focus siblings (depending where you put the cursor).

I take a very simple approach with low cognitive load, mainly using , e f and , e ; (repl experiments / design journal) and occasionally , e P if I need to pretty print a large result. I never use the REPL buffer directly (the REPL buffer needs the welcome message updating for Spacemacs useage). I have never used any of the functions that are in the proposed "mR" menu, so not best placed to give feedback on their daily use. But they do seem a much more logical grouping.

Without a survey of use of functions and developer workflow, its hard to say what works best. My aim of this change was to make the menus mnemonically sound with clear groupings of purpose and easier discover-ability. It was clear as I was writing the Practicalli Spacemacs book and teaching others Clojure development with Spacemacs, that there were several areas of confusion.

Hopefully more feedback will come than in the previous 6 months, now there is a completed PR for people to try.

kommen commented 4 years ago

@jr0cket thanks for working on this!

I will see to give the PR a try, but I can already say that I use cider-clear-repl-buffer with its current ,sc binding quite often as well, but in a different context you are describing: The stdout of our web app is also logged into the repl buffer, so even as I eval code from the source buffers, log info get printed to the repl buffer, which in some situations clear quite often.

practicalli-johnny commented 4 years ago

@kommen Thanks for the feedback, very useful. I would like to understand the benefit you get of logging into the REPL, to better understand different uses of CIDER.

I assume that the logging levels are fairly low, as otherwise I would expect the REPL would feel unusable, as you have to constantly clear the REPL buffer and may quickly loose the result of any code evaluated directly in the REPL buffer.

If there is constant or burst rates of logs in the REPL, then evaluating in the source code buffer would seem in my humble opinion to be infinitely more usable.

Or even using the Emacs scratch buffer linked to the REPL session,sesman-link-with-buffer, seems to me to be a more effective workflow than constantly clearing the REPL buffer just so you can use it. Once the scratch buffer is linked it can evaluate adhoc clojure code that calls functions in the running REPL session, effectively creating temporary REPL that does not need to be regularly cleared.

It may be too ingrained to move the logging out of the REPL buffer, so these alternatives could make it more effective to work with this system in the long run.

I have logged into the REPL when using small ClojureScript apps, where I actually look at that log in the web browser dev tools console. But only when i dont really care about logs for that system.

For logging I tend to use Riemann (excellent view of why this is useful > https://juxt.pro/blog/posts/logging.html) and of course Elastic search if you want to scale out your logging.

I appreciate changing any regularly used keybinding could be quite impacting, so appreciate you trying the PR and any feedback you have (here or on #spacemacs clojurians slack)

kommen commented 4 years ago

@jr0cket as I said, I do evaluate all code from source buffers, I almost never eval from the repl buffer. I just have the repl buffer open next to my source buffer all the time to see the logs running by.

practicalli-johnny commented 4 years ago

Ah yes, you did say you evaluated in the source code buffer, my apologies. So I am confused as to why you need to keep clearing the REPL buffer, if all you are doing is looking at the most recent log messages. Is there some performance issue you experience with Emacs over time, or are you clearing to just start with a know place in the logs?

Do you log all your Clojure apps into the REPL ?

Sorry for all the questions, just trying to understand your use case so we can have more effective set of keybindings for all.

kommen commented 4 years ago

Is there some performance issue you experience with Emacs over time, or are you clearing to just start with a know place in the logs?

Actually it is both.

Do you log all your Clojure apps into the REPL ?

Most of the logs go to stdout, which ends up in the REPL, yes.

Sorry for all the questions, just trying to understand your use case so we can have more effective set of keybindings for all.

No worries, I'm happy to answer them all. Thanks again for taking on this!

didibus commented 4 years ago

I do use the REPL buffer quite a lot. The buffer eval disappear as soon as you move the cursor.

kommen commented 4 years ago

@didibus: Just as an aside, this is configurable, see Bozhidar's recent blog post here: https://metaredux.com/posts/2019/12/12/hard-cider-customizing-the-evaluation-results.html

practicalli-johnny commented 4 years ago

Alternatively, , e ; is the same as evaluating the parent expression (, e f) and also adds a comment underneath the expression evaluated. This stays around until deleted (or u in Evil normal mode).

practicalli-johnny commented 4 years ago

I have updated the proposed keybinding changes, that would allow the inclusion of sesman keybindings in a meaningful way.

I have removed the unpopular , R menu and placed the send-to-repl functions inside the evaluation menu and kept all their keys the same, except they are ,e or ,es instead of ,s

One noticeable change is toggling between code and repl. I propose moving from ,ss to ,sa as this aligns with the toggle between source and test code in projectile and other toggles

I changed clear repl buffer to , s l to match the same l key used to clear other terminal windows, enhancing memory muscle across spacemacs and terminals.

Please let me know your feedback and if all is good I will update the documentation and change log and ask the maintainers to merge this change. Thank you.

duianto commented 4 years ago

The following PRs changes have been applied to the develop branch: [clojure] Add sesman keybindings #13140