Skip to content

Latest commit

 

History

History
555 lines (529 loc) · 54.7 KB

README.org

File metadata and controls

555 lines (529 loc) · 54.7 KB

https://melpa.org/packages/lsp-mode-badge.svg https://stable.melpa.org/packages/lsp-mode-badge.svg https://badges.gitter.im/emacs-lsp/lsp-mode.svg https://travis-ci.org/emacs-lsp/lsp-mode.svg?branch=master https://coveralls.io/repos/github/emacs-lsp/lsp-mode/badge.svg

examples/logo.png

Language Server Protocol Support for Emacs

examples/head.png

Table of Contents

Why?

  • ❤️ Community Driven
  • 💎 Fully featured - supports all features in Language Server Protocol v3.14.
  • 🚀 Fast - see performance section
  • 🌟 Flexible - choose between full-blown IDE with flashy UI or minimal distraction free
  • Easy to configure - works out of the box and automatically upgrades if additional packages are present

Overview

Client for Language Server Protocol (v3.14). lsp-mode aims to provide IDE-like experience by providing optional integration with the most popular Emacs packages like company, flycheck and projectile.

  • Non-blocking asynchronous calls
  • Real-time Diagnostics/linting via flycheck (recommended) or flymake when Emacs > 26 (requires flymake>=1.0.5)
  • Code completion - completion-at-point or external company-lsp (note that company-lsp is no longer supported and it is recommended to use builtin company-capf). If you want to use experimental company-capf integration you may force it by setting company-capf to t.
  • Hovers - using lsp-ui
  • Code actions - using lsp-execute-code-action or lsp-ui sideline.
  • Code outline - using builtin imenu or helm-imenu
  • Code navigation - using builtin xref, lsp-treemacs tree views or lsp-ui peek functions.
  • Code lens
  • Symbol highlights
  • Formatting
  • Debugger - dap-mode
  • Helm integration - helm-lsp
  • Ivy integration - lsp-ivy
  • Treemacs integration - lsp-treemacs
  • Semantic highlighting (as currently implemented by JDT LS and unreleased builds of clangd, cf. Semantic highlighting spec)
  • which-key integration for better discovery

Installation

Install via melpa

The recommended way to install lsp-mode is via package.el - the built-in package manager in Emacs. lsp-mode is available on the two major package.el community maintained repos - MELPA Stable and MELPA.

M-x package-install [RET] lsp-mode [RET]

Configuration

Install language server

Check the table bellow with the list of supported servers and the corresponding instructions on how to install the server.

Configure lsp-mode

Vanilla Emacs

You could go minimal and use lsp-mode as it is without external packages with the built-in flymake and completion-at-point or you could install the following extensions for better experience:

  • install lsp-ui for fancy sideline, popup documentation, VScode-like peek UI, etc.
  • install flycheck if you prefer the more popular flycheck over renewed flymake. lsp-mode will automatically pick it up.
  • install company-mode for completion popups.
  • install lsp-treemacs for various three based UI controls (symbols, errors overview, call hierarchy, etc.)
  • install helm-lsp provides on type completion afternative of xref-apropos using helm.
  • install lsp-ivy provides on type completion afternative of xref-apropos using ivy.
  • install dap-mode if your language is supported by the debugger.
;; if you want to change prefix for lsp-mode keybindings.
(setq lsp-keymap-prefix "s-l")

