mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 03:44:24 +00:00
auto merge of #10873 : pradeep90/rust/rust-mode-changes, r=pcwalton
Specifically, we can now use: + beginning-of-defun + end-of-defun + mark-defun where "defun" means a Rust item. + Add tests in rust-mode-tests.el + Fix indentation in rust-mode-tests.el + Add support for trait to Imenu
This commit is contained in:
commit
ad292ac8fd
@ -52,24 +52,24 @@ Also, the result should be the same regardless of whether the code is at the beg
|
||||
(loop
|
||||
for pad-at-beginning from 0 to 1
|
||||
do (loop for pad-at-end from 0 to 1
|
||||
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
|
||||
with padding-end = (if (= 0 pad-at-end) "" padding)
|
||||
with padding-adjust = (* padding-len pad-at-beginning)
|
||||
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
|
||||
with padding-end = (if (= 0 pad-at-end) "" padding)
|
||||
;; If we're adding space to the beginning, and our start position
|
||||
;; is at the very beginning, we want to test within the added space.
|
||||
;; Otherwise adjust the start and end for the beginning padding.
|
||||
with start-pos = (if (= 1 start-pos) 1 (+ padding-adjust start-pos))
|
||||
with end-pos = (+ end-pos padding-adjust)
|
||||
do (loop for pos from start-pos to end-pos
|
||||
do (rust-test-manip-code
|
||||
(concat padding-beginning unfilled padding-end)
|
||||
pos
|
||||
(lambda ()
|
||||
(let ((fill-column rust-test-fill-column))
|
||||
(fill-paragraph)))
|
||||
(concat padding-beginning expected padding-end)))))))
|
||||
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
|
||||
with padding-end = (if (= 0 pad-at-end) "" padding)
|
||||
with padding-adjust = (* padding-len pad-at-beginning)
|
||||
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
|
||||
with padding-end = (if (= 0 pad-at-end) "" padding)
|
||||
;; If we're adding space to the beginning, and our start position
|
||||
;; is at the very beginning, we want to test within the added space.
|
||||
;; Otherwise adjust the start and end for the beginning padding.
|
||||
with start-pos = (if (= 1 start-pos) 1 (+ padding-adjust start-pos))
|
||||
with end-pos = (+ end-pos padding-adjust)
|
||||
do (loop for pos from start-pos to end-pos
|
||||
do (rust-test-manip-code
|
||||
(concat padding-beginning unfilled padding-end)
|
||||
pos
|
||||
(lambda ()
|
||||
(let ((fill-column rust-test-fill-column))
|
||||
(fill-paragraph)))
|
||||
(concat padding-beginning expected padding-end)))))))
|
||||
|
||||
(ert-deftest fill-paragraph-top-level-multi-line-style-doc-comment-second-line ()
|
||||
(test-fill-paragraph
|
||||
@ -262,14 +262,14 @@ fn bar() { }" 14 67))
|
||||
/// "
|
||||
103
|
||||
"This is the second really really really really really really long paragraph"
|
||||
"/// This is the first really
|
||||
"/// This is the first really
|
||||
/// really really really really
|
||||
/// really really long paragraph
|
||||
///
|
||||
/// This is the second really
|
||||
/// really really really really
|
||||
/// really long paragraph"
|
||||
))
|
||||
))
|
||||
|
||||
(ert-deftest auto-fill-multi-line-prefixless ()
|
||||
(test-auto-fill
|
||||
@ -295,7 +295,7 @@ very very very long string
|
||||
|
||||
(ert-deftest indent-struct-fields-aligned ()
|
||||
(test-indent
|
||||
"
|
||||
"
|
||||
struct Foo { bar: int,
|
||||
baz: int }
|
||||
|
||||
@ -305,7 +305,7 @@ struct Blah {x:int,
|
||||
|
||||
(ert-deftest indent-doc-comments ()
|
||||
(test-indent
|
||||
"
|
||||
"
|
||||
/**
|
||||
* This is a doc comment
|
||||
*
|
||||
@ -411,7 +411,7 @@ fn nexted_fns(a: fn(b:int,
|
||||
0
|
||||
}
|
||||
"
|
||||
))
|
||||
))
|
||||
|
||||
(ert-deftest indent-multi-line-expr ()
|
||||
(test-indent
|
||||
@ -423,4 +423,206 @@ fn foo()
|
||||
b();
|
||||
}
|
||||
"
|
||||
))
|
||||
))
|
||||
|
||||
(setq rust-test-motion-string
|
||||
"
|
||||
fn fn1(arg: int) -> bool {
|
||||
let x = 5;
|
||||
let y = b();
|
||||
true
|
||||
}
|
||||
|
||||
fn fn2(arg: int) -> bool {
|
||||
let x = 5;
|
||||
let y = b();
|
||||
true
|
||||
}
|
||||
|
||||
pub fn fn3(arg: int) -> bool {
|
||||
let x = 5;
|
||||
let y = b();
|
||||
true
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
x: int
|
||||
}
|
||||
"
|
||||
rust-test-region-string rust-test-motion-string
|
||||
;; Symbol -> (line column)
|
||||
rust-test-positions-alist '((start-of-fn1 (2 0))
|
||||
(start-of-fn1-middle-of-line (2 15))
|
||||
(middle-of-fn1 (3 7))
|
||||
(end-of-fn1 (6 0))
|
||||
(between-fn1-fn2 (7 0))
|
||||
(start-of-fn2 (8 0))
|
||||
(middle-of-fn2 (10 4))
|
||||
(before-start-of-fn1 (1 0))
|
||||
(after-end-of-fn2 (13 0))
|
||||
(beginning-of-fn3 (14 0))
|
||||
(middle-of-fn3 (16 4))
|
||||
(middle-of-struct (21 10))
|
||||
(before-start-of-struct (19 0))
|
||||
(after-end-of-struct (23 0))))
|
||||
|
||||
(defun rust-get-buffer-pos (pos-symbol)
|
||||
"Get buffer position from POS-SYMBOL.
|
||||
|
||||
POS-SYMBOL is a symbol found in `rust-test-positions-alist'.
|
||||
Convert the line-column information from that list into a buffer position value."
|
||||
(interactive "P")
|
||||
(pcase-let ((`(,line ,column) (cadr (assoc pos-symbol rust-test-positions-alist))))
|
||||
(save-excursion
|
||||
(goto-line line)
|
||||
(move-to-column column)
|
||||
(point))))
|
||||
|
||||
;;; TODO: Maybe add an ERT explainer function (something that shows the
|
||||
;;; surrounding code of the final point, not just the position).
|
||||
(defun rust-test-motion (source-code init-pos final-pos manip-func &optional &rest args)
|
||||
"Test that MANIP-FUNC moves point from INIT-POS to FINAL-POS.
|
||||
|
||||
If ARGS are provided, send them to MANIP-FUNC.
|
||||
|
||||
INIT-POS, FINAL-POS are position symbols found in `rust-test-positions-alist'."
|
||||
(with-temp-buffer
|
||||
(rust-mode)
|
||||
(insert source-code)
|
||||
(goto-char (rust-get-buffer-pos init-pos))
|
||||
(apply manip-func args)
|
||||
(should (equal (point) (rust-get-buffer-pos final-pos)))))
|
||||
|
||||
(defun rust-test-region (source-code init-pos reg-beg reg-end manip-func &optional &rest args)
|
||||
"Test that MANIP-FUNC marks region from REG-BEG to REG-END.
|
||||
|
||||
INIT-POS is the initial position of point.
|
||||
If ARGS are provided, send them to MANIP-FUNC.
|
||||
All positions are position symbols found in `rust-test-positions-alist'."
|
||||
(with-temp-buffer
|
||||
(rust-mode)
|
||||
(insert source-code)
|
||||
(goto-char (rust-get-buffer-pos init-pos))
|
||||
(apply manip-func args)
|
||||
(should (equal (list (region-beginning) (region-end))
|
||||
(list (rust-get-buffer-pos reg-beg)
|
||||
(rust-get-buffer-pos reg-end))))))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-from-middle-of-fn ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn1
|
||||
'start-of-fn1
|
||||
#'beginning-of-defun))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-from-end ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'end-of-fn1
|
||||
'start-of-fn1
|
||||
#'beginning-of-defun))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-before-open-brace ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'start-of-fn1-middle-of-line
|
||||
'start-of-fn1
|
||||
#'beginning-of-defun))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-between-fns ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'between-fn1-fn2
|
||||
'start-of-fn1
|
||||
#'beginning-of-defun))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-with-arg ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn2
|
||||
'start-of-fn1
|
||||
#'beginning-of-defun 2))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-with-negative-arg ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn1
|
||||
'beginning-of-fn3
|
||||
#'beginning-of-defun -2))
|
||||
|
||||
(ert-deftest rust-beginning-of-defun-pub-fn ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn3
|
||||
'beginning-of-fn3
|
||||
#'beginning-of-defun))
|
||||
|
||||
(ert-deftest rust-end-of-defun-from-middle-of-fn ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn1
|
||||
'between-fn1-fn2
|
||||
#'end-of-defun))
|
||||
|
||||
(ert-deftest rust-end-of-defun-from-beg ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'start-of-fn1
|
||||
'between-fn1-fn2
|
||||
#'end-of-defun))
|
||||
|
||||
(ert-deftest rust-end-of-defun-before-open-brace ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'start-of-fn1-middle-of-line
|
||||
'between-fn1-fn2
|
||||
#'end-of-defun))
|
||||
|
||||
(ert-deftest rust-end-of-defun-between-fns ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'between-fn1-fn2
|
||||
'after-end-of-fn2
|
||||
#'end-of-defun))
|
||||
|
||||
(ert-deftest rust-end-of-defun-with-arg ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn1
|
||||
'after-end-of-fn2
|
||||
#'end-of-defun 2))
|
||||
|
||||
(ert-deftest rust-end-of-defun-with-negative-arg ()
|
||||
(rust-test-motion
|
||||
rust-test-motion-string
|
||||
'middle-of-fn3
|
||||
'between-fn1-fn2
|
||||
#'end-of-defun -2))
|
||||
|
||||
(ert-deftest rust-mark-defun-from-middle-of-fn ()
|
||||
(rust-test-region
|
||||
rust-test-region-string
|
||||
'middle-of-fn2
|
||||
'between-fn1-fn2 'after-end-of-fn2
|
||||
#'mark-defun))
|
||||
|
||||
(ert-deftest rust-mark-defun-from-end ()
|
||||
(rust-test-region
|
||||
rust-test-region-string
|
||||
'end-of-fn1
|
||||
'before-start-of-fn1 'between-fn1-fn2
|
||||
#'mark-defun))
|
||||
|
||||
(ert-deftest rust-mark-defun-start-of-defun ()
|
||||
(rust-test-region
|
||||
rust-test-region-string
|
||||
'start-of-fn2
|
||||
'between-fn1-fn2 'after-end-of-fn2
|
||||
#'mark-defun))
|
||||
|
||||
(ert-deftest rust-mark-defun-from-middle-of-struct ()
|
||||
(rust-test-region
|
||||
rust-test-region-string
|
||||
'middle-of-struct
|
||||
'before-start-of-struct 'after-end-of-struct
|
||||
#'mark-defun))
|
||||
|
@ -324,7 +324,7 @@
|
||||
;;; Imenu support
|
||||
(defvar rust-imenu-generic-expression
|
||||
(append (loop for item in
|
||||
'("enum" "struct" "type" "mod" "fn")
|
||||
'("enum" "struct" "type" "mod" "fn" "trait")
|
||||
collect `(nil ,(rust-re-item-def item) 1))
|
||||
`(("Impl" ,(rust-re-item-def "impl") 1)))
|
||||
"Value for `imenu-generic-expression' in Rust mode.
|
||||
@ -335,6 +335,46 @@ Imenu will show all the enums, structs, etc. at the same level.
|
||||
Implementations will be shown under the `Impl` subheading.
|
||||
Use idomenu (imenu with ido-mode) for best mileage.")
|
||||
|
||||
;;; Defun Motions
|
||||
|
||||
;;; Start of a Rust item
|
||||
(setq rust-top-item-beg-re
|
||||
(concat "^\\s-*\\(?:priv\\|pub\\)?\\s-*"
|
||||
(regexp-opt
|
||||
'("enum" "struct" "type" "mod" "use" "fn" "static" "impl"
|
||||
"extern" "impl" "static" "trait"
|
||||
))))
|
||||
|
||||
(defun rust-beginning-of-defun (&optional arg)
|
||||
"Move backward to the beginning of the current defun.
|
||||
|
||||
With ARG, move backward multiple defuns. Negative ARG means
|
||||
move forward.
|
||||
|
||||
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 "\\)\\b")
|
||||
nil 'move (or arg 1)))
|
||||
|
||||
(defun rust-end-of-defun ()
|
||||
"Move forward to the next end of defun.
|
||||
|
||||
With argument, do it that many times.
|
||||
Negative argument -N means move back to Nth preceding end of defun.
|
||||
|
||||
Assume that this is called after beginning-of-defun. So point is
|
||||
at the beginning of the defun body.
|
||||
|
||||
This is written mainly to be used as `end-of-defun-function' for Rust."
|
||||
(interactive "p")
|
||||
;; Find the opening brace
|
||||
(re-search-forward "[{]" nil t)
|
||||
(goto-char (match-beginning 0))
|
||||
;; Go to the closing brace
|
||||
(forward-sexp))
|
||||
|
||||
;; For compatibility with Emacs < 24, derive conditionally
|
||||
(defalias 'rust-parent-mode
|
||||
(if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
|
||||
@ -374,6 +414,8 @@ Use idomenu (imenu with ido-mode) for best mileage.")
|
||||
(set (make-local-variable 'comment-multi-line) t)
|
||||
(set (make-local-variable 'comment-line-break-function) 'rust-comment-indent-new-line)
|
||||
(set (make-local-variable 'imenu-generic-expression) rust-imenu-generic-expression)
|
||||
(set (make-local-variable 'beginning-of-defun-function) 'rust-beginning-of-defun)
|
||||
(set (make-local-variable 'end-of-defun-function) 'rust-end-of-defun)
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user