branch: externals/matlab-mode
commit b9dd03db5d9d74ebf3f4f149eb9929109d9a75ed
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>

    matlab-ts-mode--ei: phase 1 of concat elimination for speedup
---
 matlab-ts-mode--ei.el | 227 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 136 insertions(+), 91 deletions(-)

diff --git a/matlab-ts-mode--ei.el b/matlab-ts-mode--ei.el
index c25d6c80e0..4ce57461d7 100644
--- a/matlab-ts-mode--ei.el
+++ b/matlab-ts-mode--ei.el
@@ -386,54 +386,85 @@ is used in `matlab-ts-mode--ei-spacing'"
              new-line-no-spaces-or-commas orig-line-no-spaces-or-commas
              (line-number-at-pos (point)) (buffer-name)))))
 
-(defun matlab-ts-mode--ei-concat-line (ei-line node extra-chars &optional 
n-spaces-to-append)
-  "Return concat EI-LINE with NODE text.
-NODE-END is the NODE end accounting for ignored nodes (semicolons).
+(defvar-local matlab--eilb nil) ;; Buffer used to create new electric indent 
line, ei-line
+
+(defmacro matlab--eilb-length ()
+  "Current ei-line length."
+  '(with-current-buffer matlab--eilb (1- (point))))
+
+(defmacro matlab--eilb-content ()
+  "Current ei-line ."
+  '(with-current-buffer matlab--eilb (buffer-string)))
+
+(defun matlab--eilb-setup ()
+  "Initialize `matlab-ts-mode--eilb' buffer used to electric indent."
+  (if matlab--eilb
+      (with-current-buffer matlab--eilb
+        (erase-buffer))
+    ;; Else create it
+    (setq-local matlab--eilb
+                (get-buffer-create (let ((bn (buffer-name)))
+                                     (concat (when (not (string-match (rx bos 
" *") bn)) " *")
+                                             bn "-matlab-ts-mode--ei-line*"))))
+    (with-current-buffer matlab--eilb
+      (buffer-disable-undo))))
+
+(defun matlab--eilb-kill-buffer ()
+  "Kill the `matlab--eilb' buffer."
+  (when matlab--eilb
+    (kill-buffer matlab--eilb)
+    (setq-local matlab--eilb nil)))
+
+(defun matlab--eilb-add-node-text (node extra-chars &optional 
n-spaces-to-append)
+  "Update `matlab--eilb' with NODE text and more.
 EXTRA-CHARS string is appended to EL-LINE after NODE text.
 EXTRA-CHARS, when \\='(string), the string is appended to last
-non-whitspace in EL-LINE, then NODE text is appended.
+non-whitespace in EL-LINE, then NODE text is appended.
 N-SPACES-TO-APPEND is the number of spaces to append between nodes."
 
   (let* ((node-end (treesit-node-end node))
          (eol-pt (pos-eol))
          (last-pt (if (< node-end eol-pt) node-end eol-pt))
-         extra-chars-before-node)
-    (when (listp extra-chars)
-      ;; Consier: foo1 = {'one', 'two' ...
-      ;;                  ...
-      ;;              'three' 'four' 'five'};
-      ;; After the 'two' node, we have two line_continuation's, then the 
invisible comma (",")
-      ;; This is detected and extra-chars will be '(",")
-      ;; TopTester: electric_indent_cell_no_comma_before_ellipsis.m
-      (if (string-match "\\`\\(.*[^ ]\\)\\([ ]+\\)\\'" ei-line)
-          (let ((first-part (match-string 1 ei-line))
-                (trailing-spaces (match-string 2 ei-line)))
-            (setq ei-line first-part
-                  extra-chars-before-node (concat (car extra-chars) 
trailing-spaces)))
-        (setq  extra-chars-before-node (car extra-chars)))
-      (setq extra-chars nil))
-
-    (concat ei-line
-            extra-chars-before-node
-            (buffer-substring (treesit-node-start node) last-pt)
-            extra-chars
-            (if (not n-spaces-to-append) ;; last node?
-                ;; Add trailing whitespace when in an ERROR node. Consider
-                ;;    switch a
-                ;;      case                    ;; One trailing whitespace
-                ;;    end
-                ;; TopTester: electric_indent_xr_switch.m
-                (when (and (treesit-parent-until node (rx bos "ERROR" eos))
-                           (< last-pt eol-pt))
-                  (save-excursion
-                    (let ((inhibit-field-text-motion t)) (end-of-line))
-                    (when (re-search-backward "[^ \t]" (pos-bol) t)
-                      (forward-char)
-                      (when (not (= (point) (pos-eol)))
-                        (buffer-substring (point) (pos-eol))
-                        ))))
-              (when (> n-spaces-to-append 0)
-                (make-string n-spaces-to-append ? ))))))
+         (node-text (buffer-substring (treesit-node-start node) last-pt)))
+
+    (with-current-buffer matlab--eilb
+
+      (when (listp extra-chars)
+        ;; Consider: foo1 = {'one', 'two' ...
+        ;;                  ...
+        ;;              'three' 'four' 'five'};
+        ;; After the 'two' node, we have two line_continuation's, then the 
invisible comma (",")
+        ;; This is detected and extra-chars will be '(",")
+        ;; TopTester: electric_indent_cell_no_comma_before_ellipsis.m
+        (goto-char (point-min))
+        (if (re-search-forward (rx (1+ " ") eol))
+            (progn
+              (replace-match (concat (car extra-chars) "\\&") t)
+              (goto-char (point-max)))
+          (goto-char (point-max))
+          (insert (car extra-chars)))
+
+        (setq extra-chars ""))
+
+      (insert node-text extra-chars)
+
+      (if (not n-spaces-to-append) ;; last node?
+          ;; Add trailing whitespace when in an ERROR node. Consider
+          ;;    switch a
+          ;;      case                    ;; One trailing whitespace
+          ;;    end
+          ;; TopTester: electric_indent_xr_switch.m
+          (when (and (treesit-parent-until node (rx bos "ERROR" eos))
+                     (< last-pt eol-pt))
+            (save-excursion
+              (let ((inhibit-field-text-motion t)) (end-of-line))
+              (when (re-search-backward "[^ \t]" (pos-bol) t)
+                (forward-char)
+                (when (not (= (point) (pos-eol)))
+                  (buffer-substring (point) (pos-eol))))))
+        ;; Else insert the spaces
+        (when (> n-spaces-to-append 0)
+          (insert (make-string n-spaces-to-append ? )))))))
 
 (defvar matlab-ts-mode--ei-error-query (treesit-query-compile 'matlab 
'((ERROR) @e)))
 (defvar-local matlab-ts-mode--ei-errors-alist nil)
@@ -482,7 +513,7 @@ Assumes that current point is at `back-to-indentation'."
       ;; Make invisible comma visible by returning it.
       ",")
 
-     ;; Case: invisble at end of array row
+     ;; Case: invisible at end of array row
      ;;           foo = {'one', 'two' ...
      ;;                              ^   missing comma, return a comma to have 
it inserted
      ((string= node-type "line_continuation")
@@ -529,15 +560,16 @@ Assumes that current point is at `back-to-indentation'."
       line-node-types
     (concat line-node-types (when line-node-types " ") node-type)))
 
