亲测:lsp-python-ms vs pyls 性能

正准备自己写一个,既然老铁已经写了,我直接集成就好了 :smile::smile::smile:

Updated:已经集成了,我觉得可以提交上游,待我测试两天。

1 个赞

什么,你们已经写好了??

(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这个网址就没有。

已经成功集成到Centaur Emacs了。 lsp-python-ms-update-server可以强制升级server。 感谢 @twlz0ne

1 个赞

有看到,但是不影响 xml-parse-region,所以可忽略。

是说我那个版本吗?行数是多了点,但其实也就是两个 pcase 里把 xml 节点都写了出来,当作是定位锚点了,这样比 regexp 查找或者 car / cdr 取值靠谱些。

我是指 @cireu 的函数,还考虑 x86和x64,搜索也复杂好多。老兄的这个很简洁了,也不依赖于第三方库。赞!

发现有个小 bug, 因为默认是取最后一个 里面的 url, 所以不一定是最新的, 比如 daily 这个取到的 0.3.5, 但是实际上最新的版本是 0.3.20. 具体原因是因为数字排序的问题, 返回的 xml 里面把 0.3.5 排在了 0.3.20 后面…

果然,我只测了stable没有问题。这个还挺麻烦的。

果然。

我其实也有考虑过这个,但是心存侥幸,想偷点懒。

如果 url 请求参数能加一个排序字段就最好了,没有的话只能按时间戳排序了。

@smallzhan @seagle0128 排序问题已修复 145楼

:+1:测试了daily,没有问题了。老铁的代码真的很简洁啊,对Emacs原生库是相当的熟悉!

嗯,感谢,我就是用你的和 MatthewZMD 的配置来搞的,学到了

27.0.50比26速度快多了,不过27.0.50的xref有bug,用26的xref替换就可以了

xref 有什么 bug?

才发现原来我vscode一直用都是jedi啊,为啥不默认设成MS的pyls啊。(貌似ms-pyls背后也是jedi做补全。所以默认的这个jedi大概是指实时调用jedi补全吧?) 我之前还嘀咕vscode这么慢,还不如用我的Emacs,原来。。。。

跳转到定义的时候会报错 (cl-assertion-failed ((function fetcher) nil)) 用26中的xref替换就可以了

mspyls 不是用的 jedi。 是用的ms用c#专门写的,不过vscode不默认这个确实有点怪异。

1 个赞

M-x lsp-python-,d-update-server 会报错 wrong number of arguments:encode-time , 1.emacs版本是26.2.我的Microsoft.Python.LanguageServer执行文件是在,~/.local/bin路径下