Rust-Emacs racer: Racer support for Emacs — Autocompletion (see also company and auto-complete)

Racer for Emacs

MELPA MELPA Stable Build Status Coverage Status

This is the official Emacs package for Racer.

Table of Contents

Completion

racer.el supports code completion of variables, functions and modules.

racer completion screenshot

You can also press F1 to pop up a help buffer for the current completion candidate.

Note that due to a limitation of racer, racer.el cannot offer completion for macros.

Find Definitions

racer.el can jump to definition of functions and types.

racer go to definition

You can use M-. to go to the definition, and M-, to go back.

Describe Functions and Types

racer.el can show a help buffer based on the docstring of the thing at point.

racer completion screenshot

Use M-x racer-describe to open the help buffer.

Installation

  1. You will need to use a nightly version of rust. If you're using rustup, run

    $ rustup toolchain add nightly
    
  2. Install Racer and download the source code of Rust:

    $ rustup component add rust-src
    $ cargo +nightly install racer
    
  3. Allow Emacs to install packages from MELPA:

    (require 'package)
    (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  4. Install the Emacs package for Racer: M-x package-install RET racer RET

  5. Configure Emacs to activate racer when rust-mode starts:

    (add-hook 'rust-mode-hook #'racer-mode)
    (add-hook 'racer-mode-hook #'eldoc-mode)

    For completions, install company with M-x package-install RET company RET. A sample configuration:

    (add-hook 'racer-mode-hook #'company-mode)
    
    (require 'rust-mode)
    (define-key rust-mode-map (kbd "TAB") #'company-indent-or-complete-common)
    (setq company-tooltip-align-annotations t)

    For automatic completions, customize company-idle-delay and company-minimum-prefix-length.

    Racer process may be slow to respond for instance when indexing. You can customize racer-command-timeout and racer-eldoc-timeout to avoid rendering your Emacs session unresponsive. Eldoc timeout should be on the lower side and defaults to 0.5 seconds. You can probably tweak it down on a fast machine. Timeout of nil will wait indefinitely.

Testing your setup

To test completion: Open a rust file and try typing use std::io::B and press TAB.

To test go to definition: Place your cursor over a symbol and press M-. to jump to its definition.

Press C-x 4 . to jump to its definition in another window.

Press C-x 5 . to jump to its definition in another frame.

Press M-, to jump back to the previous cursor location.

If it doesn't work, try M-x racer-debug to see what command was run and what output was returned.

Tests

racer.el includes tests. To run them, you need to install Cask, then:

$ cask install
$ cask exec ert-runner

Comments

  • Do I need to manually turn on the eldoc-mode of the racer?
    Do I need to manually turn on the eldoc-mode of the racer?

    Dec 1, 2018

    Hello:

    I saw this commit of purcell: https://github.com/purcell/emacs.d/commit/f8782da7d91a0726aad8649ee77b6bfbaf31833a

    So I would like to ask, is it necessary to manually enable the eloc support for racer (under Emacs 25.1 and later)?

    Thanks, and forgive my poor English.

    Reply
  • company: back company-capf error
    company: back company-capf error "symbol's function definition is void -let" with args (candidate B)

    Dec 4, 2018

    Running on Emacs on Windows,

    When I try to autocomplete on

    use std::io::B then TAB

    I get the error

    Company: backend company-capf error "Symbol's function definition is void: -let" with args (candidates B)

    my init.el

    (add-hook 'rust-mode-hook 'cargo-minor-mode)
    
    (add-hook 'rust-mode-hook #'racer-mode)
    (add-hook 'racer-mode-hook #'eldoc-mode)
    
    (add-hook 'racer-mode-hook #'company-mode)
    (require 'rust-mode)
    (define-key rust-mode-map (kbd "TAB") #'company-indent-or-complete-common)
    (setq company-tooltip-align-annotations t)
    

    I have an environment variable set

    RUST_SRC_PATH = C:\Users\stuarts\.multirust\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src

    I can run / build with cargo fine, all I'm missing is racer and autocomplete stuff.

    I have the source the location in the RUST_SRC_PATH, it was installed via

    $ rustup component add rust-src
    $ cargo +nightly install racer
    

    Any ideas why I'm getting this error?

    Reply
  • Use racer-describe within describe buffer?
    Use racer-describe within describe buffer?

    Mar 17, 2019

    Could it be possible to add the ability to use racer-describe within the help buffer itself, i.e. to describe the return type of a function while viewing that function with racer-describe?

    Reply
  • racer-describe always fails with 'no function or type found at point'
    racer-describe always fails with 'no function or type found at point'

    Jun 30, 2019

    racer-describe always fails with 'no function or type found at point' being displayed in the minibuffer, no matter if I run racer-describe on a type I define in the file or a standard library type like Vec. Running M-x racer-debug says:

    This command terminated with exit code 0.
    
    stdout:
    
    PREFIX 17013,17016,Vec
    END
    
    Process *async-racer* finished
    
    stderr:
    
    thread 'searcher' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:347:21
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
    ERROR 2019-06-30T20:48:49.784813000Z: racer: Search thread panicked: Any
    
    Process *async-racer* stderr finished
    

    If I copy paste the command that the racer-debug page says should reproduce the same output into a terminal, the command succeeds and returns the correct documentation.

    With RUST_BACKTRACE=1, the output of racer-debug is:

    This command terminated with exit code 0.
    
    stdout:
    
    PREFIX 3374,3377,Vec
    END
    
    stderr:
    
    thread 'searcher' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:347:21
    stack backtrace:
       0: std::panicking::default_hook::{{closure}}
       1: std::panicking::default_hook
       2: std::panicking::rust_panic_with_hook
       3: std::panicking::continue_panic_fmt
       4: rust_begin_unwind
       5: core::panicking::panic_fmt
       6: core::panicking::panic
       7: racer::metadata::MetadataCache::setup
       8: <racer::metadata::MetadataCache as racer::project_model::ProjectModelProvider>::edition
       9: racer::fileres::search_crate_names
      10: racer::nameres::resolve_name
      11: racer::nameres::resolve_path
      12: racer::core::complete_from_file_
      13: racer::core::complete_from_file
      14: racer::run_the_complete_fn
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    ERROR 2019-06-30T21:05:45.530752000Z: racer: Search thread panicked: Any
    
    Reply
  • `racer-complete-at-point` fails even when `$ racer complete use std::io::B` works from terminal
    `racer-complete-at-point` fails even when `$ racer complete use std::io::B` works from terminal

    Mar 1, 2020

    I feel like there is a missed opportunity at emacs-racer working automagically without extra install steps.

    From the terminal $ racer complete use std::io::B works just fine, even though I did not explicitly install Rust sources using $ rustup component add rust-src. However, from Emacs I get the following error when trying to complete:

    completion--some: No such directory: /usr/local/Cellar/rust/1.34.0/lib/rustlib/src/rust/src. Please set ‘racer-rust-src-path’ or ‘RUST_SRC_PATH’.

    My feeling that there is a missed opportunity stems from the fact that, when I remove the check causing this error from racer--call, I get the right completions.

    I changed:

    (defun racer--call (command &rest args)
      "Call racer command COMMAND with args ARGS.
    Return stdout if COMMAND exits normally, otherwise show an
    error."
      (let ((rust-src-path (or (when racer-rust-src-path (expand-file-name racer-rust-src-path))
                               (getenv "RUST_SRC_PATH")))
            (cargo-home (or (when racer-cargo-home (expand-file-name racer-cargo-home))
                            (getenv "CARGO_HOME"))))
        (when (null rust-src-path)
          (user-error "You need to set `racer-rust-src-path' or `RUST_SRC_PATH'"))
        (unless (file-exists-p rust-src-path)
          (user-error "No such directory: %s. Please set `racer-rust-src-path' or `RUST_SRC_PATH'"
                      rust-src-path))
        (let ((default-directory (or (racer--cargo-project-root) default-directory))
              (process-environment (append (list
                                            (format "RUST_SRC_PATH=%s" rust-src-path)
                                            (format "CARGO_HOME=%s" cargo-home))
                                           process-environment)))
          (-let [(exit-code stdout _stderr)
                 (racer--shell-command racer-cmd (cons command args))]
            ;; Use `equal' instead of `zero' as exit-code can be a string
            ;; "Aborted" if racer crashes.
            (unless (equal 0 exit-code)
              (user-error "%s exited with %s. `M-x racer-debug' for more info"
                          racer-cmd exit-code))
            stdout))))
    

    to:

    (defun racer--call (command &rest args)
      "Call racer command COMMAND with args ARGS.
    Return stdout if COMMAND exits normally, otherwise show an
    error."
      (let ((rust-src-path (or (when racer-rust-src-path (expand-file-name racer-rust-src-path))
                               (getenv "RUST_SRC_PATH")))
            (cargo-home (or (when racer-cargo-home (expand-file-name racer-cargo-home))
                            (getenv "CARGO_HOME"))))
        (let ((default-directory (or (racer--cargo-project-root) default-directory)))
          (-let [(exit-code stdout _stderr)
                 (racer--shell-command racer-cmd (cons command args))]
            ;; Use `equal' instead of `zero' as exit-code can be a string
            ;; "Aborted" if racer crashes.
            (unless (equal 0 exit-code)
              (user-error "%s exited with %s. `M-x racer-debug' for more info"
                          racer-cmd exit-code))
            stdout))))
    

    and started getting the right completions when pressing after use std::io::B.

    I am not sure what to think about it as I don't have global knowledge about Racer, Emacs-racer, and even about Rust as I am a beginner.

    I need insight from someone more experienced with this codebase. Am I right in thinking that there is room for improvement ? If so, how, and would there be tradeoffs ?

    Reply
  • Build Failing on Nightly
    Build Failing on Nightly

    Apr 5, 2020

    I am getting the following error when running cargo +nightly install racer:

       Compiling rustc-ap-rustc_data_structures v651.0.0
    error[E0599]: no method named `get` found for type `u64` in the current scope
       --> /my/homepath/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-ap-rustc_data_structures-651.0.0/profiling.rs:348:66
        |
    348 |             let thread_id = std::thread::current().id().as_u64().get() as u32;
        |                                                                  ^^^ method not found in `u64`
    
    error[E0599]: no method named `get` found for type `u64` in the current scope
       --> /my/homepath/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-ap-rustc_data_structures-651.0.0/profiling.rs:525:62
        |
    525 |         let thread_id = std::thread::current().id().as_u64().get() as u32;
        |                                                              ^^^ method not found in `u64`
    
    error: aborting due to 2 previous errors
    
    For more information about this error, try `rustc --explain E0599`.
    error: could not compile `rustc-ap-rustc_data_structures`.
    

    Here is my current setup:

    OS:

    NAME="Ubuntu"
    VERSION="18.04.4 LTS (Bionic Beaver)"
    ID=ubuntu
    ID_LIKE=debian
    PRETTY_NAME="Ubuntu 18.04.4 LTS"
    VERSION_ID="18.04"
    HOME_URL="https://www.ubuntu.com/"
    SUPPORT_URL="https://help.ubuntu.com/"
    BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
    PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
    VERSION_CODENAME=bionic
    UBUNTU_CODENAME=bionic
    

    Rust:

    rustup 1.21.1 (7832b2ebe 2019-12-20)
    rustc 1.44.0-nightly (f509b26a7 2020-03-18)
    cargo 1.44.0-nightly (7019b3ed3 2020-03-17)
    
    Reply
  • Missing docs => cryptic error message
    Missing docs => cryptic error message

    Feb 14, 2017

    So I've ran racer-mode for the first time ever... and racer errored out on missing docs, I think this case should be covered by an appropriate error message.

    Reply
  • Fixed formatting of StructField completions
    Fixed formatting of StructField completions

    Aug 10, 2016

    This PR fixes the completion text for StructField completion candidates:

    Before: alt text

    After: alt text

    enhancement help wanted 
    Reply
  • Provide an option to disable completion in comments
    Provide an option to disable completion in comments

    Oct 7, 2015

    Emacs stalls while writing in some comments such as the comment: "// writing in this comment is broken" below. Try extending the comment with writing words longer than company-minimum-prefix-length and company-idle-delay "low-enough". Simply start tapping the "a" key repeatedly for example and the letters should appear in chunks. Not sure if this is emacs-racer or racer problem and what repo the issue should have been filed to.

    // company-idle-delay 0.1 is low-enough on my system
    fn main() {
        // writing in this comment is fine
    }
    
    
    struct A {
    }
    
    
    impl A {
        fn f() {
            // writing in this comment is broken
            let x = 0;
        }
    
    
        fn g() {
            // writing in this comment is fine
        }
    }
    
    bug 
    Reply
  • Use region contents in racer-describe if active
    Use region contents in racer-describe if active

    Aug 5, 2017

    (thing-at-point 'symbol) (here) doesn't always retrieve what we want - for instance, when describing a namespaced fn - so we may want to check it against the active region to work around this.

    Reply
  • emacs-racer doesn't complete for external crates
    emacs-racer doesn't complete for external crates

    Mar 7, 2019

    Follow on from an issue on the main racer repo, where we concluded that my issue was with emacs-racer rather than racer itself: https://github.com/racer-rust/racer/issues/1020#issuecomment-468424788

    Emacs version: 25.2.2 emacs-racer version: 20190124.538

    I'm using racer via the emacs-racer plugin that's included with spacemacs (https://github.com/syl20bnr/spacemacs/tree/master/layers/%2Blang/rust)

    When I'm editing, (for example, in this demo repo: https://github.com/kngwyu/simple-crate.git), racer completions work for the standard library, but not for external crates like rand.

    Output from racer-debug:

    The last racer command was:
    
    $ cd /home/shanek/tmp/simple-crate/
    $ export CARGO_HOME=/home/shanek/.cargo
    $ export RUST_SRC_PATH=/home/shanek/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src
    $ /home/shanek/.cargo/bin/racer complete 3 21 /home/shanek/tmp/simple-crate/src/main.rs /tmp/racer8927IeQ
    
    This command terminated with exit code 0.
    
    stdout:
    
    PREFIX 32,43,AsByteSlice
    END
    
    No output on stderr.
    
    The temporary file will have been deleted. You should be
    able to reproduce the same output from racer with the
    following command:
    
    $ CARGO_HOME=/home/shanek/.cargo RUST_SRC_PATH=/home/shanek/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src /home/shanek/.cargo/bin/racer complete 3 21 /home/shanek/tmp/simple-crate/src/main.rs
    
    Please report bugs on GitHub.
    
    Reply
  • Completion doesn't work
    Completion doesn't work

    Jun 16, 2016

    Hi i try to configure Emacs for rust :

    
    (use-package rust-mode
        :mode (("\\.rs\\'" . rust-mode))
        :config (setq tab-width 4))
    
      (use-package racer
        :init (progn
                (setq racer-rust-src-path (getenv "RUST_SRC_PATH"))
                (setq racer-cmd (executable-find "racer")))
        :config (progn
                  (add-hook 'rust-mode-hook #'racer-mode)
                  (add-hook 'rust-mode-hook #'company-mode)
                  (add-hook 'racer-mode-hook #'eldoc-mode)
                  (add-hook 'rust-mode-hook
                            '(lambda ()
                               (local-set-key (kbd "M-.") #'racer-find-definition)
                               (local-set-key (kbd "TAB") #'company-indent-or-complete-common)))))
    

    I press TAB after use std::io::B, i've got into minubuffer: No completion found

    Variable racer-rust-src-path is correctly set. i try the shell command, it works :

    M-x shell-command RET racer complete std::io::B
    MATCH BufReader,48,11,/home/nlamirault/Apps/rust/src/libstd/io/buffered.rs,Struct,pub struct BufReader<R>
    MATCH BufWriter,300,11,/home/nlamirault/Apps/rust/src/libstd/io/buffered.rs,Struct,pub struct BufWriter<W: Write>
    MATCH BufRead,1200,10,/home/nlamirault/Apps/rust/src/libstd/io/mod.rs,Trait,pub trait BufRead: Read
    MATCH Bytes,1528,11,/home/nlamirault/Apps/rust/src/libstd/io/mod.rs,Struct,pub struct Bytes<R>
    

    Any idea why it doesn't work ?

    Reply