3131; ; ---------------------------------------------------------------------
3232; ; Configuration
3333
34- ;;;### autoload
3534(defgroup lsp-haskell nil
3635 " Customization group for ‘lsp-haskell’."
3736 :group 'lsp-mode )
3837
39- ;;;### autoload
40- (defcustom lsp-haskell-process-path-hie
41- ; ; "hie"
42- " hie-wrapper"
43- " The path for starting the haskell-ide-engine
44- server. hie-wrapper exists on HIE master from 2018-06-10"
38+ ; ; ---------------------------------------------------------------------
39+ ; ; Language server options
40+
41+ ; ; These are registered with lsp-mode below, which handles preparing them for the server.
42+ ; ; Originally generated from the vscode extension's package.json using lsp-generate-bindings.
43+ ; ; Should ideally stay in sync with what's offered in the vscode extension.
44+
45+ (defcustom lsp-haskell-hlint-on
46+ t
47+ " Get suggestions from hlint."
4548 :group 'lsp-haskell
46- :type '(choice (const " hie-wrapper" )
47- (const " haskell-language-server-wrapper" )
48- (const " ghcide" )
49- string))
50-
51- ;;;### autoload
52- (defcustom lsp-haskell-process-args-hie
53- '(" -d" " -l" " /tmp/hie.log" )
54- " The arguments for starting the haskell-ide-engine server.
55- For a debug log, use `-d -l /tmp/hie.log'."
49+ :type 'boolean )
50+ (defcustom lsp-haskell-max-number-of-problems
51+ 100
52+ " Controls the maximum number of problems produced by the server."
5653 :group 'lsp-haskell
57- :type '(repeat (string :tag " Argument" )))
54+ :type 'number )
55+ (defcustom
56+ lsp-haskell-diagnostics-on-change
57+ t
58+ " Compute diagnostics continuously as you type. Turn off to only generate diagnostics on file save."
59+ :group 'lsp-haskell
60+ :type 'boolean )
61+ (defcustom lsp-haskell-liquid-on
62+ nil
63+ " Get diagnostics from liquid haskell."
64+ :group 'lsp-haskell
65+ :type 'boolean )
66+ (defcustom lsp-haskell-completion-snippets-on
67+ t
68+ " Show snippets with type information when using code completion."
69+ :group 'lsp-haskell
70+ :type 'boolean )
71+ (defcustom lsp-haskell-format-on-import-on
72+ t
73+ " When adding an import, use the formatter on the result."
74+ :group 'lsp-haskell
75+ :type 'boolean )
76+ (defcustom lsp-haskell-formatting-provider
77+ " ormolu"
78+ " The formatter to use when formatting a document or range."
79+ :group 'lsp-haskell
80+ :type '(choice (const :tag " brittany" " brittany" )
81+ (const :tag " floskell" " floskell" )
82+ (const :tag " fourmolu" " fourmolu" )
83+ (const :tag " ormolu" " ormolu" )
84+ (const :tag " stylish-haskell" " stylish-haskell" )
85+ (const :tag " none" " none" )))
5886
59- ;;;### autoload
60- (defcustom lsp-haskell-process-wrapper-function
61- #'identity
62- " Use this to wrap the haskell-ide-engine process started by lsp-haskell.
87+ ; ; ---------------------------------------------------------------------
88+ ; ; Non-language server options
6389
64- For example, use the following the start the hie process in a nix-shell:
90+ (defcustom lsp-haskell-server-path
91+ " haskell-language-server"
92+ " The language server executable. Can be something on the $PATH (e.g. 'ghcide') or a path to an executable itself."
93+ :group 'lsp-haskell
94+ :type 'string )
95+
96+ (defcustom lsp-haskell-server-args
97+ '(" -d" " -l" " /tmp/hls.log" )
98+ " The arguments for starting the language server.
99+ For a debug log when using haskell-language-server, use `-d -l /tmp/hls.log'."
100+ :group 'lsp-haskell
101+ :type '(repeat (string :tag " Argument" )))
65102
103+ (defcustom lsp-haskell-server-wrapper-function
104+ #'identity
105+ " Use this to wrap the language server process started by lsp-haskell.
106+ For example, use the following the start the process in a nix-shell:
66107(lambda (argv)
67108 (append
68109 (append (list \" nix-shell\" \" -I\" \" .\" \" --command\" )
@@ -76,11 +117,6 @@ For example, use the following the start the hie process in a nix-shell:
76117 (function-item :tag " None" :value identity)
77118 (function :tag " Custom function" )))
78119
79- ; ; ---------------------------------------------------------------------
80- ; ; Internal variables
81-
82- (defvar lsp-haskell--config-options (make-hash-table ))
83-
84120; ; ---------------------------------------------------------------------
85121; ; HaRe functions
86122
@@ -150,6 +186,7 @@ For example, use the following the start the hie process in a nix-shell:
150186 :pos ,(lsp-point-to-position (point ))))))
151187
152188; ; ---------------------------------------------------------------------
189+ ; ; Miscellaneous useful functions
153190
154191(defun lsp-haskell--session-cabal-dir ()
155192 " Get the session cabal-dir."
@@ -176,144 +213,42 @@ if projectile way fails"
176213 dir))))
177214
178215; ; ---------------------------------------------------------------------
179-
180- (defun lsp--haskell-hie-command ()
181- " Comamnd and arguments for launching the inferior hie process.
182- These are assembled from the customizable variables
183- `lsp-haskell-process-path-hie' and
184- `lsp-haskell-process-args-hie' . If the hie executable is
185- installed via its Makefile, there will be compiler-specific
186- versions with names like 'hie-8.0.2' or 'hie-8.2.2'."
187- (append (list lsp-haskell-process-path-hie " --lsp" ) lsp-haskell-process-args-hie) )
188-
189- ; ; ---------------------------------------------------------------------
190-
216+ ; ; Starting the server and registration with lsp-mode
217+
218+ (defun lsp-haskell--server-command ()
219+ " Command and arguments for launching the inferior language server process.
220+ These are assembled from the customizable variables `lsp-haskell-server-path'
221+ and `lsp-haskell-server-args' ."
222+ (append (list lsp-haskell-server-path " --lsp" ) lsp-haskell-server-args) )
223+
224+ ; ; Register all the language server settings with lsp-mode.
225+ ; ; Note that customizing these will currently *not* send the updated configuration to the server,
226+ ; ; users must manually restart. See https://github.com/emacs-lsp/lsp-mode/issues/1174.
227+ (lsp-register-custom-settings '(
228+ (" haskell.formattingProvider" lsp-haskell-formatting-provider)
229+ (" haskell.formatOnImportOn" lsp-haskell-format-on-import-on t )
230+ (" haskell.completionSnippetsOn" lsp-haskell-completion-snippets-on t )
231+ (" haskell.liquidOn" lsp-haskell-liquid-on t )
232+ (" haskell.diagnosticsOnChange" lsp-haskell-diagnostics-on-change t )
233+ (" haskell.maxNumberOfProblems" lsp-haskell-max-number-of-problems)
234+ (" haskell.hlintOn" lsp-haskell-hlint-on t )))
235+
236+ ; ; Register the client itself
191237(lsp-register-client
192238 (make-lsp--client
193- :new-connection (lsp-stdio-connection (lambda () (lsp-haskell--hie -command)))
239+ :new-connection (lsp-stdio-connection (lambda () (lsp-haskell--server -command)))
194240 :major-modes '(haskell-mode )
195- :server-id 'hie
241+ ; ; This is arbitrary.
242+ :server-id 'lsp-haskell
243+ ; ; We need to manually pull out the configuration section and set it. Possibly in
244+ ; ; the future lsp-mode will asssociate servers with configuration sections more directly.
196245 :initialized-fn (lambda (workspace )
197246 (with-lsp-workspace workspace
198- (lsp-haskell-- set-configuration)))
199- ; ; :multi-root t
200- ; ; :initialization-options 'lsp-haskell--make-init-options
247+ (lsp-- set-configuration (lsp-configuration-section " haskell " ) )))
248+ ; ; No need to set :language-id, since there isn't one for Haskell and we
249+ ; ; don't support multiple languages
201250 ))
202251
203- (defun lsp-haskell--hie-command ()
204- (funcall lsp-haskell-process-wrapper-function (lsp--haskell-hie-command)))
205-
206- (cl-defmethod lsp-initialization-options ((_server (eql hie)))
207- " Initialization options for haskell."
208- `(:languageServerHaskell , lsp-haskell--config-options ))
209-
210- ; ; ---------------------------------------------------------------------
211-
212- (defun lsp-haskell--set-configuration ()
213- (lsp--set-configuration `(:languageServerHaskell , lsp-haskell--config-options )))
214-
215- (defun lsp-haskell-set-config (name option )
216- " Set config option NAME to value OPTION in the haskell lsp server."
217- (puthash name option lsp-haskell--config-options))
218-
219- ; ; parseJSON = withObject "Config" $ \v -> do
220- ; ; s <- v .: "languageServerHaskell"
221- ; ; flip (withObject "Config.settings") s $ \o -> Config
222- ; ; <$> o .:? "hlintOn" .!= True
223- ; ; <*> o .:? "maxNumberOfProblems" .!= 100
224- ; ; <*> o .:? "liquidOn" .!= False
225- ; ; <*> o .:? "completionSnippetsOn" .!= True
226-
227- ; ; -------------------------------------
228-
229- (defun lsp-haskell-set-hlint (val )
230- " Enable(t)/Disable(nil) running hlint."
231- (lsp-haskell-set-config " hlintOn" val))
232-
233- (defun lsp-haskell-set-hlint-on ()
234- " Enable running hlint haskell."
235- (interactive )
236- (lsp-haskell-set-hlint t )
237- (lsp-haskell--set-configuration))
238-
239- (defun lsp-haskell-set-hlint-off ()
240- " Disable running hlint."
241- (interactive )
242- (lsp-haskell-set-hlint :json-false )
243- (lsp-haskell--set-configuration))
244-
245- ; ; -------------------------------------
246-
247- (defun lsp-haskell-set-max-problems (val )
248- " Set maximum number of problems reported to VAL."
249- (lsp-haskell-set-config " maxNumberOfProblems" val))
250-
251- (defun lsp-haskell-set-max-number-of-problems (val )
252- " Set maximum number of problems reported to VAL."
253- (interactive " nMax number of problems to report: " )
254- (lsp-haskell-set-max-problems val)
255- (lsp-haskell--set-configuration))
256-
257- ; ; -------------------------------------
258-
259- (defun lsp-haskell-set-liquid (val )
260- " Enable(t)/Disable(nil) running liquid haskell on save."
261- (lsp-haskell-set-config " liquidOn" val))
262-
263- (defun lsp-haskell-set-liquid-on ()
264- " Enable running liquid haskell on save."
265- (interactive )
266- (lsp-haskell-set-liquid t )
267- (lsp-haskell--set-configuration))
268-
269- (defun lsp-haskell-set-liquid-off ()
270- " Disable running liquid haskell on save."
271- (interactive )
272- (lsp-haskell-set-liquid :json-false )
273- (lsp-haskell--set-configuration))
274-
275- ; ; -------------------------------------
276-
277- (defun lsp-haskell-set-completion-snippets (val )
278- " Enable(t)/Disable(nil) providing completion snippets."
279- (lsp-haskell-set-config " completionSnippetsOn" val))
280-
281- (defun lsp-haskell-set-completion-snippets-on ()
282- " Enable providing completion snippets."
283- (interactive )
284- (lsp-haskell-set-completion-snippets t )
285- (lsp-haskell--set-configuration))
286-
287- (defun lsp-haskell-set-completion-snippets-off ()
288- " Disable providing completion snippets."
289- (interactive )
290- (lsp-haskell-set-completion-snippets :json-false )
291- (lsp-haskell--set-configuration))
292-
293- ; ; -------------------------------------
294-
295- (defun lsp-haskell-set-formatter (val )
296- " Set code formatter."
297- (lsp-haskell-set-config " formattingProvider" val))
298-
299- (defun lsp-haskell-set-formatter-brittany ()
300- " Use brittany."
301- (interactive )
302- (lsp-haskell-set-formatter :brittany )
303- (lsp-haskell--set-configuration))
304-
305- (defun lsp-haskell-set-formatter-floskell ()
306- " Use floskell."
307- (interactive )
308- (lsp-haskell-set-formatter :floskell )
309- (lsp-haskell--set-configuration))
310-
311- (defun lsp-haskell-set-formatter-ormolu ()
312- " Use ormolu."
313- (interactive )
314- (lsp-haskell-set-formatter :ormolu )
315- (lsp-haskell--set-configuration))
316-
317252; ; ---------------------------------------------------------------------
318253
319254(provide 'lsp-haskell )
0 commit comments