;; -*- lexical-binding: t; -*- ;; LSP booster (use-package lsp-mode :diminish :defines (lsp-diagnostics-disabled-modes lsp-clients-python-library-directories) :autoload lsp-enable-which-key-integration :commands (lsp-format-buffer lsp-organize-imports lsp lsp-deferred) :hook ((prog-mode . (lambda () (unless (derived-mode-p 'emacs-lisp-mode 'lisp-mode 'makefile-mode 'snippet-mode 'ron-mode) (lsp-deferred)))) ((markdown-mode yaml-mode yaml-ts-mode) . lsp-deferred) (lsp-mode . (lambda () ;; Integrate `which-key' (lsp-enable-which-key-integration) ;; (add-hook 'before-save-hook #'lsp-format-buffer t t) (add-hook 'before-save-hook #'lsp-organize-imports t t)))) :hook (lsp-completion-mode . my/lsp-mode-setup-completion) :bind (:map lsp-mode-map ("C-c c d" . lsp-describe-thing-at-point) ([remap xref-find-definitions] . lsp-find-definition) ([remap xref-find-references] . lsp-find-references)) :init (defun my/lsp-mode-setup-completion () (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults)) '(orderless))) (setq lsp-use-plists t lsp-log-io nil lsp-enable-suggest-server-download t ;; lsp-auto-configure t lsp-keymap-prefix "C-c c" lsp-keep-workspace-alive nil lsp-signature-auto-activate nil lsp-modeline-code-actions-enable nil lsp-modeline-diagnostics-enable nil lsp-modeline-workspace-status-enable nil lsp-completion-enable t lsp-completion-provider :none ;; using corfu lsp-completion-enable-additional-text-edit t lsp-enable-snippet t lsp-completion-show-kind t lsp-semantic-tokens-enable t lsp-progress-spinner-type 'progress-bar-filled lsp-enable-file-watchers nil lsp-enable-folding nil lsp-enable-symbol-highlighting nil lsp-enable-text-document-color nil lsp-enable-imenu t lsp-enable-indentation nil lsp-enable-on-type-formatting nil ;; For diagnostics lsp-diagnostics-disabled-modes '(markdown-mode gfm-mode)) :config (with-no-warnings ;; Disable `lsp-mode' in `git-timemachine-mode' (defun my/lsp--init-if-visible (fn &rest args) (unless (bound-and-true-p git-timemachine-mode) (apply fn args))) (advice-add #'lsp--init-if-visible :around #'my/lsp--init-if-visible)) ;; Enable `lsp-mode' in sh/bash/zsh (defun my/lsp-bash-check-sh-shell (&rest _) (and (memq major-mode '(sh-mode bash-ts-mode)) (memq sh-shell '(sh bash zsh)))) (advice-add #'lsp-bash-check-sh-shell :override #'my/lsp-bash-check-sh-shell) (add-to-list 'lsp-language-id-configuration '(bash-ts-mode . "shellscript")) :preface (defun lsp-booster--advice-json-parse (old-fn &rest args) "Try to parse bytecode instead of json." (or (when (equal (following-char) ?#) (let ((bytecode (read (current-buffer)))) (when (byte-code-function-p bytecode) (funcall bytecode)))) (apply old-fn args))) (advice-add (if (progn (require 'json) (fboundp 'json-parse-buffer)) 'json-parse-buffer 'json-read) :around #'lsp-booster--advice-json-parse) (defun lsp-booster--advice-final-command (old-fn cmd &optional test?) "Prepend emacs-lsp-booster command to lsp CMD." (let ((orig-result (funcall old-fn cmd test?))) (if (and (not test?) ;; for check lsp-server-present? (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper lsp-use-plists (not (functionp 'json-rpc-connection)) ;; native json-rpc (executable-find "emacs-lsp-booster")) (progn (when-let ((command-from-exec-path (executable-find (car orig-result)))) ;; resolve command from exec-path (in case not found in $PATH) (setcar orig-result command-from-exec-path)) (message "Using emacs-lsp-booster for %s!" orig-result) (append (list "emacs-lsp-booster" "--") orig-result)) orig-result))) (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command) ) (use-package consult-lsp :bind (:map lsp-mode-map ("C-M-." . consult-lsp-symbols))) (use-package lsp-ui :custom-face (lsp-ui-sideline-code-action ((t (:inherit warning)))) :pretty-hydra ((:color amaranth :quit-key ("q" "C-g")) ("Doc" (("d e" (progn (lsp-ui-doc-enable (not lsp-ui-doc-mode)) (setq lsp-ui-doc-enable (not lsp-ui-doc-enable))) "enable" :toggle lsp-ui-doc-mode) ("d s" (setq lsp-ui-doc-include-signature (not lsp-ui-doc-include-signature)) "signature" :toggle lsp-ui-doc-include-signature) ("d t" (setq lsp-ui-doc-position 'top) "top" :toggle (eq lsp-ui-doc-position 'top)) ("d b" (setq lsp-ui-doc-position 'bottom) "bottom" :toggle (eq lsp-ui-doc-position 'bottom)) ("d p" (setq lsp-ui-doc-position 'at-point) "at point" :toggle (eq lsp-ui-doc-position 'at-point)) ("d h" (setq lsp-ui-doc-header (not lsp-ui-doc-header)) "header" :toggle lsp-ui-doc-header) ("d f" (setq lsp-ui-doc-alignment 'frame) "align frame" :toggle (eq lsp-ui-doc-alignment 'frame)) ("d w" (setq lsp-ui-doc-alignment 'window) "align window" :toggle (eq lsp-ui-doc-alignment 'window))) "Sideline" (("s e" (progn (lsp-ui-sideline-enable (not lsp-ui-sideline-mode)) (setq lsp-ui-sideline-enable (not lsp-ui-sideline-enable))) "enable" :toggle lsp-ui-sideline-mode) ("s h" (setq lsp-ui-sideline-show-hover (not lsp-ui-sideline-show-hover)) "hover" :toggle lsp-ui-sideline-show-hover) ("s d" (setq lsp-ui-sideline-show-diagnostics (not lsp-ui-sideline-show-diagnostics)) "diagnostics" :toggle lsp-ui-sideline-show-diagnostics) ("s s" (setq lsp-ui-sideline-show-symbol (not lsp-ui-sideline-show-symbol)) "symbol" :toggle lsp-ui-sideline-show-symbol) ("s c" (setq lsp-ui-sideline-show-code-actions (not lsp-ui-sideline-show-code-actions)) "code actions" :toggle lsp-ui-sideline-show-code-actions) ("s i" (setq lsp-ui-sideline-ignore-duplicate (not lsp-ui-sideline-ignore-duplicate)) "ignore duplicate" :toggle lsp-ui-sideline-ignore-duplicate)) "Action" (("h" backward-char "←") ("j" next-line "↓") ("k" previous-line "↑") ("l" forward-char "→") ("C-a" mwim-beginning-of-code-or-line nil) ("C-e" mwim-end-of-code-or-line nil) ("C-b" backward-char nil) ("C-n" next-line nil) ("C-p" previous-line nil) ("C-f" forward-char nil) ("M-b" backward-word nil) ("M-f" forward-word nil) ("c" lsp-ui-sideline-apply-code-actions "apply code actions")))) :bind (("C-c u" . lsp-ui-imenu) :map lsp-ui-mode-map ("M-" . lsp-ui-hydra/body) ("s-" . lsp-ui-sideline-apply-code-actions) ([remap xref-find-definitions] . lsp-ui-peek-find-definitions) ([remap xref-find-references] . lsp-ui-peek-find-references)) :hook ((lsp-mode . lsp-ui-mode) (after-load-theme . lsp-ui-set-doc-border)) :init (setq lsp-ui-sideline-show-diagnostics nil lsp-ui-sideline-ignore-duplicate t lsp-ui-doc-delay 0.1 lsp-ui-doc-show-with-cursor (not (display-graphic-p)) lsp-ui-imenu-auto-refresh 'after-save lsp-ui-imenu-colors `(,(face-foreground 'font-lock-keyword-face) ,(face-foreground 'font-lock-string-face) ,(face-foreground 'font-lock-constant-face) ,(face-foreground 'font-lock-variable-name-face)))) (provide 'init-lsp)