Skip to content
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

200 lines (173 sloc) 7.49 KB
;; init-lsp.el --- Initialize LSP configurations. -*- lexical-binding: t -*-
;; Copyright (C) 2019 Vincent Zhang
;; Author: Vincent Zhang <>
;; URL:
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;; Commentary:
;; Language Server Protocol (LSP) configurations.
;;; Code:
(require 'init-custom))
(pcase centaur-lsp
(use-package eglot
:hook (prog-mode . eglot-ensure)))
;; Emacs client for the Language Server Protocol
(use-package lsp-mode
:diminish lsp-mode
:hook (prog-mode . lsp-deferred)
:bind (:map lsp-mode-map
("C-c C-d" . lsp-describe-thing-at-point))
:init (setq lsp-auto-guess-root t ; Detect project root
lsp-prefer-flymake nil ; Use lsp-ui and flycheck
flymake-fringe-indicator-position 'right-fringe)
;; Configure LSP clients
(use-package lsp-clients
:ensure nil
:init (setq lsp-clients-python-library-directories '("/usr/local/" "/usr/"))))
(use-package lsp-ui
:functions my-lsp-ui-imenu-hide-mode-line
:commands lsp-ui-doc-hide
(lsp-ui-doc-background ((t (:background ,(face-background 'tooltip)))))
(lsp-ui-sideline-code-action ((t (:inherit warning))))
:bind (:map lsp-ui-mode-map
([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
([remap xref-find-references] . lsp-ui-peek-find-references)
("C-c u" . lsp-ui-imenu))
:init (setq lsp-ui-doc-enable t
lsp-ui-doc-use-webkit nil
lsp-ui-doc-delay 1.0
lsp-ui-doc-include-signature t
lsp-ui-doc-position 'at-point
lsp-ui-doc-border (face-foreground 'default)
lsp-ui-sideline-enable t
lsp-ui-sideline-show-hover nil
lsp-ui-sideline-show-diagnostics nil
lsp-ui-sideline-ignore-duplicate t
lsp-eldoc-enable-hover nil)
(add-to-list 'lsp-ui-doc-frame-parameters '(right-fringe . 8))
;; `C-g'to close doc
(advice-add #'keyboard-quit :before #'lsp-ui-doc-hide)
;; Reset `lsp-ui-doc-background' after loading theme
(add-hook 'after-load-theme-hook
(lambda ()
(setq lsp-ui-doc-border (face-foreground 'default))
(set-face-background 'lsp-ui-doc-background
(face-background 'tooltip))))
;; WORKAROUND Hide mode-line of the lsp-ui-imenu buffer
;; @see
(defun my-lsp-ui-imenu-hide-mode-line ()
"Hide the mode-line in lsp-ui-imenu."
(setq mode-line-format nil))
(advice-add #'lsp-ui-imenu :after #'my-lsp-ui-imenu-hide-mode-line))
(use-package company-lsp
:init (setq company-lsp-cache-candidates 'auto))
;; Debug
(use-package dap-mode
:functions dap-hydra/nil
:bind (:map lsp-mode-map
("<f5>" . dap-debug)
("M-<f5>" . dap-hydra))
:hook ((after-init . dap-mode)
(dap-mode . dap-ui-mode)
(dap-session-created . (lambda (&_rest) (dap-hydra)))
(dap-terminated . (lambda (&_rest) (dap-hydra/nil)))
(python-mode . (lambda () (require 'dap-python)))
(ruby-mode . (lambda () (require 'dap-ruby)))
(go-mode . (lambda () (require 'dap-go)))
(java-mode . (lambda () (require 'dap-java)))
((c-mode c++-mode objc-mode swift) . (lambda () (require 'dap-lldb)))
(php-mode . (lambda () (require 'dap-php)))
(elixir-mode . (lambda () (require 'dap-elixir)))
((js-mode js2-mode) . (lambda () (require 'dap-chrome)))))
;; `lsp-mode' and `treemacs' integration.
(when emacs/>=25.2p
(use-package lsp-treemacs
:bind (:map lsp-mode-map
("M-9" . lsp-treemacs-errors-list))))
;; Microsoft python-language-server support
(use-package lsp-python-ms
:hook (python-mode . (lambda ()
(require 'lsp-python-ms)
;; C/C++/Objective-C support
(use-package ccls
:defines projectile-project-root-files-top-down-recurring
:hook ((c-mode c++-mode objc-mode cuda-mode) . (lambda ()
(require 'ccls)
(with-eval-after-load 'projectile
(setq projectile-project-root-files-top-down-recurring
(append '("compile_commands.json"
;; Java support
(use-package lsp-java
:hook (java-mode . (lambda ()
(require 'lsp-java)
(when centaur-lsp
;; Enable LSP in org babel
(cl-defmacro lsp-org-babel-enbale (lang)
"Support LANG in org source code block."
(cl-check-type lang stringp)
(let* ((edit-pre (intern (format "org-babel-edit-prep:%s" lang)))
(intern-pre (intern (format "lsp--%s" (symbol-name edit-pre)))))
(defun ,intern-pre (info)
(let ((filename (or (->> info caddr (alist-get :file))
(setq buffer-file-name filename)
(pcase centaur-lsp
(and (fboundp 'eglot) (eglot)))
(and (fboundp 'lsp)
;; `lsp-auto-guess-root' MUST be non-nil.
(setq lsp-buffer-uri (lsp--path-to-uri filename))
(put ',intern-pre 'function-documentation
(format "Enable `%s' in the buffer of org source block (%s)."
centaur-lsp (upcase ,lang)))
(if (fboundp ',edit-pre)
(advice-add ',edit-pre :after ',intern-pre)
(defun ,edit-pre (info)
(,intern-pre info))
(put ',edit-pre 'function-documentation
(format "Prepare local buffer environment for org source block (%s)."
(upcase ,lang))))))))
(defvar org-babel-lang-list
'("go" "python" "ipython" "ruby" "js" "css" "sass" "C" "rust" "java"))
(add-to-list 'org-babel-lang-list (if emacs/>=26p "shell" "sh"))
(dolist (lang org-babel-lang-list)
(eval `(lsp-org-babel-enbale ,lang))))
(provide 'init-lsp)
;;; init-lsp.el ends here
You can’t perform that action at this time.