branch: externals/matlab-mode
commit 64321f7b71b6e2eb564326de8f23bb4936a79092
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>
matlab-ts-mode: optimize electric indent-region to do one insertion instead
of many
This reduces the number times we ask tree-sitter to re-parse the buffer
from one per line in the
region to one re-parse for the region.
---
matlab-ts-mode--ei.el | 179 +++++++++++++++------
matlab-ts-mode.el | 63 ++++----
...ill_paragraph_strings_and_ellipsis_expected.org | 30 ++--
3 files changed, 178 insertions(+), 94 deletions(-)
diff --git a/matlab-ts-mode--ei.el b/matlab-ts-mode--ei.el
index 049e807a51..a667be69c5 100644
--- a/matlab-ts-mode--ei.el
+++ b/matlab-ts-mode--ei.el
@@ -1195,86 +1195,159 @@ TAB> x = 123 ./1 + 567
(<= (point) line-pt))
(setq line-pt (1+ line-pt)))
(insert " ")
- (setq end (1+ end))))
- (forward-char 2)))
+ (setq end (1+ end)))))
+ (forward-char 2))
(when line-pt
(goto-char line-pt)))
-(cl-defun matlab-ts-mode--ei-indent-elements-in-line (&optional
is-indent-region)
+(cl-defun matlab-ts-mode--ei-indent-elements-in-line (&optional
is-indent-region start-pt-offset)
"Indent current line by adjusting spacing around elements.
-When IS-INDENT-REGION is nil, we restore the point to it's logical
-location when the line is updated. Returns t if line was updated."
+
+When IS-INDENT-REGION is t, we return (list NEW-LINE UPDATED
+NEW-START-PT-OFFSET). Optional START-PT-OFFSET is used only when
+IS-INDENT-REGION is t and when START-PT-OFFSET is non-nil NEW-START-PT-OFFSET
+is non-nil. This is used to update the point location for
+`matlab-ts-mode-prog-fill-reindent-defun'.
+
+When IS-INDENT-REGION is nil, we update the line and restore the point
+to it's logical location when the line is updated."
;; If line was indented (nth 0 ei-info) is not same as current line, then
update the buffer
- (let* ((start-pair (when (not is-indent-region)
+ (let* ((start-pair (when (or (not is-indent-region)
+ start-pt-offset)
(matlab-ts-mode--ei-get-start-info)))
- (start-node (car start-pair))
+ (start-node (car start-pair)) ;; may be nil
(start-offset (cdr start-pair))
- (orig-line (when matlab-ts-mode--electric-indent-assert
- (buffer-substring (line-beginning-position)
(line-end-position))))
+ (at-eol (and start-offset (looking-at "[ \t]*$")))
+ (orig-line (buffer-substring (line-beginning-position)
(line-end-position)))
(ei-info (matlab-ts-mode--ei-get-new-line start-node start-offset)))
- (when ei-info
- (when matlab-ts-mode--ei-align-enabled
- (setq ei-info (matlab-ts-mode--ei-align ei-info)))
- (let* ((ei-line (nth 0 ei-info))
- (pt-offset (nth 1 ei-info))
- (line-node-types (nth 2 ei-info))
- (curr-line (buffer-substring (line-beginning-position)
(line-end-position)))
- (updated (not (string= curr-line ei-line))))
-
- (when updated
- (delete-region (line-beginning-position) (line-end-position))
- (insert ei-line)
- (when matlab-ts-mode--electric-indent-assert
- (matlab-ts-mode--ei-assert-match orig-line line-node-types))
- (when pt-offset
- (goto-char (+ (line-beginning-position) pt-offset))))
- ;; result
- updated))))
+ (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
+ (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--electric-indent-assert)
+ (matlab-ts-mode--ei-assert-match orig-line line-node-types))
+
+ (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 (line-beginning-position) (line-end-position))
+ (insert ei-line)
+ (when pt-offset
+ (goto-char (+ (line-beginning-position) pt-offset))))
+ nil ;; return nil for TAB indent
+ )))
+ ;; else nothing updated
+ (when is-indent-region
+ (list orig-line 0 nil))
+ )))
(defun matlab-ts-mode--ei-indent-region (beg end)
- "Indent BEG END region by adjusting spacing around elements."
- (let* ((start-linenum (line-number-at-pos beg))
- (curr-linenum start-linenum)
+ "Indent BEG END region by adjusting spacing around elements.
+If BEG is not at start of line, it is moved to start of the line.
+If END is not at end of line, it is moved to end of the line.
+This expansion of the region is done to simplify electric indent."
+
+ (let* ((curr-linenum (line-number-at-pos beg))
(end-linenum (save-excursion
(goto-char end)
+ (end-of-line)
(let ((linenum (line-number-at-pos)))
(when (= (point) (line-beginning-position))
(setq linenum (1- linenum)))
- linenum))))
+ linenum)))
+ (start-pt (point))
+ (start-pt-linenum (line-number-at-pos start-pt))
+ (start-pt-offset (- start-pt (save-excursion
+ (goto-char start-pt)
+ ;; offset from beginning of
start-pt-linenum
+ (pos-bol)))))
- (matlab-ts-mode--ei-workaround-143 beg end)
+ (matlab-ts-mode--ei-workaround-143 beg end) ;; may insert spaces on lines
in BEG END region
- (unwind-protect
- (progn
- ;; Add an invalid entry to each of the following associative lists.
This entry is used as
- ;; a marker to activate caching. Each entry in the lists is a cons
cell `(LINENUM . INFO)
- ;; where -1 is not a valid line number.
- (setq-local matlab-ts-mode--ei-align-assign-alist '((-1 . 0))
- matlab-ts-mode--ei-align-prop-alist '((-1 . 0))
- matlab-ts-mode--ei-align-comment-alist '((-1 . 0))
- matlab-ts-mode--ei-align-matrix-alist '((-1 . "")))
+ (save-excursion
+
+ ;; Move END to end of line. Use end-linenum to because workaround-143
could have moved END.
+ (goto-char (point-min))
+ (when (> end-linenum 1)
+ (forward-line (1- end-linenum)))
+ (end-of-line)
+ (setq end (point))
+
+ ;; Move BEG to beginning of line and leave point there.
+ (goto-char beg)
+ (beginning-of-line)
+ (setq beg (point))
+
+ (unwind-protect
+ (progn
+ ;; Add an invalid entry to each of the following associative
lists. This entry is used
+ ;; as a marker to activate caching. Each entry in the lists is a
cons cell `(LINENUM
+ ;; . INFO) where -1 is not a valid line number.
+ (setq-local matlab-ts-mode--ei-align-assign-alist '((-1 . 0))
+ matlab-ts-mode--ei-align-prop-alist '((-1 . 0))
+ matlab-ts-mode--ei-align-comment-alist '((-1 . 0))
+ matlab-ts-mode--ei-align-matrix-alist '((-1 . "")))
+
+ (let (new-content
+ updated)
- (save-excursion
- (goto-char beg)
(while (<= curr-linenum end-linenum)
(beginning-of-line)
- (matlab-ts-mode--ei-indent-elements-in-line 'indent-region)
+
+ (let* ((tuple (matlab-ts-mode--ei-indent-elements-in-line
+ 'indent-region
+ (when (= curr-linenum start-pt-linenum)
start-pt-offset)))
+ (new-line (nth 0 tuple))
+ (line-updated (nth 1 tuple))
+ (new-start-pt-offset (nth 2 tuple)))
+
+ (when new-start-pt-offset
+ (setq start-pt-offset new-start-pt-offset))
+
+ (setq new-content (concat new-content new-line
+ (when (< curr-linenum end-linenum)
"\n")))
+ (when line-updated
+ (setq updated t)))
+
(forward-line)
(setq curr-linenum (1+ curr-linenum)))
- ;; Restore point accounting for whitespace adjustments in the
lines
- (goto-char (point-min))
- (forward-line (1- start-linenum))
- (setq beg (point))
- (goto-char (point-min))
- (forward-line end-linenum)
- (setq end (point))))
+
+ (when updated
+ (save-excursion
+ (goto-char beg)
+ (delete-region beg end)
+ (insert new-content))
+
+ ;; Restore end point accounting for whitespace adjustments in
the lines
+ (goto-char (point-min))
+ (forward-line end-linenum)
+ (setq end (point)))))
(setq-local matlab-ts-mode--ei-align-assign-alist nil
matlab-ts-mode--ei-align-prop-alist nil
matlab-ts-mode--ei-align-comment-alist nil
matlab-ts-mode--ei-align-matrix-alist nil)))
- ;; Return updated BEG and END region points
- (cons beg end))
+
+ ;; Update point to keep it on the starting semantic element
+ (goto-char (point-min))
+ (forward-line (1- start-pt-linenum))
+ (forward-char start-pt-offset)
+
+ ;; Return updated BEG and END region points
+ (cons beg end)))
(provide 'matlab-ts-mode--ei)
;;; matlab-ts-mode--ei.el ends here
diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el
index 1930afe338..770dcf15f8 100644
--- a/matlab-ts-mode.el
+++ b/matlab-ts-mode.el
@@ -2880,11 +2880,8 @@ Example:
"Call `treesit-indent', then do electric indent."
(treesit-indent) ;; treesit-indent before electric indent to get updated
point on the line
(when matlab-ts-mode-electric-indent
- (let ((at-eol (looking-at "[ \t]*$")))
(matlab-ts-mode--ei-workaround-143 (line-beginning-position)
(line-end-position) (point))
- (when (and (matlab-ts-mode--ei-indent-elements-in-line)
- at-eol)
- (end-of-line)))))
+ (matlab-ts-mode--ei-indent-elements-in-line)))
(defun matlab-ts-mode--treesit-indent-region (beg end)
"Call `treesit-indent-region' on BEG END, then do electric indent."
@@ -4198,31 +4195,39 @@ This exists because ellipsis line continuations cause
`prog-fill-reindent-defun' to not behave well. Thus, we handle
these locally."
(interactive "P")
- (save-excursion
- (let ((treesit-text-node
- (and (treesit-available-p)
- (treesit-parser-list)
- (let ((node (treesit-node-at (point))))
- (and (treesit-node-match-p node 'text t)
- (not (equal (treesit-node-type node)
"line_continuation")))))))
- (if (or treesit-text-node
- ;; We can't fill strings because doing so introduces syntax
errors
- (let ((sp (syntax-ppss)))
- (and (nth 8 sp) ;; string or comment
- (not (nth 3 sp)))) ;; not string
- (let ((comment-start-pt
- (save-excursion
- (when (and (re-search-forward "\\s-*\\s<"
(line-end-position) t)
- (not (equal (treesit-node-type
(treesit-node-at (point)))
- "line_continuation")))
- (point)))))
- (when comment-start-pt
- (goto-char comment-start-pt))))
- (fill-paragraph justify (region-active-p))
- (beginning-of-defun)
- (let ((start (point)))
- (end-of-defun)
- (indent-region start (point) nil))))))
+
+ (let ((treesit-text-node
+ (and (treesit-available-p)
+ (treesit-parser-list)
+ (let ((node (treesit-node-at (point))))
+ (and (treesit-node-match-p node 'text t)
+ (not (equal (treesit-node-type node)
"line_continuation")))))))
+ (if (or treesit-text-node
+ ;; We can't fill strings because doing so introduces syntax errors
+ (let ((sp (syntax-ppss)))
+ (and (nth 8 sp) ;; string or comment
+ (not (nth 3 sp)))) ;; not string
+ (let ((comment-start-pt
+ (save-excursion
+ (when (and (re-search-forward "\\s-*\\s<"
(line-end-position) t)
+ (not (equal (treesit-node-type
(treesit-node-at (point)))
+ "line_continuation")))
+ (point)))))
+ (when comment-start-pt
+ (goto-char comment-start-pt))))
+ (save-excursion
+ (fill-paragraph justify (region-active-p)))
+
+ ;; else "prog fill reindent"
+ (let ((beg (save-excursion
+ (beginning-of-defun)
+ (point)))
+ (end (save-excursion
+ (end-of-defun)
+ (point))))
+ (indent-region beg end nil)
+ (when (looking-at "[ \t]")
+ (back-to-indentation))))))
;;; Keymap
diff --git
a/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_strings_and_ellipsis_expected.org
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_strings_and_ellipsis_expected.org
index c650f5ee56..7dee61c591 100644
---
a/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_strings_and_ellipsis_expected.org
+++
b/tests/test-matlab-ts-mode-fill-paragraph-files/fill_paragraph_strings_and_ellipsis_expected.org
@@ -20,7 +20,9 @@
- Invoking : "M-q" = matlab-ts-mode-prog-fill-reindent-defun
Start point : 309
- No point movement
+ Moved to point: 313
+ : 9:4: a = c + ...
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
@@ -60,7 +62,9 @@
- Invoking : "M-q" = matlab-ts-mode-prog-fill-reindent-defun
Start point : 378
- No point movement
+ Moved to point: 394
+ : 13:16: a = a + 3; % foo bar goo
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
@@ -89,9 +93,9 @@
- Invoking : "M-q" = matlab-ts-mode-prog-fill-reindent-defun
Start point : 586
- Moved to point: 579
- : 25:22: b = "a long string a long string a long string a long string a
long string a long string a long string a long string a long string a long
string a long string a long string a long string a long string ";
- : ^
+ Moved to point: 561
+ : 25:4: b = "a long string a long string a long string a long string a
long string a long string a long string a long string a long string a long
string a long string a long string a long string a long string ";
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
@@ -127,7 +131,9 @@
- Invoking : "M-q" = matlab-ts-mode-prog-fill-reindent-defun
Start point : 835
- No point movement
+ Moved to point: 839
+ : 31:4: foobar = struct( ...
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
@@ -173,9 +179,9 @@
- Invoking : "M-q" = matlab-ts-mode-prog-fill-reindent-defun
Start point : 1007
- Moved to point: 1008
- : 40:0: 'field1', 1, ...
- : ^
+ Moved to point: 1016
+ : 40:8: 'field1', 1, ...
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
@@ -228,9 +234,9 @@
- Invoking : "M-q" = matlab-ts-mode-prog-fill-reindent-defun
Start point : 1186
- Moved to point: 1187
- : 49:0: 'field1', 2);
- : ^
+ Moved to point: 1195
+ : 49:8: 'field1', 2);
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents