From 1d4a75f84865356a3cf6dbc1b0b32ec43496446e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 2 Aug 2017 12:53:43 -0600 Subject: Make rust-beginning-of-defun ignore comments and strings Change rust-beginning-of-defun to keep searching when it stops in a comment or a string. Fixes #222. --- rust-mode-tests.el | 37 +++++++++++++++++++++++++++++++++++++ rust-mode.el | 18 ++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/rust-mode-tests.el b/rust-mode-tests.el index 7f1020f..de8a2cc 100644 --- a/rust-mode-tests.el +++ b/rust-mode-tests.el @@ -1025,6 +1025,43 @@ All positions are position symbols found in `rust-test-positions-alist'." 'beginning-of-fn3 #'beginning-of-defun)) +(ert-deftest rust-beginning-of-defun-string-comment () + (let (fn-1 fn-2 p-1 p-2) + (with-temp-buffer + (rust-mode) + (insert "fn test1() { + let s=r#\" +fn test2(); +\"#;") + (setq p-1 (point)) + (setq fn-1 (1+ p-1)) + (insert " +fn test3() { + /* +fn test4();") + (setq p-2 (point)) + (insert "\n*/\n}\n") + (setq fn-2 (point)) + (insert "fn test5() { }") + + (goto-char p-1) + (beginning-of-defun) + (should (eq (point) (point-min))) + + (beginning-of-defun -2) + (should (eq (point) fn-2)) + + (goto-char p-2) + (beginning-of-defun) + (should (eq (point) fn-1)) + + (beginning-of-defun -1) + (should (eq (point) fn-2)) + + (goto-char (point-max)) + (beginning-of-defun 2) + (should (eq (point) fn-1))))) + (ert-deftest rust-end-of-defun-from-middle-of-fn () (rust-test-motion rust-test-motion-string diff --git a/rust-mode.el b/rust-mode.el index 46231fd..33e6b28 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -1198,8 +1198,22 @@ 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 "\\)") - nil 'move (or arg 1))) + (let* ((arg (or arg 1)) + (magnitude (abs arg)) + (sign (if (< arg 0) -1 1))) + ;; If moving forward, don't find the defun we might currently be + ;; on. + (when (< sign 0) + (end-of-line)) + (catch 'done + (dotimes (_ magnitude) + ;; Search until we find a match that is not in a string or comment. + (while (if (re-search-backward (concat "^\\(" rust-top-item-beg-re "\\)") + nil 'move sign) + (rust-in-str-or-cmnt) + ;; Did not find it. + (throw 'done nil))))) + t)) (defun rust-end-of-defun () "Move forward to the next end of defun. -- cgit v1.2.3