lsp-haskell
lsp-haskell copied to clipboard
Try both `haskell-language-server-wrapper` and `haskell-language-server` by default
Might need to make the executable path a list of paths.
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
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)
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))))
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.