diff --git a/layers/+tools/lsp/README.org b/layers/+tools/lsp/README.org index 0aeaed478bf3..5087e757606d 100644 --- a/layers/+tools/lsp/README.org +++ b/layers/+tools/lsp/README.org @@ -4,38 +4,89 @@ - [[#description][Description]] - [[#features][Features:]] - [[#configuration][Configuration]] + - [[#derived-layers][Derived layers]] + - [[#spacemacslsp-append-jump-handlers-mode][=(spacemacs/lsp-append-jump-handlers mode)=]] + - [[#spacemacslsp-define-keys-for-mode-mode][=spacemacs/lsp-define-keys-for-mode mode=]] + - [[#variables][Variables]] + - [[#diagnostics][Diagnostics]] * 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. + +** Derived layers + A number of elisp functions have been added to facilitate development of derived layers. + +*** =(spacemacs/lsp-append-jump-handlers mode)= + Appends =lsp-ui-peek-find-definitions= to the list of jump-handlers for a given mode. + +*** =spacemacs/lsp-define-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~ | browse file symbols (lsp-ui-imenu) | + | ~m g d~ | find definitions | + | ~m g r~ | find references | + | ~m g s~ | find-workspace-symbol | + |---------+-------------------------------------------------| + | ~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 | + +** 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-define-keys-for-mode mode)= -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. + | Variable name | Default | Description | + |---------------------------------+---------+-------------------------------------------------------------------------------------------| + | =lsp-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= | nil | 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-expend-by-default= | t | When non-nil, =lsp-ui-peek= overlay expands file matches automatically | -If some features doe not work as intended, here is a common check list. +** 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 + - =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 diff --git a/layers/+tools/lsp/config.el b/layers/+tools/lsp/config.el new file mode 100644 index 000000000000..4d4889b71b08 --- /dev/null +++ b/layers/+tools/lsp/config.el @@ -0,0 +1,19 @@ +;;; config.el --- lsp Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Fangrui Song +;; 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-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 "Omit type signature in the lsp-ui-doc overlay") +(defvar lsp-ui-sideline-enable nil "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") diff --git a/layers/+tools/lsp/funcs.el b/layers/+tools/lsp/funcs.el index 5b6aa6ae6097..053079698c99 100644 --- a/layers/+tools/lsp/funcs.el +++ b/layers/+tools/lsp/funcs.el @@ -1,4 +1,4 @@ -;;; packages.el --- Language Server Protocol functions File for Spacemacs +;;; funcs.el --- lsp Layer funcs File for Spacemacs ;; ;; Copyright (c) 2012-2018 Sylvain Benner & Contributors ;; @@ -30,3 +30,68 @@ :background (face-attribute 'highlight :background nil t) :foreground (face-attribute 'default :foreground nil t)) ) + +(defun spacemacs/lsp-append-jump-handlers (mode) + ;;; Override + (let ((handler (intern (format "spacemacs-jump-handlers-%s" mode)))) + (add-to-list handler 'lsp-ui-peek-find-definitions)) + ;; The notion of 'spacemacs-reference-handlers' is the subject of this PR: + ;; https://github.com/syl20bnr/spacemacs/pull/9911 + ;; Disabling for now... + ;; (let ((handler (intern (format "spacemacs-reference-handlers-%s" mode)))) + ;; (add-to-list handler 'lsp-ui-peek-find-references)) + ) + +(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 "ml" "lsp") + (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" #'spacemacs/lsp-format-buffer + ;;goto + "gi" #'lsp-ui-imenu + "gd" #'lsp-ui-peek-find-definitions + "gr" #'lsp-ui-peek-find-references + "gs" #'lsp-ui-peek-find-workspace-symbol + ;;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)))) diff --git a/layers/+tools/lsp/packages.el b/layers/+tools/lsp/packages.el index 83c3651221c8..cfddf70aa7ed 100644 --- a/layers/+tools/lsp/packages.el +++ b/layers/+tools/lsp/packages.el @@ -1,4 +1,4 @@ -;;; packages.el --- Language Server Protocol packages File for Spacemacs +;;; packages.el --- lsp Layer packages File for Spacemacs ;; ;; Copyright (c) 2012-2018 Sylvain Benner & Contributors ;; @@ -11,15 +11,17 @@ (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 - )) + (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-imenu :requires imenu :location built-in) + (lsp-ui-imenu :requires lsp-imenu :location built-in) + )) (defun lsp/init-company-lsp () (use-package company-lsp @@ -28,8 +30,8 @@ ;; 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 @@ -37,15 +39,39 @@ (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 :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)))) + #'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-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)))