mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
Add eglot.md; mv Emacs.md lsp-mode.md
parent
4f08ab476f
commit
41c4d67491
@ -6,7 +6,9 @@
|
|||||||
- [[FAQ]]
|
- [[FAQ]]
|
||||||
* Editor configuration
|
* Editor configuration
|
||||||
- [[Atom]]
|
- [[Atom]]
|
||||||
- [[Emacs]]
|
- Emacs
|
||||||
|
+ [[lsp-mode]] (+ emacs-ccls)
|
||||||
|
+ [[eglot]]
|
||||||
- Vim/Neovim
|
- Vim/Neovim
|
||||||
+ [[coc.nvim]]
|
+ [[coc.nvim]]
|
||||||
+ [[LanguageClient-neovim]]
|
+ [[LanguageClient-neovim]]
|
||||||
|
59
eglot.md
Normal file
59
eglot.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
1. See [[Getting started]] to build the `ccls` executable
|
||||||
|
2. Install [eglot](https://github.com/joaotavora/eglot)
|
||||||
|
3. Open a C/C++/ObjC source file.
|
||||||
|
4. `M-x eglot-ensure`
|
||||||
|
|
||||||
|
|
||||||
|
eglot uses builtin `project.el` to detect the project root. If you want to use projectile:
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(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:
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(setq company-transformers nil)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Misc
|
||||||
|
|
||||||
|
Use help window to display hierarchies:
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(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")))
|
||||||
|
```
|
@ -1,6 +1,6 @@
|
|||||||
1. See [[Getting started]] to build the `ccls` executable
|
1. See [[Getting started]] to build the `ccls` executable
|
||||||
2. Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) and optionally, [lsp-ui](https://github.com/emacs-lsp/lsp-ui) + [company-lsp](https://github.com/tigersoldier/company-lsp)
|
2. Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) and optionally, [lsp-ui](https://github.com/emacs-lsp/lsp-ui) + [company-lsp](https://github.com/tigersoldier/company-lsp)
|
||||||
3. Install [emacs-ccls](https://github.com/MaskRay/emacs-ccls) (ccls on Melpa) and [configure](#configure) it
|
3. Install [emacs-ccls](https://github.com/MaskRay/emacs-ccls) (Melpa: https://melpa.org/#/ccls) and [configure](#configure) it
|
||||||
4. Open a source file where either [[.ccls|Getting-started#ccls]] or [[compile_commands.json]] is in the project root (it works without them, if you don't need extra compiler command line options like `-I`)
|
4. Open a source file where either [[.ccls|Getting-started#ccls]] or [[compile_commands.json]] is in the project root (it works without them, if you don't need extra compiler command line options like `-I`)
|
||||||
5. `(require 'ccls)`, `M-x lsp`
|
5. `(require 'ccls)`, `M-x lsp`
|
||||||
|
|
||||||
@ -10,10 +10,6 @@
|
|||||||
|
|
||||||
Alternatively, you may install https://github.com/joaotavora/eglot
|
Alternatively, you may install https://github.com/joaotavora/eglot
|
||||||
|
|
||||||
### Install [emacs-ccls](https://github.com/MaskRay/emacs-ccls)
|
|
||||||
|
|
||||||
https://melpa.org/#/ccls
|
|
||||||
|
|
||||||
### Configure
|
### Configure
|
||||||
|
|
||||||
#### spacemacs
|
#### spacemacs
|
||||||
@ -27,8 +23,12 @@ set `c-c++-backend` to `lsp-ccls` in the `+lang/c-c++` layer
|
|||||||
:commands lsp
|
:commands lsp
|
||||||
:config (require 'lsp-clients))
|
:config (require 'lsp-clients))
|
||||||
|
|
||||||
(use-package ccls :defer t)
|
(use-package company-lsp
|
||||||
(add-hook 'c++-mode-hook (lambda () (require 'ccls) (lsp)))
|
:commands company-lsp)
|
||||||
|
|
||||||
|
(use-package ccls
|
||||||
|
:hook ((c-mode c++-mode objc-mode) .
|
||||||
|
(lambda () (cl-pushnew #'company-lsp company-backends) (require 'ccls) (lsp))))
|
||||||
```
|
```
|
||||||
|
|
||||||
The only required configuration is `ccls-executable`. Others have good defaults.
|
The only required configuration is `ccls-executable`. Others have good defaults.
|
||||||
@ -41,7 +41,7 @@ The only required configuration is `ccls-executable`. Others have good defaults.
|
|||||||
;; (setq ccls-executable "/usr/bin/ccls")
|
;; (setq ccls-executable "/usr/bin/ccls")
|
||||||
|
|
||||||
;; ;; Log file
|
;; ;; Log file
|
||||||
;; (setq ccls-extra-args '("--log-file=/tmp/cq.log"))
|
;; (setq ccls-extra-args '("--log-file=/tmp/ccls.log"))
|
||||||
```
|
```
|
||||||
|
|
||||||
A more flexible way is to leave `ccls-executable` unchanged (default: `ccls`) and create a shell wrapper named `ccls` that is in your `PATH`:
|
A more flexible way is to leave `ccls-executable` unchanged (default: `ccls`) and create a shell wrapper named `ccls` that is in your `PATH`:
|
||||||
@ -59,36 +59,10 @@ Some common settings to lsp-mode lsp-ui and emacs-ccls:
|
|||||||
|
|
||||||
#### Projects with subprojects
|
#### Projects with subprojects
|
||||||
|
|
||||||
When `M-x lsp-ccls-enable` is invoked, projectile is consulted to locate the project root which determines the associated lsp-mode workspace.
|
When `M-x lsp` is invoked, projectile is consulted to locate the project root which determines the associated lsp-mode workspace.
|
||||||
If your project has subprojects, `(projectile-project-root)` may think files in the subproject belong to the child workspace, which is not desired. `touch .ccls-root` in the root directory to override projectile roots.
|
If your project has subprojects, `(projectile-project-root)` may think files in the subproject belong to the child workspace, which is not desired. `touch .ccls-root` in the root directory to override projectile roots.
|
||||||
|
|
||||||
If you do not mind files in subprojects are treated as part of the whole project in projectile:
|
Read `lsp-project-whitelist lsp-project-blacklist` if you don't want to start ccls for some paths.
|
||||||
|
|
||||||
```elisp
|
|
||||||
(with-eval-after-load 'projectile
|
|
||||||
(setq projectile-project-root-files-top-down-recurring
|
|
||||||
(append '("compile_commands.json"
|
|
||||||
".ccls")
|
|
||||||
projectile-project-root-files-top-down-recurring)))
|
|
||||||
```
|
|
||||||
|
|
||||||
To turn on ccls for all C/C++ modes:
|
|
||||||
```elisp
|
|
||||||
(defun +ccls/enable ()
|
|
||||||
(condition-case nil
|
|
||||||
(lsp-ccls-enable)
|
|
||||||
(user-error nil)))
|
|
||||||
|
|
||||||
(use-package ccls
|
|
||||||
:commands lsp-ccls-enable
|
|
||||||
:init
|
|
||||||
(add-hook 'c-mode-hook #'+ccls/enable)
|
|
||||||
(add-hook 'c++-mode-hook #'+ccls/enable)
|
|
||||||
(add-hook 'objc-mode-hook #'+ccls/enable)
|
|
||||||
(add-hook 'cuda-mode-hook #'+ccls/enable)
|
|
||||||
)
|
|
||||||
;; Also see lsp-project-whitelist lsp-project-blacklist
|
|
||||||
```
|
|
||||||
|
|
||||||
### Diagnostics
|
### Diagnostics
|
||||||
|
|
||||||
@ -322,36 +296,3 @@ For out-of-band changes to the files in the workspace that are not made in the L
|
|||||||
`(ccls-reload)` to reload/rebuild indexes for every file.
|
`(ccls-reload)` to reload/rebuild indexes for every file.
|
||||||
|
|
||||||
* Performance of lsp-ui-flycheck https://github.com/emacs-lsp/lsp-ui/issues/45
|
* Performance of lsp-ui-flycheck https://github.com/emacs-lsp/lsp-ui/issues/45
|
||||||
|
|
||||||
### eglot
|
|
||||||
|
|
||||||
Use help window to display hierarchies:
|
|
||||||
|
|
||||||
```elisp
|
|
||||||
(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")))
|
|
||||||
```
|
|
Loading…
Reference in New Issue
Block a user