Skip to content

Emacs racer is slow when autocompleting certain types, e.g. strings, with company-mode #91

Open
@Wojtek242

Description

@Wojtek242

There is noticeable lag when trying to autocomplete string types on thy fly with company-mode. Taking the example from the guessing game in the rust book

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);

    match guess.cmp(&secret_number) {
        Ordering::Less    => println!("Too small!"),
        Ordering::Greater => println!("Too big!"),
        Ordering::Equal   => println!("You win!"),
    }
}

When typing out the match guess.cmp ... line, Emacs noticeably stalls as soon as it tries to do completion at point, i.e. when I pause at match guess. and then subsequently after every letter I type.

At first I thought that something isn't playing well with company-mode, which did turn out to be the case, but that also turned out not to be the bottleneck. Having played around with it a bit further, I think the slow down is due to Emacs making a synchronous call to racer with every keystroke and in this case the racer command doesn't return fast enough to allow for smooth typing.

i) Is there some known configuration I can use to avoid this problem?

My current configuration for company, and racer is as follows:

(use-package company
    :init
    (add-hook 'after-init-hook 'global-company-mode)
    :config
    ;; For this to correctly complete headers, need to add all include paths to
    ;; `company-c-headers-path-system'.
    (add-to-list 'company-backends 'company-c-headers)
    (setq company-backends (delete 'company-clang company-backends)))

(use-package rust-mode
    :defer t)

  ;; This requires some additional setup as the racer binary must be installed
  ;; and the Rust libstd sources must be installed.
  ;; $ rustup component add rust-src
  ;; $ cargo install racer
  (use-package racer
    :init
    (add-hook 'rust-mode-hook #'racer-mode)
    (add-hook 'racer-mode-hook #'eldoc-mode)
    :config
    (setq-default
     racer-rust-src-path
     "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/")

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

ii) If not, is this a known limitation? If so, are there any ideas how it can be fixed? Recently, I finally learned Elisp properly and have been hacking away at my config so I'm happy to help out myself, I just want to make sure I'm not going to be foolishly trying something that simply won't work. I don't think Emacs-racer currently does any caching and the calls are synchronous so those are two areas of improvement I can think of the top of my head with the latter perhaps being more attractive seeing as it could follow the example set by emacs-clang-complete-async.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions