lsp-haskell icon indicating copy to clipboard operation
lsp-haskell copied to clipboard

Try both `haskell-language-server-wrapper` and `haskell-language-server` by default

Open michaelpj opened this issue 2 years ago • 4 comments

Might need to make the executable path a list of paths.

michaelpj avatar Mar 30 '23 14:03 michaelpj

I've just run into this. I'm surprised this has not been fixed yet.

One might say that "Oh, just modify lsp-haskell-server-path variable". Well, I don't want to do that globally, because I might have projects that will require the wrapper.

I've tried to set that variable locally to my project by adding an entry in dir-locales.el but it worked with issues (sometimes it would pick the modified value of the lsp-haskell-server-path, sometimes it would use the default one.

I think ideal is what @michaelpj proposed: setting this variable to a list and defaulting to haskell-language-server-wrapper and haskell-language-server

EncodePanda avatar Oct 04 '24 21:10 EncodePanda

I think I have something that works. But I wonder now, how much of a problem is backward compatibility? Should we keep lsp-haskell-server-path as is and introduce a new variable (e.g lsp-haskell-server-paths - plural) where thelsp-haskell-server-path is its default OR should we just modify existing lsp-haskell-server-path to be list and be done with it (ppl will have to migrate)

EncodePanda avatar Oct 04 '24 21:10 EncodePanda

I was thinking this

--- lsp-haskell.el

+++ lsp-haskell.el

@@ -1,4 +1,17 @@

-(defcustom lsp-haskell-server-path "haskell-language-server-wrapper"
-  "Path to the Haskell Language Server executable."
-  :type 'string
+(defcustom lsp-haskell-server-path '("haskell-language-server-wrapper" "haskell-language-server")
+  "List of possible paths to the Haskell Language Server executable."
+  :type '(repeat string)
   :group 'lsp-haskell)
+
+(defun lsp-haskell--find-server ()
+  "Try each server in `lsp-haskell-server-path` and return the first that works."
+  (seq-find #'executable-find lsp-haskell-server-path))
+
- (defun lsp-haskell--server-command ()
-  "Command and arguments for launching the inferior language server process.
- These are assembled from the customizable variables `lsp-haskell-server-path'
- and `lsp-haskell-server-args' and `lsp-haskell-server-wrapper-function'."
-  (funcall lsp-haskell-server-wrapper-function (append (list lsp-haskell-server-path "--lsp") lsp-haskell-server-args) ))
+(defun lsp-haskell--server-command ()
+  "Command and arguments for launching the inferior language server process.
+These are assembled from the customizable variables `lsp-haskell-server-path'
+and `lsp-haskell-server-args' and `lsp-haskell-server-wrapper-function'."
+  (let ((server (lsp-haskell--find-server)))
+    (unless server
+      (error "No valid Haskell Language Server found in `lsp-haskell-server-path`"))
+    (funcall lsp-haskell-server-wrapper-function (append (list server "--lsp") lsp-haskell-server-args))))

EncodePanda avatar Oct 04 '24 21:10 EncodePanda

I guess my experience has been that it works well enough with direnv. More generally, it is an example of a common thing: a setting that you want to be different in different locations. So I do feel like we should be able to defer to generic solutions like direnv or .dir-locals.el, and if those don't work then we should work out why not and fix that.

michaelpj avatar Oct 05 '24 10:10 michaelpj