spacemacs icon indicating copy to clipboard operation
spacemacs copied to clipboard

Understanding the value of LSP for Clojure

Open practicalli-johnny opened this issue 4 years ago • 1 comments

At the moment I am struggling to understand the benefit of using LSP for Clojure, especially when used to REPL driven development in a Clojure aware editor. The REPL already provides a wide range of features and I cant really imagine doing any Clojure development without a running REPL, as its such an intrinsic part of the developer experience.

A common features seems to be refactoring with LSP, especially finding function calls across a project so they can be updated together. I currently refactor using Emacs tools, for example https://practicalli.github.io/spacemacs/refactor/within-a-project.html or using clojure-mode commands.

clj-refactor does provide many refactor tools, some of which have been migrated into clojure-mode. The migration could use a volunteer to continue this work, unfortunately clj-refactor doesnt get as much attention as it requires (I am not currently using clj-refactor)

static analysis of a project with clojure-lsp, the only implementation of an LSP server as far as I know, does use considerable resources (over 3Gb of memory on one project) which seems to be dependent on the dependencies included.

There is a need for more documentation on how to use clojure-lsp effectively, especially with CIDER. https://github.com/emacs-lsp/lsp-mode/issues/2445

The Language Server Protocol Support for Emacs project has a growing set of docs https://emacs-lsp.github.io/lsp-mode/

A simpler alternative is anakondo (not actually using LSP) but provides similar features to clojure-lsp without clashes with CIDER (or at least documented configuration on how to avoid clashing features).

Discussions Several aspects covered in this discussion - although to me its the opposite thought - is LSP redundant because of cider https://www.reddit.com/r/Clojure/comments/d01ux4/is_lspclojure_redundant_with_cider/

Demos / Tutorials Are there any demos / tutorials that describe how to use the features of Clojure-lsp?

Overview Language Server Protocol is for language providers and tool developers, to provide a consistent protocol common tool actions across all languages. This is in part achieved via the LSP json protocol and the ELIF database created from static analysis of the code in a project.

Implementations

  • clojure-lsp - https://github.com/clojure-lsp/clojure-lsp

Alternatives

  • anakondo - static analysis of projects for similar benefits to clojure-lsp without the conflicts with CIDER https://github.com/didibus/anakondo

Specific uses lsp-find-definition lsp-find-references

Configuration of LSP to avoid conflict with CIDER The following may be useful to set to avoid LSP conflicting with existing CIDER functionality

  (setq lsp-enable-indentation nil)
  (setq lsp-enable-completion-at-point nil)

Global configuration Create a ~/.lsp/config.edn file which will be used across all projects (I assume a .lsp/config.edn configuration will merge/replace with the global settings)

https://github.com/ericdallo/dotfiles/blob/master/.lsp/config.edn

Known issues with LSP

  • clojure-lsp UI conflicts with CIDER UI (requires documentation on how to use these together)
  • clojure-lsp can take significant time to analyze a project, especially some jar files
  • Emacs is single threaded and can be blocked by clojure-lsp processing
  • In Emacs, clojure-lsp will index a project as soon as a file is open. Using layouts with Emacs stalls the startup process of Emacs as it indexes each Clojure project opened in a layout

Resources

  • https://emacs-lsp.github.io/lsp-mode/
  • https://langserver.org/
  • https://github.com/clojure-lsp/clojure-lsp
  • https://nrepl.org/nrepl/alternatives.html#language-server-protocol
  • https://practicalli.github.io/spacemacs/install-spacemacs/clj-kondo-via-lsp.html
  • https://github.com/clojure-emacs/cider/issues/2747
  • https://twitter.com/pesterhazy/status/1259466914969067525 - thread on twitter trying to explain lsp (not that useful)

practicalli-johnny avatar Jan 02 '21 14:01 practicalli-johnny

Hello! LSP works very good for a lot of languages and there are languages that already have built-in support for it like dart for example. Clojure REPL development is what we known for years and it works very good indeed, but we can always improve it :) Imagine having all cider features without the need of plugin a REPL :)

clojure-lsp can provide some cool things that AFAIK doesn't exist on Cider like:

  • call hierarchy
  • Code lens where we use for references of a symbol
  • clean-ns cleaning non used requires, not sure if it exists on cider.
  • a lot of features that are already included if you follow the LPS spec, you can check most of them here

It's possible to use LSP and a REPL driven development like Cider at the same time, there are few conflicts that after resolved, it works really nice, I use it for almost a year already.

clojure-lsp ATM use 2GB of max memory to work well with huge projects, we are already talking a look on that here We are in a process of integrating with clj-kondo which will probably improve a lot performance ;)

ericdallo avatar Jan 03 '21 19:01 ericdallo