[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/rust-mode 664c7b0 277/486: improve position recovery in ru
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/rust-mode 664c7b0 277/486: improve position recovery in rust-format-buffer |
Date: |
Sat, 7 Aug 2021 09:25:35 -0400 (EDT) |
branch: elpa/rust-mode
commit 664c7b037c2fe2e2b2d1c0629835715194b844bb
Author: Trevor Spiteri <tspiteri@ieee.org>
Commit: Trevor Spiteri <tspiteri@ieee.org>
improve position recovery in rust-format-buffer
---
rust-mode.el | 145 ++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 103 insertions(+), 42 deletions(-)
diff --git a/rust-mode.el b/rust-mode.el
index 55148f6..cced21c 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -1281,6 +1281,88 @@ This is written mainly to be used as
`end-of-defun-function' for Rust."
(kill-buffer))
(error "Rustfmt failed, see *rustfmt* buffer for details"))))
+(defconst rust--format-word
"\\b\\(else\\|enum\\|fn\\|for\\|if\\|let\\|loop\\|match\\|struct\\|unsafe\\|while\\)\\b")
+(defconst rust--format-line "\\([\n]\\)")
+
+;; Counts number of matches of regex beginning up to max-beginning,
+;; leaving the point at the beginning of the last match.
+(defun rust--format-count (regex max-beginning)
+ (let ((count 0)
+ save-point
+ beginning)
+ (while (and (< (point) max-beginning)
+ (re-search-forward regex max-beginning t))
+ (setq count (1+ count))
+ (setq beginning (match-beginning 1)))
+ ;; try one more in case max-beginning lies in the middle of a match
+ (setq save-point (point))
+ (when (re-search-forward regex nil t)
+ (let ((try-beginning (match-beginning 1)))
+ (if (> try-beginning max-beginning)
+ (goto-char save-point)
+ (setq count (1+ count))
+ (setq beginning try-beginning))))
+ (when beginning (goto-char beginning))
+ count))
+
+;; Gets list describing pos or (point).
+;; The list contains:
+;; 1. the number of matches of rust--format-word,
+;; 2. the number of matches of rust--format-line after that,
+;; 3. the number of columns after that.
+(defun rust--format-get-loc (buffer &optional pos)
+ (with-current-buffer buffer
+ (save-excursion
+ (let ((pos (or pos (point)))
+ words lines columns)
+ (goto-char (point-min))
+ (setq words (rust--format-count rust--format-word pos))
+ (setq lines (rust--format-count rust--format-line pos))
+ (if (> lines 0)
+ (if (= (point) pos)
+ (setq columns -1)
+ (forward-char 1)
+ (goto-char pos)
+ (setq columns (current-column)))
+ (let ((initial-column (current-column)))
+ (goto-char pos)
+ (setq columns (- (current-column) initial-column))))
+ (list words lines columns)))))
+
+;; Moves the point forward by count matches of regex up to max-pos,
+;; and returns new max-pos making sure final position does not include another
match.
+(defun rust--format-forward (regex count max-pos)
+ (when (< (point) max-pos)
+ (let ((beginning (point)))
+ (while (> count 0)
+ (setq count (1- count))
+ (re-search-forward regex nil t)
+ (setq beginning (match-beginning 1)))
+ (when (re-search-forward regex nil t)
+ (setq max-pos (min max-pos (match-beginning 1))))
+ (goto-char beginning)))
+ max-pos)
+
+;; Gets the position from a location list obtained using rust--format-get-loc.
+(defun rust--format-get-pos (buffer loc)
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char (point-min))
+ (let ((max-pos (point-max))
+ (words (pop loc))
+ (lines (pop loc))
+ (columns (pop loc)))
+ (setq max-pos (rust--format-forward rust--format-word words max-pos))
+ (setq max-pos (rust--format-forward rust--format-line lines max-pos))
+ (when (> lines 0) (forward-char))
+ (let ((initial-column (current-column))
+ (save-point (point)))
+ (move-end-of-line nil)
+ (when (> (current-column) (+ initial-column columns))
+ (goto-char save-point)
+ (forward-char columns)))
+ (min (point) max-pos)))))
+
(defun rust-format-buffer ()
"Format the current buffer using rustfmt."
(interactive)
@@ -1289,58 +1371,37 @@ This is written mainly to be used as
`end-of-defun-function' for Rust."
(let* ((current (current-buffer))
(base (or (buffer-base-buffer current) current))
- buffer-pos
- window-pos)
+ buffer-loc
+ window-loc)
(dolist (buffer (buffer-list))
(when (or (eq buffer base)
(eq (buffer-base-buffer buffer) base))
- (with-current-buffer buffer
- (push (list buffer
- (line-number-at-pos)
- (current-column))
- buffer-pos))))
+ (push (list buffer
+ (rust--format-get-loc buffer nil))
+ buffer-loc)))
(dolist (window (window-list))
(let ((buffer (window-buffer window)))
(when (or (eq buffer base)
(eq (buffer-base-buffer buffer) base))
(let ((start (window-start window))
(point (window-point window)))
- (with-current-buffer buffer
- (push (list window
- (line-number-at-pos start)
- (save-excursion (goto-char start) (current-column))
- (line-number-at-pos point)
- (save-excursion (goto-char point) (current-column)))
- window-pos))))))
- (rust--format-call current)
- (dolist (pos buffer-pos)
- (let ((buffer (pop pos))
- (line (pop pos))
- (column (pop pos)))
+ (push (list window
+ (rust--format-get-loc buffer start)
+ (rust--format-get-loc buffer point))
+ window-loc)))))
+ (rust--format-call (current-buffer))
+ (dolist (loc buffer-loc)
+ (let* ((buffer (pop loc))
+ (pos (rust--format-get-pos buffer (pop loc))))
(with-current-buffer buffer
- ;; 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- line))
- (forward-char column))))
- (dolist (pos window-pos)
- (let ((window (pop pos))
- (start-line (pop pos))
- (start-column (pop pos))
- (point-line (pop pos))
- (point-column (pop pos)))
- (with-current-buffer (window-buffer window)
- (let ((start (save-excursion (goto-char (point-min))
- (forward-line (1- start-line))
- (forward-char start-column)
- (point)))
- (point (save-excursion (goto-char (point-min))
- (forward-line (1- point-line))
- (forward-char point-column)
- (point))))
- (set-window-start window start)
- (set-window-point window point))))))
+ (goto-char pos))))
+ (dolist (loc window-loc)
+ (let* ((window (pop loc))
+ (buffer (window-buffer window))
+ (start (rust--format-get-pos buffer (pop loc)))
+ (pos (rust--format-get-pos buffer (pop loc))))
+ (set-window-start window start)
+ (set-window-point window pos))))
;; Issue #127: Running this on a buffer acts like a revert, and could cause
;; the fontification to get out of sync. Call the same hook to ensure it is
- [nongnu] elpa/rust-mode 339afba 206/486: Highlight the unsafe keyword, (continued)
- [nongnu] elpa/rust-mode 339afba 206/486: Highlight the unsafe keyword, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode fa5b38f 218/486: Merge pull request #117 from TheBB/fix-closing-delim, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 1ceac8b 212/486: Re-fontify buffer after it is reverted, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 01db4cb 225/486: Fix font-locking for Unicode escapes in character literals., ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode b874bbe 213/486: Merge pull request #113 from MicahChalmer/fix-issue-104, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 2cd3cf9 216/486: Merge pull request #116 from Wilfred/type_annotation_highlighting, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 3517321 230/486: Merge pull request #129 from MicahChalmer/fix-issue-127, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 8400638 241/486: update README.md and Package-Requires to require emacs 24, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode c3feac1 243/486: Fill regular block comments correctly too, in addition to rustdoc comments, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 1587839 268/486: Merge pull request #169 from mrBliss/fix-168, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 664c7b0 277/486: improve position recovery in rust-format-buffer,
ELPA Syncer <=
- [nongnu] elpa/rust-mode 46e7fc0 285/486: fix PR link in README, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 35298ed 288/486: Don't use "&optional &rest", ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 3301c70 047/486: Align field names in struct expressions with fields on same line as the opening curly brace, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode fe55b71 046/486: Multiline comments with leading *s line up the *s, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode af2aba9 049/486: Indent correctly after opening square bracket, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode b83aabf 054/486: Add ERT tests, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 38dab12 063/486: Fix rust-align-to-expr-after-brace, closes #11239., ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 7625c5c 058/486: Add 'continue' keyword to emacs, vim, gedit, kate, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode d82b5a7 062/486: Add "proc" as keyword to emacs mode, ELPA Syncer, 2021/08/07
- [nongnu] elpa/rust-mode 891716a 059/486: Fix single-line-style paragraph fills with code immediately before or after, ELPA Syncer, 2021/08/07