Rust-Lsp rust: lsp-rust lsp-modelsp-rust — Add rls support to lsp-mode


Support for RUST is now configured and enabled in lsp-mode by default.


Rust support for lsp-mode using the Rust Language Server.

Warning: RLS is currently very unstable, which can make Emacs hang indefinitely. Using this in production isn't recommended.


First, install the RLS.

Then you should just load lsp-rust after lsp-mode by adding the following to your init file:

(with-eval-after-load 'lsp-mode
  (setq lsp-rust-rls-command '("rustup" "run" "nightly" "rls"))
  (require 'lsp-rust))

If you installed the RLS via rustup (the recommended way), then the setq line tells lsp-rust how to launch the RLS. If you would rather use the RLS_ROOT variable to locate the RLS, then set lsp-rust-rls-command to nil.

Now, you can activate lsp-mode in a Rust buffer, and you should have all the benefits of the RLS as handled by lsp-mode.

If you want on-the-fly syntax checking, first make sure that lsp-flycheck is loaded (see lsp-mode installation), then simply turn on flycheck-mode.

If you want to automatically launch lsp-mode and flycheck-mode whenever you open a rust buffer, you can add the following to your init file:

(add-hook 'rust-mode-hook #'lsp-rust-enable)
(add-hook 'rust-mode-hook #'flycheck-mode)


  • Restart rls on crash
    Restart rls on crash

    Apr 9, 2018

    As rls often crashes, maybe it could be possible to detect that and restart it from the emacs side?

  • Question: how is it different using RLS with Emacs than rust-mode?
    Question: how is it different using RLS with Emacs than rust-mode?

    May 23, 2018


    I just need a clarification (perhaps useful for a README addition?). I'm currently using rust-mode in EMACS and I have:

    • goto-definition (although it seems to me not always working)
    • syntax-highlight
    • rustfmt on buffer save
    • completion suggestions (although it seems to me not always working)

    What would using RLS add to these features? Looking at the feature list of RLS perhaps I'm missing refactoring tools (like mass-rename in the whole project). Or these two tools accomplish the same goal?

    thank you

  • Use workspace root instead of project root
    Use workspace root instead of project root

    Jul 21, 2018

    The RLS has workspace mode enabled by default nowadays, but lsp-rust doesn't take advantage of it because it uses the project directory as root, so it starts a separate RLS process for each workspace member.

    This uses cargo metadata instead of cargo locate-project to find the workspace root to fix that.

  • Use native json
    Use native json

    Oct 11, 2018

    Hi. lsp-mode supports native json if available, but it seems that client should pass an explicit parameter to enable it, like this:

    (lsp-define-stdio-client lsp-rust "rust" #'lsp-rust--get-root nil
    			 :command-fn #'lsp-rust--rls-command
    			 :initialize #'lsp-rust--initialize-client
                             :use-native-json t)

    Do you want to accept a PR which enables it?

  • Change :get-root to nil
    Change :get-root to nil

    Oct 23, 2018

    lsp-mode has fallback root detection logic (projectile or project.el) when get-root is nil projectile has Cargo project support

  • void-function lsp-rust-enable
    void-function lsp-rust-enable

    Dec 11, 2018

    I got the error, File mode specification error: (void-function lsp-rust-enable) in latest lsp-mode and lsp-rust. After some trials, I found that lsp-mode caused this error. Because lsp-rust-enable worked at commit d27200dc8d0bf8c47fa62cf95ec6a200fb4c5d9d of lsp-mode.

    But I can't find the cause of this error and lsp-rust-enable function itself. Do someone have an idea about this?

  • Implement rustDocument/implementations
    Implement rustDocument/implementations

    Nov 28, 2017

    Allow to find all implementions for a trait, struct or enum.

    lsp-mode/#199 needs to be merged first.

  • No Language server associated with this buffer/Installation help
    No Language server associated with this buffer/Installation help

    Mar 28, 2018

    Hi, sorry for cluttering the issues, but I didn't know where to ask for help. I'm trying to install lsp-rust, to test it out. I have followed the steps, but when I run lsp-capabilities, no server is found. Clearly I'm doing something wrong, but I'm new to Emacs, and configuring this whole thing is somewhat of an undertaking. I'm also running spacemacs, could this be causing any conflicts? I'm on Linux, have the RLS set up, and it can be run from the commandline. Thanks in advance.

  • Error loading autoloads: (void-function lsp-define-stdio-client)
    Error loading autoloads: (void-function lsp-define-stdio-client)

    Jul 22, 2017

    Steps to reproduce:

    run emacs 25 with such ~/.emacs:

    (require 'package)
    (add-to-list 'package-archives
                 '("melpa" . ""))

    install lsp-rust with M-x list-packages, restart emacs and see this message (bug topic I mean).

    the source of problem is lsp-rust-autoloads.el that not contains (require 'lsp-mode) and (require 'lsp-rust), but execute functions from both of them via

    (lsp-define-stdio-client 'rust-mode "rust" 'stdio
                        "Rust Language Server"
  • "Unknown method" error messages

    Dec 1, 2017

    I have problems configuring lsp.

    (require 'lsp-mode)
    (require 'lsp-rust)
    (setq lsp-rust-rls-command '("rustup" "run" "nightly" "rls"))
    (add-hook 'rust-mode-hook #'lsp-rust-enable)
    (add-hook 'rust-mode-hook #'lsp-mode)
    (lsp-define-stdio-client rust-mode 
    (add-hook 'rust-mode-hook #'rust-mode-enable)

    When I open a rust file the rls process starts but I get these error messages

    Unknown method: rustDocument/beginBuild
    Unknown method: rustDocument/diagnosticsBegin
    Unknown method: rustDocument/diagnosticsEnd
  • something wrong with lsp-rust--get-root function
    something wrong with lsp-rust--get-root function

    Jun 14, 2017

    I install lsp-rust via use-package, but when I restart Emacs, an error occur :

    Debugger entered--Lisp error: (void-function lsp-define-stdio-client)
      (lsp-define-stdio-client (quote rust-mode) "rust" (quote stdio) (function lsp-rust--get-root) "Rust Language Server" (lsp-rust--rls-command))
      eval-buffer(#<buffer  *load*-233591> nil "/home/samray/.emacs.d/elpa/lsp-rust-20170421.326/lsp-rust-autoloads.el" nil t)  ; Reading at buffer position 416
      load-with-code-conversion("/home/samray/.emacs.d/elpa/lsp-rust-20170421.326/lsp-rust-autoloads.el" "/home/samray/.emacs.d/elpa/lsp-rust-20170421.326/lsp-rust-autoloads.el" nil t)
      load("/home/samray/.emacs.d/elpa/lsp-rust-20170421.326/lsp-rust-autoloads" nil t)
      package--activate-autoloads-and-load-path([cl-struct-package-desc lsp-rust (20170421 326) "Rust support for lsp-mode" ((lsp-mode (2 0)) (rust-mode (0 3 0))) nil nil "/home/samray/.emacs.d/elpa/lsp-rust-20170421.326" ((:keywords "rust") (:url . "") (:commit . "bd9b1f5d9195067decc496e61ad383d615b7f054")) nil])
      package--load-files-for-activation([cl-struct-package-desc lsp-rust (20170421 326) "Rust support for lsp-mode" ((lsp-mode (2 0)) (rust-mode (0 3 0))) nil nil "/home/samray/.emacs.d/elpa/lsp-rust-20170421.326" ((:keywords "rust") (:url . "") (:commit . "bd9b1f5d9195067decc496e61ad383d615b7f054")) nil] nil)
      package-activate-1([cl-struct-package-desc lsp-rust (20170421 326) "Rust support for lsp-mode" ((lsp-mode (2 0)) (rust-mode (0 3 0))) nil nil "/home/samray/.emacs.d/elpa/lsp-rust-20170421.326" ((:keywords "rust") (:url . "") (:commit . "bd9b1f5d9195067decc496e61ad383d615b7f054")) nil] nil deps)
      (let ((file-name-handler-alist nil)) (setq load-prefer-newer t) (package-initialize) (require (quote package)) (setq package-enable-at-startup nil) (defconst samray/query-public-ip-url "") (defalias (quote samray/send-get-request) (function (lambda (api-url) "Send get request, return JSON as an alist if successes." (let (json) (save-current-buffer (set-buffer (url-retrieve-synchronously api-url)) (set-buffer-multibyte t) (goto-char (point-min)) (if (not ...) (progn ...)) (re-search-forward "^$") (setq json (buffer-substring-no-properties ... ...)) (kill-buffer (current-buffer))) json)))) (defalias (quote samray/setup-query-ip) (function (lambda nil (let* ((query-ip-result (samray/send-get-request samray/query-public-ip-url)) (public-ip (samray/remove-eof query-ip-result))) (concat "" public-ip "/country/"))))) (defalias (quote samray/remove-eof) (function (lambda (string-with-eof) (replace-regexp-in-string "\n" "" string-with-eof)))) (defalias (quote samray/ip-from-china-p) (function (lambda nil (let* ((query-result (samray/send-get-request ...)) (ip-location (samray/remove-eof query-result))) (string= "CN" ip-location))))) (if t (progn (message "There is a wall here.") (setq package-archives (quote (("gnu" . "") ("melpa" . ""))))) (progn (message "You are free.") (setq package-archives (quote (("gnu" . "") ("marmalade" . "") ("melpa" . "")))))) (message "load") (if (package-installed-p (quote use-package)) nil (package-refresh-contents) (package-install (quote use-package))) (defalias (quote display-startup-echo-area-message) (function (lambda nil "Display startup echo area message." (message "Initialized in %s" (emacs-init-time))))) (if init-file-debug (progn (require (quote benchmark)))) (let ((lisp-dir "~/.emacs.d/lisp") (manual-add-packages "~/.emacs.d/additional-packages")) (add-to-list (quote load-path) lisp-dir) (add-to-list (quote load-path) manual-add-packages) (mapc (function (lambda (fname) (let ((feat ...)) (if init-file-debug (message "Feature '%s' loaded in %.2fs" feat ...) (require feat fname))))) (directory-files lisp-dir t "\\.el"))) (require (quote cl)) (require (quote init-auto-completion)) (require (quote init-better-editing)) (require (quote init-better-default)) (require (quote init-chinese)) (require (quote init-c-c++)) (require (quote init-elisp)) (require (quote init-eshell)) (require (quote init-evil)) (require (quote init-go)) (require (quote init-ivy)) (require (quote init-keybindings)) (require (quote init-lsp)) (require (quote init-markdown)) (require (quote init-misc)) (require (quote init-org)) (require (quote init-python)) (require (quote init-programming)) (require (quote init-rust)) (require (quote init-scheme)) (require (quote init-syntax-checking)) (require (quote init-ui)) (require (quote init-version-control)) (require (quote init-web)) (setq custom-file (expand-file-name "lisp/custom.el" user-emacs-directory)) (if (file-exists-p custom-file) (progn (load custom-file))))
      eval-buffer(#<buffer  *load*> nil "/home/samray/.emacs.d/init.el" nil t)  ; Reading at buffer position 4999
      load-with-code-conversion("/home/samray/.emacs.d/init.el" "/home/samray/.emacs.d/init.el" t t)
      load("/home/samray/.emacs.d/init" t t)
      #[0 "\205\266

    Emacs version: 25.2 OS platform : Arch linux rustup version: rustup 1.4.0 (a77fbedf2 2017-06-09) rustc version: rustc 1.18.0 (03fc9d622 2017-06-06) binaries in ~/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/bin are: cargo rustc rustdoc rust-gdb rust-lldb binaries in ~/.cargo/bin are: cargo cargo-add cargo-fmt cargo-list cargo-rm racer rls rustc rustdoc rustfmt rust-gdb rust-lldb rustup And I have open an issue on rls

  • Add variable to customize RLS executable
    Add variable to customize RLS executable

    Oct 19, 2017

    The suggested way of running the RLS is now through rustup run nightly rls. Since this can change, there's no point of hardcoding it in lsp-rust.

    This commit adds a customizable variable to use as the default command. If the variable is nil, lsp-rust will fallback to use the RLS defined by RLS_ROOT, if any.