根据你这个改了一下, 试了试, 暂时没发现 reloading 了, 我再多试试.
用了你的配置,也用了vscode的server,还是卡的不行。请问你的mac os版本以及emacs版本分别是多少?emacs是用的emacsosx.com下载的dmg还是brew安装的版本?
我用的macOS Mojave 10.14.5,GNU Emacs 27.0.50 (brew install emacs-plus --without-spacemacs-icon --with-jansson --with-xwidgets --HEAD
安装的)。
谢谢! 刚才试了一下27.0.50的版本, 确实lsp-python-ms就很顺滑了. 希望这个帖子能够帮助到同样在mac os下对lsp有疑惑的人~
不客气!看来native json parser 性能还是有很大提升的。
写了一个获取最新 nupkg url 的函数:
(defun lsp-python-ms-latest-nupkg-url (&optional channel)
(let ((channel (or channel "stable")))
(unless (member channel '("stable" "beta" "daily"))
(error (format "Unknown channel: %s" cnannel)))
(with-temp-buffer
(url-insert-file-contents
(concat
"https://pvsc.blob.core.windows.net/python-language-server-"
channel
"?restype=container&comp=list&prefix=Python-Language-Server-"
(cond (*macos* "osx")
(*linux* "linux")
(*winnt* "win")
(t (error (format "Unknown system: %s" system-type))))
"-x64"))
(pcase (xml-parse-region (point) (point-max))
(`((EnumerationResults
((ContainerName . ,_))
(Prefix nil ,_)
(Blobs nil . ,blobs)
(NextMarker nil)))
(cdar
(sort
(mapcar (lambda (blob)
(pcase blob
(`(Blob
nil
(Name nil ,_)
(Url nil ,url)
(Properties nil (Last-Modified nil ,last-modified) . ,_))
(cons (encode-time (parse-time-string last-modified)) url))))
blobs)
(lambda (t1 t2)
(time-less-p (car t2) (car t1))))))))))
把中间判断 system-type
那几行替换城你自己的应该就可以了,以下是在 macOS 的测试结果:
(list
(lsp-python-ms-latest-nupkg-url)
(lsp-python-ms-latest-nupkg-url "beta")
(lsp-python-ms-latest-nupkg-url "daily"))
;; =>
;; ("https://pvsc.blob.core.windows.net/python-language-server-stable/Python-Language-Server-osx-x64.0.3.20.nupkg"
;; "https://pvsc.blob.core.windows.net/python-language-server-beta/Python-Language-Server-osx-x64.0.3.20.nupkg"
;; "https://pvsc.blob.core.windows.net/python-language-server-daily/Python-Language-Server-osx-x64.0.3.20.nupkg")
另外需要特别注意的是,输出的原始 xml 里有个 NextMarker 好像是分页标记,我目前直接当作 nil 处理没有问题(如果为 t 则 pcase pattern 不起作用),说明目前是没有分页的。将来有可能会返回分页数据,不过也可能源头控制好了,不产生分页数据,否则 daily 每天一个包早就该分页了。
UPDATE: 2019-06-27 01.43.47
修复排序问题 154楼
UPDATE: 2019-06-28 15.54.21
Replace url-retrieve-synchronously
with url-insert-file-contents
手动点赞! 我也想写, 不过 elisp 不熟,还在查 url-retrieve-synchronously 和 xml-parse-<file, region, string> 之类的用法, 好好研究下你这个…
正准备自己写一个,既然老铁已经写了,我直接集成就好了
Updated:已经集成了,我觉得可以提交上游,待我测试两天。
什么,你们已经写好了??
(defun lsp-python-ms--parse-xml-result ()
(goto-char (point-min))
(if (not (and (re-search-forward (rx point (0+ (or " " "\t" "\n")) "HTTP/"
(1+ (or digit ".")) " "
(group (1+ digit))) nil t)
(= (string-to-number (match-string 1)) 200)))
(error "Failed to retrieve latest python language server resource.")
;; Goto response body
(when (re-search-forward (rx bol eol) nil t)
(forward-line)
;; Skip BOM
(re-search-forward (format "%c%c%c" #xEF #xBB #xBF) nil t)
(xml-parse-tag t))))
(defun lsp-python-ms--get-binary-alist (xml-nodes)
(cl-labels
((extract-version (str)
(when (string-match (rx "Python-Language-Server-"
(1+ char)
"-x" (or "86" "64") "."
(group (1+ (or digit ".")))
".nupkg")
str)
(match-string 1 str)))
(get-elem-body-by-name (name node)
(xml-node-children (assq name (xml-node-children node)))))
(-when-let* ((cands (-some->> xml-nodes
(get-elem-body-by-name 'Blobs)
(-map (lambda (it)
(append
(get-elem-body-by-name 'Name it)
(get-elem-body-by-name 'Url it))))))
(grouped-cands (-group-by (lambda (it)
(extract-version (car it)))
cands))
(result (cl-sort grouped-cands (lambda (a b)
(not (version< a b)))
:key #'car)))
result)))
(defun lsp-python-ms--build-url (base params)
(concat base "?"
(cl-loop for sep = "" then "&"
for (k . v) in params
concat sep
concat (url-hexify-string (format "%s" k))
concat "="
concat (url-hexify-string (format "%s" v)))))
(defun lsp-python-ms--retrieve-versions (os)
(if (not (memq os '(windows-nt gnu/linux darwin)))
(error "There's no suitable prebuilt binary for your system \"%s\"." os)
(let* ((base "https://pvsc.blob.core.windows.net/python-language-server-stable")
(params '((restype . "container")
(comp . "list")
(prefix . "Python-Language-Server")))
(url (lsp-python-ms--build-url base params))
(buf (url-retrieve-synchronously url))
(bin-alist (with-current-buffer buf
(lsp-python-ms--get-binary-alist
(lsp-python-ms--parse-xml-result)))))
bin-alist)))
我在写的时候,发现微软的服务器返回的response body居然有BOM,仁兄没遇到这种情况?
哈哈,已经写好了。仁兄这个很全面啊,但是好复杂
我遇到过,但是用pvsc.azureedge.net
这个网址就没有。
有看到,但是不影响 xml-parse-region
,所以可忽略。
是说我那个版本吗?行数是多了点,但其实也就是两个 pcase 里把 xml 节点都写了出来,当作是定位锚点了,这样比 regexp 查找或者 car / cdr 取值靠谱些。
发现有个小 bug, 因为默认是取最后一个 里面的 url, 所以不一定是最新的, 比如 daily 这个取到的 0.3.5, 但是实际上最新的版本是 0.3.20. 具体原因是因为数字排序的问题, 返回的 xml 里面把 0.3.5 排在了 0.3.20 后面…
果然,我只测了stable没有问题。这个还挺麻烦的。
果然。
我其实也有考虑过这个,但是心存侥幸,想偷点懒。
如果 url 请求参数能加一个排序字段就最好了,没有的话只能按时间戳排序了。
测试了daily,没有问题了。老铁的代码真的很简洁啊,对Emacs原生库是相当的熟悉!