jdtsmith / eglot-booster

Boost eglot using lsp-booster
GNU General Public License v3.0
165 stars 4 forks source link

`eglot-booster--wrap` doesn't work with `eglot-alternatives` #4

Closed krisbalintona closed 8 months ago

krisbalintona commented 9 months ago

As far as I can tell, Eglot is not being boosted for entries in eglot-server-programs that are set with eglot-alternatives. For example, (eglot-alternatives '("clangd" "ccls")) is used for C programs. I have tested that when I just use "clangd" it works.

I am on the master branch of both eglot-booster and eglot.

jdtsmith commented 9 months ago

These are indeed boosted.

krisbalintona commented 9 months ago

It does not work on the master branch. The commit in which Eglot was upgraded to version 1.16 (c5a4366b3f3c6ee4178d954e58eb226441d1d2ee) is the last version these programs get boosted. The very next commit (4f017f5f0e89e07757dd2d5e0971219420920b79) breaks eglot-booster. This commit makes changes to eglot-alternatives for "experimental support for Eglot-only subprojects."

jdtsmith commented 9 months ago

I see, unfortunate. All this does is wraps an alternatives function and adds the booster prefix to its results. Can you investigate the change to alternatives and report back?

jdtsmith commented 9 months ago

Can you try initializing eglot-booster before eglot gets enabled? Seems eglot only calls alternatives once now.

krisbalintona commented 9 months ago

Can you try initializing eglot-booster before eglot gets enabled? Seems eglot only calls alternatives once now.

Unfortunately not. Doing so (from the commit after 1.16) results in the following error when starting eglot:

cl-no-applicable-method: No applicable method: make-instance, closure, :name, "EGLOT (coding/(c-ts-mode c-mode c++-mode c++-ts-mode objc-mode))", :events-buffer-config, (:size 2000000 :format full), :notification-dispatcher, (closure ((fn . eglot-handle-notification)) (server method params) (let ((eglot--cached-server server)) (apply fn server method (append params nil)))), :request-dispatcher, (closure ((fn . eglot-handle-request)) (server method params) (let ((eglot--cached-server server)) (apply fn server method (append params nil)))), :on-shutdown, eglot--on-shutdown

I wish I could help more, but my novice coding skills aren't enough to figure out a fix. For now, I've stuck to using Eglot 1.16.

jdtsmith commented 9 months ago

Just added a small fix let me know how it goes.

krisbalintona commented 9 months ago

I've tested both on 4f017f5f0e and the current master and unfortunately still not working.

On master, trying to start an eglot session works fine, but just doesn't boost. On 4f017f5f0e, the following error still occurs:

cl-no-applicable-method: No applicable method: make-instance, closure, :name, "EGLOT (coding/(c-ts-mode c-mode c++-mode c++-ts-mode objc-mode))", :events-buffer-config, (:size 2000000 :format full), :notification-dispatcher, (closure ((fn . eglot-handle-notification)) (server method params) (let ((eglot--cached-server server)) (apply fn server method (append params nil)))), :request-dispatcher, (closure ((fn . eglot-handle-request)) (server method params) (let ((eglot--cached-server server)) (apply fn server method (append params nil)))), :on-shutdown, eglot--on-shutdown

Not sure how helpful this is, but for reference, on both 4f017f5f0e and master, the following is the cdr of the c-mode entry in eglot-server-programs:

#[512
  "\211\203\0\300\207\300!\302!\203\0\303\301\"\207\207"
  [(closure
       ((alternatives
         "clangd" "ccls"))
       (&optional
        interactive
        _project)
     (let*
         ((listified
           (let*
               ((--cl-var--
                 alternatives)
                (a nil)
                (--cl-var--
                 nil))
             (while
                 (consp
                  --cl-var--)
               (setq a
                     (car
                      --cl-var--))
               (setq
                --cl-var--
                (cons
                 (if
                     (listp
                      a)
                     a
                   (list a))
                 --cl-var--))
               (setq
                --cl-var--
                (cdr
                 --cl-var--)))
             (nreverse
              --cl-var--)))
          (err
           #'(lambda nil
               (error
                "None of '%s' are valid executables"
                (mapconcat
                 #'car
                 listified
                 ", ")))))
       (cond
        ((and interactive
              current-prefix-arg)
         nil)
        (interactive
         (let*
             ((augmented
               (mapcar
                #'(lambda
                    (a)
                    (let
                        ((found
                          (eglot--executable-find
                           (car
                            a)
                           t)))
                      (and
                       found
                       (cons
                        (car
                         a)
                        (cons
                         found
                         (cdr
                          a))))))
                listified))
              (available
               (remove nil
                       augmented)))
           (cond
            ((cdr
              available)
             (cdr
              (assoc
               (completing-read
                "[eglot] More than one server executable available: "
                (mapcar
                 #'car
                 available)
                nil t nil
                nil
                (car
                 (car
                  available)))
               available
               #'equal)))
            ((cdr
              (car
               available)))
            (t nil))))
        (t
         (let*
             ((--cl-var--
               listified)
              (args nil)
              (p nil)
              (probe nil)
              (--cl-var--
               t)
              (--cl-var--
               t)
              --cl-var--)
           (while
               (and
                (consp
                 --cl-var--)
                (progn
                  (progn
                    (setq
                     args
                     (car
                      --cl-var--))
                    (setq
                     p
                     (car-safe
                      (prog1
                          args
                        (setq
                         args
                         (cdr
                          args))))))
                  (setq
                   probe
                   (eglot--executable-find
                    p t))
                  (if
                      probe
                      (progn
                        (setq
                         --cl-var--
                         (cons
                          probe
                          args))
                        (setq
                         --cl-var--
                         nil))
                    t)))
             (setq
              --cl-var--
              (cdr
               --cl-var--))
             (setq
              --cl-var--
              nil))
           (if --cl-var--
               (progn
                 (funcall
                  err)
                 nil)
             --cl-var--))))))
   ("emacs-lsp-booster"
    "--json-false-value"
    ":json-false" "--")
   eglot-booster-plain-command
   append]
  6 "
(fn &optional INTERACTIVE RETURN-OLD-FUNC)"]
jdtsmith commented 8 months ago

Can you try this with latest commit (1519a0c)? I've switched the boosting method.

krisbalintona commented 8 months ago

Tested on a few LSP servers. As far as I can tell, it works great! Even on the latest Eglot commit.

Thank you.