2
2
3
3
; ; Author: Charl Botha
4
4
; ; Maintainer: Andrew Christianson
5
- ; ; Version: 0.1 .0
5
+ ; ; Version: 0.2 .0
6
6
; ; Package-Requires: ((cl-lib "0.6.1") (lsp-mode "6.0") (python "0.26.1") (json "1.4") (emacs "24.4"))
7
7
; ; Homepage: https://github.com/andrew-christianson/lsp-python-ms
8
8
; ; Keywords: languages tools
39
39
; ; forward declare variable
40
40
(defvar lsp-render-markdown-markup-content )
41
41
42
- (defvar lsp-python-ms-dir nil
42
+ (defvar lsp-python-ms-dir ( expand-file-name " mspyls/ " user-emacs-directory)
43
43
" Path to language server directory.
44
44
45
45
This is the directory containing Microsoft.Python.LanguageServer.dll." )
@@ -53,20 +53,6 @@ This is the directory containing Microsoft.Python.LanguageServer.dll.")
53
53
; ; If this is nil, the language server will write cache files in a directory
54
54
; ; sibling to the root of every project you visit")
55
55
56
- (defun lsp-python-ms--find-dotnet ()
57
- " Get the path to dotnet, or return `lsp-python-ms-dotnet' ."
58
- (cond
59
- ((boundp 'lsp-python-ms-dotnet ) lsp-python-ms-dotnet)
60
- ((executable-find " dotnet" ))
61
- ((eq system-type 'windows-nt ) " dotnet" )
62
- (t nil )))
63
-
64
- (defvar lsp-python-ms-dotnet
65
- (lsp-python-ms--find-dotnet)
66
- " Full path to dotnet executable.
67
-
68
- You only need to set this if dotnet is not on your path." )
69
-
70
56
(defvar lsp-python-ms-extra-paths '()
71
57
" A list of additional paths to search for python packages.
72
58
@@ -85,19 +71,86 @@ e.g, there are `python2' and `python3', both in system PATH,
85
71
and the default `python' links to python2,
86
72
set as `python3' to let ms-pyls use python 3 environments." )
87
73
88
- (defun lsp-python-ms--find-server-executable ()
89
- " Get path to the python language server executable."
90
- (cond
91
- ((boundp 'lsp-python-ms-executable ) lsp-python-ms-executable)
92
- ((executable-find " Microsoft.Python.LanguageServer" ))
93
- ((executable-find " Microsoft.Python.LanguageServer.LanguageServer" ))
94
- ((executable-find " Microsoft.Python.LanguageServer.exe" ))
95
- (t nil )))
96
-
97
- (defvar lsp-python-ms-executable
98
- (lsp-python-ms--find-server-executable)
74
+ (defvar lsp-python-ms-executable (concat lsp-python-ms-dir
75
+ " Microsoft.Python.LanguageServer"
76
+ (and (eq system-type 'windows-nt ) " .exe" ))
99
77
" Path to Microsoft.Python.LanguageServer.exe." )
100
78
79
+ (defvar lsp-python-ms-nupkg-channel " stable"
80
+ " The channel of nupkg for Microsoft Python Language Server:
81
+ stable, beta or daily." )
82
+
83
+ (defun lsp-python-ms-latest-nupkg-url (&optional channel )
84
+ " Get the nupkg url of the latest Microsoft Python Language Server."
85
+ (let ((channel (or channel " stable" )))
86
+ (unless (member channel '(" stable" " beta" " daily" ))
87
+ (error (format " Unknown channel: %s " channel)))
88
+ (with-current-buffer
89
+ (url-retrieve-synchronously
90
+ (format " https://pvsc.blob.core.windows.net/python-language-server-%s \
91
+ ?restype=container&comp=list&prefix=Python-Language-Server-%s -x64 "
92
+ channel
93
+ (cond ((eq system-type 'darwin ) " osx" )
94
+ ((eq system-type 'gnu/linux ) " linux" )
95
+ ((eq system-type 'windows-nt ) " win" )
96
+ (t (error (format " Unsupported system: %s " system-type))))))
97
+ (goto-char (point-min ))
98
+ (re-search-forward " \n\n " )
99
+ (pcase (xml-parse-region (point ) (point-max ))
100
+ (`((EnumerationResults
101
+ ((ContainerName . , _ ))
102
+ (Prefix nil , _ )
103
+ (Blobs nil . , blobs )
104
+ (NextMarker nil )))
105
+ (cdar
106
+ (sort
107
+ (mapcar (lambda (blob )
108
+ (pcase blob
109
+ (`(Blob
110
+ nil
111
+ (Name nil , _ )
112
+ (Url nil , url )
113
+ (Properties nil (Last-Modified nil , last-modified ) . , _ ))
114
+ (cons (encode-time (parse-time-string last-modified)) url))))
115
+ blobs)
116
+ (lambda (t1 t2 )
117
+ (time-less-p (car t2) (car t1))))))))))
118
+
119
+ (defun lsp-python-ms-setup (&optional forced )
120
+ " Downloading Microsoft Python Language Server to path specified.
121
+ With prefix, FORCED to redownload the server."
122
+ (interactive " P" )
123
+ (unless (and (not forced)
124
+ (file-exists-p lsp-python-ms-executable))
125
+ (let ((temp-file (make-temp-file " mspyls" nil " .zip" ))
126
+ (unzip-script (cond ((executable-find " unzip" )
127
+ " bash -c 'mkdir -p %2$s && unzip -qq %1$s -d %2$s'" )
128
+ ((executable-find " powershell" )
129
+ " powershell -noprofile -noninteractive \
130
+ -nologo -ex bypass Expand-Archive -path '%s' -dest '%s'" )
131
+ (t nil ))))
132
+ (message " Downloading Microsoft Python Language Server... " )
133
+
134
+ (url-copy-file (lsp-python-ms-latest-nupkg-url lsp-python-ms-nupkg-channel)
135
+ temp-file 'overwrite )
136
+ (when (file-exists-p lsp-python-ms-dir)
137
+ (delete-directory lsp-python-ms-dir 'recursive ))
138
+ (shell-command (format unzip-script temp-file lsp-python-ms-dir))
139
+ (when (file-exists-p lsp-python-ms-executable)
140
+ (chmod lsp-python-ms-executable #o755 ))
141
+
142
+ (message " Downloaded Microsoft Python Language Server! " ))))
143
+
144
+ (defun lsp-python-ms-update-server ()
145
+ " Update Microsoft Python Language Server.
146
+
147
+ On Windows, if the server is running, the updating will fail.
148
+ After stopping or killing the process, retry to update."
149
+ (interactive )
150
+ (message " Server update started... " )
151
+ (lsp-python-ms-setup t )
152
+ (message " Server update finished... " ))
153
+
101
154
; ; it's crucial that we send the correct Python version to MS PYLS,
102
155
; ; else it returns no docs in many cases furthermore, we send the
103
156
; ; current Python's (can be virtualenv) sys.path as searchPaths
@@ -137,7 +190,7 @@ lsp-workspace-root function that finds the current buffer's
137
190
workspace root. If nothing works, default to the current file's
138
191
directory"
139
192
(let ((workspace-root (if workspace (lsp--workspace-root workspace) (lsp-python-ms--workspace-root))))
140
- (cl-destructuring-bind (pyver pysyspath )
193
+ (cl-destructuring-bind (pyver _pysyspath )
141
194
(lsp-python-ms--get-python-ver-and-syspath workspace-root)
142
195
`(:interpreter
143
196
(:properties (:InterpreterPath
@@ -160,7 +213,6 @@ directory"
160
213
:asyncStartup t
161
214
:typeStubSearchPaths ,(vector (concat lsp-python-ms-dir " Typeshed" ))))))
162
215
163
-
164
216
(defun lsp-python-ms--filter-nbsp (str )
165
217
" Filter nbsp entities from STR."
166
218
(let ((rx " " ))
@@ -201,26 +253,35 @@ other handlers. "
201
253
202
254
(defun lsp-python-ms--command-string ()
203
255
" Return the command to start the server."
204
- (cond
205
- ((lsp-python-ms--find-server-executable))
206
- ((and (lsp-python-ms--find-dotnet) lsp-python-ms-dir)
207
- (list (lsp-python-ms--find-dotnet)
208
- (concat lsp-python-ms-dir " Microsoft.Python.LanguageServer.dll" )))
209
- (t (error " Could find Microsoft python language server " ))))
256
+ ; ; Try to download server if it doesn't exists
257
+ (unless (file-exists-p lsp-python-ms-executable)
258
+ (lsp-python-ms-setup))
259
+
260
+ (if (file-exists-p lsp-python-ms-executable)
261
+ lsp-python-ms-executable
262
+ (error " Could find Microsoft python language server " )))
210
263
264
+ (defgroup lsp-mspyls nil
265
+ " LSP support for Python, using Microsoft Python Language Server."
266
+ :group 'lsp-mode
267
+ :link '(url-link " https://github.com/emacs-lsp/lsp-python-ms" ))
211
268
212
269
; ; See https://github.com/microsoft/python-language-server for more diagnostics
213
270
(defcustom lsp-mspyls-errors [" unknown-parameter-name"
214
271
" undefined-variable"
215
272
" parameter-missing"
216
273
" positional-argument-after-keyword"
217
274
" too-many-function-arguments" ]
218
- " Microsoft Python LSP Error types." )
275
+ " Microsoft Python LSP Error types."
276
+ :group 'lsp-mspyls
277
+ :type 'vector )
219
278
220
279
(defcustom lsp-mspyls-warnings [" unresolved-import"
221
280
" parameter-already-specified"
222
281
" too-many-positional-arguments-before-star" ]
223
- " Microsoft Python LSP Warning types." )
282
+ " Microsoft Python LSP Warning types."
283
+ :group 'lsp-mspyls
284
+ :type 'vector )
224
285
225
286
(lsp-register-custom-settings '((" python.analysis.errors" lsp-mspyls-errors)))
226
287
(lsp-register-custom-settings '((" python.analysis.warnings" lsp-mspyls-warnings)))
0 commit comments