(require 'lsp-mode)
(add-hook 'XXX-mode-hook #'lsp)

where XXX could be major mode like python, java, c++. Alternatively, if you want to minimize you configuration you may use prog-mode-hook. In case you do that, lsp will try to start for each programming mode and echo a message when there is no client registered for the current mode or if the corresponding server is not present. In addition, lsp-mode will automatically detect and configure lsp-ui and company-lsp. To turn off that behavior you could set lsp-auto-configure to nil.

To defer LSP server startup (and DidOpen notifications) until the buffer is visible you can use lsp-deferred instead of lsp:

(add-hook 'XXX-mode-hook #'lsp-deferred)

Spacemacs

lsp-mode is included in spacemacs develop branch. Add lsp to dotspacemacs-configuration-layers and configure the language that you want to use to be backed by lsp backend.

use-package

Replace (require 'lsp-mode) with the following if you use use-package.

;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "s-l")

(use-package lsp-mode
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         (XXX-mode . lsp)
         ;; if you want which-key integration
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp)

;; optionally
(use-package lsp-ui :commands lsp-ui-mode)
;; if you are helm user
(use-package helm-lsp :commands helm-lsp-workspace-symbol)
;; if you are ivy user
(use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
(use-package lsp-treemacs :commands lsp-treemacs-errors-list)

;; optionally if you want to use debugger
(use-package dap-mode)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language

;; optional if you want which-key integration
(use-package which-key
  :config
  (which-key-mode))

To defer LSP server startup (and DidOpen notifications) until the buffer is visible you can use lsp-deferred instead of lsp:

(use-package lsp-mode
  :hook (XXX-mode . lsp-deferred)
  :commands (lsp lsp-deferred))

Recomended settings for lsp-mode related packages

company
(setq company-minimum-prefix-length 1
      company-idle-delay 0.0) ;; default is 0.2

Formatting

In general the formatter settings are language server specific(e. g. JDT LS uses eclipse formatter file and lsp-java-format-settings-url to configure it while clangd uses clangd-format). The only settings that are controlled on lsp-mode level are indent size and whether the server should use tabs or spaces.

  • Use c-basic-offset for cc-mode derived moves(e. g. java, C++) to control the tab size.
  • Use tab-width for any other mode to do the same.
  • Use indent-tabs-mode for sellecting tab/spaces.

Docker

Refer to lsp-docker README which provide a guide how you can run lsp-mode in docker container.

Performance

When configured properly lsp-mode’s performance is on par with mainstream LSP clients (e. g. VScode, Theia, etc). Here are steps to achieve optimal results.

  • Use Emacs 27+ with native json support. In order to validate that you match this criteria do M-: (functionp 'json-serialize) RET. Benchmarks show that Emacs 27 is ~15 times faster than Emacs when using Elisp json parser implementation.
  • Adjust gc-cons-threshold. The default setting is too low for lsp-mode’s needs due to the fact that client/server communication generates a lot of memory/garbage. You have two options:
    • Set it to big number(100mb) like most of the popular starter kits like Spacemacs/Doom/Prelude, etc do:
    (setq gc-cons-threshold 100000000)
        
    • Follow the method recommended by Gnu Emacs Maintainer Eli Zaretskii: “My suggestion is to repeatedly multiply gc-cons-threshold by 2 until you stop seeing significant improvements in responsiveness, and in any case not to increase by a factor larger than 100 or somesuch. If even a 100-fold increase doesn’t help, there’s some deeper problem with the Lisp code which produces so much garbage, or maybe GC is not the reason for slowdown.” Source: https://www.reddit.com/r/emacs/comments/brc05y/is_lspmode_too_slow_to_use_for_anyone_else/eofulix/
  • Increase the amount of data which Emacs reads from the process. Again the emacs default is too low 4k considering that the some of the language server responses are in 800k - 3M range.
(setq read-process-output-max (* 1024 1024)) ;; 1mb
  • Optional: use company-capf . Although company-lsp also supports caching lsp-mode’s company-capf does that by default. To achieve that uninstall company-lsp or put these lines in your config:
(setq lsp-prefer-capf t)

Note: - to verify which company backend implementation you are using do M-x company-diag when performing auto-completion.

  • Optional: Disable lsp-ui. Normally, lsp-ui is very fast but in some systems (especially when using Windows) lsp-ui overlays and popups might slow down emacs.
  • Optional: fine-tune lsp-idle-delay. This variable determines how often lsp-mode will refresh the highlights, lenses, links, etc while you type.
(setq lsp-idle-delay 0.500)

Reporting performance problems

If you have tried all of the non-optional steps from the list and emacs is still not very responsive please open a PR with the following information:

  • Collect lsp-log data after setting lsp-print-performance to t.
(setq lsp-print-performance t)
  • Include emacs performance report. Use the following step to collect it:
    • M-x profiler-start and select CPU
    • Reproduce the slow behavior.
    • M-x profiler-stop
    • In the profiler report expand all nodes by doing C-u TAB.

    Note: - lsp-mode is just a frontend and the performance depends on server as well. Some servers (e. g. Palantir’s Python Language Server) might be slow when performing auto-completion.

How does it work?

lsp-mode has predefined list of server configurations (loaded in lsp-clients.el) containing a mapping from major-mode to the server configuration or by using activation function. In addition to the default server configuration located in lsp-clients.el there are few languages servers which require separate package(check Supported languages). When you open a file from a particular project lsp-mode and call lsp command lsp-mode will look for server registrations able to handle current file. If there is such client lsp-mode will look for the project root. If you open a file from the project for the first time you will be prompted to define the current project root. Once the project root is selected it is saved in lsp-session file and it will be loaded the next time you start Emacs so you no longer will be asked for a project root when you open a file from that project. Later if you want to change the project root you may use lsp-workspace-folder-remove to remove the project and call lsp-workspace-folder-add to add the root. If you want to force starting a particular language server in a file you may use C-u M-x lsp which will prompt you to select language server to start.

Supported languages

Some of the servers are directly supported by lsp-mode by requiring lsp-clients.el while others require installing additional packages which provide server specific functionality.

LanguageLanguage ServerBuilt-inInstallation commandDebugger
Adaada_language_serverYesInstallation instructionsYes (gdb)
Angularvscode-ng-language-serviceYesInstallation instructionsNot relevant
Bashbash-language-serverYesnpm i -g bash-language-server
C++cclsemacs-cclscclsYes (gdb or lldb)
C++clangdYesclangdYes (gdb or lldb)
C++cqueryemacs-cquerycqueryYes (gdb or lldb)
C#OmniSharp-RoslynYesOmniSharp-RoslynNo
Clojureclojure-lspYesclojure-lsp
CMakecmake-language-serverYespip install cmake-language-serverNot relevant
CrystalscryYesscry
CSS/LessCSS/SASS/SCSScssYesnpm install -g vscode-css-languageserver-bin
Dartdart_analysis_serverlsp-dartbuilt into dart-sdk
Dhalldhall-lsp-serverYesInstallation instructionsNo
Dockerfiledockerfile-language-server-nodejsYesnpm install -g dockerfile-language-server-nodejs
Elixirelixir-lsp/elixir-lsYeselixir-lsp/elixir-lsYes
Elixirelixir-lsYeselixir-lsYes
ElmelmLSYesnpm i -g @elm-tooling/elm-language-server, or clone the repository and follow installation instructionsNo
Erlangerlang_lsYeserlang_ls
EslinteslintYesLSP ESLint GuideN/A
F#fsautocompleteYesAutomatic by lsp-fsharpNo
Fortranfortran-language-serverYespip install fortran-language-serverYes
GogoplsYesgo get golang.org/x/tools/gopls@latest docsYes
GobingoYesbingoYes
Groovygroovy-language-serverYesgroovy-language-server
HackhhvmYeshhvm
HTMLhtmlYesnpm install -g vscode-html-languageserver-bin
HaskellIDE enginelsp-haskellIDE engine
LuaEmmyLuaYesInstallation
JavaEclipse JDT LSlsp-javaAutomatic by lsp-javaYes
JavaScript/TypeScripttypescript-language-server (recommended)Yesnpm i -g typescript-language-server; npm i -g typescriptYes (Firefox/Chrome)
JavaScript/TypeScriptjavascript-typescript-stdioYesnpm i -g javascript-typescript-langserverYes (Firefox/Chrome)
JavaScript Flowflow (add-on if working on a Flow file)YesflowYes (Firefox/Chrome)
Jsonvscode-json-languageserverYesAutomatic or manual by npm i -g vscode-json-languageserver
Julialsp-julialsp-juliaLanguageServer.jl
Kotlinkotlin-language-serverYeskotlin-language-server
NimnimlspYesnimble install nimlspNo
OCamlocaml-language-serverYesocaml-language-server
OCamlocaml-lsp-serverYesocaml-lsp-server
PerlPerl::LanguageServerYescpanm Perl::LanguageServer
PHP(recommended)intelephenseYesnpm i intelephense -gYes
PHPphp-language-serverYesphp-language-serverYes
PowershellPowerShellEditorServicesYesAutomaticYes
PureScriptpurescript-language-serverYesnpm i purescript-language-serverNo
PythonpylsYespip install ‘python-language-server[all]’Yes
Python(Microsoft)Microsoft Python Language Serverlsp-python-mslsp-python-msYes
RlanguageserverYesinstall.packages(“languageserver”)No
RubysolargraphYesgem install solargraphYes
RustrlsYesrlsYes
Rustrust-analyzerYesrust-analyzer
ScalaMetalsYesMetals
Swiftsourcekit-LSPlsp-sourcekitsourcekit-LSPYes (via llvm debug adapter)
Terraformterraform-lspNoGit clone outside of $GOPATH; go install. (Requires go > 1.11)No
TeX, LaTeX, etc.DigestifYesluarocks --server http://luarocks.org/dev install digestif
TeX, LaTeX, etc.texlabYescargo install –git https://github.com/latex-lsp/texlab.git
Verilog/SystemVeriloghdl_checkerYespip install hdl-checker –upgradeNo
VHDLVHDL ToolYesDownload from http://www.vhdltool.com/downloadNo
Vimscriptvim-language-serverYesnpm install -g vim-language-servern/a
Vuevue-language-serverYesnpm install -g vlsYes (Firefox/Chrome)
XMLlsp4xmlYesDownload from lsp4xml releases
YAMLyamlYesnpm install -g yaml-language-server

Commands

When using lsp-mode most of the features depend on server capabilities. lsp-mode provides default bindings which are dynamically enabled/disabled based on the server functionality. All the commands are configured lsp-command-map which is bound to lsp-keymap-prefix (default s-l).

KeybindingDescription
s-l s sEntry point for the server startup.
s-l s rRestart language server
s-l s qShutdown language server
s-l s dDescribes current session
s-l s DDisconnect the buffer from the language server keeping the server running.
s-l = =Ask the server to format this document.
s-l = rAsk the server to format the region, or if none is selected, the current line.
s-l F aAdd new project root to the list of workspace folders.
s-l F rRemove project root from the list of workspace folders.
s-l F bRemove project root from the workspace blacklist.
s-l T lToggle code-lens overlays.
s-l T LToggle client-server protocol logging.
s-l T hToggle symbol highlighting.
s-l T SToggle minor mode for showing information for current line in sideline. (requires lsp-ui)
s-l T dToggle minor mode for showing hover information in child frame. (requires lsp-ui)
s-l T sToggle signature auto activate.
s-l T fToggle on type formatting.
s-l T TToggle global minor mode for synchronizing lsp-mode workspace folders and treemacs projects. (requires lsp-treemacs)
s-l g gFind definitions of the symbol under point.
s-l g rFind references of the symbol under point.
s-l g iFind implementations of the symbol under point.
s-l g tFind type definitions of the symbol under point.
s-l g dFind declarations of the symbol under point.
s-l g hShow the incoming call hierarchy for the symbol at point. (requires lsp-treemacs)
s-l g aFind all meaningful symbols that match pattern.
s-l h hDisplay the type signature and documentation of the thing at
s-l h sActivate signature help.
s-l h gTrigger display hover information popup and hide it on next typing.
s-l r rRename the symbol (and all references to it).
s-l r oPerform the source.organizeImports code action, if available.
s-l a aExecute code action action.
s-l a lClick lsp lens using ‘avy’ package.
s-l a hHighlight symbol at point.
s-l G gPeek definitions to the identifier at point. (requires lsp-ui)
s-l G rPeek references to the identifier at point. (requires lsp-ui)
s-l G iPeek implementation locations of the symbol at point. (requires lsp-ui)
s-l G sPeek symbols in the worskpace. (requires lsp-ui)

which-key integration

To enable which-key integration put that in your config.

(with-eval-after-load 'lsp-mode
  (add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration))

examples/which-key.png

Modeline errors

To see all error statistics in the modeline you can enable lsp-diagnostics-modeline-mode. This is especially useful for languages that compilation might be broken due to errors in other files(e. g. Java/Haskell).

(with-eval-after-load 'lsp-mode
  ;; :project/:workspace/:file
  (setq lsp-diagnostics-modeline-scope :project)
  (add-hook 'lsp-managed-mode-hook 'lsp-diagnostics-modeline-mode))

Tip: To find out the global errors you might use lsp-treemacs-errors-list.

Settings

  • lsp-log-io - If non-nil, print all messages to and from the language server to *lsp-log*.
  • lsp-print-performance - If non-nil, print performance info. to *lsp-log*.
  • lsp-inhibit-message - If non-nil, inhibit the message echo via inhibit-message.
  • lsp-report-if-no-buffer - If non nil the errors will be reported even when the file is not open.
  • lsp-keep-workspace-alive - If non nil keep workspace alive when the last workspace buffer is closed.
  • lsp-enable-snippet - Enable/disable snippet completion support.
  • lsp-auto-guess-root - Automatically guess the project root using projectile/project. Do not use this setting unless you are familiar with lsp-mode internals and you are sure that all of your projects are following projectile=/=project.el conventions.
  • lsp-restart - Defines how server exited event must be handled.
  • lsp-session-file - File where session information is stored.
  • lsp-auto-configure - Auto configure lsp-mode. When set to t lsp-mode will auto-configure lsp-ui and company-lsp.
  • lsp-document-sync-method - How to sync the document with the language server.
  • lsp-auto-execute-action - Auto-execute single action.
  • lsp-eldoc-render-all - Display all of the info returned by document/onHover. If this is nil, eldoc will show only the symbol information.
  • lsp-enable-completion-at-point - Enable completion-at-point integration.
  • lsp-enable-xref - Enable xref integration.
  • lsp-diagnostic-package - Specifies which package to use for diagnostics. Choose from :auto, :flycheck, :flymake and :none. Default is :auto which means use :flycheck if present.
  • lsp-enable-indentation - Indent regions using the file formatting functionality provided by the language server.
  • lsp-enable-on-type-formatting - Enable textDocument/onTypeFormatting integration.
  • lsp-before-save-edits - If non-nil, lsp-mode will apply edits suggested by the language server before saving a document.
  • lsp-imenu-show-container-name - Display the symbol’s container name in an imenu entry.
  • lsp-imenu-container-name-separator - Separator string to use to separate the container name from the symbol while displaying imenu entries.
  • lsp-imenu-sort-methods - How to sort the imenu items. The value is a list of kind, name or position. Priorities are determined by the index of the element.
  • lsp-response-timeout - Number of seconds to wait for a response from the language server before timing out.
  • lsp-enable-file-watchers - If non-nil lsp-mode will watch the files in the workspace if the server has requested that.
  • lsp-server-trace - Request trace mode on the language server.
  • lsp-semantic-highlighting - Enable experimental semantic highlighting support
  • lsp-enable-imenu - If non-nil, automatically enable imenu integration when server provides textDocument/documentSymbol.
  • lsp-signature-auto-activate - Auto activate signature when trigger char is pressed.
  • lsp-signature-render-documentation - Include signature documentation in signature help.
  • lsp-enable-text-document-color - Enable textDocument/documentColor when server supports it.

Screenshots

  • RUST Completion examples/completion.png
  • Typescript references using lsp-ui examples/references.png
  • Debugging Python using dap-mode examples/python_debugging.png
  • Call hierarchy via ccls examples/call-hierarchy-ccls.png
  • Metals Doctor examples/metals-doctor.png
  • Semantic highlighting as provided by clangd (built from unreleased 10.0 branch). In this screenshot, all other font-locking has been disabled (hence no syntax highlighting of comments or basic keywords such as auto) examples/clangd_semantic_highlighting.png
  • clang-tidy error explanations (from the clangd language server) examples/clangd-clang-tidy-integration.png

Extensions

TRAMP

LSP mode has support for tramp buffers with the following requirements:

  • The language server has to be present on the remote server.
  • Having multi folder language server (like Eclipse JDT LS) cannot have local and remote workspace folders.

How does it work?

lsp-mode detects whether a particular file is located on remote machine and looks for a client which matches current file and it is marked as :remote? t. Then lsp-mode starts the client through tramp.

Sample configuration

Here it is example how you can configure python language server to work when using TRAMP. Note that if you are trying to convert existing language server configuration you should copy all of it’s properties(e. g. :request-handlers, activation-fn, etc).

(lsp-register-client
 (make-lsp-client :new-connection (lsp-tramp-connection "<insert your LS's binary name or path here>")
                  :major-modes '(python-mode)
                  :remote? t
                  :server-id 'pyls-remote))

Dealing with stderr

With TRAMP, Emacs does not have an easy way to distinguish stdout and stderr, so when the underlying LSP process writes to stderr, it breaks the lsp-mode parser. As a workaround, lsp-mode is redirecting stderr to /tmp/<process-name>-<id>~stderr.

Limitations

File watches

When some of the workspaces that are active in the current project requests file notifications via workspace/didChangeWatchedFiles lsp-mode will start monitoring each of the folders in the workspace for changes. In case your project contains a lot of files you might want to disable file monitoring via lsp-enable-file-watchers (you may use dir-locals).

Contributions

Contributions are very much welcome.

Members

Here it is a list of the current lsp-mode members and what they are primary working on/responsible for.

MemberResponsible for:
TOTBWFF#
brotzeitRust
dsyzlingScala
kurnevskyScala & Rust
seagle0128Go & MS Python Language Server
sebastiansturmlsp-mode core & C++
vibhavplsp-mode core
yyoncholsp-mode core and Java

Troubleshooting

  • check *lsp-log* buffer and verify that lsp-mode is able to find the server. If lsp-mode is unable to find the binary but it is on the path it is probably caused by the fact that emacs is running with different path. You may check the current path by executing M-: (getenv "PATH"). If this is the case, you have several options to fix the issue.
    • make sure that emacs is using the proper path by running emacs from terminal
    • Modify the path using setpath
    • Look for lsp-mode variable to customize server path. Usually, you may find the variable by doing M-x customize-group RET lsp-LANGUAGE-SERVER-ID.
  • set lsp-log-io to t to inspect communication between client and the server. Use lsp-workspace-show-log to switch to the corresponding log buffer.
  • lsp-describe-session will show the current projects roots + the started severs and allows inspecting the server capabilities.

examples/describe.png

Adding support for languages

Registering server

Here it is the minimal configuration that is needed for new language server registration. Refer to the documentation of lsp-client.el for the additional settings supported on registration time. lsp-language-id-configuration must be updated to contain the corresponding mode -> language id - in this case (python-mode . "python")

(defvar lsp-language-id-configuration
  '(...
    (python-mode . "python")
    ...))
;; if you are adding the support for your language server in separate repo use
;; (add-to-list 'lsp-language-id-configuration '(python-mode . "python"))

(lsp-register-client
 (make-lsp-client :new-connection (lsp-stdio-connection "pyls")
                  :major-modes '(python-mode)
                  :server-id 'pyls))

If the language server supports environment variables to control additional behavior, you can register that by using the :environment-fn function, like the Bash language client does:

(lsp-register-client
 (make-lsp-client :new-connection (lsp-stdio-connection '("bash-language-server" "start"))
                  :major-modes '(sh-mode)
                  :priority -1
                  :environment-fn (lambda ()
                                    (("EXPLAINSHELL_ENDPOINT" . lsp-bash-explainshell-endpoint)
                                     ("HIGHLIGHT_PARSING_ERRORS" . lsp-bash-highlight-parsing-errors)))
                  :server-id 'bash-ls))

lsp-bash-explainshell-endpoint and lsp-bash-highlight-parsing-errors are language client defcustom that expose supported server environment settings in a type-safe way. If you change any of those variables, restart the language server with lsp-restart-workspace for the changes to be applied.

Sections

lsp-mode provides tools to bridge emacs defcustom as a language configuration sections properties(see specification workspace/configuration). In addition you may use lsp-generate-settings from Generate Settings script to generate defcustom from package.json VScode plugin manifest. Example:

(defcustom lsp-foo-language-server-property "bar"
  "Demo property."
  :group 'foo-ls
  :risky t)

(lsp-register-custom-settings '(("foo.section.property" lsp-foo-language-server-property)))

(lsp-configuration-section  "foo")
;; =>  (("foo" ("settings" ("property" . "bar"))))

FAQ

  • How do I troubleshoot “Server FOO-LS:pid exited with status signal. Do you want to restart it? (y or n)”?
    • This message indicates that the language server has crashed for some reason. You may check the server stderr which is *FOO-LS::stderr*. If you get this message on startup you may try to run the exact command that lsp-mode is running in the terminal. You may find it in *lsp-log* buffer.
  • How to configure a server with local variables?
    • Add lsp server call to hack-local-variables-hook which runs right after the local variables are loaded.
      (add-hook 'hack-local-variables-hook
                (lambda () (when (derived-mode-p 'XXX-mode) (lsp))))
              
  • I have multiple language servers registered for language FOO. Which one will be used when opening a project?
    • The one with highest priority wins. lsp-clients.el predefined servers have priority -1, lower than external packages (priority 0 if unspecified). If a server is registered with :add-on? flag set to t it will be started in parallel to the other servers that are registered for the current mode.
  • I have multiple language servers for language FOO and I want to select the server per project, what can I do?
    • You may create dir-local for each of the projects and specify list of lsp-enabled-clients. This will narrow the list of the clients that are going to be tested for the project.
  • The completion does not work fine and inserts arguments and placeholders, what I am doing wrong?
    • Snippet support works only with company-lsp so if you are using completion-at-point the snippets won’t be expanded and you should either disable them by setting lsp-enable-snippet to nil or you should switch to company-lsp. Note also that company-tng frontend does not support snippet expansion(see company-mode#891)
  • I am getting “Package ‘spinner-1.7.3’ is unavailable” when trying to install lsp-mode.
    • This is caused by GPG keys used by the ELPA package manager not being up to date. You may fix by installing: gnu-elpa-keyring-update
  • The flycheck does not work in typescript, html and javascript blocks in vue-mode. How to fix that?
    • This is caused by the fact that vue-mode uses multiple major modes in single file and the lsp-ui checker may not associated with the major mode at point. You could fix that by adding the following lines to your config.
      (with-eval-after-load 'lsp-mode
        (mapc #'lsp-flycheck-add-mode '(typescript-mode js-mode css-mode vue-html-mode)))
              
  • I have disabled snippets and Rust Analyzer server inserts redundant $0 when performing completion?

See also

  • lsp-docker - provide docker image with preconfigured language servers with corresponding emacs configuration.
  • company-box - company frontend with icons.
  • dap-mode - Debugger integration for lsp-mode.
  • eglot - An alternative minimal LSP implementation.
  • which-key - Emacs package that displays available keybindings in popup
  • projectile - Project Interaction Library for Emacs