The Wayback Machine - https://web.archive.org/web/20190815044313/https://github.com/emacs-lsp/lsp-mode
Skip to content
Emacs client/library for the Language Server Protocol
Emacs Lisp Other
Branch: master
Clone or download
Latest commit e4efbab Aug 12, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github/ISSUE_TEMPLATE bug_report.md: lsp-print-io goes to *lsp-log* (#769) Apr 16, 2019
doc Updated changelog Aug 7, 2019
examples Handle the metals/executeClientCommand extension notification. (#936) Jul 18, 2019
features Add undercover.el support. Apr 13, 2019
scripts Remove lsp-focus from lsp-start-plain.el Jul 29, 2019
test Fix content-length parsing for case without space after Content-Lengt… Apr 25, 2019
.editorconfig Remove 2 spaces setting from editor config May 6, 2018
.gitignore Byte compilation test (#687) Mar 4, 2019
.travis.yml Add Emacs 26.1 and 26.2 to CI Build (#812) (#834) Jul 10, 2019
AUTHORS Add some gopls configuration settings (#771) Apr 18, 2019
CODE_OF_CONDUCT.md Create CODE_OF_CONDUCT.md Feb 25, 2019
Cask Add undercover.el support. Apr 13, 2019
LICENSE Switch to GPL v3 Dec 9, 2016
Makefile Add docs target. May 20, 2019
README.org add dockerfile-language-server-nodejs (#951) Jul 23, 2019
lsp-clients.el add dockerfile-language-server-nodejs (#951) Jul 23, 2019
lsp-clojure.el Add clean-ns refactoring (#855) May 24, 2019
lsp-css.el lsp-css: Use correct syntax for defcustoms with a choice type May 5, 2019
lsp-dart.el Add package-version to dart-analysis group. May 27, 2019
lsp-elm.el Remove treesitter-runtime option as that is now loaded with the server ( Aug 12, 2019
lsp-erlang.el Add support for Erlang Language Server (#947) Jul 19, 2019
lsp-fsharp.el Fix call to format in lsp-fsharp.el Aug 13, 2019
lsp-go.el lsp-{clojure,css,go,gopls} - Refactor documentation and defcustoms. May 5, 2019
lsp-html.el Lower the priority of html server Jun 16, 2019
lsp-intelephense.el lsp-xml: Use the correct package symbol name. May 5, 2019
lsp-metals.el Fix typo within lsp-metals-sources-scan (#960) Aug 5, 2019
lsp-mode.el Fix handling of single location result Aug 10, 2019
lsp-pyls.el [fix] wrong default value in pylint-args (#958) Aug 1, 2019
lsp-rust.el improve rust support (#707) Jun 14, 2019
lsp-solargraph.el lsp-solargraph: Use the correct package symbol name. May 5, 2019
lsp-vetur.el Pass vetur initialization-options May 22, 2019
lsp-xml.el lsp-xml-jar-file: Set type to file. Jun 18, 2019
lsp.el Add lsp.el Dec 21, 2018

README.org

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

examples/logo.png

Language Server Protocol Support for Emacs

examples/head.png

Table of Contents

Why?

  • ❤️ Community Driven
  • 💎 Fully featured - supports LSP core and Language Server non-standard extensions
  • 🚀 Easy to configure - works out of the box and automatically upgrades if additional packages are present
  • 🌟 Flexible - could be configured as full-blown IDE with flashy UI or minimal distraction free

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 builtin flymake when Emacs > 26 or flycheck/lsp-ui)
  • Code completion - using company-lsp or builtin completion-at-point
  • Hovers - using lsp-ui
  • Code actions - using lsp-execute-code-action or lsp-ui
  • Code outline - using builtin imenu or helm-imenu
  • Code navigation - using builtin xref
  • Code lens (references/implementations) - using builtin xref
  • Highlights
  • Formatting
  • Debugger - dap-mode
  • Helm integration - helm-lsp
  • Treemacs integration - lsp-treemacs

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 flycheck integration and higher level UI modules.
  • install company-lsp if you want to use company-mode for completion.
  • install lsp-treemacs for project wide error overview.
  • install helm-lsp provides on type completion for xref-apropos.
  • install dap-mode if your language is supported by the debugger.
(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.

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

;; optionally
(use-package lsp-ui :commands lsp-ui-mode)
(use-package company-lsp :commands company-lsp)
(use-package helm-lsp :commands helm-lsp-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

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))

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
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)
Clojureclojure-lspYesclojure-lisp
CSS/LessCSS/SASS/SCSScssYesnpm install -g vscode-css-languageserver-bin
Dartdart_analysis_serverYesbuilt into dart-sdk
Dockerfiledockerfile-language-server-nodejsYesnpm install -g dockerfile-language-server-nodejs
Dartdart_language_serverYespub global activate dart_language_server
Elixirelixir-lsYeselixir-lsYes
ElmelmLSYesnpm i -g @elm-tooling/elm-language-server, or clone the repository and follow installation instructionsNo
Erlangerlang_lsYeserlang_ls
F#fsautocompleteYesAutomatic by lsp-fsharpNo
Fortranfortran-language-serverYespip install fortran-language-serverYes
GogoplsYesgopls go get -u golang.org/x/tools/cmd/goplsYes
GobingoYesbingoYes
Groovygroovy-language-serverYesgroovy-language-server
HackhhvmYeshhvm
HTMLhtmlYesnpm install -g vscode-html-languageserver-bin
HaskellIDE enginelsp-haskellIDE engine
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)
Julialsp-julialsp-juliaLanguageServer.jl
Kotlinkotlin-language-serverYeskotlin-language-server
Ocamlocaml-language-serverYesocaml-language-server
PHP(recommended)intelephenseYesnpm i intelephense -gYes
PHPphp-language-serverYesphp-language-serverYes
PowershellPowerShellEditorServiceslsp-powershellAutomatic by lsp-powershell
PythonpylsYespip install ‘python-language-server[all]’Yes
Python(Microsoft)Microsoft Python Language Serverlsp-python-mslsp-python-msYes
RubysolargraphYesgem install solargraphYes
RustrlsYesrlsYes
ScalaMetalsYesMetals
Swiftsourcekit-LSPlsp-sourcekitsourcekit-LSPYes (via llvm debug adapter)
Vuevue-language-serverYesnpm install -g vue-language-serverYes (Firefox/Chrome)
XMLlsp4xmlYesDownload from lsp4xml releases

Commands

  • lsp-describe-session - Display session folders and running servers.
  • lsp-describe-thing-at-point - Display help for the thing at point.
  • lsp-execute-code-action - Execute code action
  • lsp-format-buffer - Format current buffer
  • lsp-organize-imports - Organize library imports
  • lsp-goto-implementation - Go to implementation
  • lsp-goto-type-definition - Go to type definition
  • lsp-rename - Rename symbol at point
  • lsp-restart-workspace - Restart project
  • lsp-symbol-highlight - Highlight all relevant references to the symbol under point.
  • lsp-workspace-folders-add - Add workspace folder
  • lsp-workspace-folders-remove - Remove workspace folder
  • lsp-workspace-folders-switch - Switch workspace folder
  • imenu or helm-imenu - display document structure.
  • completion-at-point - display completion using built-in emacs completion-at-point framework.
  • lsp-find-definition - to find the definition for the symbol under point.
  • lsp-find-references - Find references for the symbol under point.
  • lsp-disconnect - Disconnect the buffer from the language server.
  • lsp-lens-show - Show lenses in the current file
  • lsp-lens-hide - Hide lenses in the current file
  • lsp-lens-mode (experimental) - Turn on/off lenses in the current file.

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.
  • 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-signature-render-all - Display all of the info returned by textDocument/signatureHelp. If this is nil, eldoc will show only the active signature.
  • lsp-enable-completion-at-point - Enable completion-at-point integration.
  • lsp-enable-xref - Enable xref integration.
  • lsp-prefer-flymake - If you prefer flycheck and lsp-ui-flycheck is available, (setq lsp-prefer-flymake nil). If set to :none neither of two will be enabled.
  • 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.

Screenshots

  • RUST Completion with company-lsp 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

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 "binary-or-full-path")
                  :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.

Here is a throughput graph of the repository for the last few weeks:

https://graphs.waffle.io/emacs-lsp/lsp-mode/throughput.svg

Troubleshooting

  • set lsp-log-io to t to inspect communication between client and the server.
  • 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))

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 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.

See also

  • company-box - company frontend with icons.
  • dap-mode - Debugger integration for lsp-mode.
  • eglot - An alternative minimal LSP implementation.
You can’t perform that action at this time.