.emacs.d/init.d/programming/lsp.el
2021-08-23 16:50:27 +02:00

127 lines
5.1 KiB
EmacsLisp

;;; lsp.el --- Language Server Protocol. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'basics/package-management)
(require 'basics/global-variables)
(require 'basics/input)
(require 'misc/completion)
(require 'programming/common)
(require 'text/common)
;; Client for Language Server Protocol servers.
(use-package lsp-mode
:defines (lsp-clients-clangd-args)
:diminish lsp-mode
:custom ((lsp-prefer-flymake nil) ; Disable flymake.
(lsp-auto-guess-root t) ; Don't ask for project root.
(lsp-eldoc-render-all nil)
(lsp-restart 'auto-restart)
(lsp-enable-semantic-highlighting t) ; Needs clangd 11(?).
(lsp-semantic-tokens-apply-modifiers t)
(lsp-keymap-prefix "C-c l")
(lsp-keep-workspace-alive nil)
(lsp-headerline-breadcrumb-segments
'(path-up-to-project file symbols))
(lsp-bash-highlight-parsing-errors t)
(lsp-modeline-diagnostics-enable nil))
:custom-face
;; Semantic highlighting. TODO: Check later if better options are available.
(lsp-face-semhl-variable ((t (:inherit font-lock-variable-name-face
:italic t))))
(lsp-face-semhl-parameter ((t (:inherit font-lock-variable-name-face
:italic t :underline t))))
(lsp-face-semhl-member ((t (:inherit default :weight semibold))))
(lsp-face-semhl-macro ((t (:inherit font-lock-preprocessor-face
:weight normal))))
(lsp-face-semhl-enum ((t (:inherit font-lock-variable-name-face
:weight semibold))))
:config (progn
(setq lsp-clients-clangd-args '("--compile-commands-dir=build"))
(when (>= (my/clangd-version) 9.0)
(add-to-list 'lsp-clients-clangd-args "--clang-tidy" t))
;; Ranking algorithm trained on snippets from a large C++ codebase.
(when (>= (my/clangd-version) 12.0)
(add-to-list 'lsp-clients-clangd-args
"--ranking-model=decision_forest" t))
;; Always enabled in >= 12.0
(when (< (my/clangd-version) 12.0)
(add-to-list 'lsp-clients-clangd-args "--recovery-ast" t)
(add-to-list 'lsp-clients-clangd-args "--background-index" t))
;; Mark lsp-clients-clangd-args as safe to override.
(put 'lsp-clients-clangd-args 'safe-local-variable #'consp)
(add-to-list 'lsp-language-id-configuration '(".*\\.csp$" . "html"))
(defun my/lsp-init ()
"Change some settings after entering lsp-mode."
;; Rebind C-: to LSP equivalent.
(when (equal major-mode 'c++-mode)
(bind-key "C-:" #'lsp-clangd-find-other-file 'c++-mode-map))
;; Don't show function name in modeline.
(which-function-mode -1)))
:bind ("C-c C-f" . lsp-execute-code-action)
:hook ((c++-mode . lsp)
(c-mode . lsp)
(python-mode . lsp)
(nxml-mode . lsp)
(json-mode . lsp)
(web-mode . lsp)
(css-mode . lsp)
(js-mode . lsp)
(dockerfile-mode . lsp)
(lsp-mode . lsp-enable-which-key-integration)
(lsp-mode . my/lsp-init)
(lsp-mode . my/company-prescient-sort-length-off)))
;; Eye-candy and flycheck support for lsp-mode.
(use-package lsp-ui
:after (lsp-mode flycheck whitespace)
:functions (my/whitespace-mode-on my/whitespace-mode-off)
:custom ((lsp-ui-sideline-enable t) ; Documentation in buffer.
(lsp-ui-doc-include-signature nil)
(lsp-ui-doc-max-width 100)
(lsp-ui-doc-max-height 20)
(lsp-ui-doc-enable t) ; Documentation popup.
(lsp-ui-doc-show-with-mouse nil)
(lsp-ui-sideline-show-diagnostics nil))
:config (defun my/lsp-ws-toggle ()
"Works around the dots-in-wrong-color bug."
(if lsp-ui-peek-mode
(my/whitespace-mode-off)
(my/whitespace-mode-on)))
:bind (:map lsp-ui-mode-map
("M-." . lsp-ui-peek-find-definitions)
("C-M-." . lsp-ui-peek-find-references)
("C-M-," . lsp-ui-peek-find-implementation))
:hook ((lsp-mode . lsp-ui-mode)
(lsp-ui-peek-mode . my/lsp-ws-toggle)))
;; ivy interface to lsp-mode.
(use-package lsp-ivy
:demand t
:after (lsp-mode ivy))
;; Integration between lsp-mode and treemacs.
(use-package lsp-treemacs
:after (treemacs lsp-ui)
:bind (:map lsp-ui-mode-map
("<f7>" . lsp-treemacs-errors-list)))
;; Debugging
(use-package dap-mode
:after (lsp-mode vterm)
:custom (dap-lldb-debug-program "/usr/bin/lldb-vscode")
:config (progn
(require 'dap-cpptools)
(require 'dap-lldb)
(add-hook 'dap-stopped-hook ; Didn't work with :hook.
(lambda (arg) (call-interactively #'dap-hydra))))
:bind (:map dap-mode-map
("C-c b" . dap-breakpoint-toggle))
:commands (dap-debug))
(provide 'programming/lsp)
;;; lsp.el ends here