71 lines
3.1 KiB
Org Mode
71 lines
3.1 KiB
Org Mode
:PROPERTIES:
|
|
:ID: cce/emacs_and_the_language_server_protocol
|
|
:ROAM_ALIASES: "Language Server Protocol" LSP
|
|
:END:
|
|
#+TITLE: Emacs and the Language Server Protocol
|
|
#+filetags: :Emacs:CCE:Coding:
|
|
#+PROPERTY: header-args :mkdirp yes :results none
|
|
#+PROPERTY: header-args:emacs-lisp :tangle lsp-base.el
|
|
|
|
#+ARCOLOGY_KEY: cce/lsp-base
|
|
#+ARCOLOGY_ALLOW_CRAWL: t
|
|
|
|
#+ARROYO_EMACS_MODULE: lsp-base
|
|
#+ARROYO_MODULE_WANTS: cce/hydra.org
|
|
#+ARROYO_MODULE_WANTS: cce/evil_mode.org
|
|
#+ARROYO_MODULE_WANTS: cce/company_code_completion.org
|
|
|
|
#+begin_src emacs-lisp
|
|
(provide 'cce/lsp-base)
|
|
#+end_src
|
|
|
|
[[https://langserver.org][Language Server Protocol]] is a semi-standard protocol for IDEs and tools to be able to reason about code without having to implement direct support for that language. The complexity of language integration is handled in a server (usually written in the same language) which exposes smart information and functionality to work with the code.
|
|
|
|
What this means for me is that there is always a basic amount of support that can be implied -- there are packages which integrate [[id:cce/emacs][Emacs]] better with a language than LSP, perhaps, but that is also perhaps not necessary. I work through programming philosophy of arbitrary languages in their own pages, and focus here instead on configuring =lsp-mode= and =company-mode=
|
|
|
|
[[https://github.com/scalameta/metals/issues/2641][company-lsp is deprecated]]...
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package lsp-mode
|
|
:config
|
|
(setq lsp-file-watch-threshold nil)
|
|
(add-to-list 'company-backends 'company-capf))
|
|
(use-package lsp-ui
|
|
:config
|
|
(setq lsp-ui-doc-enable nil))
|
|
#+end_src
|
|
|
|
With =lsp-mode= installed, language support pages can just add =lsp-mode= to their programming language's mode-hook to enable it. It'll try to connect to the language server or start one, and then present functionality. I present that functionality to myself with =hydra-lsp=:
|
|
|
|
#+begin_src emacs-lisp
|
|
(defhydra hydra-lsp (:exit t :hint nil)
|
|
"
|
|
Buffer^^ Server^^ Symbol
|
|
-------------------------------------------------------------------------------------
|
|
[_f_] format [_M-r_] restart [_d_] declaration [_i_] implementation [_o_] documentation
|
|
[_m_] imenu [_S_] shutdown [_D_] definition [_t_] type [_r_] rename
|
|
[_x_] execute action [_M-s_] describe session [_R_] references [_s_] signature [_e_] flycheck"
|
|
("d" lsp-find-declaration)
|
|
("D" lsp-ui-peek-find-definitions)
|
|
("R" lsp-ui-peek-find-references)
|
|
("i" lsp-ui-peek-find-implementation)
|
|
("t" lsp-find-type-definition)
|
|
("s" lsp-signature-help)
|
|
("o" lsp-describe-thing-at-point)
|
|
("r" lsp-rename)
|
|
("e" lsp-ui-flycheck-list)
|
|
|
|
("f" lsp-format-buffer)
|
|
("m" lsp-ui-imenu)
|
|
("x" lsp-execute-code-action)
|
|
|
|
("M-s" lsp-describe-session)
|
|
("M-r" lsp-restart-workspace)
|
|
("S" lsp-shutdown-workspace))
|
|
|
|
(add-hook 'lsp-mode-hook (lambda ()
|
|
(evil-local-set-key 'normal (kbd "<SPC>l") #'hydra-lsp/body)))
|
|
#+end_src
|
|
|
|
and so in languages which support =lsp-mode=, I can hit =<SPC>ld= to jump to the declaration of a the function my point is underneath. useful stuff.
|