From e452995b8ccd388f4be13a11443cffe3cdcd0619 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Tue, 2 Aug 2016 22:29:40 -0400 Subject: rust--after-revert-hook should preserve point position. Otherwise, rust-format-buffer always moves point to the end of the buffer. --- rust-mode-tests.el | 12 ++++++++++++ rust-mode.el | 7 ++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rust-mode-tests.el b/rust-mode-tests.el index 1e60768..3c3ba03 100644 --- a/rust-mode-tests.el +++ b/rust-mode-tests.el @@ -2561,6 +2561,18 @@ Fontification needs to include this whole string or none of it. ) ) +(ert-deftest rust-test-revert-hook-preserves-point () + (with-temp-buffer + ;; Insert some code, and put point in the middle. + (insert "fn foo() {}\n") + (insert "fn bar() {}\n") + (insert "fn baz() {}\n") + (goto-char (point-min)) + (forward-line 1) + (let ((initial-point (point))) + (rust--after-revert-hook) + (should (equal initial-point (point)))))) + ;; If electric-pair-mode is available, load it and run the tests that use it. If not, ;; no error--the tests will be skipped. (require 'elec-pair nil t) diff --git a/rust-mode.el b/rust-mode.el index 6259b48..1fbc3e8 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -1365,9 +1365,10 @@ This is written mainly to be used as `end-of-defun-function' for Rust." ;; to use `font-lock-ensure', which doesn't exist in Emacs 24 and earlier. ;; If it's not available, fall back to calling `font-lock-fontify-region' ;; on the whole buffer. - (if (fboundp 'font-lock-ensure) - (font-lock-ensure) - (font-lock-fontify-region (point-min) (point-max)))) + (save-excursion + (if (fboundp 'font-lock-ensure) + (font-lock-ensure) + (font-lock-fontify-region (point-min) (point-max))))) (defun rust--before-save-hook () (when rust-format-on-save (rust-format-buffer))) -- cgit v1.2.3 From 2540d7eff0faa7e966b6c4391e53617800275f85 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Tue, 2 Aug 2016 23:00:25 -0400 Subject: Go back to the current line and column after formatting. The previous approach simply moved to the same character offset. This is unlikely to preserve the position of point, as rustfmt often changes whitespace, changing the number of characters before point. Instead, we go back to the line number and column number we were on before. Provided that rustfmt has not radically changed the number of lines, this will typically put point back to its previous position, or at least close. Improves, but doesn't completely solve, issue #162. --- rust-mode.el | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rust-mode.el b/rust-mode.el index 1fbc3e8..99e4bb4 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -1270,10 +1270,16 @@ This is written mainly to be used as `end-of-defun-function' for Rust." (unless (executable-find rust-rustfmt-bin) (error "Could not locate executable \"%s\"" rust-rustfmt-bin)) - (let ((cur-point (point)) + (let ((cur-line (line-number-at-pos)) + (cur-column (current-column)) (cur-win-start (window-start))) (rust--format-call (current-buffer)) - (goto-char cur-point) + ;; Move to the same line and column as before. This is best + ;; effort: if rustfmt inserted lines before point, we end up in + ;; the wrong place. See issue #162. + (goto-char (point-min)) + (forward-line (1- cur-line)) + (forward-char cur-column) (set-window-start (selected-window) cur-win-start)) ;; Issue #127: Running this on a buffer acts like a revert, and could cause -- cgit v1.2.3