Git Product home page Git Product logo

rust-mode's Introduction

rust-mode

NonGNU ELPA MELPA

Table of Contents

Introduction

rust-mode makes editing Rust code with Emacs enjoyable. It requires Emacs 25 or later, and is included in both Emacs Prelude and Spacemacs by default.

This mode provides:

  • Syntax highlighting (for Font Lock Mode)
  • Indentation
  • Integration with Cargo, clippy and rustfmt

This mode does not provide auto completion, or jumping to function / trait definitions. See Auto-completion below for tips on how to enable this.

If you are missing features in rust-mode, please check out rustic before you open a feature request. It depends on rust-mode and provides additional features. This allows us to keep rust-mode light-weight for users that are happy with basic functionality.

Known issues

  • rust-syntax-propertize and adaptive-wrap-prefix-mode can lead to severe lag when editing larger files (brotzeit/rustic#107)

Installation

Melpa

The package is available on MELPA. Add this to your init.el.

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(package-refresh-contents)

Now you can install rust-mode with:

M-x package-install rust-mode

And put this in your config to load rust-mode automatically:

(require 'rust-mode)

NonGNU ELPA

NonGNU ELPA can be used out of the box in emacs28.

For older versions you need to add something like the following to your init file:

(with-eval-after-load 'package (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/")))

Manual installation

Clone this repository locally, and add this to your init.el:

(add-to-list 'load-path "/path/to/rust-mode/")
(autoload 'rust-mode "rust-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))

Feature guide

Indentation

Commands like TAB should indent correctly.

The Rust style guide recommends spaces rather than tabs for indentation; to follow the recommendation add this to your init.el, which forces indentation to always use spaces.

(add-hook 'rust-mode-hook
          (lambda () (setq indent-tabs-mode nil)))

Since Emacs ≥ 24.4, electric-indent-mode is turned on by default. If you do not like it, call (electric-indent-mode 0) in rust-mode-hook.

Code formatting

The rust-format-buffer function will format your code with rustfmt if installed. By default, this is bound to C-c C-f.

The variable rust-format-on-save enables automatic formatting on save. For example, add the following in your init.el to enable format on save:

(setq rust-format-on-save t)

Prettifying

You can toggle prettification of your code by running M-x prettify-symbols-mode. If you'd like to automatically enable this for all rust files, add the following to your init.el.

(add-hook 'rust-mode-hook
          (lambda () (prettify-symbols-mode)))

You can add your own prettifications to rust-prettify-symbols-alist. For example, to display x.add(y) as x∔(y), simply add to your init file (push '(".add" . ?∔) rust-prettify-symbols-alist).

Running / testing / compiling code

The rust-run, rust-test, rust-compile and rust-check functions shell out to Cargo to run, test, build and check your code. Under the hood, these use the standard Emacs compile function.

By default these are bound to:

  • C-c C-c C-u rust-compile
  • C-c C-c C-k rust-check
  • C-c C-c C-t rust-test
  • C-c C-c C-r rust-run

To run programs requiring user input use universal argument when invoking rust-run (C-u C-c C-c C-r).

Clippy

rust-run-clippy runs Clippy, a linter. By default, this is bound to C-c C-c C-l.

Easy insertion of dbg!

rust-dbg-wrap-or-unwrap either wraps or unwraps the current region in dbg!. This can be useful for easily adding debug lines to your program.

This is bound to C-c C-d by default.

More commands

  • rust-toggle-mutability toggle mut for var defined at current line

tree-sitter

You can try the new native treesitter mode rust-ts-mode with:

(use-package rust-mode
  :init
  (setq rust-mode-treesitter-derive t))

In case you want to use treesitter but can't use Emacs 29.1, you can take a look at tree-sitter. When the dependencies are installed you can activate the feature with:

(use-package tree-sitter
  :config
  (require 'tree-sitter-langs)
  (global-tree-sitter-mode)
  (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))

LSP

eglot

A lightweight lsp client.

(add-hook 'rust-mode-hook 'eglot-ensure)

lsp-mode

Provides more features and you can enhance the functionality by using additional packages. You can find more information in the lsp-mode wiki.

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

Auto-completion

You can either use a lsp client or racer with emacs-racer.

Note that racer and rls are considered deprecated. You should use rust-analyzer instead.

Other recommended packages

flycheck

flycheck allows highlighting compile errors and Clippy lints inline.

cargo.el

cargo.el provides a minor mode for integration with Cargo, Rust's package manager.

cargo-mode

cargo-mode is an Emacs minor mode which allows to dynamically select a Cargo command. The reasons behind this package can be found in the post.

rustic

rustic is based on rust-mode, extending it with other features such as integration with LSP and with flycheck.

Optional features

The features of the following files can be disabled with rust-load-optional-libraries.

  • rust-cargo.el
  • rust-compile.el
  • rust-playpen.el
  • rust-rustfmt.el

They are disabled by default when you use rustic as it has its own implementations for those features.

Customization

rust-cargo-default-arguments set additional cargo args used for check,compile,run,test

For package maintainers

Tests

Run elisp tests:

make test

Contributing

Contributions are very welcome. We are also looking for additional maintainers.

rust-mode's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-mode's Issues

impl fn indented to left margin

Under some circumstances, impl functions, such as method_allows below, are indented to the left margin. I have tried to reduce this example further but have failed to reproduce the behaviour with anything simpler.

In some case indentation is also not fixed - invoking indent-for-tab-command several times results in toggling of indentation levels.

#[derive(RustcEncodable)]
struct Unit {
    name: String,
}
/// Handler for Units
#[derive(Debug,Clone)]
pub struct Units;
resource_handler!(Units);

impl Resource for Units {
    fn available_content_types(&self, _: &Request, _: &mut Response) -> Vec<Mime> {
        vec![Mime(TopLevel::Application, SubLevel::Json, vec![])]
    }

fn method_allowed(&self, req: &Request, _: &mut Response) -> Vec<Mime> {
        match req.method {
        method::Get|method::Head|method::Post => true,
        _ => false
        }
    }

    fn handle_ok(&self, _: &Request, resp: &mut Response) -> ResourceResult {
        "connection failed"
    }
}

emacs auto-complete should be enabled by default

Issue by pcn
Sunday Jan 04, 2015 at 06:33 GMT

For earlier discussion, see rust-lang/rust#20509

This issue was labelled with: A-infrastructure in the Rust repository


Even without specialized support for e.g. names in crates, enabling auto-complete in rust-mode should be on by default to some extent.

I'm not a guru, but I think that there are two approaches.

  1. Either auto-complete can be active by default (where it will pop-up completions as you type)
  2. or, if that's not preferred, auto-complete functionality should be bound to some fairly common key ("Tab", or "M-/" are the most common choices from what I'm aware of) that enables completion when the cursor is in the middle of some typed text (e.g. http://cx4a.org/software/auto-complete/manual.html#Trigger_Key).

For more advanced completion stuff, is there a canonical set of places that could be searched for symbols to be completed? I searched and found this: http://www.reddit.com/r/rust/comments/1xfjo7/ide_support/. Is there a plan for this kind of support?

Incorrect indentation with character literal '('

Using the character literal '(' causes incorrect indentation:

fn base(&mut self) -> ParseResult {
    if self.peek() == '(' {
        self.consume('(').unwrap(); // The '(' here seems to be the problem
                     let r = try!(self.regex());
                     self.consume(')').unwrap();
        Ok(r)
    } else {
        Ok(RegEx::Terminal(self.next()))
    }
    }

I suspect this problem will occur other character literals but I haven't tested anything else.

everything shows up as Function in imenu

Is this expected or is it something on my end? Everything except for impls shows up as "Function" on my end, is that what is meant by "Imenu will show all the enums, structs, etc. at the same level." in the source comment? Is there a reason we can't have different headings like "Struct" and "Enum" etc.?

RFE: cargo compilation integration

It would be great to integrate with cargo in a manner similar to how compilation works in other modes (run a command to compile; "C-c C-c" or "M-x compile" or such, and then "C-x `" ("M-x next-error") to jump to the next error in the source file).

Although "M-x compile" can be set to invoke cargo build, this integrates poorly with next-error since the output is not really formatted for use with that, and a lot of things are selected as errors in the compile output that really aren't.

ert has two failures out-of-box on OS X, GNU Emacs 24.3.92.1

To reproduce: Grab Emacs.app from http://emacsformacosx.com/

% /Applications/Emacs.app/Contents/MacOS/Emacs -batch -l rust-mode.el -l rust-mode-tests.el -f ert-run-tests-batch-and-exit
Warning: arch-dependent data dir `/Users/build/workspace/Emacs-Multi-Build/label/mavericks/emacs-source/nextstep/Emacs.app/Contents/MacOS/libexec/': No such file or directory
Running 63 tests (2015-02-06 00:47:59+0100)
Test auto-fill-multi-line-doc-comment backtrace:
  (if (unwind-protect (setq value-72102 (apply fn-72100 args-72101)) (
  (let (form-description-72104) (if (unwind-protect (setq value-72102 
  (let ((value-72102 (quote ert-form-evaluation-aborted-72103))) (let 
  (let ((fn-72100 (function rust-compare-code-after-manip)) (args-7210
  (progn (rust-mode) (insert original) (goto-char point-pos) (funcall 
  (unwind-protect (progn (rust-mode) (insert original) (goto-char poin
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-b
  rust-test-manip-code("/**\n *\n */" 8 (lambda nil (unwind-protect (p
  test-auto-fill("/**\n *\n */" 8 "This is a very very very very very 
  (lambda nil (test-auto-fill "/**\n *\n */" 8 "This is a very very ve
  #[0 "\306\307!r\211q\210\310\311\312\313\314\315!\316\"\317\320%DC
  funcall(#[0 "\306\307!r\211q\210\310\311\312\313\314\315!\316\"\31
  ert--run-test-internal([cl-struct-ert--test-execution-info [cl-struc
  #[0 "r\304 q\210\305 )\306\307\310\311\312\313!\314\"\315\316%DC\2
  funcall(#[0 "r\304 q\210\305 )\306\307\310\311\312\313!\314\"\315\
  ert-run-test([cl-struct-ert-test auto-fill-multi-line-doc-comment ni
  ert-run-or-rerun-test([cl-struct-ert--stats t [[cl-struct-ert-test a
  ert-run-tests(t #[385 "\306\307\"\203D\211\211G\310U\203\211@\20
  ert-run-tests-batch(nil)
  ert-run-tests-batch-and-exit()
  command-line-1(("-l" "rust-mode.el" "-l" "rust-mode-tests.el" "-f" "
  command-line()
  normal-top-level()
Test auto-fill-multi-line-doc-comment condition:
    (ert-test-failed
     ((should
       (rust-compare-code-after-manip original point-pos manip-func expected
                      (buffer-string)))
      :form
      (rust-compare-code-after-manip "/**\n *\n */" 8
                     (lambda nil
                       (unwind-protect ... ...))
                     "/**\n * This is a very very very very\n * very very very long string\n */" "/**\n *\nThis is a very very very very\nvery very very long string */")
      :value nil :explanation
      ("Rust code was manipulated wrong after:"
       (insert "/**\n *\n */")
       (goto-char 8)
       expected
       (insert "/**\n * This is a very very very very\n * very very very long string\n */")
       got
       (insert "/**\n *\nThis is a very very very very\nvery very very long string */")
       (first-difference-at
    (goto-char 7)
    expected " " got "\n"))))
   FAILED   1/63  auto-fill-multi-line-doc-comment
   passed   2/63  auto-fill-multi-line-prefixless
   passed   3/63  auto-fill-single-line-doc-comment
   passed   4/63  fill-paragraph-multi-line-style-inner-doc-comment
   passed   5/63  fill-paragraph-multi-paragraph-multi-line-style-doc-comment
   passed   6/63  fill-paragraph-multi-paragraph-single-line-style-doc-comment
   passed   7/63  fill-paragraph-multi-paragraph-single-line-style-indented
   passed   8/63  fill-paragraph-prefixless-multi-line-doc-comment
   passed   9/63  fill-paragraph-single-line-style-code-before-and-after
   passed  10/63  fill-paragraph-single-line-style-inner-doc-comment
   passed  11/63  fill-paragraph-single-line-style-with-code-after
   passed  12/63  fill-paragraph-single-line-style-with-code-before
   passed  13/63  fill-paragraph-top-level-multi-line-style-doc-comment-first-line
   passed  14/63  fill-paragraph-top-level-multi-line-style-doc-comment-second-line
   passed  15/63  fill-paragraph-with-no-space-after-star-prefix
   passed  16/63  font-lock-attribute-around-comment
   passed  17/63  font-lock-attribute-inner
   passed  18/63  font-lock-attribute-inside-comment
   passed  19/63  font-lock-attribute-inside-string
   passed  20/63  font-lock-attribute-key-value
   passed  21/63  font-lock-attribute-simple
Indenting region...
Indenting region...done
   passed  22/63  indent-curly-braces-within-parens
Indenting region...
Indenting region...done
Test indent-doc-comments backtrace:
  (if (unwind-protect (setq value-72102 (apply fn-72100 args-72101)) (
  (let (form-description-72104) (if (unwind-protect (setq value-72102 
  (let ((value-72102 (quote ert-form-evaluation-aborted-72103))) (let 
  (let ((fn-72100 (function rust-compare-code-after-manip)) (args-7210
  (progn (rust-mode) (insert original) (goto-char point-pos) (funcall 
  (unwind-protect (progn (rust-mode) (insert original) (goto-char poin
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-b
  rust-test-manip-code("      \n      /**\n      * This is a doc comme
  (let ((deindented (replace-regexp-in-string "^[[:blank:]]*" "      "
  test-indent("\n/**\n * This is a doc comment\n *\n */\n\n/// So is t
  (lambda nil (test-indent "\n/**\n * This is a doc comment\n *\n */\n
  #[0 "\306\307!r\211q\210\310\311\312\313\314\315!\316\"\317\320%DC
  funcall(#[0 "\306\307!r\211q\210\310\311\312\313\314\315!\316\"\31
  ert--run-test-internal([cl-struct-ert--test-execution-info [cl-struc
  #[0 "r\304 q\210\305 )\306\307\310\311\312\313!\314\"\315\316%DC\2
  funcall(#[0 "r\304 q\210\305 )\306\307\310\311\312\313!\314\"\315\
  ert-run-test([cl-struct-ert-test indent-doc-comments nil (lambda nil
  ert-run-or-rerun-test([cl-struct-ert--stats t [[cl-struct-ert-test a
  ert-run-tests(t #[385 "\306\307\"\203D\211\211G\310U\203\211@\20
  ert-run-tests-batch(nil)
  ert-run-tests-batch-and-exit()
  command-line-1(("-l" "rust-mode.el" "-l" "rust-mode-tests.el" "-f" "
  command-line()
  normal-top-level()
Test indent-doc-comments condition:
    (ert-test-failed
     ((should
       (rust-compare-code-after-manip original point-pos manip-func expected
                      (buffer-string)))
      :form
      (rust-compare-code-after-manip "      \n      /**\n      * This is a doc comment\n      *\n      */\n      \n      /// So is this\n      \n      fn foo() {\n      /*!\n      * this is a nested doc comment\n      */\n      \n      //! And so is this\n      }" 1
                     (lambda nil
                       (indent-region 1 ...))
                     "\n/**\n * This is a doc comment\n *\n */\n\n/// So is this\n\nfn foo() {\n    /*!\n     * this is a nested doc comment\n     */\n\n    //! And so is this\n}" "\n/**\n * This is a doc comment\n *\n */\n\n/// So is this\n\nfn foo() {\n    /*!\n     * this is a nested doc comment\n     */\n    \n    //! And so is this\n}")
      :value nil :explanation
      ("Rust code was manipulated wrong after:"
       (insert "      \n      /**\n      * This is a doc comment\n      *\n      */\n      \n      /// So is this\n      \n      fn foo() {\n      /*!\n      * this is a nested doc comment\n      */\n      \n      //! And so is this\n      }")
       (goto-char 1)
       expected
       (insert "\n/**\n * This is a doc comment\n *\n */\n\n/// So is this\n\nfn foo() {\n    /*!\n     * this is a nested doc comment\n     */\n\n    //! And so is this\n}")
       got
       (insert "\n/**\n * This is a doc comment\n *\n */\n\n/// So is this\n\nfn foo() {\n    /*!\n     * this is a nested doc comment\n     */\n    \n    //! And so is this\n}")
       (first-difference-at
    (goto-char 118)
    expected "\n" got " "))))
   FAILED  23/63  indent-doc-comments
Indenting region...
Indenting region...done
   passed  24/63  indent-indented-match
Indenting region...
Indenting region...done
   passed  25/63  indent-inside-braces
Mark set
Mark set
   passed  26/63  indent-line-after-whitespace-motion
Mark set
Mark set
   passed  27/63  indent-line-blank-line-indented-already-bol
Mark set
Mark set
   passed  28/63  indent-line-blank-line-indented-already-middle
Mark set
Mark set
   passed  29/63  indent-line-blank-line-motion
Mark set
Mark set
   passed  30/63  indent-line-closing-brace-motion
Mark set
Mark set
   passed  31/63  indent-line-middle-pull-motion
Mark set
Mark set
   passed  32/63  indent-line-middle-push-motion
Mark set
Mark set
   passed  33/63  indent-line-nonblank-line-indented-already-bol
Mark set
Mark set
   passed  34/63  indent-line-nonblank-line-indented-already-middle
Indenting region...
Indenting region...done
   passed  35/63  indent-match
Indenting region...
Indenting region...done
   passed  36/63  indent-match-multiline-pattern
Indenting region...
Indenting region...done
   passed  37/63  indent-multi-line-attrib
Indenting region...
Indenting region...done
   passed  38/63  indent-multi-line-expr
Indenting region...
Indenting region...done
   passed  39/63  indent-nested-fns
Indenting region...
Indenting region...done
   passed  40/63  indent-nonmatch-or-expression
Indenting region...
Indenting region...done
   passed  41/63  indent-params-align
Indenting region...
Indenting region...done
   passed  42/63  indent-params-no-align
Indenting region...
Indenting region...done
   passed  43/63  indent-square-bracket-alignment
Indenting region...
Indenting region...done
   passed  44/63  indent-struct-fields-aligned
Indenting region...
Indenting region...done
   passed  45/63  indent-top-level
   passed  46/63  indent-weirdly-indented-block
Mark set
Mark set
   passed  47/63  rust-beginning-of-defun-before-open-brace
Mark set
Mark set
   passed  48/63  rust-beginning-of-defun-between-fns
Mark set
Mark set
   passed  49/63  rust-beginning-of-defun-from-end
Mark set
Mark set
   passed  50/63  rust-beginning-of-defun-from-middle-of-fn
Mark set
Mark set
   passed  51/63  rust-beginning-of-defun-pub-fn
Mark set
Mark set
   passed  52/63  rust-beginning-of-defun-with-arg
Mark set
Mark set
   passed  53/63  rust-beginning-of-defun-with-negative-arg
Mark set
Mark set
   passed  54/63  rust-end-of-defun-before-open-brace
Mark set
Mark set
   passed  55/63  rust-end-of-defun-between-fns
Mark set
Mark set
   passed  56/63  rust-end-of-defun-from-beg
Mark set
Mark set
   passed  57/63  rust-end-of-defun-from-middle-of-fn
Mark set
Mark set
   passed  58/63  rust-end-of-defun-with-arg
Mark set
Mark set
   passed  59/63  rust-end-of-defun-with-negative-arg
Mark set
Mark set
Mark set
Mark set
Mark set
   passed  60/63  rust-mark-defun-from-end
Mark set
Mark set
Mark set
Mark set
Mark set
   passed  61/63  rust-mark-defun-from-middle-of-fn
Mark set
Mark set
Mark set
Mark set
Mark set
   passed  62/63  rust-mark-defun-from-middle-of-struct
Mark set
Mark set
Mark set
Mark set
Mark set
   passed  63/63  rust-mark-defun-start-of-defun

Ran 63 tests, 61 results as expected, 2 unexpected (2015-02-06 00:48:01+0100)

2 unexpected results:
   FAILED  auto-fill-multi-line-doc-comment
   FAILED  indent-doc-comments


(I don't know if this is Mac-specific or Emacs-version specific or what. I will hopefully check against a Linux VM in the near future.)

PR 38 had some ill-formed comments

My review on PR #38 noted some comments that needed fixing.

@MicahChalmer please post a PR with fixes to the comments. Preferably soon, before you forget the context in which you had written them. :)

(If this issue goes for two weeks without being addressed, then we should just close it and live with the ill comments.)

{forward,backward}-word behavior is unexpected

Because _ is treated as a "word" character, functions operating on words do not behave in the usual way - eg. instead of jumping over "var" in var_name, forward-word jumps over the whole symbol (ie. does the same thing as forward-symbol).
I tried to address this before but did not fix it properly, I will have a PR soon that is a proper fix.

indent-method-chain fails to indent in this case

    let llargs: Vec<_> =
        input_tys.iter()
                 .enumerate()
                 .map(|(i, _)| get_param(fcx.llfn, fcx.arg_pos(i+1) as u32))
                 .collect();

indents for me as

    let llargs: Vec<_> =
        input_tys.iter()
                 .enumerate()
                 .map(|(i, _)| get_param(fcx.llfn, fcx.arg_pos(i+1) as u32))
             .collect();

it also occurs to me that the impl will fail to indent properly if there is a // ... comment at the end of the previous line.

possible to show error messages on their own line?

Woops, submitted before I wrote the body.

So I'm wondering if there's a way, any way, even a hack on my end, to show the error message starting on its own new line. For some reason the error messages show the full absolute path to the file which makes the error message wrap around unnecessarily in most cases.

Is there a way to make the error message show up on its own line?

See this question for a picture and more information.

Alternatively/additionally, is there a way to modify the way the file path is presented? I'd like to apply a function like abbreviate-file-name to it so that it becomes relative and shortens it a bit.

markdown mode in docs

It would be lovely to have emacs use markdown mode in the docs embedded in rust files.

imenu regexps are confused by comments

Given the code

// struct X

struct Y {
    A: i64,
}

 struct Z {
    A: i64,
}

"
struct Q {
    A: i64,
}
"

fn foo() {}

// fn bar() {}

imenu offers X, Y, Z, foo and bar. I'm not sure why this occurs, since imenu--generic-function tries hard to avoid strings and comments (unless you modify imenu-generic-skip-comments-and-strings).

Provide releases for melpa-stable

Some people don't want to install bleeding-edge (daily snapshot) emacs lisp packages from Melpa. For those, melpa-stable automatically collects tagged releases from Github and publishes those.

It would be very nice if rust-mode could start adding git-tags for releases for it to appear in melpa-stable.

misc not provided

Error 'misc' is not provided, error thrown when opening *.rs files. I am assuming this is referring to line 13 in rust-mode.el. Any help is welcome, Thanks

Emacs rust-mode: backward-word and backward-kill broken

Issue by fzzy
Thursday Nov 13, 2014 at 14:40 GMT

For earlier discussion, see rust-lang/rust#18923

This issue was labelled with: A-infrastructure in the Rust repository


When I move backwards a word (M-b) or delete a word (M-d) while rust-mode and subword-mode are enabled, Emacs' text cursor will skip a snake cased subword.
I sometimes get similar problems with forward word moving as well, but not as often.
(If subword-mode is disabled, both M-f and M-b will advance whole snake cased words, which it doesn't normally do)

I'm not sure if this is just a issue with me, but this problem only occurs with rust-mode and not any other language modes, so I assume it's something with rust-mode.
I don't have any weird settings to my knowledge that should break this.

eg.

what i get

before M-b

pub fn mount(&self, path: &str, mount_point: &str, append_to_path: bool) {}
                                           ^

after M-b:

pub fn mount(&self, path: &str, mount_point: &str, append_to_path: bool) {}
                                ^

what it should do

before M-b

pub fn mount(&self, path: &str, mount_point: &str, append_to_path: bool) {}
                                           ^

after M-b:

pub fn mount(&self, path: &str, mount_point: &str, append_to_path: bool) {}
                                     ^

Function movement commands don't work

C-M-a and C-M-e (beginning-of-defun and end-of-defun) should move point to the beginning/end of functions. These currently don't work in rust-mode.

I believe this is also why C-x n d (narrow-to-defun) doesn't work.

Marmalade is still recommended in the README, but package there is old and outdated

The README recommends either Marmalade or MELPA to install rust-mode. MELPA automatically keeps itself up to date with the master branch from this repo. Marmalade does not--the owner has to keep updating it themselves as far as I can tell. It has a very old version up there now.

I would recommend one of these options:

  • Set up a bot that uploads the latest version to Marmalade based on the master branch here
  • Remove the package from Marmalade, and change the README recommend MELPA only

Either of these would require action from a Mozilla person--it can't be done in just a PR on this repo.

injected code results in errors that emacs hates

Issue by brson
Wednesday Sep 19, 2012 at 00:56 GMT

For earlier discussion, see rust-lang/rust#3530

This issue was labelled with: A-diagnostics, A-tools, I-wrong, P-low in the Rust repository


For example:

<core-macros>:3:10: 3:61 note: in expansion of #error

Emacs wants to load <core-macros> and interrupts your workflow to prompt for it. Injected code should come from files on disk (like intrinsic.rs) and we should use the correct file path when inserting them into the AST, so that the error messages work.

Alternately, we can come up with another way to indicate injected code so that the diagnostic emitter can generate error messages that emacs doesn't complain about. This could be a better solution, since getting dumped into core_macros.rs may not be so useful.

emacs mode wraps comments incorrectly

Issue by brson
Thursday Jan 22, 2015 at 20:42 GMT

For earlier discussion, see rust-lang/rust#21524

This issue was labelled with: A-tools in the Rust repository


This is a regression that has existed for a while. If I enter a long line of comments:

    // The reason for the current stability level. If deprecated, the reason for deprecation.

and press Alt-Q it does this:

    // The reason for the current stability level. If deprecated, the
    reason for deprecation.

which is invalid syntax.

emacs mode indentation is wrong when function return -> is on its own line

Issue by nikomatsakis
Wednesday Apr 16, 2014 at 19:39 GMT

For earlier discussion, see rust-lang/rust#13566

This issue was labelled with: A-tools in the Rust repository


The following code indents as shown here, which is weird:

pub fn from_pointer_kind(base_mutbl: MutabilityCategory,
                         ptr: PointerKind)
                         -> MutabilityCategory {
                             match ptr {
                             }
                         }

I expect it to be:

pub fn from_pointer_kind(base_mutbl: MutabilityCategory,
                         ptr: PointerKind)
                         -> MutabilityCategory {
    match ptr {
    }
}

Emacs: rust-indent-method-chains indents beginning of line oddly

Issue by ProjectMoon
Monday Jan 26, 2015 at 10:29 GMT

For earlier discussion, see rust-lang/rust#21650

This issue was labelled with: A-infrastructure in the Rust repository


Trying out rust-mode in emacs, and set rust-indent-method-chains because I like me some aligned dots.

It does what it advertises, but for some reason shoves the beginning of the line (and thus the lines underneath it) over one more tab.

I'm using spaces for tabs, configured to width 4.

What I expect:

let x = thing.do_it()
             .aligned()
             .more_alignment();

What I get:

    let x = thing.do_it()
                 .aligned()
                 .more_alignment();

I am using el-get to install rust-mode so it should be pulling off the latest master.

Indent closing bracket of multi-line function calls, arrays etc.

The closing bracket of multi-line expressions currently gets indented like this:

let a = vec!(1,
             2,
             );

and

let a = [1, 
         2, 
         ];

whereas it should be:

let a = vec!(
  1,
  2,
);

and

let a = [1, 
         2, 
];

I quickly hacked rust-mode-indent-line to use

;; A closing brace is 1 level unindented
((looking-at "[])}]") (- baseline rust-indent-offset))

which works fine, but I haven't read the wider context, so I don't know if that breaks any other things.

Highlight matching angle brackets

We have some structs with very long nested types:

type SqrtCli<R, S, T> =
    Choose<Eps,
    Choose<R,
    Choose<S,
    Choose<Send<f64, Offer<Recv<f64, Var<Z>>, Var<Z>>>,
    T>>>>;

It would be very nice to have the syntax highlightingin rust-mode work for angle brackets as well --- as in, highlighting matching delimiters --- since it is a pain to keep track of them yourself. This goes for type parameters in functions, structures, impls and traits as well.

I realize that the problem is to parse < and > differently whether they're used as delimiters or simple less-than/greater-than signs --- a problem that the rustc parser has as well --- but this is something that would help us tremendously. I'm not very familiar with writing indentation modes but if there's any way I can help, please let me know.

It'd probably also be desirable for rust-mode to be able to indent type parameters properly, but the above code isn't the best example of how to do that.

handle examples in docs

It would be lovely to have proper rust highlighting and handling in doc examples. e.g. when editing

//! ```
//! let x = 1;
//! ```

I would love to have rust indentation and syntax highlighting on the example code.

end-of-buffer warning on emacs GNU Emacs 24.5.1

Compiling file .emacs.d/elpa/rust-mode-20150408.1716/rust-mode.el at Thu Apr 30 09:35:53 2015
In rust-playpen-region:
rust-mode.el:773:32:Warning: `end-of-buffer' is for interactive use only; use `(goto-char (point-max))' instead.

Method chain alignment interacts poorly with `if`

This code:

if
    !cache_fresh_trait_pred.0.substs.regions.is_noop() &&
    cache_fresh_trait_pred.0.input_types().iter().any(
        |&t| ty::type_has_self(t) || ty::type_has_params(t) || ty::type_has_regions(
{
}

indents like

if
!cache_fresh_trait_pred.0.substs.regions.is_noop() ||
    cache_fresh_trait_pred.0.input_types().iter().any(
        |&t| ty::type_has_self(t) || ty::type_has_params(t) || ty::type_has_regions(t))
{
}

I suspect this is an issue with method-chain alignment, though I haven't verified that. There seems to be something wrong with the regexp that causes it to kick in more than I expect.

emacs mode: ']', ')', and '}' close previous open paren/brace/bracket

Issue by pnkfelix
Monday Nov 04, 2013 at 15:42 GMT

For earlier discussion, see rust-lang/rust#10262

This issue was labelled with: A-tools in the Rust repository


Here is the illustrative example:

fn foo() {
    { bar('}'); }
    { bar(']'); }
    { bar(')'); }
}

The characters within ' characters above are incorrectly treated by src/etc/rust-mode.el as closing the opening paren of the invocation of bar. This confuses Emacs in a number of ways (e.g. obviously paren matching; but also the auto-indentation gets confused too, which is more annoying).

Emacs mode has issues with single quotes

Issue by haxney
Thursday Oct 31, 2013 at 04:58 GMT

For earlier discussion, see rust-lang/rust#10190

This issue was labelled with: A-tools in the Rust repository


The latest version of rust-mode for Emacs (20130928.1740) has issues with
single-quoted characters, especially when that character is a " (double
quote). The following program executes correctly in Rust 0.8, but is font-locked
improperly in Emacs:

fn main() {
    println!("{}", '"');
}

It treats the double quote as the beginning of a string which runs to the end of
the file. If the double quote character is escaped like so:

fn main() {
    println!("{}", '\"');
}

Then there is not a problem with an unterminated string, but the characters
inside the single quotes are not fontified at all.

Note: Both programs compile and execute successfully under Rust 0.8.

This is related to #8793

Adding a line break after a Trait in a template argument list breaks emacs-mode indentation

Issue by gsingh93
Friday Aug 22, 2014 at 01:25 GMT

For earlier discussion, see rust-lang/rust#16665

This issue was labelled with: A-infrastructure in the Rust repository


I think this is a somewhat serious bug with emacs-mode, since I can't use the tab key for indentation inside a function block in many cases.

My code ends up with a long list of traits with bounds in the template argument list, and according to the style guide, I can wrap between traits. However, if I wrap between traits, identation is broken for the function. Consider the following example,

pub fn foo<T,
           V>() {
              // Indentation puts me here
}

As you can see, hitting tab inside the function idents too much. I should mention that I aligned the second template argument to match up with the first, as hitting tab there doesn't work either.

End of string match failures

Using rust-mode.el 8d99bf8, the following highlights everything after "xs" as a string literal. Editting either string causes the syntax highlighting to work correctly (and reloading the buffer breaks it again).

fn g() -> &str {
    "Er"
}

fn g() -> bool {
    assert!(false,"xs");
    true
}

Documentation String Highlight

It would be nice if documentation strings were highlight a different colour to the usual comment strings. Emacs' font-lock seems to support documentation strings through setting font-lock-doc-face.

The vim analogue of rust-mode does this and highlights documentation in a very-visible colour (red in solarized dark), this makes reading the documentation really nice within the code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.