From 866b59d634c3de902e0979b6015f8b5824ea0b04 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 2 Sep 2018 12:08:00 -0700 Subject: [PATCH] emacs --- Emacs.md | 83 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/Emacs.md b/Emacs.md index 30b7589..f4eb8d3 100644 --- a/Emacs.md +++ b/Emacs.md @@ -1,8 +1,9 @@ 1. See [[Getting started]] to build the `ccls` executable -2. Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) -3. Install [emacs-ccls](https://github.com/MaskRay/emacs-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 may work without them, though not recommended) -5. `M-x lsp-ccls-enable`. Don't invoke `M-x lsp-mode`. `lsp-ccls-enable` will turn on `lsp-mode` for you +2. Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) and (optional) [lsp-ui](https://github.com/emacs-lsp/lsp-ui) +3. (optionally) Install [company-lsp](https://github.com/tigersoldier/company-lsp) +4. Install [emacs-ccls](https://github.com/MaskRay/emacs-ccls) and [configure](#configure) it +5. Open a source file where either [[.ccls|Getting-started#ccls]] or [[compile_commands.json]] is in the project root (it may work without them, though not recommended) +6. `M-x lsp-ccls-enable`. Don't invoke `M-x lsp-mode`. `lsp-ccls-enable` will turn on `lsp-mode` for you ### Install [emacs-ccls](https://github.com/MaskRay/emacs-ccls) @@ -15,28 +16,36 @@ The only required configuration is `ccls-executable`. Others have good defaults. `xref-find-definitions` (default: `M-.`) / highlighting of the symbol at point / type signature in echo area should work out-of-box. Read on for customization and more features. ```elisp -(setq ccls-executable "/path/to/ccls/release/ccls") +(setq ccls-executable "/path/to/ccls/Release/ccls") +;; ;; Some Linux distributions have packages that install to /usr/bin/ccls ;; (setq ccls-executable "/usr/bin/ccls") ;; ;; Log file ;; (setq ccls-extra-args '("--log-file=/tmp/cq.log")) ;; ;; Cache directory, both relative and absolute paths are supported -;; (setq ccls-cache-dir ".ccls_cached_index") +;; (setq ccls-cache-dir ".ccls-cache") ;; ;; Initialization options ;; (setq ccls-extra-init-params '(:completion (:detailedLabel t))) ``` -You may leave `ccls-executable` unchanged (default: `ccls`) and create a shell wrapper named `ccls` and put it into your `PATH`: +A more flexibal way is to leave `ccls-executable` unchanged (default: `ccls`) and create a shell wrapper named `ccls` that is in your `PATH`: ```zsh #!/bin/zsh #export CCLS_TRACEME=1 # if you want to debug ccls, stop it right after main() is called -#export LD_LIBRARY_PATH=~/Dev/llvm/release/lib # if you link against shared library libLLVM.so, not statically -exec ~/Dev/Util/ccls/release/ccls --log-file=/tmp/ccls.log "$@" +#export LD_LIBRARY_PATH=~/llvm/release/lib # if you link against shared library libLLVM.so, not statically +exec ~/ccls/Release/ccls --log-file=/tmp/ccls.log "$@" ``` +Some common settings to lsp-mode lsp-ui and emacs-ccls: + +* spacemacs `+tools/lsp` and https://github.com/syl20bnr/spacemacs/pull/11242 +* doom-emacs https://github.com/hlissner/doom-emacs/pull/716 +* MaskRay's doom-emacs configuration: + #### Projects with subprojects -For each source file that has turned on `lsp-ccls-enable`, projectile is consulted to locate the project root and 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. +When `M-x lsp-ccls-enable` 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 you do not mind files in subprojects are treated as part of the whole project in projectile: @@ -64,8 +73,6 @@ To turn on ccls for all C/C++ modes: ;; Also see lsp-project-whitelist lsp-project-blacklist ccls-root-matchers ``` -MaskRay's doom-emacs configuration: - ### Diagnostics * `M-x lsp-capabilities` LSP workspace is initialized correctly @@ -99,14 +106,7 @@ There are Helm/Ivy alternatives for `xref-find-{definitions,references,apropos}` * [helm-xref](https://github.com/brotzeit/helm-xref) * [ivy-xref](https://github.com/alexmurray/ivy-xref) -Check https://github.com/emacs-lsp/lsp-ui for a supplement of lsp-mode. It provides some higher level UI features. - -`lsp-ui-peek-find-{definitions,references}` from [lsp-ui-peek.el](https://github.com/emacs-lsp/lsp-ui/blob/master/lsp-ui-peek.el) provide peek views. An additional benefit is you get a window local jump list dedicated to cross references which I bind to C-p and C-t - -```elisp - (define-key evil-normal-state-map (kbd "C-p") 'lsp-ui-peek-jump-forward) - (define-key evil-normal-state-map (kbd "C-t") 'lsp-ui-peek-jump-backward) -``` +`lsp-ui-peek-find-{definitions,references}` from [lsp-ui-peek.el](https://github.com/emacs-lsp/lsp-ui/blob/master/lsp-ui-peek.el) provide peek views. An additional benefit is you get a window local jump list dedicated to cross references (`lsp-ui-peek-jump-forward` `lsp-ui-peek-jump-backward`) ![lsp-ui-peek-find-references](https://ptpb.pw/KUYz.jpg) @@ -114,10 +114,9 @@ Check https://github.com/emacs-lsp/lsp-ui for a supplement of lsp-mode. It provi Refer to [MaskRay's doom-emacs configuration](https://github.com/MaskRay/Config/blob/master/home/.config/doom/modules/private/my-cc/autoload.el) for fine-grained `textDocument/references` (different roles: Read/Write/Dynamic/...) -### Symbol highlight - -The identifier (or user-defined operator) at point is highlighted with its other references. If you build trunk libclang, the references will be differentiated for different usage: read/write. +### documentHighlight +The identifier (or user-defined operator) at point is highlighted with its other references. You may customize `lsp-face-highlight-*`. ![textDocument/documentHighlight](https://ptpb.pw/lQ3K.jpg) ### imenu/workspace symbol search @@ -134,15 +133,19 @@ For a symbol named `Name::FooBar`, all of `FooBar`, `foo bar`, `nafoba` find the Aside from definitions/references/workspace symbol, ccls provides some LSP extensions that find base/derived classes/methods, vars of a type, callers of a function. You may call: ```elisp -(ccls-xref-find-custom "$ccls/base") -(ccls-xref-find-custom "$ccls/callers") +(lsp-find-custom "$ccls/base") +(lsp-find-custom "$ccls/callers") ; Use lsp-goto-implementation or lsp-ui-peek-find-implementation for derived types/functions -(ccls-xref-find-custom "$ccls/vars") +(lsp-find-custom "$ccls/vars") ;; Alternatively, use lsp-ui-peek interface (lsp-ui-peek-find-custom 'base "$ccls/base") (lsp-ui-peek-find-custom 'callers "$ccls/callers") -(lsp-ui-peek-find-custom 'random "$ccls/random") ;; jump to a random declaration + +(defun ccls/vars (kind) (lsp-ui-peek-find-custom 'vars "$ccls/vars" (plist-put (lsp--text-document-position-params) :kind kind))) +(ccls/vars 3) ;; field or local variable +(ccls/vars 1) ;; field +(ccls/vars 4) ;; parameter ``` There are flattened versions of hierarchies with `:flat t`: @@ -158,6 +161,23 @@ There are flattened versions of hierarchies with `:flat t`: (append (lsp--text-document-position-params) '(:flat t :level 3 :derived t)))) ``` +Hierarchies provide a flattened xref interface: + +```elisp +(defun ccls/bases () + (interactive) + (lsp-ui-peek-find-custom 'base "$ccls/inheritanceHierarchy" + (append (lsp--text-document-position-params) '(:flat t :level 3)))) +(defun ccls/derived () + (interactive) + (lsp-ui-peek-find-custom 'derived "$ccls/inheritanceHierarchy" + (append (lsp--text-document-position-params) '(:flat t :level 3 :derived t)))) +(defun ccls/members () + (interactive) + (lsp-ui-peek-find-custom 'base "$ccls/memberHierarchy" + (append (lsp--text-document-position-params) '(:flat t)))) +``` + ### Documentation (comments) lsp-ui-doc.el renders comments in a child frame (Emacs >= 26) or inline (< 26). @@ -168,11 +188,9 @@ lsp-ui-doc.el renders comments in a child frame (Emacs >= 26) or inline (< 26). (setq lsp-ui-sideline-show-symbol nil) ; don't show symbol on the right of info ``` -Check out [MaskRay's config](https://github.com/MaskRay/Config/blob/master/home/.emacs.d/private/%2Bmy/my-code/packages.el) for some (ab)use, e.g. a hydra for next/prev arbitrary/read/write reference. The `"role"` is highly experimental, and you need a trunk libclang (>= 7.0.0) for the role feature. - ### Completion -Install [company-lsp](https://github.com/tigersoldier/company-lsp) and add `company-lsp` to `company-backends`. Consider disabling client-side cache and sorting because the server does a better job. +Add `company-lsp` to `company-backends`. ccls has a fuzzy matching algorithm to order candidates according to your query. You may want to disable client-side cache and sorting: ```elisp (setq company-transformers nil company-lsp-async t company-lsp-cache-candidates nil) @@ -180,7 +198,8 @@ Install [company-lsp](https://github.com/tigersoldier/company-lsp) and add `comp Type `#i"` (or `#include "`) for quote-style includes and `#i<` (or `#include <`) for system headers. -See https://github.com/cquery-project/cquery/pull/391#issuecomment-362872732 for an alternative view (contextual parent as detail, signature as label) +There is an alternative view (irony-mode style): + ```elisp (setq ccls-extra-init-params '(:completion (:detailedLabel t))) ``` @@ -252,6 +271,6 @@ For the long story, refer to the corresponding [emacs-devel thread](https://list For out-of-band changes to the files in the workspace that are not made in the LSP client (e.g. git pull), call `(ccls-freshen-index)` to rebuild indexes for every file or `(ccls-freshen-index (list "^/tmp/c/"))` to rebuild indexes for files matched by a regex whitelist. -* A proposal to integrate ccls and lsp-mode into spacemacs: https://github.com/syl20bnr/spacemacs/issues/10134 * Discussion of symbol hierarchies (member hierarchy, inheritance hierarchy, call hierarchy) https://github.com/emacs-lsp/lsp-ui/issues/73 * Performance of lsp-ui-flycheck https://github.com/emacs-lsp/lsp-ui/issues/45 +* A proposal to mention ccls in eglot https://github.com/joaotavora/eglot/pull/94