lsp-layer configuration and building blocks for derived layers.
See README.org for details
<<amendment 1>>
Updated some keybindings based on CONVENTIONS doc
Corrected file headers
Incorporated some immediate feedback from MaskRay
<<amendment 2>>
Corrected keybindings in README.org
<<amendment 3>>
Eliminated stray org-mode tag at table foot in README.org
Eliminated new 'l' prefix and moved bindings under 'g'
<<amendment 4>>
Updated defaults in config.el based on feedback from sebastiencs (lsp/lsp-ui dev)
- lsp-ui-sideline enabled by default
- lsp-ui-peek-expand-by-default disabled
<<amendment 5 09/04/18>>
Removed 'spacemacs/' prefix from lsp-format-buffer binding
<<amendment 6 09/04/18>>
Moved lsp-ui-peek bindings under j (jump)
Added goto bindings for new lsp-mode functions goto type definition and goto implementation
<<amendment 7 31/05/18>>
Corrected layer title in file headers
Rebased on dev tip (390462e
)
<<amendment 8 03/07/18>>
Added keybindings for lsp-describe-thing-at-point,
lsp-workspace-restart, lsp-execute-code-action suggested by Yyoncho (LSP
Java)
Added avy keyboard navigation function provided by MaskRay
Reverted lsp-ui-peek to expand by default after an upstream change that
restricts expansion to current document, addressing the previous
performance issue.
<<amendment 9 04/07/18>>
Corrected keybinding for lsp-describe-thing-at-point
<<amendment 10 19/07/18>>
Rebound lsp-restart-workspace under mlq
Declared 'lsp' prefix (myrgy)
Added evil-set-command-property fix suggested by Yyoncho
Moved lsp-c-c++ layer from private branch to this PR after spending too
many hours of my life rebasing after circle CI picks up a formatting
error :)
<<amendment 11 25/07/18>>
Rebased
Bound cquery-freshen-index under lf
Bound cquery-preprocess-file under lp
<<amendment 12 01/08/18>>
Rebased
(c-c++ layer) moved semantic refactor refactor-at-point binding from mr
to mrp to prevent key binding error when semantic layer enabled
<<amendment 13 17/08/18>>
Added option to select ccls or cquery backend based on work by myrgy
Rebased on current upstream develop
<<amendment 14 20/08/18>>
Incorporated feedback from myrgy and maskray.
Corrected some duplication/inconsistencies.
Rebased.
<<amendment 15 21/08/18>>
Reduced duplication in backend config
<<amendment 16 22/08/18>>
Removed lsp-c-c++ layer example -- to be merged with c-c++ layer once
this PR is sorted
<<amendment 17 23/08/18>>
Added CHANGELOG.develop entry as per updated contribution guidelines.
<<amendment 18 24/08/18>>
Moved some keybindings as per feedback from sdwolfz
This commit is contained in:
parent
31f4c2a005
commit
c122eb6a05
|
@ -93,7 +93,10 @@ This file containes the change log for the next major version of Spacemacs.
|
|||
- Add support for multiple backends. Supported backends are: =megahnada=,
|
||||
=eclim= and =ensime=. The default backend is =meghanada=.
|
||||
- ~SPC m e e~ is now to fix error around point. Use ~SPC e~ prefix to navigate
|
||||
between errorsl
|
||||
between errors.
|
||||
**** LSP
|
||||
- Added function =spacemacs/lsp-bind-keys-for-mode= to provide a consistent set of core keybindings across LSP layers.
|
||||
- Added a number of =lsp-ui= configuration variables to the layer - see [[file:./layers/+tools/lsp/README.org][LSP layer README]] for details.
|
||||
**** Org
|
||||
- Add package =org-journal= (Nick Anderson)
|
||||
- Move clock related key bindings to ~SPC a o k~
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
(defun spacemacs-editing/init-avy ()
|
||||
(use-package avy
|
||||
:defer t
|
||||
:commands (spacemacs/avy-open-url spacemacs/avy-goto-url avy-pop-mark)
|
||||
:commands (spacemacs/avy-open-url spacemacs/avy-goto-url avy-pop-mark avy-with)
|
||||
:init
|
||||
(progn
|
||||
(setq avy-all-windows 'all-frames)
|
||||
|
|
|
@ -4,38 +4,111 @@
|
|||
- [[#description][Description]]
|
||||
- [[#features][Features:]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#derived-layers][Derived layers]]
|
||||
- [[#spacemacslsp-bind-keys-for-mode-mode][=spacemacs/lsp-bind-keys-for-mode mode=]]
|
||||
- [[#variables][Variables]]
|
||||
- [[#diagnostics][Diagnostics]]
|
||||
- [[#future-additionsimprovements][Future additions/improvements]]
|
||||
- [[#make-spacemacslsp-bind-keys-for-mode-bind-conditionally][Make =spacemacs/lsp-bind-keys-for-mode= bind conditionally]]
|
||||
- [[#references][References]]
|
||||
|
||||
* Description
|
||||
This layer adds support for basic language server protocol packages speaking
|
||||
[[https://microsoft.github.io/language-server-protocol/specification][language server protocol]].
|
||||
This layer adds support for basic language server protocol packages speaking
|
||||
[[https://microsoft.github.io/language-server-protocol/specification][language server protocol]].
|
||||
|
||||
Different language servers may support the language server protocol to varying degrees
|
||||
and they may also provide extensions; check the language server's website for
|
||||
details.
|
||||
=M-x lsp-capabilities= in a LSP buffer to list capabilities of the server.
|
||||
|
||||
** Features:
|
||||
- Cross references (definitions, references, document symbol, workspace symbol
|
||||
search and others)
|
||||
- Workspace-wide symbol rename
|
||||
- Symbol highlighting
|
||||
- Flycheck
|
||||
- Completion with =company-lsp=
|
||||
- Signature help with eldoc
|
||||
- Symbol documentation in a child frame (=lsp-ui-doc=)
|
||||
|
||||
Each language server may support the language server protocol in varying degree
|
||||
and they may also provide extensions, check the language server's website for
|
||||
details.
|
||||
=M-x lsp-capabilities= in a LSP buffer to list capabilities of the server.
|
||||
- Cross references (definitions, references, document symbol, workspace symbol
|
||||
search and others)
|
||||
- Workspace-wide symbol rename
|
||||
- Symbol highlighting
|
||||
- Flycheck
|
||||
- Completion with =company-lsp=
|
||||
- Signature help with eldoc
|
||||
- Symbol documentation in a child frame (=lsp-ui-doc=)
|
||||
- Navigation using imenu
|
||||
|
||||
* 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]].
|
||||
Please check out their documentation.
|
||||
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]].
|
||||
Please check out their documentation.
|
||||
|
||||
If you add =lsp-*-enable= to major mode hooks for auto initialization of
|
||||
language clients, customize =lsp-project-whitelist= =lsp-project-blacklist= to
|
||||
disable projects you don't want to enable LSP.
|
||||
If you add =lsp-*-enable= to major mode hooks for auto initialization of
|
||||
language clients, customize =lsp-project-whitelist= =lsp-project-blacklist= to
|
||||
disable projects you don't want to enable LSP.
|
||||
|
||||
If some features doe not work as intended, here is a common check list.
|
||||
** Derived layers
|
||||
A number of elisp functions have been added to facilitate development of derived layers.
|
||||
|
||||
- =M-x lsp-capabilities= If the LSP workspace is initialized correctly
|
||||
- =M-: xref-backend-functions= should be =(lsp--xref-backend)= for cross
|
||||
references
|
||||
- =M-: completion-at-point-functions= should be =(lsp-completion-at-point)= for
|
||||
completion
|
||||
*** =spacemacs/lsp-bind-keys-for-mode mode=
|
||||
Binds keys to a number of lsp features useful for all/most modes for the given major mode.
|
||||
|
||||
The prefix conventions suggested in spacemacs CONVENTIONS.org have been observed, where appropriate.
|
||||
|
||||
The default bindings are listed below. Derived language server layers should extend this list.
|
||||
|
||||
| binding | function |
|
||||
|---------+-------------------------------------------------|
|
||||
| ~m = b~ | format buffer (lsp) |
|
||||
|---------+-------------------------------------------------|
|
||||
| ~m g i~ | goto implementation |
|
||||
| ~m g t~ | goto type-definition |
|
||||
| ~m g a~ | goto viewport symbol (avy) |
|
||||
| ~m g m~ | browse file symbols (lsp-ui-imenu) |
|
||||
| ~m g d~ | find definitions |
|
||||
| ~m g r~ | find references |
|
||||
| ~m g s~ | find-workspace-symbol |
|
||||
| ~m g p~ | jump prev (lsp-ui-peek stack - see Note 1) |
|
||||
| ~m g n~ | jump next (lsp-ui-peek stack - see Note 1) |
|
||||
| ~m g f~ | jump to flycheck error |
|
||||
|---------+-------------------------------------------------|
|
||||
| ~m h h~ | describe thing at point |
|
||||
|---------+-------------------------------------------------|
|
||||
| ~m l r~ | lsp-restart-workspace |
|
||||
| ~m l a~ | execute code action |
|
||||
|---------+-------------------------------------------------|
|
||||
| ~m r r~ | rename |
|
||||
|---------+-------------------------------------------------|
|
||||
| ~m T d~ | toggle documentation overlay |
|
||||
| ~m T F~ | toggle documentation overlay function signature |
|
||||
| ~m T s~ | toggle symbol info overlay |
|
||||
| ~m T S~ | toggle symbol info overlay symbol name |
|
||||
| ~m T I~ | toggle symbol info overlay duplicates |
|
||||
|
||||
Note 1: There is a window local jump list dedicated to cross references
|
||||
|
||||
** Variables
|
||||
A number of configuration variables have been exposed via the LSP layer =config.el=.
|
||||
Sensible defaults have been provided, however they may all be overridden in your .spacemacs, or dynamically using the bindings added
|
||||
under the derived mode t prefix by =(spacemacs/lsp-bind-keys-for-mode mode)=
|
||||
|
||||
| Variable name | Default | Description |
|
||||
|---------------------------------+---------+-------------------------------------------------------------------------------------------|
|
||||
| =lsp-ui-remap-xref-keybindings= | nil | When non-nil, xref keybindings 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) |
|
||||
| =lsp-ui-sideline-enable= | t | When non-nil, the symbol information overlay is displayed |
|
||||
| =lsp-ui-sideline-show-symbol= | nil | When non-nil, the symbol information overlay includes symbol name (redundant for c-modes) |
|
||||
| =lsp-ui-peek-expand-by-default= | nil | When non-nil, =lsp-ui-peek= expands file matches automatically (may degrade performance) |
|
||||
|
||||
** 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
|
||||
references
|
||||
- =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]]
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
;;; config.el --- Language Server Protocol Layer config file for Spacemacs
|
||||
;;
|
||||
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors
|
||||
;;
|
||||
;; Author: Fangrui Song <i@maskray.me>
|
||||
;; URL: https://github.com/syl20bnr/spacemacs
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
;;
|
||||
;;; License: GPLv3
|
||||
|
||||
;; ;; These all have toggles bound under 't' in spacemacs/lsp-define-keys-for-mode
|
||||
(defvar lsp-ui-remap-xref-keybindings nil "When non-nil, xref keybindings remapped to lsp-ui-peek-find-*")
|
||||
(defvar lsp-ui-peek-expand-by-default t "Expand lsp-ui-peek by default (may have performance implications)")
|
||||
(defvar lsp-ui-doc-enable t "Enable/disable lsp-ui-doc overlay")
|
||||
(defvar lsp-ui-doc-include-signature nil "When non-nil, type signature included in the lsp-ui-doc overlay")
|
||||
(defvar lsp-ui-sideline-enable t "Enable/disable lsp-ui-sideline overlay")
|
||||
(defvar lsp-ui-sideline-show-symbol nil "When non-nil, sideline includes symbol info (largely redundant for c modes)") ; don't show symbol on the right of info
|
||||
(defvar lsp-ui-sideline-ignore-duplicate t "Ignore duplicates")
|
|
@ -1,4 +1,4 @@
|
|||
;;; packages.el --- Language Server Protocol functions File for Spacemacs
|
||||
;;; funcs.el --- Language Server Protocol Layer functions file for Spacemacs
|
||||
;;
|
||||
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors
|
||||
;;
|
||||
|
@ -46,3 +46,98 @@ https://github.com/emacs-lsp/lsp-javascript/issues/9#issuecomment-379515379"
|
|||
(all-completions (company-grab-symbol) 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 "mg" "goto")
|
||||
(spacemacs/declare-prefix-for-mode mode "mh" "hierarchy")
|
||||
(spacemacs/declare-prefix-for-mode mode "ml" "lsp/backend")
|
||||
(spacemacs/declare-prefix-for-mode mode "mr" "refactor")
|
||||
(spacemacs/declare-prefix-for-mode mode "mT" "toggle")
|
||||
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
;;format
|
||||
"=b" #'lsp-format-buffer
|
||||
;;goto
|
||||
"gi" #'lsp-goto-implementation
|
||||
"gt" #'lsp-goto-type-definition
|
||||
"ga" #'spacemacs/lsp-avy-document-symbol
|
||||
"gm" #'lsp-ui-imenu
|
||||
"gd" #'lsp-ui-peek-find-definitions
|
||||
"gr" #'lsp-ui-peek-find-references
|
||||
"gs" #'lsp-ui-peek-find-workspace-symbol
|
||||
"gp" #'lsp-ui-peek-jump-backward
|
||||
"gn" #'lsp-ui-peek-jump-forward
|
||||
"gf" #'lsp-ui-flycheck-list
|
||||
;;hierarchy
|
||||
"hh" #'lsp-describe-thing-at-point
|
||||
;;jump
|
||||
;;lsp/backend
|
||||
"la" #'lsp-execute-code-action
|
||||
"lr" #'lsp-restart-workspace
|
||||
;;refactor
|
||||
"rr" #'lsp-rename
|
||||
;;toggles
|
||||
"Td" #'lsp-ui-doc-mode
|
||||
"Ts" #'lsp-ui-sideline-mode
|
||||
"TF" #'spacemacs/lsp-ui-doc-func
|
||||
"TS" #'spacemacs/lsp-ui-sideline-symb
|
||||
"TI" #'spacemacs/lsp-ui-sideline-ignore-duplicate
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
|
||||
(defun spacemacs/lsp-ui-doc-func ()
|
||||
"Toggle the function signature in the lsp-ui-doc overlay"
|
||||
(interactive)
|
||||
(setq lsp-ui-doc-include-signature (not lsp-ui-doc-include-signature)))
|
||||
|
||||
(defun spacemacs/lsp-ui-sideline-symb ()
|
||||
"Toggle the symbol in the lsp-ui-sideline overlay.
|
||||
(generally redundant in C modes)"
|
||||
(interactive)
|
||||
(setq lsp-ui-sideline-show-symbol (not lsp-ui-sideline-show-symbol)))
|
||||
|
||||
(defun spacemacs/lsp-ui-sideline-ignore-duplicate ()
|
||||
"Toggle ignore duplicates for lsp-ui-sideline overlay"
|
||||
(interactive)
|
||||
(setq lsp-ui-sideline-ignore-duplicate (not lsp-ui-sideline-ignore-duplicate)))
|
||||
|
||||
;; Used for lsp-ui-peek-mode, but may be able to use some spacemacs fn. instead?
|
||||
(defun spacemacs/lsp-define-key (keymap key def &rest bindings)
|
||||
"Define multiple key bindings with KEYMAP KEY DEF BINDINGS."
|
||||
(interactive)
|
||||
(while key
|
||||
(define-key keymap (kbd key) def)
|
||||
(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)))))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
;;; packages.el --- Language Server Protocol packages File for Spacemacs
|
||||
;;; packages.el --- Language Server Protocol Layer packages file for Spacemacs
|
||||
;;
|
||||
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors
|
||||
;;
|
||||
|
@ -11,15 +11,26 @@
|
|||
|
||||
(defconst lsp-packages
|
||||
'(
|
||||
(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)
|
||||
lsp-mode
|
||||
lsp-ui
|
||||
))
|
||||
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 ()
|
||||
(use-package lsp-mode
|
||||
:defer t
|
||||
:config
|
||||
(progn
|
||||
(spacemacs|hide-lighter lsp-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
|
||||
|
@ -28,20 +39,13 @@
|
|||
;; 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)))
|
||||
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-mode ()
|
||||
(use-package lsp-mode
|
||||
:defer t
|
||||
:config
|
||||
(progn
|
||||
(spacemacs|hide-lighter lsp-mode))))
|
||||
|
||||
(defun lsp/init-lsp-ui ()
|
||||
(use-package lsp-ui
|
||||
:defer t
|
||||
|
@ -49,5 +53,26 @@
|
|||
:config
|
||||
(progn
|
||||
(spacemacs//lsp-sync-peek-face)
|
||||
(add-hook 'spacemacs-post-theme-change-hook
|
||||
#'spacemacs//lsp-sync-peek-face))))
|
||||
(add-hook 'spacemacs-post-theme-change-hook #'spacemacs//lsp-sync-peek-face)
|
||||
|
||||
(if lsp-ui-peek-expand-by-default
|
||||
(setq lsp-ui-peek-expand-function (lambda (xs) (mapcar #'car xs))))
|
||||
|
||||
(if lsp-ui-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)))
|
||||
|
||||
(spacemacs/lsp-define-key
|
||||
lsp-ui-peek-mode-map
|
||||
"h" #'lsp-ui-peek--select-prev-file
|
||||
"j" #'lsp-ui-peek--select-next
|
||||
"k" #'lsp-ui-peek--select-prev
|
||||
"l" #'lsp-ui-peek--select-next-file
|
||||
)
|
||||
)))
|
||||
|
||||
(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)))
|
||||
|
|
Loading…
Reference in New Issue