branch: externals/matlab-mode
commit f542d981d7016253c9c148428e37c2bf0d04f7d9
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>
matlab-ts-mode: workaround tree-sitter-matlab issue 143
---
matlab-ts-mode--ei.el | 98 ++++++++++++++++++++--
matlab-ts-mode.el | 36 ++------
.../electric_indent_workaround_issue143.m | 7 ++
.../electric_indent_workaround_issue143_expected.m | 7 ++
...tric_indent_workaround_issue143_expected_msgs.m | 7 ++
5 files changed, 116 insertions(+), 39 deletions(-)
diff --git a/matlab-ts-mode--ei.el b/matlab-ts-mode--ei.el
index 6e1ae396e4..cdca424d44 100644
--- a/matlab-ts-mode--ei.el
+++ b/matlab-ts-mode--ei.el
@@ -114,7 +114,7 @@
eos))
(defvar matlab-ts-mode--ei-pad-op-re
- (rx bos (or "+" "-" "*" "/" ".*" "./" "\\"
+ (rx bos (or "+" "-" "*" "/" ".*" "./" ".\\" "\\"
"==" "~=" ">" ">=" "<" "<="
"&" "|" "&&" "||"
"="
@@ -499,7 +499,7 @@ or nil."
(cl-return)))))
(when (not n-spaces-between)
- (error "Internal error, unhandled node <\"%s\" %S> and next-node
<\"%s\" %S>"
+ (error "Assert: ei, unhandled node <\"%s\" %S> and next-node
<\"%s\" %S>"
node-type node next-node-type next-node))
(let* ((node-end (treesit-node-end node))
@@ -1101,13 +1101,95 @@ See `matlab-ts-mode--ei-get-new-line' for EI-INFO
contents."
(setq ei-info (matlab-ts-mode--ei-align-trailing-comments ei-info)))
ei-info)
-(cl-defun matlab-ts-mode--ei-indent-elements-in-line (&optional start-node
start-offset)
+(defun matlab-ts-mode--ei-get-start-info ()
+ "Get start node and start offset in line prior to electric indent.
+Returns (cons start-node start-offset) where
+- start-node is non-nil if the point is at a node
+- start-offset is the offset of the point from the beginning of start-node.
+Example where point is on the \"d\" in width:
+ area = width * length;
+ ^
+start-node is the identifier node for width and start-offset is 2."
+ (let (start-node
+ start-offset
+ (at-eol (looking-at "[ \t]*$")))
+
+ ;; The node when at-eol is not on the current line.
+ (when (not at-eol)
+ (let ((node (treesit-node-at (point))))
+ ;; Consider: A = [B C];
+ ;; ^
+ ;; node is the invisible "," and moving to start gives us node for C
+ (save-excursion
+ (when (< (point) (treesit-node-start node))
+ (if (re-search-forward "[^ \t]" (line-end-position) t)
+ (progn
+ (backward-char)
+ (setq node (treesit-node-at (point))))
+ (if (re-search-backward "[^ \t]" (line-beginning-position) t)
+ (setq node (treesit-node-at (point)))
+ (setq node nil))))
+
+ (when (and node
+ (>= (point) (treesit-node-start node))
+ (<= (point) (treesit-node-end node)))
+ (setq start-node node)
+ (setq start-offset (- (point) (treesit-node-start node)))))))
+ (cons start-node start-offset)))
+
+(defun matlab-ts-mode--ei-workaround-143 ()
+ "Workaround https://github.com/acristoffers/tree-sitter-matlab/issues/143."
+
+ (let ((line-pt (point))
+ (eol-pt (line-end-position)))
+ (save-excursion
+ (back-to-indentation)
+
+ (while (< (point) eol-pt)
+ (let ((node (if (looking-at "[ \t]")
+ (if (re-search-forward "[^ \t]" (line-end-position) t)
+ (progn (backward-char)
+ (treesit-node-at (point)))
+ (goto-char eol-pt)
+ nil)
+ (treesit-node-at (point)))))
+ (when node
+ (if (<= (treesit-node-end node) (point))
+ ;; Consider
+ ;; a= [1, 2; 3, 44 ];
+ ;; ^ ==> node at ';' returns the node for 2
because
+ ;; ';' is an ignored node.
+ (forward-char)
+ (if (string= (or (treesit-node-type node) "") "number") ;;
Something like 1234./2?
+ (progn
+ (goto-char (treesit-node-end node))
+ (backward-char)
+ ;; Note, .' (e.g. 1234.') is not parsed correctly and
that's okay because
+ ;; electric indent binds the transpose to the item to its
left.
+ (if (looking-at "\\.[/\\*\\\\]")
+ (progn
+ (when (<= (point) line-pt)
+ (setq line-pt (1+ line-pt)))
+ (insert " ")
+ (setq eol-pt (line-end-position)))
+ (forward-char)))
+ ;; Nodes can span multiple lines, so new point maybe > eol-pt.
+ (goto-char (treesit-node-end node))))))))
+ (goto-char line-pt)))
+
+(cl-defun matlab-ts-mode--ei-indent-elements-in-line (&optional
is-indent-region)
"Indent current line by adjust spacing around elements.
-Optional START-NODE and START-OFFSET are used to restore the point when
-line is updated. Returns t if line was updated."
-
- ;; If line was indented (ei-line is not same as current line), then update
the buffer
- (let ((ei-info (matlab-ts-mode--ei-get-new-line start-node start-offset)))
+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."
+
+ (matlab-ts-mode--ei-workaround-143)
+
+ ;; 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)
+ (matlab-ts-mode--ei-get-start-info)))
+ (start-node (car start-pair))
+ (start-offset (cdr start-pair))
+ (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)))
diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el
index 534bd12c1b..a7e39588dc 100644
--- a/matlab-ts-mode.el
+++ b/matlab-ts-mode.el
@@ -2864,36 +2864,10 @@ Example:
"Call `treesit-indent', then do electric indent."
(treesit-indent)
(when matlab-ts-mode-electric-indent
- (let ((start-pt (point))
- start-node
- start-offset
- (at-eol (looking-at "[ \t]*$")))
-
- (when (not at-eol)
- (let ((node (treesit-node-at (point))))
- ;; Consider: A = [B C];
- ;; ^
- ;; node is the invisible "," and moving to start gives us node for C
- (save-excursion
- (when (< (point) (treesit-node-start node))
- (if (re-search-forward "[^ \t]" (line-end-position) t)
- (progn
- (backward-char)
- (setq node (treesit-node-at (point))))
- (if (re-search-backward "[^ \t]" (line-beginning-position) t)
- (setq node (treesit-node-at (point)))
- (setq node nil))))
-
- (when (and node
- (>= (point) (treesit-node-start node))
- (<= (point) (treesit-node-end node)))
- (setq start-node node)
- (setq start-offset (- (point) (treesit-node-start node)))))))
-
- (if (matlab-ts-mode--ei-indent-elements-in-line start-node start-offset)
- (when at-eol
- (end-of-line))
- (goto-char start-pt)))))
+ (let ((at-eol (looking-at "[ \t]*$")))
+ (when (matlab-ts-mode--ei-indent-elements-in-line)
+ (when at-eol
+ (end-of-line))))))
(defun matlab-ts-mode--treesit-indent-region (beg end)
"Call `treesit-indent-region' on BEG END, then do electric indent."
@@ -2931,7 +2905,7 @@ Example:
(goto-char beg)
(while (<= curr-linenum end-linenum)
(beginning-of-line)
- (matlab-ts-mode--ei-indent-elements-in-line)
+ (matlab-ts-mode--ei-indent-elements-in-line 'indent-region)
(forward-line)
(setq curr-linenum (1+ curr-linenum)))
;; Restore point accounting for whitespace adjustments in the
lines
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143.m
new file mode 100644
index 0000000000..411af10c5c
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143.m
@@ -0,0 +1,7 @@
+% -*- matlab-ts -*-
+
+% workaround https://github.com/acristoffers/tree-sitter-matlab/issues/143
+
+if 1
+ a=1234./2+500./4+600.'+700.\1+800.*2+sum([444.,555.]);
+end
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143_expected.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143_expected.m
new file mode 100644
index 0000000000..676d722d5f
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143_expected.m
@@ -0,0 +1,7 @@
+% -*- matlab-ts -*-
+
+% workaround https://github.com/acristoffers/tree-sitter-matlab/issues/143
+
+if 1
+ a = 1234 ./ 2 + 500 ./ 4 + 600.' + 700 .\ 1 + 800 .* 2 + sum([444., 555.]);
+end
diff --git
a/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143_expected_msgs.m
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143_expected_msgs.m
new file mode 100644
index 0000000000..5d3e8d8e68
--- /dev/null
+++
b/tests/test-matlab-ts-mode-electric-indent-files/electric_indent_workaround_issue143_expected_msgs.m
@@ -0,0 +1,7 @@
+% -*- matlab-ts -*- % <{Matched rule: (matlab-ts-mode--i-top-level
matlab-ts-mode--column-0 0)}>
+
+% workaround https://github.com/acristoffers/tree-sitter-matlab/issues/143 %
<{Matched rule: (matlab-ts-mode--i-top-level matlab-ts-mode--column-0 0)}>
+
+if 1 % <{Matched rule: (matlab-ts-mode--i-top-level matlab-ts-mode--column-0
0)}>
+ a = 1234 ./ 2 + 500 ./ 4 + 600.' + 700 .\ 1 + 800 .* 2 + sum([444.,
555.]); % <{Matched rule: ((node-is
"\\`\\(?:arguments_statement\\|block\\|e\\(?:num\\(?:eration\\)?\\|vents\\)\\|function_definition\\|methods\\|propert\\(?:ies\\|y\\)\\)\\'")
parent 4)}>
+end % <{Matched rule: ((node-is
"\\`\\(?:catch_clause\\|e\\(?:lse\\(?:\\(?:if\\)?_clause\\)\\|nd\\)\\)\\'")
parent 0)}>