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

clj-refactor, clj-kondo, clojure-lsp #22

Open
plexus opened this issue Apr 25, 2022 · 6 comments
Open

clj-refactor, clj-kondo, clojure-lsp #22

plexus opened this issue Apr 25, 2022 · 6 comments

Comments

@plexus
Copy link
Collaborator

plexus commented Apr 25, 2022

Corgi aims to be a fairly minimal config, while at the same time being fairly complete when it comes to Clojure development. You should have a setup out of the box that gives you the amenities you would expect from a Clojure editing environment. But what does that mean, what do we include out of the box, and what don't we? I'm somewhat torn on some of these choices. Below I'll try to lay out my mental framework of how I'm thinking about these choices.

Currently we include clojure-mode, CIDER, clj-ns-name, and cider-connection-indicator. We still have clj-refactor listed as a dependency in corgi-clojure, so it gets installed, but we don't do anything to enable it (the dependency is a leftover that was intended to be removed).

So currently we don't include clj-refactor, clj-kondo, clojure-lsp, even though a lot of people are using these, and clearly get value out of them. The reason is that I personally don't use linters, and I've tried clojure-lsp and found it too immature. High CPU usage, a few times I had to kill Emacs. I've also had plenty of issues with clj-refactor in the past, although that's been a few years and I feel like it's pretty stable now.

The trade-off we need to think about is that each of these packages adds significant complexity, which means higher resource usage, more things that can go wrong, more layers to wade through when troubleshooting, and more things the user needs to learn about. That complexity can only be justified if we get enough value in return. key phrase: return on complexity

This value I think can be split into "passive" value, and "active" value. For instance: clj-ns-name automatically renames your buffers so they have the same name as the namespace name. That passively provides value, you don't have to know that that package exist or even that something is actively doing that, You automatically get value out of that. Syntax highlighting is another good example of passive value, and I imagine having a good clj-kondo setup out of the box can also provide passive value. You get warnings in your code without having to ask for them or having to know what is doing that. That means even complete beginners immediately get something out of it. passive return on complexity vs active return on complexity

clj-refactor provides some passive value, it automatically adds an ns declaration, but mostly it's active, you need to learn what it is, what it can do, and what the key bindings are to trigger it. I think clojure-lsp is similar (I may be wrong), there's a bit of passive value, but it's mostly active, you need to learn more things to make good use of it. Just setting it up involves a lot of informed choices. For packages like that the return on complexity is high for power users who take the time to study the docs and practice the key bindings, but it's low for a less advanced user who's still figuring out the basics of vim-style editing and interactive development. In fact it might be negative for new users who get overwhelmed with things they don't understand. "Smart" functionality can very easily get into people's way.

One of my annoyances with Spacemacs is that it loads a lod of things that only provide active value. Even after using it for years I would learn about packages that had been active all this time, that I didn't know exist, and that I had never used. I want to avoid that in Corgi. No "latent" functionality, we load the stuff that we know 90% of Clojure devs will get value out of.

So given all of the above I think the current situation is not wrong, we're being conservative so as not to load things that people might not get value out of, or that get into people's way. That said a lot of users are starting to swear by clj-kondo it seems, and I'm seeing a lot of appreciation for clojure-lsp as well, so I do want us to provide some kind of solution for those. My current thinking is a separate meta-package, maybe called corgi-clojure-smarts, that loads these two and sets them up.

But then we have to do it in a good way, make sure they have good defaults and integrate seamlessly, that any bindings are consistent with Corgi's approach to key bindings, and making sure that these things are properly explained in the Corgi manual. Our docs still leave a lot to be desired, but the goal is to have everything that is included with Corgi and that you need to actively know about to get value out of, to be explained in our own docs. You should be able to read the Corgi manual top to bottom and be productive, without having to branch out to other package's docs. (I guess I should write a separate issue for my vision on docs).

@theophilusx
Copy link

