From 32adc69faa17f7685d432e2eaca242ae2b4291b9 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sat, 12 Dec 2020 01:49:24 +0000 Subject: [PATCH 1/2] Add automatic download for haskell-language-server --- lsp-haskell.el | 89 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/lsp-haskell.el b/lsp-haskell.el index c85b430..d52f156 100644 --- a/lsp-haskell.el +++ b/lsp-haskell.el @@ -1,7 +1,7 @@ -;;; lsp-haskell.el --- Haskell support for lsp-mode +;;; lsp-haskell.el --- Haskell support for lsp-mode -*- lexical-binding: t; -*- ;; Version: 1.0 -;; Package-Requires: ((lsp-mode "3.0") (haskell-mode "1.0")) +;; Package-Requires: ((lsp-mode "7.0") (haskell-mode "1.0")) ;; Keywords: haskell ;; URL: https://github.com/emacs-lsp/lsp-haskell @@ -74,14 +74,14 @@ :group 'lsp-haskell :type 'boolean) (defcustom lsp-haskell-formatting-provider - "ormolu" + "ormolu" "The formatter to use when formatting a document or range." :group 'lsp-haskell - :type '(choice (const :tag "brittany" "brittany") - (const :tag "floskell" "floskell") - (const :tag "fourmolu" "fourmolu") - (const :tag "ormolu" "ormolu") - (const :tag "stylish-haskell" "stylish-haskell") + :type '(choice (const :tag "brittany" "brittany") + (const :tag "floskell" "floskell") + (const :tag "fourmolu" "fourmolu") + (const :tag "ormolu" "ormolu") + (const :tag "stylish-haskell" "stylish-haskell") (const :tag "none" "none"))) ;; --------------------------------------------------------------------- @@ -229,7 +229,7 @@ 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) )) ;; Register all the language server settings with lsp-mode. -;; Note that customizing these will currently *not* send the updated configuration to the server, +;; Note that customizing these will currently *not* send the updated configuration to the server, ;; users must manually restart. See https://github.com/emacs-lsp/lsp-mode/issues/1174. (lsp-register-custom-settings '( ("haskell.formattingProvider" lsp-haskell-formatting-provider) @@ -246,15 +246,60 @@ and `lsp-haskell-server-args' and `lsp-haskell-server-wrapper-function'." ;; https://microsoft.github.io/language-server-protocol/specification#textDocumentItem (add-to-list 'lsp-language-id-configuration '(haskell-literate-mode . "haskell")) +(defun lsp-haskell--github-system-type-suffix () + (pcase system-type + ('gnu/linux "Linux") + ('windows-nt "Windows") + ('darwin "macOS"))) + +(defcustom lsp-haskell-language-server-github-releases-url + "https://github.com/haskell/haskell-language-server/releases/latest/download/" + "GitHub releases url for haskell-language-server and its binaries. Make sure to include the trailing directory slash." + :type 'string + :group 'lsp-haskell + :package-version '(lsp-mode . "7.1")) + +(lsp-dependency + 'haskell-language-server-wrapper + '(:system "haskell-language-server-wrapper") + `(:download :url ,(concat lsp-haskell-language-server-github-releases-url + (format "haskell-language-server-wrapper-%s.gz" + (lsp-haskell--github-system-type-suffix))) + :store-path ,(f-join lsp-server-install-dir "haskell" "haskell-language-server-wrapper") + :decompress :gzip + :set-executable? t)) + +(defun lsp-haskell--project-ghc-version () + (let* ((path-exe (executable-find "haskell-language-server-wrapper")) + (downloaded-exe (lsp-package-path 'haskell-language-server-wrapper)) + (wrapper-exe (if path-exe path-exe downloaded-exe))) + (if wrapper-exe + (s-trim + (shell-command-to-string + (format "%s --project-ghc-version 2>/dev/null" wrapper-exe))) + nil))) + ;; Register the client itself (lsp-register-client (make-lsp--client - :new-connection (lsp-stdio-connection (lambda () (lsp-haskell--server-command))) + :new-connection (lsp-stdio-connection + (lambda () + (let* ((proj-ghc-ver (lsp-haskell--project-ghc-version)) + (server-name (format "haskell-language-server-%s" proj-ghc-ver)) + (path-exe (executable-find server-name)) + (downloaded-exe + (lsp-download-path + :store-path (f-join lsp-server-install-dir "haskell" server-name) + :set-executable? t))) + (lsp--info "Project GHC version is %s" proj-ghc-ver) + (if path-exe + (list path-exe "--lsp") + (list downloaded-exe "--lsp"))))) + ;; Should run under haskell-mode and haskell-literate-mode. We need to list the ;; latter even though it's a derived mode of the former :major-modes '(haskell-mode haskell-literate-mode) - ;; This is arbitrary. - :server-id 'lsp-haskell + :server-id 'haskell-language-server ;; We need to manually pull out the configuration section and set it. Possibly in ;; the future lsp-mode will asssociate servers with configuration sections more directly. :initialized-fn (lambda (workspace) @@ -263,6 +308,26 @@ and `lsp-haskell-server-args' and `lsp-haskell-server-wrapper-function'." ;; This is somewhat irrelevant, but it is listed in lsp-language-id-configuration, so ;; we should set something consistent here. :language-id "haskell" + :download-server-fn (lambda (_client callback error-callback _update?) + (lsp-package-ensure + 'haskell-language-server-wrapper + (lambda () + (let* + ((proj-ghc-ver (lsp-haskell--project-ghc-version)) + (binary-store-path + (f-join lsp-server-install-dir "haskell" (format "haskell-language-server-%s" proj-ghc-ver)))) + (lsp-download-install + callback + error-callback + :url (concat + lsp-haskell-language-server-github-releases-url + (format + "haskell-language-server-%s-%s.gz" + (lsp-haskell--github-system-type-suffix) + proj-ghc-ver)) + :store-path binary-store-path + :decompress :gzip))) + error-callback)) )) ;; --------------------------------------------------------------------- From b6fb370986421f9b9ef726bab607b08130c7be0a Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sun, 13 Dec 2020 22:20:08 +0000 Subject: [PATCH 2/2] Use lsp-package-path more --- lsp-haskell.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lsp-haskell.el b/lsp-haskell.el index d52f156..4c07c89 100644 --- a/lsp-haskell.el +++ b/lsp-haskell.el @@ -257,7 +257,7 @@ and `lsp-haskell-server-args' and `lsp-haskell-server-wrapper-function'." "GitHub releases url for haskell-language-server and its binaries. Make sure to include the trailing directory slash." :type 'string :group 'lsp-haskell - :package-version '(lsp-mode . "7.1")) + :package-version '(lsp-haskell . "1.0")) (lsp-dependency 'haskell-language-server-wrapper @@ -270,9 +270,7 @@ and `lsp-haskell-server-args' and `lsp-haskell-server-wrapper-function'." :set-executable? t)) (defun lsp-haskell--project-ghc-version () - (let* ((path-exe (executable-find "haskell-language-server-wrapper")) - (downloaded-exe (lsp-package-path 'haskell-language-server-wrapper)) - (wrapper-exe (if path-exe path-exe downloaded-exe))) + (let ((wrapper-exe (lsp-package-path 'haskell-language-server-wrapper))) (if wrapper-exe (s-trim (shell-command-to-string