From 5469d9bc3a13c75a8e98a86b6005d3540eb92524 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 18 Mar 2017 21:55:18 +0100 Subject: fix rust indentation bug This patch fixes a bug I found where rust-mode would misindent code like: fn each_split_within<'a, F>(ss: &'a str, lim: usize, mut it: F) -> bool where F: FnMut(&'a str) -> bool { } fn test_split_within() { } In particular the second "fn" would be indented a level. On the "fn" line, rust-mode-indent-line was calling rust-beginning-of-defun, which would go to the previous defun. Fixing this required moving the definition of rust-top-item-beg-re higher in the file, before its first use (recent versions of Emacs insist on this). And, this required removing the "^" from this regexp, which is ok because the sole use is already adding a "^". Additionally, I moved the "\\_>" into the regexp, rather than have it added at the point of use, so that the new use would also benefit. This patch includes two new test cases. --- rust-mode.el | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'rust-mode.el') diff --git a/rust-mode.el b/rust-mode.el index 2307cc0..f1c3994 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -35,6 +35,14 @@ (defconst rust-re-unsafe "unsafe") (defconst rust-re-extern "extern") +;;; Start of a Rust item +(defvar rust-top-item-beg-re + (concat "\\s-*\\(?:priv\\|pub\\)?\\s-*" + (regexp-opt + '("enum" "struct" "type" "mod" "use" "fn" "static" "impl" + "extern" "trait")) + "\\_>")) + (defun rust-looking-back-str (str) "Like `looking-back' but for fixed strings rather than regexps (so that it's not so slow)" (let ((len (length str))) @@ -394,6 +402,10 @@ buffer." ;; our search for "where ". (let ((function-start nil) (function-level nil)) (save-excursion + ;; If we're already at the start of a function, + ;; don't go back any farther. We can easily do + ;; this by moving to the end of the line first. + (end-of-line) (rust-beginning-of-defun) (back-to-indentation) ;; Avoid using multiple-value-bind @@ -437,6 +449,10 @@ buffer." ;; baseline as well. (looking-at "\\\\|{\\|/[/*]") + ;; If this is the start of a top-level item, + ;; stay on the baseline. + (looking-at rust-top-item-beg-re) + (save-excursion (rust-rewind-irrelevant) ;; Point is now at the end of the previous line @@ -1136,13 +1152,6 @@ Use idomenu (imenu with `ido-mode') for best mileage.") ;;; Defun Motions -;;; Start of a Rust item -(defvar rust-top-item-beg-re - (concat "^\\s-*\\(?:priv\\|pub\\)?\\s-*" - (regexp-opt - '("enum" "struct" "type" "mod" "use" "fn" "static" "impl" - "extern" "trait")))) - (defun rust-beginning-of-defun (&optional arg) "Move backward to the beginning of the current defun. @@ -1153,7 +1162,7 @@ This is written mainly to be used as `beginning-of-defun-function' for Rust. Don't move to the beginning of the line. `beginning-of-defun', which calls this, does that afterwards." (interactive "p") - (re-search-backward (concat "^\\(" rust-top-item-beg-re "\\)\\_>") + (re-search-backward (concat "^\\(" rust-top-item-beg-re "\\)") nil 'move (or arg 1))) (defun rust-end-of-defun () -- cgit v1.2.3