;;; lsp.el --- Language Server Protocol. -*- lexical-binding: t; -*- ;;; Commentary: ;;; Code: (require 'basics/package-management) (require 'basics/global-variables) (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)) :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-enum ((t (:inherit font-lock-type-face)))) :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) (defun my/rebind-other-file-maybe () "Rebind C-: to LSP equivalent." (when (equal major-mode 'c++-mode) (bind-key "C-:" #'lsp-clangd-find-other-file 'c++-mode-map)))) :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) (lsp-mode . lsp-enable-which-key-integration) (lsp-mode . my/rebind-other-file-maybe))) ;; 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 nil) ; 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. :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 ("" . lsp-treemacs-errors-list))) (provide 'programming/lsp) ;;; lsp.el ends here