-(defun matlab-ts-mode--ei-get-indent-level-spaces ()
-  "Get indent-level spaces for current line expanding tabs."
+(defun matlab-ts-mode--ei-insert-indent-level-spaces ()
+  "Insert indent-level spaces for current line expanding tabs."
   (let ((spaces (buffer-substring (pos-bol) (point))))
     (when (string-match "\t" spaces)
       (setq spaces (with-temp-buffer
                      (insert spaces)
                      (untabify (point-min) (point-max))
                      (buffer-string))))
-    spaces))
+    (with-current-buffer matlab--eilb
+      (insert spaces))))
 
 (cl-defun matlab-ts-mode--ei-get-new-line (&optional start-node start-offset)
   "Get new line content with element spacing adjusted.
@@ -559,9 +591,10 @@ final amount of leading whitespace because we do electric 
indent before
                 (matlab-ts-mode--ei-no-elements-to-indent))
         (cl-return-from matlab-ts-mode--ei-get-new-line)))
 
-    ;; Compute ei-line, the electric indented line content
+    ;; Compute new electric indented line content in matlab--eilb
+    (matlab--eilb-setup)
+
     (let* (pt-offset ;; used in restoring point
-           (ei-line (matlab-ts-mode--ei-get-indent-level-spaces))
            (pair (matlab-ts-mode--ei-move-to-and-get-node))
            (node (or (car pair)
                      (cl-return-from matlab-ts-mode--ei-get-new-line)))
@@ -572,6 +605,8 @@ final amount of leading whitespace because we do electric 
indent before
            next2-n-spaces-between
            (eol-pt (pos-eol)))
 
+      (matlab-ts-mode--ei-insert-indent-level-spaces)
+
       (cl-loop
        while (and (< (point) eol-pt)
                   (< (treesit-node-end node) eol-pt))
@@ -638,19 +673,19 @@ final amount of leading whitespace because we do electric 
indent before
          (let* ((node-end (treesit-node-end node))
                 (next-node-start (treesit-node-start next-node))
                 (extra-chars (matlab-ts-mode--ei-node-extra-chars node 
node-end next-node-start)))
-           ;; Update ei-line
+
            (when (equal start-node node)
-             (setq pt-offset (+ (length ei-line) start-offset)))
+             (setq pt-offset (+ (matlab--eilb-length) start-offset)))
 
-           (setq ei-line (matlab-ts-mode--ei-concat-line ei-line node 
extra-chars n-spaces-between))
+           (matlab--eilb-add-node-text node extra-chars n-spaces-between))
 
            (setq node next-node
                  node-type next-node-type)
-           )))
+           ))
 