My 2 cents worth ....

  • clj-refactor. For me, I find most of the useful functionality 'I use' from clj-refactor has now been incorporated into cider. I no longer use it.
  • clj-kondo. I do find this package useful. I currently use the flymake integration and I don't find it nagging or distracting. However, I do find it useful.
  • lsp-mode/eglot. The lsp-mode stability has definitely improved. However, I'm not 100% sold on it, especially in conjunction with cider (they have a lot of overlap). Recently, I've been experimenting with eglot, which is another language server implementation. Unlike lsp-mode, it tries much harder to leverage of existing Emacs functionality rather than rolling/re-inventing its own. For me, it feels like you either use cider or you use one of the LSP modes. One small advantage LSP modes do provide is that because they use static analysis, they can provide completion, additional syntax highlighting/formatting, documentation lookup etc without running a repl. However, as a repl is a key component in my development workflow, this advantage isn't really worth a lot.
  • The other advantage is that now, the clojure-lsp server (which both lsp-mode and eglot use) incorporates clj-kondo, so you do get both and don't need an additional installation/configuration to also have clj-kondo support.

Iff we wanted to include LSP support (either eglot or lsp-mode), the key would likely be in having a configuration which turns off LSP features already provided by cider and only leave functionality which adds benefit. Not yet convinced this is worth it. Will likely take a bit of time playing with it before I know for certain.

I think I only partially agree with your active value argument. For me, I don't really care about things being loaded that I don't use/need provided they don't get in the way. My biggest gripe with spacemacs was too often, my workflow was broken by additional packages I didn't use. I guess it is really the same argument in the end. For me, the more things you have installed and configured, the more complex and the more complex, the more opportunity for breakage and more time wasted tracking down issues. I don't mind complex configurations, provided that additional complexity does give me value.

So I would say no to clj-refactor, yes to flymake and clj-kondo and a watch and wait on LSP mode support. If we do decide to include LSP support, then we would remove flymake and clj-kondo.

@plexus
Copy link
Collaborator Author

plexus commented Apr 25, 2022

Thanks Tim, that largely tracks with how I feel about things. Even though I'm not a Kondo user myself I do think its adoption is wide enough at this point that we need to have a good answer for that out of the box. The others we'll punt on, perhaps indefinitely.

@practicalli-johnny
Copy link

I have found clojure-lsp most valuable when joining an existing project, especially when it comes to a significant refactor or rewrite of the code (which is typically not well documented).

My own experience with clojure-lsp has very positive over the last 6 months and performance has been greatly optomised in that time. I no longer notice the analysis that takes place when opening a new project.

The visual components from emacs-lsp/lsp-ui used to be very disruptive, but are much more subtle default settings now.
The only visual feature I disable is the documentation pop-ups - lsp-ui-doc-enable nil

I also found the cljfmt based formatting a little too opinionated, although there are documented settings to tone that down too. The formatting was where I found the most tension between LSP and CIDER in the past.

Hopefully Corgi will provide clojure-lsp as an optional feature, which is off by default. Providing a simple configuration to enable clojure-lsp with sensible key bindings would be much appreciated.
I think this is less work that previous, but appreciate its still some amount of work.

@plexus
Copy link
Collaborator Author

plexus commented May 12, 2022

We're erring on the side of doing less here, which is a general principle we're following. Corgi is meant to be a baseline config that people can build on, for it to do that it's better to not have things that some people might want, than to have things that some people might not want.

I'm going out on a limb with Kondo, since it means adding something that I have no intention of using, that I have no experience with, and where I don't have a clear image of what people expect of it. I have to rely on others to implement the integration, and try to muddle through the inevitable support issues as best as I can.

We'll see how that goes, adding Kondo seems an order of magnitude less risky to me than adding LSP. When dozens to hundreds of people are happily using our Kondo setup without a hitch then we can say we did a good job and can maybe reopen this conversation. No is temporary, yes is forever.

I also don't want this to become a snowball project that drags in ever more stuff. We're just a collection of packages. Other people can create their own packages. They can set up their own straight repos. Let's encourage a marketplace of ideas. Maybe someone makes a Corgi-style package for lsp that becomes so widely used that we decide to add it to the sample config, or we go a step further and link to their project from our straight repo and pin it in our version file. That would be a fantastic outcome because it'll feel like an integrated whole, but the package will have its own git repo, maintained by people who actually use and care about lsp.

@theophilusx
Copy link

theophilusx commented Oct 11, 2022 via email

@theophilusx
Copy link

theophilusx commented Oct 11, 2022 via email

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

No branches or pull requests

3 participants