3 eglot
brotherbus edited this page 2024-01-30 15:23:20 +00:00
  1. Install eglot
  2. Open a C/C++/ObjC source file.
  3. M-x eglot-ensure

eglot uses builtin project.el to detect the project root. If you want to use projectile:

(defun projectile-project-find-function (dir)
  (let* ((root (projectile-project-root dir)))
    (and root (cons 'transient root))))

(with-eval-after-load 'project
  (add-to-list 'project-find-functions 'projectile-project-find-function))

Completion

eglot defines completion-at-point-functions, set company-capf to the only or the first item of company-backends.

ccls has a fuzzy matching algorithm to order candidates according to your query. You may want to disable client-side sorting:

(setq company-transformers nil)

Misc

Use help window to display hierarchies:

(defun eglot-ccls-inheritance-hierarchy (&optional derived)
  "Show inheritance hierarchy for the thing at point.
If DERIVED is non-nil (interactively, with prefix argument), show
the children of class at point."
  (interactive "P")
  (if-let* ((res (jsonrpc-request
                  (eglot--current-server-or-lose)
                  :$ccls/inheritance
                  (append (eglot--TextDocumentPositionParams)
                          `(:derived ,(if derived t :json-false))
                          '(:levels 100) '(:hierarchy t))))
            (tree (list (cons 0 res))))
      (with-help-window "*ccls inheritance*"
        (with-current-buffer standard-output
          (while tree
            (pcase-let ((`(,depth . ,node) (pop tree)))
              (cl-destructuring-bind (&key uri range) (plist-get node :location)
                (insert (make-string depth ?\ ) (plist-get node :name) "\n")
                (make-text-button (+ (point-at-bol 0) depth) (point-at-eol 0)
                                  'action `(lambda (_arg)
                                            (interactive)
                                            (find-file (eglot--uri-to-path ',uri))
                                            (goto-char (car (eglot--range-region ',range)))))
                (cl-loop for child across (plist-get node :children)
                         do (push (cons (1+ depth) child) tree)))))))
    (eglot--error "Hierarchy unavailable")))