-      (when node
+      (when node ;; last node in line
         (when (equal start-node node)
-          (setq pt-offset (+ (length ei-line) start-offset)))
+          (setq pt-offset (+ (matlab--eilb-length) start-offset)))
         (when matlab-ts-mode--indent-assert
           (setq orig-line-node-types
                 (matlab-ts-mode--ei-update-line-node-types 
orig-line-node-types node node-type)))
@@ -658,9 +693,9 @@ final amount of leading whitespace because we do electric 
indent before
                             node
                             (min (treesit-node-end node) eol-pt)
                             eol-pt)))
-          (setq ei-line (matlab-ts-mode--ei-concat-line ei-line node 
extra-chars))))
+          (matlab--eilb-add-node-text node extra-chars)))
 
-      (list ei-line pt-offset orig-line-node-types first-node))))
+      (list (matlab--eilb-content) pt-offset orig-line-node-types 
first-node))))
 
 (defvar-local matrix-ts-mode--ei-m-matrix-first-col-extra-alist nil)
 
@@ -906,6 +941,7 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO contents."
                             (setq pt-offset (+ pt-offset n-spaces)))
                           (if (string= (treesit-node-type element) "string") 
;; left align strings
                               (let ((e-len (length (treesit-node-text 
element))))
+                                ;; xxx use temp buffer
                                 (setq content (concat (substring content 0 (+ 
offset e-len))
                                                       (make-string n-spaces ? )
                                                       (substring content (+ 
offset e-len)))))
@@ -1146,6 +1182,7 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO."
 
     (let ((n-spaces-to-add (- new-comma-offset comma-offset)))
       (when (not (= n-spaces-to-add 0))
+        ;; xxx use temp buffer
         (setq ei-line (concat (substring ei-line 0 comma-offset)
                               (make-string n-spaces-to-add ? )
                               (substring ei-line comma-offset)))
@@ -1301,6 +1338,7 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO 
contents."
                                       (if (<= loc pt-offset)
                                           (+ pt-offset diff)
                                         pt-offset)))))
+              ;; xxx use temp buffer
               (setq ei-line (concat (substring ei-line 0 loc)
                                     (make-string diff ? )
                                     (substring ei-line loc)))
@@ -1666,43 +1704,49 @@ to it's logical location when the line is updated."
          (start-offset (cdr start-pair))
          (at-eol (and start-offset (looking-at "[ \t]*$")))
          (orig-line (buffer-substring (pos-bol) (pos-eol)))
