Skip to content

Commit 28853d5

Browse files
committed
Generate LSP configuration sections from defcustom
Fixes emacs-lsp#727 Fixes emacs-lsp#715 Fixes emacs-lsp#695 - introduced `lsp-configuration-section` for converting defcustom to configuration sections - introduces `lsp-generate-settings` to make converting from package.json manifest to Emacs defcustom sections - Used `lsp-configuration-section` for rls/vls/ruby-ls/pyls. TODO: fix get configuration method TODO: send the configuration to the server when it has changed.
1 parent 7c7e40b commit 28853d5

File tree

9 files changed

+1471
-195
lines changed

9 files changed

+1471
-195
lines changed

README.org

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
- [[#contributions][Contributions]]
3737
- [[#troubleshooting][Troubleshooting]]
3838
- [[#adding-support-for-languages][Adding support for languages]]
39+
- [[#registering-server][Registering server]]
40+
- [[#sections][Sections]]
3941
- [[#faq][FAQ]]
4042
- [[#see-also][See also]]
4143

@@ -218,13 +220,28 @@
218220
#+caption: Describe session
219221
[[file:examples/describe.png]]
220222
** Adding support for languages
221-
Here it is the minimal configuration that is needed for new language server registration. Refer to the documentation of ~lsp-client.el~ for the additional settings supported on registration time. ~lsp-language-id-configuration~ must be updated to contain the corresponding mode -> language id - in this case ~(python-mode . "python")~
222-
#+BEGIN_SRC emacs-lisp
223-
(lsp-register-client
224-
(make-lsp-client :new-connection (lsp-stdio-connection "pyls")
225-
:major-modes '(python-mode)
226-
:server-id 'pyls))
227-
#+END_SRC
223+
*** Registering server
224+
Here it is the minimal configuration that is needed for new language server registration. Refer to the documentation of ~lsp-client.el~ for the additional settings supported on registration time. ~lsp-language-id-configuration~ must be updated to contain the corresponding mode -> language id - in this case ~(python-mode . "python")~
225+
#+BEGIN_SRC emacs-lisp
226+
(lsp-register-client
227+
(make-lsp-client :new-connection (lsp-stdio-connection "pyls")
228+
:major-modes '(python-mode)
229+
:server-id 'pyls))
230+
#+END_SRC
231+
*** Sections
232+
~lsp-mode~ provides tools to bridge emacs ~defcustom~ as a language configuration sections properties(see [[https://microsoft.github.io/language-server-protocol/specification#workspace_configuration][specification workspace/configuration]]). In addition you may use ~lsp-generate-settings~ from [[https://github.com/emacs-lsp/lsp-mode/blob/master/scripts/lsp-generate-settings.el][Generate Settings script]] to generate ~defcustom~ from ~package.json~ VScode plugin manifest. Example:
233+
#+BEGIN_SRC emacs-lisp
234+
(defcustom lsp-foo-language-server-property "bar"
235+
"Demo property."
236+
:group 'foo-ls
237+
:risky t)
238+
239+
(lsp-register-custom-settings '(("foo.section.property" lsp-foo-language-server-property)))
240+
241+
(lsp-configuration-section "foo")
242+
;; => (("foo" ("settings" ("property" . "bar"))))
243+
#+END_SRC
244+
228245
** FAQ
229246
- How to configure a server with local variables?
230247
Add ~lsp~ server call to ~hack-local-variables-hook~ which runs right after the local variables are loaded.

lsp-clients.el

Lines changed: 15 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -27,118 +27,11 @@
2727
(require 'lsp)
2828
(require 'dash)
2929
(require 'dash-functional)
30+
(require 'lsp-pyls)
31+
(require 'lsp-rust)
32+
(require 'lsp-solargraph)
33+
(require 'lsp-vetur)
3034

31-
32-
;; Python
33-
34-
(defgroup lsp-python nil
35-
"Python."
36-
:group 'lsp-mode
37-
:tag "Python")
38-
39-
(defcustom lsp-clients-python-library-directories '("/usr/")
40-
"List of directories which will be considered to be libraries."
41-
:group 'lsp-python
42-
:risky t
43-
:type '(repeat string))
44-
45-
(defcustom lsp-clients-python-command '("pyls")
46-
"PYLS command."
47-
:group 'lsp-python
48-
:risky t
49-
:type 'list)
50-
51-
(defcustom lsp-clients-python-settings
52-
'(
53-
:plugins.jedi_completion.enabled t
54-
:plugins.jedi_definition.follow_imports t
55-
;; List of configuration sources to use. (enum: ["pycodestyle" "pyflakes"])
56-
:configurationSources ["pycodestyle"]
57-
;; Enable or disable the plugin.
58-
:plugins.jedi_completion.enabled t
59-
;; Enable or disable the plugin.
60-
:plugins.jedi_definition.enabled t
61-
;; The goto call will follow imports.
62-
:plugins.jedi_definition.follow_imports nil
63-
;; If follow_imports is True will decide if it follow builtin imports.
64-
:plugins.jedi_definition.follow_builtin_imports nil
65-
;; Enable or disable the plugin.
66-
:plugins.jedi_hover.enabled t
67-
;; Enable or disable the plugin.
68-
:plugins.jedi_references.enabled t
69-
;; Enable or disable the plugin.
70-
:plugins.jedi_signature_help.enabled nil
71-
;; Enable or disable the plugin.
72-
:plugins.jedi_symbols.enabled nil
73-
;; If True lists the names of all scopes instead of only the module namespace.
74-
:plugins.jedi_symbols.all_scopes t
75-
;; Enable or disable the plugin.
76-
:plugins.mccabe.enabled nil
77-
;; The minimum threshold that triggers warnings about cyclomatic complexity.
78-
:plugins.mccabe.threshold 15
79-
;; Enable or disable the plugin.
80-
:plugins.preload.enabled t
81-
;; List of modules to import on startup
82-
:plugins.preload.modules nil
83-
;; Enable or disable the plugin.
84-
:plugins.pycodestyle.enabled t
85-
;; Exclude files or directories which match these patterns(list of strings).
86-
:plugins.pycodestyle.exclude nil
87-
;; When parsing directories, only check filenames matching these patterns.
88-
:plugins.pycodestyle.filename nil
89-
;; Select errors and warnings (list of string)
90-
:plugins.pycodestyle.select nil
91-
;; Ignore errors and warnings (list of string)
92-
:plugins.pycodestyle.ignore nil
93-
;; Hang closing bracket instead of matching indentation of opening bracket's line.
94-
:plugins.pycodestyle.hangClosing nil
95-
;; Set maximum allowed line length.
96-
:plugins.pycodestyle.maxLineLength nil
97-
;; Enable or disable the plugin.
98-
:plugins.pydocstyle.enabled nil
99-
;; Choose the basic list of checked errors by specifying an existing
100-
;; convention. One of ("pep257","numpy")
101-
:plugins.pydocstyle.convention nil
102-
;; Ignore errors and warnings in addition to the specified convention.
103-
:plugins.pydocstyle.addIgnore nil
104-
;; Select errors and warnings in addition to the specified convention.
105-
:plugins.pydocstyle.addSelect nil
106-
;; Ignore errors and warnings
107-
:plugins.pydocstyle.ignore nil
108-
;; Select errors and warnings
109-
:plugins.pydocstyle.select nil
110-
;; Check only files that exactly match the given regular expression; default
111-
;; is to match files that don't start with 'test_' but end with '.py'.
112-
:plugins.pydocstyle.match "(?!test_).*\\.py"
113-
;; Enable or disable the plugin.
114-
:plugins.pydocstyle.matchDir nil
115-
;; Enable or disable the plugin.
116-
:plugins.pyflakes.enabled t
117-
;; Enable or disable the plugin.
118-
:plugins.rope_completion.enabled t
119-
;; Enable or disable the plugin.
120-
:plugins.yapf.enabled t
121-
;; Builtin and c-extension modules that are allowed to be imported and inspected by rope.
122-
:rope.extensionModules nil
123-
;; The name of the folder in which rope stores project configurations and
124-
;; data. Pass `nil' for not using such a folder at all.
125-
:rope.ropeFolder nil)
126-
"Lsp clients configuration settings."
127-
:group 'lsp-python
128-
:risky t
129-
:type 'plist)
130-
131-
;;; pyls
132-
(lsp-register-client
133-
(make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-clients-python-command))
134-
:major-modes '(python-mode)
135-
:priority -1
136-
:server-id 'pyls
137-
:initialized-fn (lambda (workspace)
138-
(with-lsp-workspace workspace
139-
(lsp--set-configuration `(:pyls ,lsp-clients-python-settings))))
140-
:library-folders-fn (lambda (_workspace)
141-
lsp-clients-python-library-directories)))
14235

14336
;;; CSS
14437
(defun lsp-clients-css--apply-code-action (action)
@@ -214,7 +107,7 @@ finding the executable with variable `exec-path'."
214107
:type '(repeat string))
215108

216109
(defun lsp-typescript-javascript-tsx-jsx-activate-p (filename mode)
217-
"Checks if the javascript-typescript language server should be enabled
110+
"Check if the javascript-typescript language server should be enabled
218111
based on FILE-NAME and MAJOR-MODE"
219112
(or (member mode '(typescript-mode typescript-tsx-mode js-mode js2-mode rjsx-mode))
220113
(and (eq major-mode 'web-mode)
@@ -283,7 +176,7 @@ finding the executable with variable `exec-path'."
283176
:type '(repeat string))
284177

285178
(defun lsp-clients-flow-tag-file-present-p (file-name)
286-
"Checks if the '// @flow' or `/* @flow */' tag is present in
179+
"Check if the '// @flow' or `/* @flow */' tag is present in
287180
the contents of FILE-NAME."
288181
(with-temp-buffer
289182
(insert-file-contents file-name)
@@ -321,12 +214,12 @@ with the file contents."
321214
found))))
322215

323216
(defun lsp-clients-flow-project-p (file-name)
324-
"Checks if FILE-NAME is part of a Flow project, that is, if
217+
"Check if FILE-NAME is part of a Flow project, that is, if
325218
there is a .flowconfig file in the folder hierarchy."
326219
(locate-dominating-file file-name ".flowconfig"))
327220

328221
(defun lsp-clients-flow-activate-p (file-name _mode)
329-
"Checks if the Flow language server should be enabled for a
222+
"Check if the Flow language server should be enabled for a
330223
particular FILE-NAME and MODE."
331224
(and (derived-mode-p 'js-mode 'web-mode 'js2-mode 'flow-js2-mode 'rjsx-mode)
332225
(lsp-clients-flow-project-p file-name)
@@ -340,38 +233,6 @@ particular FILE-NAME and MODE."
340233
:activation-fn 'lsp-clients-flow-activate-p
341234
:server-id 'flow-ls))
342235

343-
;;; Vue
344-
(defgroup lsp-vue nil
345-
"Vue."
346-
:group 'lsp-mode
347-
:tag "Vue")
348-
349-
(defcustom lsp-clients-vue-server "vls"
350-
"The vue-language-server executable to use.
351-
Leave as just the executable name to use the default behavior of
352-
finding the executable with `exec-path'."
353-
:group 'lsp-vue
354-
:risky t
355-
:type 'file)
356-
357-
(defcustom lsp-clients-vue-server-args '()
358-
"Extra arguments for the vue-language-server language server."
359-
:group 'lsp-vue
360-
:risky t
361-
:type '(repeat string))
362-
363-
(defun lsp-vue--ls-command ()
364-
"Generate the language server startup command."
365-
`(,lsp-clients-vue-server
366-
,@lsp-clients-vue-server-args))
367-
368-
(lsp-register-client
369-
(make-lsp-client :new-connection (lsp-stdio-connection 'lsp-vue--ls-command)
370-
:major-modes '(vue-mode)
371-
:priority -1
372-
:ignore-messages '("readFile .*? requested by Vue but content not available")
373-
:server-id 'vls))
374-
375236

376237
;;; GO language
377238

@@ -443,13 +304,13 @@ defaults to half of your CPU cores."
443304
(defun lsp-clients-go--make-init-options ()
444305
"Init options for golang."
445306
`(:funcSnippetEnabled ,(lsp-clients-go--bool-to-json lsp-clients-go-func-snippet-enabled)
446-
:disableFuncSnippet ,(lsp-clients-go--bool-to-json (not lsp-clients-go-func-snippet-enabled))
447-
:gocodeCompletionEnabled ,(lsp-clients-go--bool-to-json lsp-clients-go-gocode-completion-enabled)
448-
:formatTool ,lsp-clients-go-format-tool
449-
:goimportsLocalPrefix ,lsp-clients-go-imports-local-prefix
450-
:maxParallelism ,lsp-clients-go-max-parallelism
451-
:useBinaryPkgCache ,lsp-clients-go-use-binary-pkg-cache
452-
:diagnosticsEnabled ,lsp-clients-go-diagnostics-enabled))
307+
:disableFuncSnippet ,(lsp-clients-go--bool-to-json (not lsp-clients-go-func-snippet-enabled))
308+
:gocodeCompletionEnabled ,(lsp-clients-go--bool-to-json lsp-clients-go-gocode-completion-enabled)
309+
:formatTool ,lsp-clients-go-format-tool
310+
:goimportsLocalPrefix ,lsp-clients-go-imports-local-prefix
311+
:maxParallelism ,lsp-clients-go-max-parallelism
312+
:useBinaryPkgCache ,lsp-clients-go-use-binary-pkg-cache
313+
:diagnosticsEnabled ,lsp-clients-go-diagnostics-enabled))
453314

454315

455316
(lsp-register-client
@@ -482,28 +343,6 @@ defaults to half of your CPU cores."
482343
lsp-clients-go-library-directories)))
483344

484345

485-
;; RUST
486-
(defun lsp-clients--rust-window-progress (_workspace params)
487-
"Progress report handling.
488-
PARAMS progress report notification data."
489-
;; Minimal implementation - we could show the progress as well.
490-
(lsp-log (gethash "title" params)))
491-
492-
(lsp-register-client
493-
(make-lsp-client :new-connection (lsp-stdio-connection '("rls"))
494-
:major-modes '(rust-mode rustic-mode)
495-
:priority -1
496-
:server-id 'rls
497-
:notification-handlers (lsp-ht ("window/progress" 'lsp-clients--rust-window-progress))))
498-
499-
;; Ruby
500-
(lsp-register-client
501-
(make-lsp-client :new-connection (lsp-stdio-connection '("solargraph" "stdio"))
502-
:major-modes '(ruby-mode enh-ruby-mode)
503-
:priority -1
504-
:multi-root t
505-
:server-id 'ruby-ls))
506-
507346
;; PHP
508347
(defgroup lsp-php nil
509348
"PHP."

0 commit comments

Comments
 (0)