emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/tree-sitter f847ecc40b 3/3: Don't indent empty lines in treesit-


From: Yuan Fu
Subject: feature/tree-sitter f847ecc40b 3/3: Don't indent empty lines in treesit-indent-region
Date: Sat, 5 Nov 2022 20:59:35 -0400 (EDT)

branch: feature/tree-sitter
commit f847ecc40bc768d97ba57083fd669ca0104e500f
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Don't indent empty lines in treesit-indent-region
    
    * lisp/treesit.el (treesit-indent-region): Wrap the old code in an if
    form that checks whether we are at an empty line.  Add comments.
---
 lisp/treesit.el | 43 ++++++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/lisp/treesit.el b/lisp/treesit.el
index 02bf026bc0..09e5d8084e 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -1184,6 +1184,8 @@ Return (ANCHOR . OFFSET).  This function is used by
         (when (> (- (point-max) delta) (point))
           (goto-char (- (point-max) delta)))))))
 
+;; Batch size can't be too large, because we put markers on each
+;; ANCHOR, so a batch size of 400 lines means 400 markers.
 (defvar treesit--indent-region-batch-size 400
   "How many lines of indent value do we precompute.
 In `treesit-indent-region' we indent in batches: precompute
@@ -1195,12 +1197,21 @@ reparse after indenting every single line.")
   "Indent the region between BEG and END.
 Similar to `treesit-indent', but indent a region instead."
   (treesit-update-ranges beg end)
+  ;; We indent `treesit--indent-region-batch-size' lines at a time, to
+  ;; reduce the number of times the parser needs to re-parse.  In each
+  ;; batch, we go through each line and calculate the anchor and
+  ;; offset as usual, but instead of modifying the buffer, we save
+  ;; these information in a vector.  Once we've collected ANCHOR and
+  ;; OFFSET for each line in the batch, we go through each line again
+  ;; and apply the changes.  Now that buffer is modified, we need to
+  ;; reparse the buffer before continuing to indent the next batch.
   (let* ((meta-len 2)
          (vector-len (* meta-len treesit--indent-region-batch-size))
          ;; This vector saves the indent meta for each line in the
-         ;; batch.  It is a vector of [ANCHOR OFFSET BOL DELTA], where
-         ;; BOL is the position of BOL of that line, and DELTA =
-         ;; DESIRED-INDENT - CURRENT-INDENT.
+         ;; batch.  It is a vector [ANCHOR OFFSET ANCHOR OFFSET...].
+         ;; ANCHOR is a marker on the anchor position, and OFFSET is
+         ;; an integer.  ANCHOR and OFFSET are either both nil, or
+         ;; both valid.
          (meta-vec (make-vector vector-len 0))
          (lines-left-to-move 0)
          (end (copy-marker end t))
@@ -1217,16 +1228,22 @@ Similar to `treesit-indent', but indent a region 
instead."
         (while (and (eq lines-left-to-move 0)
                     (< idx treesit--indent-region-batch-size)
                     (< (point) end))
-          (pcase-let* ((`(,anchor . ,offset) (treesit--indent-1))
-                       (marker (aref meta-vec (* idx meta-len))))
-            ;; Set ANCHOR.
-            (when anchor
-              (if (markerp marker)
-                  (move-marker marker anchor)
-                (setf (aref meta-vec (* idx meta-len))
-                      (copy-marker anchor t))))
-            ;; SET OFFSET.
-            (setf (aref meta-vec (+ 1 (* idx meta-len))) offset))
+          (if (looking-at (rx (* whitespace) eol) t)
+              ;; Unlike in `indent-line' where we sometimes pre-indent
+              ;; an empty line, We don't indent empty lines in
+              ;; `indent-region'.  Set ANCHOR and OFFSET to nil.
+              (setf (aref meta-vec (* idx meta-len)) nil
+                    (aref meta-vec (+ 1 (* idx meta-len))) nil)
+            (pcase-let* ((`(,anchor . ,offset) (treesit--indent-1))
+                         (marker (aref meta-vec (* idx meta-len))))
+              ;; Set ANCHOR.
+              (when anchor
+                (if (markerp marker)
+                    (move-marker marker anchor)
+                  (setf (aref meta-vec (* idx meta-len))
+                        (copy-marker anchor t))))
+              ;; SET OFFSET.
+              (setf (aref meta-vec (+ 1 (* idx meta-len))) offset)))
           (cl-incf idx)
           (setq lines-left-to-move (forward-line 1)))
         ;; Now IDX = last valid IDX + 1.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]