lsp4clj icon indicating copy to clipboard operation
lsp4clj copied to clipboard

Support custom request and notification handlers

Open ferdinand-beyer opened this issue 1 year ago • 2 comments
trafficstars

This PR allows users to specify custom handler functions instead of the receive-* multi-methods.

The main reason for that is to enable middleware, e.g. to log/time/trace requests, execute them on different threads, etc. Using the :request-handler and :notification-handler options, one could create Ring-style middleware:

(defn wrap-vthread [handler]
  (fn [method context params]
    (p/vthread (handler method context params))))

;; ...

(defmulti receive-request (fn [method _ _] method))

(def server (server/chan-server {:request-handler (wrap-vthread #'receive-request)}))

Avoiding global state in the multi-methods also allows having multiple LSP implementations on the classpath. Not a common use case, but we found ourselves in the situation where we had both clojure-lsp (to use the linter) and our custom LSP on the dev classpath.

Some tests could now be simplified, using :request-handler instead of with-redefs.

ferdinand-beyer avatar Aug 08 '24 10:08 ferdinand-beyer