lsp4clj
lsp4clj copied to clipboard
Support custom request and notification handlers
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.