-         (ei-info (matlab-ts-mode--ei-get-new-line start-node start-offset)))
+         (ei-info (matlab-ts-mode--ei-get-new-line start-node start-offset))
+         result)
+
     (if ei-info
-        (progn
-          (when matlab-ts-mode--ei-align-enabled
-            (setq ei-info (matlab-ts-mode--ei-align ei-info)))
-          (let* ((ei-line (or (nth 0 ei-info) orig-line))
-                 (pt-offset (nth 1 ei-info)) ;; non-nil if start-offset is 
non-nil
-                 (orig-line-node-types (nth 2 ei-info))
-                 (updated (and ei-info
-                               (not (string= orig-line ei-line)))))
-
-            (when (and updated
-                       pt-offset
-                       at-eol)
-              (setq pt-offset (length ei-line)))
-
-            (when (and updated
-                       matlab-ts-mode--indent-assert)
-              (when matlab-ts-mode--ei-orig-line-node-types-alist
-                (push `(,(line-number-at-pos) . ,orig-line-node-types)
-                      matlab-ts-mode--ei-orig-line-node-types-alist))
-              (matlab-ts-mode--ei-assert-line-match ei-line orig-line))
-
-            (if is-indent-region
-                (list ei-line updated pt-offset) ;; result
-              ;; Else updated the line if needed (TAB on a line to electric 
indents it).
-              (when updated
-                (delete-region (pos-bol) (pos-eol))
-                (insert ei-line)
-                (when pt-offset
-                  (goto-char (+ (pos-bol) pt-offset))))
-              nil ;; return nil for TAB indent
-              )))
+        (setq result
+              (progn
+                (when matlab-ts-mode--ei-align-enabled
+                  (setq ei-info (matlab-ts-mode--ei-align ei-info)))
+                (let* ((ei-line (or (nth 0 ei-info) orig-line))
+                       (pt-offset (nth 1 ei-info)) ;; non-nil if start-offset 
is non-nil
+                       (orig-line-node-types (nth 2 ei-info))
+                       (updated (and ei-info
+                                     (not (string= orig-line ei-line)))))
+
+                  (when (and updated
+                             pt-offset
+                             at-eol)
+                    (setq pt-offset (length ei-line)))
+
+                  (when (and updated
+                             matlab-ts-mode--indent-assert)
+                    (when matlab-ts-mode--ei-orig-line-node-types-alist
+                      (push `(,(line-number-at-pos) . ,orig-line-node-types)
+                            matlab-ts-mode--ei-orig-line-node-types-alist))
+                    (matlab-ts-mode--ei-assert-line-match ei-line orig-line))
+
+                  (if is-indent-region
+                      (list ei-line updated pt-offset) ;; result
+                    ;; Else updated the line if needed (TAB on a line to 
electric indents it).
+                    (when updated
+                      (delete-region (pos-bol) (pos-eol))
+                      (insert ei-line)
+                      (when pt-offset
+                        (goto-char (+ (pos-bol) pt-offset))))
+                    nil ;; return nil for TAB indent
+                    ))))
       ;; else nothing updated
       (when is-indent-region
-        (list orig-line 0 nil))
-      )))
+        (setq result (list orig-line 0 nil))))
+
+    (when (not is-indent-region)
+      (matlab--eilb-kill-buffer))
+    result))
 
 (defun matlab-ts-mode--ei-move-to-loc (start-pt-linenum start-pt-offset)
   "Move to location START-PT-LINENUM at column START-PT-OFFSET."
@@ -1818,6 +1862,7 @@ This expansion of the region is done to simplify electric 
indent."
           (matlab-ts-mode--ei-move-to-loc start-pt-linenum start-pt-offset)
           (treesit-indent-region beg end))
 
+      (matlab--eilb-kill-buffer)
       (matlab-ts-mode--ei-set-alist-caches nil)
       (kill-buffer new-content-buf))))
 
@@ -1825,5 +1870,5 @@ This expansion of the region is done to simplify electric 
indent."
 ;;; matlab-ts-mode--ei.el ends here
 
 ;; LocalWords:  SPDX gmail treesit defcustom bos eos isstring defun eol eobp 
setq curr cdr xr progn
-;; LocalWords:  listp alist dolist setf tmp buf utils linenum nums bobp pcase 
untabify SPC
-;; LocalWords:  linenums reindent bol fubar repeat:ans
+;; LocalWords:  listp alist dolist setf tmp buf utils linenum nums bobp pcase 
untabify SPC eilb
+;; LocalWords:  linenums reindent bol fubar repeat:ans defmacro bn

Reply via email to