Created core lsp minor mode keybindings
Replaced opt-in use of `spacemacs/lsp-bind-keys-for-mode` function with keybindings for the lsp minor mode, which should be enabled for all derived layers. <<Amendment 1 26/11/2018>> Added call to (spacemacs//setup-lsp-jump-handler) to lsp-after-open-hook <<Amendment 2 04/12/2018>> Migrated to new lsp-mode package API. Updated c-c++ layer accordingly. <<Amendment 3 05/12/2018>> Incorporated PR feedback / corrections from gessen <<Amendment 4 05/12/2018>> Incorporated further feedback / corrections from gessen
This commit is contained in:
parent
5b2e969b3b
commit
aacf2a4cc1
|
@ -27,9 +27,10 @@
|
|||
- [[#formatting-clang-format][Formatting (clang-format)]]
|
||||
- [[#rtags-1][RTags]]
|
||||
- [[#cquery--ccls][cquery / ccls]]
|
||||
- [[#goto][goto]]
|
||||
- [[#helphierarchy][help/hierarchy]]
|
||||
- [[#backend-language-server][backend (language server)]]
|
||||
- [[#goto][goto]]
|
||||
- [[#gotohierarchy][goto/hierarchy]]
|
||||
- [[#gotomember][goto/member]]
|
||||
|
||||
* Description
|
||||
This layer adds configuration for C/C++ language.
|
||||
|
@ -321,6 +322,14 @@ generally applicable.
|
|||
|
||||
** cquery / ccls
|
||||
The key bindings listed below are in addition to the default key bindings defined by the [[file:../../+tools/lsp/README.org][LSP layer]].
|
||||
A ~[ccls]~ or ~[cquery]~ suffix indicates that the binding is for the indicated backend only.
|
||||
|
||||
*** backend (language server)
|
||||
|
||||
| Key Binding | Description |
|
||||
|-------------+------------------------------------------|
|
||||
| ~SPC m b f~ | refresh index (e.g. after branch change) |
|
||||
| ~SPC m b p~ | preprocess file |
|
||||
|
||||
*** goto
|
||||
|
||||
|
@ -332,23 +341,25 @@ The key bindings listed below are in addition to the default key bindings define
|
|||
| ~SPC m g c~ | find callers |
|
||||
| ~SPC m g C~ | find callees |
|
||||
| ~SPC m g v~ | vars |
|
||||
| ~SPC m g f~ | find file at point (ffap) |
|
||||
| ~SPC m g F~ | ffap other window |
|
||||
|
||||
*** help/hierarchy
|
||||
**** goto/hierarchy
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+-----------------------------|
|
||||
| ~SPC m h b~ | base class(es) |
|
||||
| ~SPC m h d~ | derived class(es) |
|
||||
| ~SPC m h c~ | call hierarchy |
|
||||
| ~SPC m h C~ | call hierarchy (inv) |
|
||||
| ~SPC m h i~ | inheritance hierarchy |
|
||||
| ~SPC m h I~ | inheritance hierarchy (inv) |
|
||||
| ~SPC m h m~ | member hierarchy |
|
||||
| ~SPC m h M~ | member hierarchy (inv) |
|
||||
| Key Binding | Description |
|
||||
|---------------+-----------------------------|
|
||||
| ~SPC m g h b~ | base class(es) |
|
||||
| ~SPC m g h d~ | derived class(es) [ccls] |
|
||||
| ~SPC m g h c~ | call hierarchy |
|
||||
| ~SPC m g h C~ | call hierarchy (inv) |
|
||||
| ~SPC m g h i~ | inheritance hierarchy |
|
||||
| ~SPC m g h I~ | inheritance hierarchy (inv) |
|
||||
|
||||
*** backend (language server)
|
||||
**** goto/member
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+------------------------------------------|
|
||||
| ~SPC m b f~ | refresh index (e.g. after branch change) |
|
||||
| ~SPC m b p~ | preprocess file |
|
||||
| Key Binding | Description |
|
||||
|---------------+-----------------------------|
|
||||
| ~SPC m g m h~ | member hierarchy |
|
||||
| ~SPC m g m t~ | member types [ccls] |
|
||||
| ~SPC m g m f~ | member functions [ccls] |
|
||||
| ~SPC m g m v~ | member variables [ccls] |
|
||||
|
|
|
@ -76,10 +76,18 @@ if no pattern matches the project root, lsp-c-c++ will be initialized.")
|
|||
(defvar c-c++-lsp-sem-highlight-rainbow nil
|
||||
"When non-nil, use rainbow semantic highlighting")
|
||||
|
||||
(defvar c-c++-lsp-initialization-options nil
|
||||
"Extra initialisation parameters to pass to the ccls backend. See
|
||||
https://github.com/MaskRay/ccls/blob/master/src/config.hh
|
||||
for details. N.B. cquery still uses the deprecated extra-init-params (below)")
|
||||
|
||||
;; I've left cquery/ccls -extra-init-params separate for now, as one has defaults while the other doesn't
|
||||
;; Just to facilitate switching between the two easily
|
||||
(defvar c-c++-lsp-extra-init-params '(:cacheFormat "msgpack")
|
||||
"Extra initialisation parameters to pass to the backend. See
|
||||
https://github.com/cquery-project/cquery/blob/master/src/config.h or
|
||||
https://github.com/MaskRay/ccls/blob/master/src/config.h
|
||||
for details.")
|
||||
|
||||
(defvar c-c++-lsp-extra-args nil
|
||||
"Extra args to pass to the backend. E.g. to log to file.
|
||||
https://github.com/MaskRay/ccls/wiki/Emacs for details")
|
||||
|
|
|
@ -225,28 +225,27 @@ and the arguments for flyckeck-clang based on a project-specific text file."
|
|||
(spacemacs//c-c++-lsp-set-config (intern (concat "c-c++-lsp-" suffix)) nil (concat "-" suffix)))
|
||||
;; -- END helper functions for common configuration of cquery and ccls backends
|
||||
|
||||
|
||||
(defun spacemacs//c-c++-lsp-enable ()
|
||||
"Enable the LSP backend specified by the `c-c++-backend' configuration variable."
|
||||
(progn (condition-case nil
|
||||
(spacemacs//c-c++-lsp-call-function "lsp-" "-enable")
|
||||
(user-error nil))))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-config ()
|
||||
"Configure the LSP backend specified by the `c-c++-backend' configuration variable."
|
||||
(progn
|
||||
(spacemacs//c-c++-lsp-setup-company)
|
||||
(spacemacs//c-c++-lsp-define-extensions)
|
||||
(spacemacs//c-c++-lsp-wrap-functions)
|
||||
(setq-default flycheck-disabled-checkers '(c/c++-clang c/c++-gcc))
|
||||
|
||||
(dolist (param '("executable" "extra-init-params" "initialization-options" "extra-args" "project-whitelist" "project-blacklist" "sem-highlight-method"))
|
||||
(spacemacs//c-c++-lsp-apply-config param))
|
||||
|
||||
(if (eq c-c++-lsp-cache-dir nil)
|
||||
(progn
|
||||
(setq c-c++-lsp-cache-dir (file-truename(concat "~/.emacs.d/.cache/" (symbol-name c-c++-backend))))
|
||||
(message (concat "c-c++: No c-c++-lsp-cache-dir specified: defaulting to " c-c++-lsp-cache-dir))))
|
||||
|
||||
(dolist (param '("executable" "extra-init-params" "cache-dir" "project-whitelist" "project-blacklist" "sem-highlight-method"))
|
||||
(spacemacs//c-c++-lsp-apply-config param))
|
||||
(ecase c-c++-backend
|
||||
('lsp-cquery (setq cquery-cache-dir c-c++-lsp-cache-dir))
|
||||
('lsp-ccls (setq ccls-initialization-options
|
||||
(if ccls-initialization-options
|
||||
(append ccls-initialization-options `(:cacheDirectory ,c-c++-lsp-cache-dir))
|
||||
`(:cacheDirectory ,c-c++-lsp-cache-dir)))))
|
||||
|
||||
(when c-c++-lsp-sem-highlight-rainbow
|
||||
(unless c-c++-lsp-sem-highlight-method
|
||||
|
@ -258,23 +257,15 @@ and the arguments for flyckeck-clang based on a project-specific text file."
|
|||
('lsp-ccls (ccls-use-default-rainbow-sem-highlight))))
|
||||
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/lsp-bind-keys-for-mode mode)
|
||||
(spacemacs//c-c++-lsp-bind-keys-for-mode mode))
|
||||
|
||||
(evil-set-initial-state '(spacemacs//c-c++-lsp-symbol nil "-tree-mode") 'emacs)
|
||||
;;evil-record-macro keybinding clobbers q in cquery-tree-mode-map for some reason?
|
||||
(evil-make-overriding-map (symbol-value (spacemacs//c-c++-lsp-symbol nil "-tree-mode-map")))))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-setup-company ()
|
||||
"Setup LSP backend auto-completion."
|
||||
(progn
|
||||
(spacemacs|add-company-backends :backends company-lsp :modes c-mode-common)
|
||||
;;Disable client-side cache and sorting, as server does a better job
|
||||
(setq company-transformers nil company-lsp-async t company-lsp-cache-candidates nil)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-wrap-functions ()
|
||||
"Wrap navigation functions for the LSP backend specified by the `c-c++-backend' configuration variable."
|
||||
(defun c-c++/call-hierarchy () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-call-hierarchy" nil))
|
||||
(defun c-c++/call-hierarchy () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-call-hierarchy"))
|
||||
(defun c-c++/call-hierarchy-inv () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-call-hierarchy" t))
|
||||
(defun c-c++/inheritance-hierarchy () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-inheritance-hierarchy"))
|
||||
(defun c-c++/inheritance-hierarchy-inv () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-inheritance-hierarchy" t))
|
||||
|
@ -302,6 +293,7 @@ and the arguments for flyckeck-clang based on a project-specific text file."
|
|||
;; members
|
||||
"gmh" #'c-c++/member-hierarchy)
|
||||
|
||||
;; goto/peek
|
||||
(spacemacs/lsp-bind-extensions-for-mode mode "c-c++"
|
||||
"&" 'refs-address
|
||||
"R" 'refs-read
|
||||
|
@ -312,10 +304,9 @@ and the arguments for flyckeck-clang based on a project-specific text file."
|
|||
"hb" 'base) ;;Replace this with lsp-goto-implementation in lsp-layer?
|
||||
|
||||
(when (eq c-c++-backend 'lsp-ccls)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"bR" 'ccls-reload)
|
||||
(spacemacs/lsp-bind-extensions-for-mode mode "c-c++"
|
||||
"mc" 'member-classes
|
||||
"hd" 'derived
|
||||
"mt" 'member-types
|
||||
"mf" 'member-functions
|
||||
"mv" 'member-vars)))
|
||||
|
||||
|
@ -348,6 +339,7 @@ and the arguments for flyckeck-clang based on a project-specific text file."
|
|||
(spacemacs/lsp-define-extensions "c-c++" 'callees "$ccls/call" '(:callee t))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'base "$ccls/inheritance")
|
||||
;;ccls features without a cquery analogue...
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'derived "$ccls/inheritance" '(:derived t))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'member-types "$ccls/member" `(:kind 2))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'member-functions "$ccls/member" `(:kind 3))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'member-vars "$ccls/member" `(:kind 0)))
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
:init
|
||||
(progn
|
||||
(add-to-list 'auto-mode-alist
|
||||
`("\\.h\\'" . ,c-c++-default-mode-for-headers))
|
||||
`("\\.h\\'" . ,c-c++-default-mode-for-headers))
|
||||
(when c-c++-enable-auto-newline
|
||||
(add-hook 'c-mode-common-hook 'spacemacs//c-toggle-auto-newline)))
|
||||
:config
|
||||
|
@ -259,15 +259,15 @@
|
|||
(spacemacs/set-leader-keys-for-major-mode mode "gi" 'cscope-index-files))))
|
||||
|
||||
;; BEGIN LSP BACKEND PACKAGES
|
||||
|
||||
;; See also https://github.com/cquery-project/cquery/wiki/Emacs
|
||||
;; :mode "\\.c..'" appears to work for deferred loading, in terms of registration with lsp layer
|
||||
;; however results in a warning in the log as the package doesn't define a function 'cquery'
|
||||
;; So probably preferable not to defer
|
||||
(defun c-c++/init-cquery ()
|
||||
(use-package cquery
|
||||
:if (eq c-c++-backend 'lsp-cquery)
|
||||
:defer t
|
||||
:commands lsp-cquery-enable
|
||||
:init
|
||||
(add-hook 'c-mode-common-hook #'spacemacs//c-c++-lsp-enable)
|
||||
(add-hook 'c-mode-common-hook 'lsp)
|
||||
:config
|
||||
(spacemacs//c-c++-lsp-config)))
|
||||
|
||||
|
@ -275,10 +275,8 @@
|
|||
(defun c-c++/init-ccls ()
|
||||
(use-package ccls
|
||||
:if (eq c-c++-backend 'lsp-ccls)
|
||||
:defer t
|
||||
:commands lsp-ccls-enable
|
||||
:init
|
||||
(add-hook 'c-mode-common-hook #'spacemacs//c-c++-lsp-enable)
|
||||
(add-hook 'c-mode-common-hook 'lsp)
|
||||
:config
|
||||
(spacemacs//c-c++-lsp-config)))
|
||||
|
||||
|
|
|
@ -6,16 +6,13 @@
|
|||
- [[#configuration][Configuration]]
|
||||
- [[#variables][Variables]]
|
||||
- [[#navigation-mode][Navigation mode]]
|
||||
- [[#extended-navigation-functions-for-derived-layers][Extended navigation functions for derived layers]]
|
||||
- [[#spacemacslsp-define-extensions-layer-name-kind-request-optional-extra-parameters][~spacemacs/lsp-define-extensions layer-name kind request &optional extra-parameters~]]
|
||||
- [[#spacemacslsp-bind-extensions-for-mode][~spacemacs/lsp-bind-extensions-for-mode~]]
|
||||
- [[#core-key-bindings-for-derived-layers][Core key bindings for derived layers]]
|
||||
- [[#declared-prefixes][Declared prefixes]]
|
||||
- [[#navigation-prefixes][Navigation prefixes]]
|
||||
- [[#default-key-bindings][Default key bindings]]
|
||||
- [[#diagnostics][Diagnostics]]
|
||||
- [[#future-additionsimprovements][Future additions/improvements]]
|
||||
- [[#make-spacemacslsp-bind-keys-for-mode-bind-conditionally][Make =spacemacs/lsp-bind-keys-for-mode= bind conditionally]]
|
||||
- [[#key-bindings][Key bindings]]
|
||||
- [[#key-binding-prefixes][Key binding prefixes]]
|
||||
- [[#core-key-bindings][Core key bindings]]
|
||||
- [[#language-specific-key-binding-extensions][Language-specific key binding extensions]]
|
||||
- [[#spacemacslsp-define-extensions-layer-name-kind-request-optional-extra-parameters][~spacemacs/lsp-define-extensions layer-name kind request &optional extra-parameters~]]
|
||||
- [[#spacemacslsp-bind-extensions-for-mode][~spacemacs/lsp-bind-extensions-for-mode~]]
|
||||
- [[#diagnostics][Diagnostics]]
|
||||
- [[#references][References]]
|
||||
|
||||
* Description
|
||||
|
@ -37,6 +34,7 @@ details.
|
|||
- Signature help with eldoc
|
||||
- Symbol documentation in a child frame (=lsp-ui-doc=)
|
||||
- Navigation using imenu
|
||||
- Consistent core keybindings in LSP modes
|
||||
|
||||
* Configuration
|
||||
The LSP ecosystem is based on two packages: [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]] and [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]].
|
||||
|
@ -53,7 +51,7 @@ under the derived mode t prefix by =(spacemacs/lsp-bind-keys-for-mode mode)=
|
|||
|
||||
| Variable name | Default | Description |
|
||||
|---------------------------------+---------+-------------------------------------------------------------------------------------------|
|
||||
| =lsp-navigation= | `both’ | `simple’ or `peek’ to bind xref OR lsp-ui-peek navigation functions |
|
||||
| =lsp-navigation= | `both’ | `simple’ or `peek’ to bind only xref OR lsp-ui-peek navigation functions |
|
||||
| =lsp-ui-remap-xref-keybindings= | nil | When non-nil, xref key bindings remapped to lsp-ui-peek-find-{definition,references} |
|
||||
| =lsp-ui-doc-enable= | t | When non-nil, the documentation overlay is displayed |
|
||||
| =lsp-ui-doc-include-signature= | nil | When nil, signature omitted from lsp-ui-doc overlay (this is usually redundant) |
|
||||
|
@ -66,12 +64,82 @@ The ~lsp-navigation~ variable defined in =config.el= allows you to define a pref
|
|||
and the =lsp-ui-peek= variants under ~SPC m G~. Setting ~lsp-navigation~ to either ~'simple~ or ~'peek~ eliminates
|
||||
the bindings under ~SPC m G~ and creates bindings under ~SPC m g~ according to the specified preference.
|
||||
|
||||
*** Extended navigation functions for derived layers
|
||||
* Key bindings
|
||||
A number of lsp features useful for all/most modes have been bound to the lsp minor mode, meaning they'll be
|
||||
available in all language layers based on the lsp layer.
|
||||
|
||||
** Key binding prefixes
|
||||
The key bindings are grouped under the following prefixes:
|
||||
|
||||
| prefix | name | functional area |
|
||||
|-----------+-------------+----------------------------------------------------------------------------|
|
||||
| ~SPC m =~ | format | Source formatting |
|
||||
| ~SPC m g~ | goto | Source navigation |
|
||||
| ~SPC m G~ | peek | Source navigation (lsp-ui-peek overlay) |
|
||||
| ~SPC m h~ | help | Help |
|
||||
| ~SPC m b~ | lsp/backend | Catchall. Restart LSP backend, other implementation-specific functionality |
|
||||
| ~SPC m r~ | refactor | What it says on the tin |
|
||||
| ~SPC m T~ | toggle | Toggle LSP backend features (documentation / symbol info overlays etc.) |
|
||||
|
||||
Some navigation keybindings (i.e. ~SPC m g~ / ~SPC m G~) use an additional level of grouping:
|
||||
|
||||
| prefix | name | functional area |
|
||||
|-----------------+------------------+----------------------------------------------------------|
|
||||
| ~SPC m <g/G> h~ | hierarchy | Heirarchy (i.e. call/inheritance hierarchy etc. ) |
|
||||
| ~SPC m <g/G> m~ | member hierarchy | Class/namespace members (functions, nested classes, vars |
|
||||
|
||||
** Core key bindings
|
||||
The lsp minor mode bindings are:
|
||||
|
||||
| binding | function |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m = b~ | format buffer (lsp) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m g t~ | goto type-definition (lsp) |
|
||||
| ~SPC m g k~ | goto viewport word (avy) (See Note 1) |
|
||||
| ~SPC m g K~ | goto viewport symbol (avy) (See Note 1) |
|
||||
| ~SPC m g e~ | browse flycheck errors |
|
||||
| ~SPC m g M~ | browse file symbols (lsp-ui-imenu) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| Note | /Replaced by the lsp-ui-peek equivalents when ~lsp-navigation~ == ='peek=/ |
|
||||
| ~SPC m g i~ | find implementations (lsp) |
|
||||
| ~SPC m g d~ | find definitions (xref/lsp) |
|
||||
| ~SPC m g r~ | find references (xref/lsp) |
|
||||
| ~SPC m g s~ | find-workspace-symbol (lsp-ui) |
|
||||
| ~SPC m g p~ | goto previous (xref-pop-marker-stack) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| Note | /Omitted when ~lsp-navigation~ == ='peek= or ='simple=/ |
|
||||
| | /Bound under ~SPC m g~ rather than ~SPC m G~ when ~lsp-navigation~ == ='peek=/ |
|
||||
| ~SPC m G i~ | find implementation (lsp-ui-peek) |
|
||||
| ~SPC m G d~ | find definitions (lsp-ui-peek) |
|
||||
| ~SPC m G r~ | find references (lsp-ui-peek) |
|
||||
| ~SPC m G s~ | find-workspace-symbol (lsp-ui-peek) |
|
||||
| ~SPC m G p~ | goto previous (lsp-ui-peek stack - see Note 2) |
|
||||
| ~SPC m G n~ | goto next (lsp-ui-peek stack - see Note 2) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m h h~ | describe thing at point |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m b r~ | lsp-restart-workspace |
|
||||
| ~SPC m b a~ | execute code action |
|
||||
| ~SPC m b c~ | lsp-capabilities |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m r r~ | rename |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m T d~ | toggle documentation overlay |
|
||||
| ~SPC m T F~ | toggle documentation overlay function signature |
|
||||
| ~SPC m T s~ | toggle symbol info overlay |
|
||||
| ~SPC m T S~ | toggle symbol info overlay symbol name |
|
||||
| ~SPC m T I~ | toggle symbol info overlay duplicates |
|
||||
|
||||
Note 1: Your language server may not distinguish between the word and symbol variants of this binding.
|
||||
Note 2: There is a window local jump list dedicated to cross references.
|
||||
|
||||
** Language-specific key binding extensions
|
||||
Some LSP server implementations provide extensions to the protocol, which can be leveraged using ~lsp-find-custom~
|
||||
or ~lsp-ui-peek-find-custom~. A number of additional functions have been provided to facilitate wrapping these extensions
|
||||
in a manner consistent with the ~lsp-navigation~ setting.
|
||||
|
||||
**** ~spacemacs/lsp-define-extensions layer-name kind request &optional extra-parameters~
|
||||
*** ~spacemacs/lsp-define-extensions layer-name kind request &optional extra-parameters~
|
||||
Use this to define an extension to the lsp find functions. An example from the c-c++ layer:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
|
@ -84,7 +152,7 @@ This defines the following interactive functions:
|
|||
- ~c-c++/find-refs-address~
|
||||
- ~c-c++/peek-refs-address~
|
||||
|
||||
**** ~spacemacs/lsp-bind-extensions-for-mode~
|
||||
*** ~spacemacs/lsp-bind-extensions-for-mode~
|
||||
Use this to bind one or more extensions under ~SPC m g~ and/or ~SPC m G~, as dictated by the value of ~lsp-navigation~.
|
||||
Using another example from the c-c++ layer:
|
||||
|
||||
|
@ -130,76 +198,7 @@ whereas with ~lsp-navigation~ set to ~'peek~, this is equivalent to:
|
|||
|
||||
etc.
|
||||
|
||||
** Core key bindings for derived layers
|
||||
The ~spacemacs/lsp-bind-keys-for-mode mode~ function binds keys to a number of lsp features useful for all/most modes
|
||||
for the given major mode. It also declares some relevant keyboard shortcut prefixes.
|
||||
|
||||
*** Declared prefixes
|
||||
The following prefixes have been declared:
|
||||
|
||||
| prefix | name | functional area |
|
||||
|-----------+-------------+----------------------------------------------------------------------------|
|
||||
| ~SPC m =~ | format | Source formatting |
|
||||
| ~SPC m g~ | goto | Source navigation |
|
||||
| ~SPC m G~ | peek | Source navigation (lsp-ui-peek overlay) |
|
||||
| ~SPC m h~ | help | Help |
|
||||
| ~SPC m b~ | lsp/backend | Catchall. Restart LSP backend, other implementation-specific functionality |
|
||||
| ~SPC m r~ | refactor | What it says on the tin |
|
||||
| ~SPC m T~ | toggle | Toggle LSP backend features (documentation / symbol info overlays etc.) |
|
||||
|
||||
**** Navigation prefixes
|
||||
The following prefixes have been declared under each of the navigation prefixes (i.e. ~SPC m g~ / ~SPC m G~)
|
||||
|
||||
| prefix | name | functional area |
|
||||
|-----------------+------------------+----------------------------------------------------------|
|
||||
| ~SPC m <g/G> h~ | hierarchy | Heirarchy (i.e. call/inheritance hierarchy etc. ) |
|
||||
| ~SPC m <g/G> m~ | member hierarchy | Class/namespace members (functions, nested classes, vars |
|
||||
|
||||
*** Default key bindings
|
||||
The default bindings are listed below. Derived language server layers should extend this list.
|
||||
|
||||
| binding | function |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m = b~ | format buffer (lsp) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m g t~ | goto type-definition (lsp) |
|
||||
| ~SPC m g k~ | goto viewport symbol (avy) |
|
||||
| ~SPC m g e~ | browse flycheck errors |
|
||||
| ~SPC m g M~ | browse file symbols (lsp-ui-imenu) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| Note | /Replaced by the lsp-ui-peek equivalents when ~lsp-navigation~ == ='peek=/ |
|
||||
| ~SPC m g i~ | find implementations (lsp) |
|
||||
| ~SPC m g d~ | find definitions (xref/lsp) |
|
||||
| ~SPC m g r~ | find references (xref/lsp) |
|
||||
| ~SPC m g s~ | find-workspace-symbol (lsp-ui) |
|
||||
| ~SPC m g p~ | goto previous (xref-pop-marker-stack) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| Note | /Omitted when ~lsp-navigation~ == ='peek= or ='simple=/ |
|
||||
| | /Bound under ~SPC m g~ rather than ~SPC m G~ when ~lsp-navigation~ == ='peek=/ |
|
||||
| ~SPC m G i~ | find implementation (lsp-ui-peek) |
|
||||
| ~SPC m G d~ | find definitions (lsp-ui-peek) |
|
||||
| ~SPC m G r~ | find references (lsp-ui-peek) |
|
||||
| ~SPC m G s~ | find-workspace-symbol (lsp-ui-peek) |
|
||||
| ~SPC m G p~ | goto previous (lsp-ui-peek stack - see Note 1) |
|
||||
| ~SPC m G n~ | goto next (lsp-ui-peek stack - see Note 1) |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m h h~ | describe thing at point |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m b r~ | lsp-restart-workspace |
|
||||
| ~SPC m b a~ | execute code action |
|
||||
| ~SPC m b c~ | lsp-capabilities |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m r r~ | rename |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
| ~SPC m T d~ | toggle documentation overlay |
|
||||
| ~SPC m T F~ | toggle documentation overlay function signature |
|
||||
| ~SPC m T s~ | toggle symbol info overlay |
|
||||
| ~SPC m T S~ | toggle symbol info overlay symbol name |
|
||||
| ~SPC m T I~ | toggle symbol info overlay duplicates |
|
||||
|
||||
Note 1: There is a window local jump list dedicated to cross references
|
||||
|
||||
** Diagnostics
|
||||
* Diagnostics
|
||||
If some features do not work as expected, here is a common check list.
|
||||
- =M-x lsp-capabilities= If the LSP workspace is initialized correctly
|
||||
- =M-: xref-backend-functions= should be =(lsp--xref-backend)= for cross
|
||||
|
@ -207,12 +206,6 @@ If some features do not work as expected, here is a common check list.
|
|||
- =M-: completion-at-point-functions= should be =(lsp-completion-at-point)= for
|
||||
completion
|
||||
|
||||
* Future additions/improvements
|
||||
** Make =spacemacs/lsp-bind-keys-for-mode= bind conditionally
|
||||
i.e. only bind keys if the language server supports the capability (queried using =lsp-capabilities=).
|
||||
=lsp-capabilities= uses current buffer to determine the language server, so this would probably entail adding the bindings dynamically in
|
||||
a mode hook.
|
||||
|
||||
* References
|
||||
- [[https://github.com/emacs-lsp/lsp-mode][lsp-mode repo]]
|
||||
- [[https://github.com/emacs-lsp/lsp-ui][lsp-ui repo]]
|
||||
|
|
|
@ -9,33 +9,11 @@
|
|||
;;
|
||||
;;; License: GPLv3
|
||||
|
||||
(defun spacemacs//lsp-sync-peek-face ()
|
||||
"Synchronize the face used in `lsp-ui' peek window according to the theme."
|
||||
(set-face-attribute 'lsp-ui-peek-list nil
|
||||
:background (face-attribute 'hl-line :background nil t))
|
||||
(set-face-attribute 'lsp-ui-peek-peek nil
|
||||
:background (face-attribute 'hl-line :background nil t))
|
||||
(set-face-attribute 'lsp-ui-peek-selection nil
|
||||
:background (face-attribute 'highlight :background nil t)
|
||||
:foreground (face-attribute 'default :foreground nil t))
|
||||
(set-face-attribute 'lsp-ui-peek-filename nil
|
||||
:foreground (face-attribute 'font-lock-constant-face
|
||||
:foreground nil t))
|
||||
(set-face-attribute 'lsp-ui-peek-highlight nil
|
||||
:background (face-attribute 'highlight :background nil t)
|
||||
:foreground (face-attribute 'highlight :foreground nil t)
|
||||
:distant-foreground (face-attribute 'highlight
|
||||
:foreground nil t))
|
||||
(set-face-attribute 'lsp-ui-peek-header nil
|
||||
:background (face-attribute 'highlight :background nil t)
|
||||
:foreground (face-attribute 'default :foreground nil t))
|
||||
)
|
||||
|
||||
(defun spacemacs//setup-lsp-jump-handler (&rest modes)
|
||||
"Set jump handler for LSP with the given MODE."
|
||||
(dolist (m modes)
|
||||
(add-to-list (intern (format "spacemacs-jump-handlers-%S" m))
|
||||
'(lsp-ui-peek-find-definitions :async t))))
|
||||
'(lsp-ui-peek-find-definitions :async t))))
|
||||
|
||||
(defun fix-lsp-company-prefix ()
|
||||
"fix lsp-javascript company prefix
|
||||
|
@ -44,33 +22,28 @@ https://github.com/emacs-lsp/lsp-javascript/issues/9#issuecomment-379515379"
|
|||
(defun lsp-prefix-company-transformer (candidates)
|
||||
(let ((completion-ignore-case t))
|
||||
(if (and (car candidates)
|
||||
(get-text-property 0 'lsp-completion-prefix (car candidates)))
|
||||
(all-completions (company-grab-symbol) candidates)
|
||||
(get-text-property 0 'lsp-completion-prefix (car candidates)))
|
||||
(all-completions (company-grab-symbol) candidates)
|
||||
candidates)))
|
||||
(make-local-variable 'company-transformers)
|
||||
(add-to-list 'company-transformers 'lsp-prefix-company-transformer))
|
||||
|
||||
(defun spacemacs/lsp-bind-keys-for-mode (mode)
|
||||
"Define key bindings for the specific MODE."
|
||||
(spacemacs/declare-prefix-for-mode mode "m=" "format")
|
||||
(spacemacs/declare-prefix-for-mode mode "mh" "help")
|
||||
(spacemacs/declare-prefix-for-mode mode "mb" "backend")
|
||||
(spacemacs/declare-prefix-for-mode mode "mr" "refactor")
|
||||
(spacemacs/declare-prefix-for-mode mode "mT" "toggle")
|
||||
(spacemacs/declare-prefix-for-mode mode "mg" "goto")
|
||||
(spacemacs/declare-prefix-for-mode mode "mG" "peek")
|
||||
(dolist (prefix '("mg" "mG"))
|
||||
(spacemacs/declare-prefix-for-mode mode (concat prefix "h") "hierarchy")
|
||||
(spacemacs/declare-prefix-for-mode mode (concat prefix "m") "members"))
|
||||
(defun spacemacs/lsp-bind-keys ()
|
||||
"Define key bindings for the lsp minor mode."
|
||||
(ecase lsp-navigation
|
||||
('simple (spacemacs//lsp-bind-simple-navigation-functions "g"))
|
||||
('peek (spacemacs//lsp-bind-peek-navigation-functions "g"))
|
||||
('both
|
||||
(spacemacs//lsp-bind-simple-navigation-functions "g")
|
||||
(spacemacs//lsp-bind-peek-navigation-functions "G")))
|
||||
|
||||
(spacemacs//lsp-bind-navigation-keys-for-mode mode)
|
||||
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
(spacemacs/set-leader-keys-for-minor-mode 'lsp-mode
|
||||
;;format
|
||||
"=b" #'lsp-format-buffer
|
||||
;;goto
|
||||
"gt" #'lsp-goto-type-definition
|
||||
"gk" #'spacemacs/lsp-avy-document-symbol
|
||||
"gk" #'spacemacs/lsp-avy-goto-word
|
||||
"gK" #'spacemacs/lsp-avy-goto-symbol
|
||||
"ge" #'lsp-ui-flycheck-list
|
||||
"gM" #'lsp-ui-imenu
|
||||
;;help
|
||||
|
@ -89,24 +62,16 @@ https://github.com/emacs-lsp/lsp-javascript/issues/9#issuecomment-379515379"
|
|||
"TS" #'spacemacs/lsp-ui-sideline-symb
|
||||
"TI" #'spacemacs/lsp-ui-sideline-ignore-duplicate))
|
||||
|
||||
(defun spacemacs//lsp-bind-navigation-keys-for-mode (mode)
|
||||
(ecase lsp-navigation
|
||||
('simple (spacemacs//lsp-bind-simple-navigation-functions-for-mode mode "g"))
|
||||
('peek (spacemacs//lsp-bind-peek-navigation-functions-for-mode mode "g"))
|
||||
('both
|
||||
(spacemacs//lsp-bind-simple-navigation-functions-for-mode mode "g")
|
||||
(spacemacs//lsp-bind-peek-navigation-functions-for-mode mode "G"))))
|
||||
|
||||
(defun spacemacs//lsp-bind-simple-navigation-functions-for-mode (mode prefix-char)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
(defun spacemacs//lsp-bind-simple-navigation-functions (prefix-char)
|
||||
(spacemacs/set-leader-keys-for-minor-mode 'lsp-mode
|
||||
(concat prefix-char "i") #'lsp-goto-implementation
|
||||
(concat prefix-char "d") #'xref-find-definitions
|
||||
(concat prefix-char "r") #'xref-find-references
|
||||
(concat prefix-char "s") #'lsp-ui-find-workspace-symbol
|
||||
(concat prefix-char "p") #'xref-pop-marker-stack))
|
||||
|
||||
(defun spacemacs//lsp-bind-peek-navigation-functions-for-mode (mode prefix-char)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
(defun spacemacs//lsp-bind-peek-navigation-functions (prefix-char)
|
||||
(spacemacs/set-leader-keys-for-minor-mode 'lsp-mode
|
||||
(concat prefix-char "i") #'lsp-ui-peek-find-implementation
|
||||
(concat prefix-char "d") #'lsp-ui-peek-find-definitions
|
||||
(concat prefix-char "r") #'lsp-ui-peek-find-references
|
||||
|
@ -114,6 +79,19 @@ https://github.com/emacs-lsp/lsp-javascript/issues/9#issuecomment-379515379"
|
|||
(concat prefix-char "p") #'lsp-ui-peek-jump-backward
|
||||
(concat prefix-char "n") #'lsp-ui-peek-jump-forward))
|
||||
|
||||
(defun spacemacs//lsp-declare-prefixes-for-mode (mode)
|
||||
"Define key binding prefixes for the specific MODE."
|
||||
(spacemacs/declare-prefix-for-mode mode "m=" "format")
|
||||
(spacemacs/declare-prefix-for-mode mode "mh" "help")
|
||||
(spacemacs/declare-prefix-for-mode mode "mb" "backend")
|
||||
(spacemacs/declare-prefix-for-mode mode "mr" "refactor")
|
||||
(spacemacs/declare-prefix-for-mode mode "mT" "toggle")
|
||||
(spacemacs/declare-prefix-for-mode mode "mg" "goto")
|
||||
(spacemacs/declare-prefix-for-mode mode "mG" "peek")
|
||||
(dolist (prefix '("mg" "mG"))
|
||||
(spacemacs/declare-prefix-for-mode mode (concat prefix "h") "hierarchy")
|
||||
(spacemacs/declare-prefix-for-mode mode (concat prefix "m") "members")))
|
||||
|
||||
(defun spacemacs/lsp-ui-doc-func ()
|
||||
"Toggle the function signature in the lsp-ui-doc overlay"
|
||||
(interactive)
|
||||
|
@ -139,35 +117,6 @@ https://github.com/emacs-lsp/lsp-javascript/issues/9#issuecomment-379515379"
|
|||
(setq key (pop bindings)
|
||||
def (pop bindings))))
|
||||
|
||||
;; From https://github.com/MaskRay/Config/blob/master/home/.config/doom/autoload/misc.el#L118
|
||||
;;;###autoload
|
||||
(defun spacemacs/lsp-avy-document-symbol ()
|
||||
(interactive)
|
||||
(let (ranges point0 point1 (line 0) (col 0) (w (selected-window)) candidates)
|
||||
(save-excursion
|
||||
(goto-char 1)
|
||||
(dolist (loc
|
||||
(lsp--send-request (lsp--make-request
|
||||
"textDocument/documentSymbol"
|
||||
;;;;;; I added :all t in ccls to return all symbols in the document
|
||||
`(:textDocument ,(lsp--text-document-identifier) :all t))))
|
||||
(let ((range (->> loc (gethash "location") (gethash "range"))))
|
||||
(-let* [((&hash "line" l0 "character" c0) (gethash "start" range))
|
||||
((&hash "line" l1 "character" c1) (gethash "end" range))]
|
||||
(when (or (< line l0) (and (= line l0) (<= col c0)))
|
||||
(forward-line (- l0 line))
|
||||
(forward-char c0)
|
||||
(setq point0 (point))
|
||||
(forward-line (- l1 l0))
|
||||
(forward-char c1)
|
||||
(setq point1 (point))
|
||||
(setq line l1 col c1)
|
||||
(push `((,point0 . ,point1) . ,w) candidates))))))
|
||||
(avy-with avy-document-symbol
|
||||
(avy--process candidates
|
||||
(avy--style-fn avy-style)))))
|
||||
|
||||
|
||||
;; These functions facilitate extension of the navigation-mode keybindings in derived layers
|
||||
;; See c/c++ layer for a usage example
|
||||
(defun spacemacs//lsp-get-extension-name (layer-name nav-mode kind)
|
||||
|
@ -209,3 +158,51 @@ a find extension defined using `lsp-define-extensions'"
|
|||
(while key
|
||||
(spacemacs//lsp-bind-extensions mode layer-name key kind)
|
||||
(setq key (pop bindings) kind (pop bindings))))
|
||||
|
||||
(defun spacemacs/lsp-avy-goto-word ()
|
||||
(interactive)
|
||||
(spacemacs//lsp-avy-document-symbol t))
|
||||
|
||||
(defun spacemacs/lsp-avy-goto-symbol ()
|
||||
(interactive)
|
||||
(spacemacs//lsp-avy-document-symbol nil))
|
||||
|
||||
;; From https://github.com/MaskRay/Config/blob/master/home/.config/doom/autoload/misc.el#L118
|
||||
(defun spacemacs//lsp-avy-document-symbol (all)
|
||||
(interactive)
|
||||
(let ((line 0) (col 0) (w (selected-window))
|
||||
(ccls (and (memq major-mode '(c-mode c++-mode objc-mode)) (eq c-c++-backend 'lsp-ccls)))
|
||||
(start-line (1- (line-number-at-pos (window-start))))
|
||||
(end-line (1- (line-number-at-pos (window-end))))
|
||||
ranges point0 point1
|
||||
candidates)
|
||||
(save-excursion
|
||||
(goto-char 1)
|
||||
(cl-loop for loc in
|
||||
(lsp--send-request (lsp--make-request
|
||||
"textDocument/documentSymbol"
|
||||
`(:textDocument ,(lsp--text-document-identifier)
|
||||
:all ,(if all t :json-false)
|
||||
:startLine ,start-line :endLine ,end-line)))
|
||||
for range = (if ccls loc (->> loc (gethash "location") (gethash "range")))
|
||||
for range_start = (gethash "start" range)
|
||||
for range_end = (gethash "end" range)
|
||||
for l0 = (gethash "line" range_start)
|
||||
for c0 = (gethash "character" range_start)
|
||||
for l1 = (gethash "line" range_end)
|
||||
for c1 = (gethash "character" range_end)
|
||||
while (<= l0 end-line)
|
||||
when (>= l0 start-line)
|
||||
do
|
||||
(forward-line (- l0 line))
|
||||
(forward-char c0)
|
||||
(setq point0 (point))
|
||||
(forward-line (- l1 l0))
|
||||
(forward-char c1)
|
||||
(setq point1 (point))
|
||||
(setq line l1 col c1)
|
||||
(push `((,point0 . ,point1) . ,w) candidates)))
|
||||
;; (require 'avy)
|
||||
(avy-with avy-document-symbol
|
||||
(avy--process candidates
|
||||
(avy--style-fn avy-style)))))
|
||||
|
|
|
@ -13,14 +13,7 @@
|
|||
'(
|
||||
lsp-mode
|
||||
lsp-ui
|
||||
(lsp-imenu :requires imenu :location built-in)
|
||||
(lsp-ui-imenu :requires lsp-imenu :location built-in)
|
||||
(company-lsp :requires company)
|
||||
;; `flycheck-lsp' does not exist so we defined it as built-in to avoid
|
||||
;; fetching it from ELPA repositories.
|
||||
;; this logical package serves to hook all flycheck related configuration
|
||||
;; for LSP.
|
||||
(flycheck-lsp :requires flycheck :location built-in)
|
||||
))
|
||||
|
||||
(defun lsp/init-lsp-mode ()
|
||||
|
@ -28,33 +21,19 @@
|
|||
:defer t
|
||||
:config
|
||||
(progn
|
||||
(spacemacs|hide-lighter lsp-mode)
|
||||
(spacemacs/lsp-bind-keys)
|
||||
(add-hook 'lsp-after-open-hook (lambda ()
|
||||
"Setup xref jump handler and declare keybinding prefixes"
|
||||
(spacemacs//setup-lsp-jump-handler major-mode)
|
||||
(spacemacs//lsp-declare-prefixes-for-mode major-mode)))
|
||||
(evil-set-command-property 'lsp-goto-type-definition :jump t)
|
||||
(evil-set-command-property 'lsp-goto-implementation :jump t))))
|
||||
|
||||
(defun lsp/init-company-lsp ()
|
||||
(use-package company-lsp
|
||||
:defer t
|
||||
:init
|
||||
;; Language servers have better idea filtering and sorting,
|
||||
;; don't filter results on the client side.
|
||||
(setq company-transformers nil
|
||||
company-lsp-async t
|
||||
company-lsp-cache-candidates nil)))
|
||||
|
||||
(defun lsp/init-flycheck-lsp ()
|
||||
;; Disable lsp-flycheck.el in favor of lsp-ui-flycheck.el
|
||||
(setq lsp-enable-flycheck nil))
|
||||
|
||||
(defun lsp/init-lsp-ui ()
|
||||
(use-package lsp-ui
|
||||
:defer t
|
||||
:init (add-hook 'lsp-mode-hook #'lsp-ui-mode)
|
||||
:config
|
||||
(progn
|
||||
(spacemacs//lsp-sync-peek-face)
|
||||
(add-hook 'spacemacs-post-theme-change-hook #'spacemacs//lsp-sync-peek-face)
|
||||
|
||||
(if lsp-remap-xref-keybindings
|
||||
(progn (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
|
||||
(define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)))
|
||||
|
@ -68,8 +47,5 @@
|
|||
)
|
||||
)))
|
||||
|
||||
(defun lsp/init-lsp-imenu ()
|
||||
(use-package lsp-imenu :defer t :init (add-hook 'lsp-after-open-hook #'lsp-enable-imenu)))
|
||||
|
||||
(defun lsp/init-lsp-ui-imenu ()
|
||||
(use-package lsp-ui-imenu :defer t :config (evil-make-overriding-map lsp-ui-imenu-mode-map)))
|
||||
(defun lsp/init-company-lsp ()
|
||||
(use-package company-lsp :defer t))
|
||||
|
|
Loading…
Reference in New Issue