branch: externals/matlab-mode
commit d8256fca3696755d76d618fd8548b159b0fc7c4f
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>
matlab-ts-mode: fix indent in cells during typing, add indent typing
line-by-line
---
matlab-ts-mode.el | 73 +++++++++++++++-------
tests/t-utils.el | 70 ++++++++++++++-------
.../indent_comment_after_prop.skip.typing.txt | 1 +
.../indent_comment_fcn.skip.typing.txt | 1 +
.../indent_comments.skip.typing.txt | 1 +
.../indent_comments_in_blocks.skip.typing.txt | 1 +
.../indent_cont_statements.skip.typing.txt | 1 +
.../indent_copyright_in_code.skip.typing.txt | 1 +
.../indent_end_less_function.skip.typing.txt | 1 +
.../indent_enum.skip.typing.txt | 1 +
.../indent_fcn_calls.skip.typing.txt | 1 +
.../indent_fcn_ellipsis.skip.typing.txt | 1 +
.../indent_if_continued.skip.typing.txt | 1 +
.../indent_keywords.skip.typing.txt | 1 +
.../indent_line_continuation.skip.typing.txt | 1 +
.../indent_nested.skip.typing.txt | 1 +
.../indent_xr_switch_expected.org | 40 ++++++------
17 files changed, 134 insertions(+), 63 deletions(-)
diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el
index c70eb7fad9..3e709f625e 100644
--- a/matlab-ts-mode.el
+++ b/matlab-ts-mode.el
@@ -1267,7 +1267,13 @@ Prev-siblings:
(goto-char bol)
(beginning-of-line)
(looking-at "^[ \t]*$")))
- ;; parent should be a newline
+ ;; Consider the one-liner:
+ ;; classdef indent_xr_classdef1
+ ;; ^ TAB should go here
+ ;; on entry node is nil and parent is ERROR, so backup to the newline:
+ ;; (source_file
+ ;; (ERROR classdef (identifier) \n))
+ ;; See: tests/test-matlab-ts-mode-indent-xr-files/indent_xr_classdef1.m
(setq parent (treesit-node-at (point))))
;; Handle continuation where it's not part of the error node. Example:
@@ -1299,8 +1305,10 @@ Prev-siblings:
"properties"
"property"
"methods"
+ "("
"["
- "{")
+ "{"
+ "row")
eos)))
(node-to-check (or last-child-of-error-node node parent))
in-error ;; is node, parent, or one of it's ancestors an ERROR?
@@ -1329,7 +1337,9 @@ Prev-siblings:
;; prev-sibling-to-check
- (let ((prev-sibling (treesit-node-prev-sibling node-to-check)))
+ (let ((prev-sibling (if last-child-of-error-node
+ last-child-of-error-node ;; is our
"prev-sibling"
+ (treesit-node-prev-sibling node-to-check))))
(while (and prev-sibling
(not prev-sibling-to-check)
(not prev-sibling-has-error))
@@ -1338,8 +1348,13 @@ Prev-siblings:
((string= prev-sibling-type "ERROR")
(setq prev-sibling-has-error t))
- ((and (not prev-sibling-to-check)
- (string-match-p anchors-rx prev-sibling-type))
+ ((and (string-match-p anchors-rx prev-sibling-type)
+ (or (not (string= prev-sibling-type "("))
+ ;; Assueme nodes: identifer "(" is a function call
and we don't want
+ ;; to match that.
+ (and (not (equal (treesit-node-type
+ (treesit-node-prev-sibling
prev-sibling))
+ "identifier")))))
(setq prev-sibling-to-check prev-sibling)))
(setq prev-sibling (if prev-sibling-has-error
@@ -1356,14 +1371,22 @@ Prev-siblings:
(let ((indent-level (if (and node (string= (treesit-node-type
node) "end"))
0
(pcase (treesit-node-type anchor-node)
- ("property" (if last-child-of-error-node
-
matlab-ts-mode--indent-level
- 0))
- ((rx (seq bos (or "[" "{" eos)))
matlab-ts-mode--array-indent-level)
- ("function_definition"
matlab-ts-mode--function-indent-level)
- (_ (if last-child-of-error-node
- ;; Part of a line continuation so 4
for that plus 4 for parent
- (* 2 matlab-ts-mode--indent-level)
+ ("property"
+ (if last-child-of-error-node
+ matlab-ts-mode--indent-level
+ 0))
+ ("("
+ 1)
+ ((rx (seq bos (or "[" "{" eos)))
+ matlab-ts-mode--array-indent-level)
+ ("function_definition"
+ matlab-ts-mode--function-indent-level)
+ ("row"
+ 0)
+ (_
+ (if last-child-of-error-node
+ ;; Part of a continuation, so 4 for
that plus 4 for parent
+ (* 2 matlab-ts-mode--indent-level)
matlab-ts-mode--indent-level))))))
(setq matlab-ts-mode--i-next-line-pair
(cons (treesit-node-start anchor-node) indent-level))
@@ -1390,14 +1413,6 @@ Prev-siblings:
(defvar matlab-ts-mode--indent-rules
`((matlab
- ;; I-Rule: cell/matrix row matcher when in an error node
- ;; mat0 = [1, 2
- ;; ^ <-- TAB or RET on prior line goes here
- ;; See: tests/test-matlab-ts-mode-indent-xr-files/indent_xr_mat*.m
- (,#'matlab-ts-mode--i-error-row-matcher
- ,#'matlab-ts-mode--i-error-row-anchor
- ,#'matlab-ts-mode--i-error-row-offset)
-
;; I-Rule: RET on an incomplete statement. Example:
;; classdef foo
;; ^ <== TAB or RET on prior line goes
here.
@@ -1406,7 +1421,11 @@ Prev-siblings:
,#'matlab-ts-mode--i-next-line-offset)
;; I-Rule: classdef's, function's, or code for a script that is at the
top-level
- ((parent-is ,(rx bos "source_file" eos)) column-0 0)
+ ((lambda (node parent _bol &rest _)
+ (and node
+ (not (string= (treesit-node-type node) "line_continuation"))
+ (equal (treesit-node-type parent) "source_file")))
+ column-0 0)
;; I-Rule: within a function/classdef doc block comment "%{ ... %}"?
(,#'matlab-ts-mode--i-doc-block-comment-matcher parent 2)
@@ -1461,7 +1480,7 @@ Prev-siblings:
;; I-Rule: property continuation
((n-p-gp nil ,(rx bos "default_value" eos) ,(rx bos "property" eos))
grand-parent ,matlab-ts-mode--indent-level)
-
+
;; I-Rule: property after a property
;; properties
;; p1
@@ -1603,6 +1622,14 @@ Prev-siblings:
;; See: tests/test-matlab-ts-mode-indent-files/indent_comment_after_prop.m
((node-is "comment") parent 0)
+ ;; I-Rule: cell/matrix row matcher when in an error node
+ ;; mat0 = [1, 2
+ ;; ^ <-- TAB or RET on prior line goes here
+ ;; See: tests/test-matlab-ts-mode-indent-xr-files/indent_xr_mat*.m
+ (,#'matlab-ts-mode--i-error-row-matcher
+ ,#'matlab-ts-mode--i-error-row-anchor
+ ,#'matlab-ts-mode--i-error-row-offset)
+
;; I-Rule: error-switch-matcher
;; switch fcn1(a)
;; ^ <== TAB to here
diff --git a/tests/t-utils.el b/tests/t-utils.el
index b93c4c3bc4..d98aa3e427 100644
--- a/tests/t-utils.el
+++ b/tests/t-utils.el
@@ -179,6 +179,18 @@
(let ((delete-trailing-lines t))
(delete-trailing-whitespace (point-min) (point-max))))
+(defun t-utils--skip-message (test-file skip-file &optional test-description)
+ "Display message, skipping TEST-FILE because of SKIP-FILE.
+Optional TEST-DESCRIPTION defaults to \"this test input\"."
+ (let ((skip-file-contents (with-temp-buffer
+ (insert-file-contents-literally skip-file)
+ (string-trim-right
+ (replace-regexp-in-string "^" " "
+ (buffer-string))))))
+ (message "%s:1: warning: skipping %s because %s exists\n%s"
+ test-file (or test-description "this test input") skip-file
skip-file-contents)))
+
+
(defun t-utils-get-files (test-name base-regexp &optional skip-regexp
file-to-use)
"Return list of test input files, /abs/path/to/TEST-NAME-files/FILE.LANG.
The basename of each returned file matches BASE-REGEXP and not optional
@@ -220,13 +232,7 @@ skipping all *_expected.lang files."
(dolist (file files)
(let ((skip-file (replace-regexp-in-string "\\.[^.]\\'" ".skip.txt"
file)))
(if (file-exists-p skip-file)
- (let ((skip-file-contents (with-temp-buffer
- (insert-file-contents-literally
skip-file)
- (string-trim-right
- (replace-regexp-in-string "^" " "
-
(buffer-string))))))
- (message "%s:1: warning: skipping this test input because %s
exists\n%s"
- file skip-file skip-file-contents))
+ (t-utils--skip-message file skip-file)
;; Not skipped. Note we ignore hidden link files, e.g. .#foo.lang
(when (not (string-match-p "\\`\\.#" file))
(push file files-not-skipped)))))
@@ -1093,7 +1099,7 @@ Two methods are used to indent each file in LANG-FILES,
the temporary buffer in context after the `indent-region'.
2. Indent the unindented contents of lang-file when there are no
- error nodes. In a temporary buffer
+ error nodes in lang-file. In a temporary buffer
- Insert all non-empty non-blank lines unindented
- TAB on each line
- RET to add blank lines
@@ -1101,7 +1107,7 @@ Two methods are used to indent each file in LANG-FILES,
verifies they are handled. Error nodes are identified by using
ERROR-NODES-REGEXP which defaults to (rx bos \"ERROR\" eos).
- If the test fails, a file named NAME_indented_unindented.LANG~ is
+ If the test fails, a file named NAME_indent_unindented.LANG~ is
created.
The typing buffer is initialized with the string-trim'd version of
@@ -1116,7 +1122,25 @@ Two methods are used to indent each file in LANG-FILES,
`indent-for-tab-command' and blank lines are inserted by calling
`newline'.`
- 3. xxx line-by-line
+ 3. Indent the contents of lang-file line-by-line when there are no
+ error nodes in lang-file. In a temporary buffer
+ - Insert the string-trim'd line of lang-file
+ - RET to indent via `newline'
+ - Repeat for each line of lang-file.
+ Validate result matches the EXPECTED.
+
+ If the test fails, a file named NAME_typing_line_by_line.LANG~ is
+ created.
+
+ It can be difficult to make the typing part of the test for
+ lang-file pass due to ERROR nodes in the tree-sitter parse tree.
+ Therefore, if you want to disable this part of the test for lang-file
+ with basename NAME.LANG create basename NAME.typing.skip.txt.
+ For example, if lang-file has name
+ .../tests/test-LANGUAGE-ts-mode-indent-files/indent_fcn.lang
+ create the following to skip it and put a comment in the .typing.skip.txt
+ file as to why it's skipped
+ .../tests/test-LANGUAGE-ts-mode-indent-files/indent_fcn.skip.typing.txt
Example test setup:
@@ -1215,17 +1239,21 @@ To debug a specific indent test file
(when unindented-error-msg
(push unindented-error-msg error-msgs)))
- ;; (message "START: %s <indent-via-typing-line-by-line> %s"
test-name lang-file)
- ;; (let ((start-time (current-time))
- ;; (typing-error-msg (t-utils--test-indent-typing-line-by-line
- ;; lang-file lang-file-major-mode
- ;; expected expected-file)))
- ;; (message "%s: %s <indent-via-typing-line-by-line> %s %s"
test-name lang-file
- ;; (if typing-error-msg "FAIL" "PASS")
- ;; (t-utils--took start-time))
- ;; (when typing-error-msg
- ;; (push typing-error-msg error-msgs)))
-
+ (let ((skip-typing-file (replace-regexp-in-string "\\.[^.]\\'"
".skip.typing.txt"
+ lang-file)))
+ (if (file-exists-p skip-typing-file)
+ (t-utils--skip-message lang-file skip-typing-file
+ "typing line-by-line this test input")
+ (message "START: %s <indent-via-typing-line-by-line> %s"
test-name lang-file)
+ (let ((start-time (current-time))
+ (typing-error-msg (t-utils--test-indent-typing-line-by-line
+ lang-file lang-file-major-mode
+ expected expected-file)))
+ (message "%s: %s <indent-via-typing-line-by-line> %s %s"
test-name lang-file
+ (if typing-error-msg "FAIL" "PASS")
+ (t-utils--took start-time))
+ (when typing-error-msg
+ (push typing-error-msg error-msgs)))))
)
))
;; Validate t-utils-test-indent result
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_comment_after_prop.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_comment_after_prop.skip.typing.txt
new file mode 100644
index 0000000000..1433285fbe
--- /dev/null
+++
b/tests/test-matlab-ts-mode-indent-files/indent_comment_after_prop.skip.typing.txt
@@ -0,0 +1 @@
+Some comments are not indented correctly
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_comment_fcn.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_comment_fcn.skip.typing.txt
new file mode 100644
index 0000000000..c73ba6717e
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_comment_fcn.skip.typing.txt
@@ -0,0 +1 @@
+Some items not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_comments.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_comments.skip.typing.txt
new file mode 100644
index 0000000000..6d9c24a567
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_comments.skip.typing.txt
@@ -0,0 +1 @@
+Some comments not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_comments_in_blocks.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_comments_in_blocks.skip.typing.txt
new file mode 100644
index 0000000000..9596a8a33f
--- /dev/null
+++
b/tests/test-matlab-ts-mode-indent-files/indent_comments_in_blocks.skip.typing.txt
@@ -0,0 +1 @@
+Some items not indented correclty.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_cont_statements.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_cont_statements.skip.typing.txt
new file mode 100644
index 0000000000..6d9c24a567
--- /dev/null
+++
b/tests/test-matlab-ts-mode-indent-files/indent_cont_statements.skip.typing.txt
@@ -0,0 +1 @@
+Some comments not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_copyright_in_code.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_copyright_in_code.skip.typing.txt
new file mode 100644
index 0000000000..957547022e
--- /dev/null
+++
b/tests/test-matlab-ts-mode-indent-files/indent_copyright_in_code.skip.typing.txt
@@ -0,0 +1 @@
+Some comments not indented correclty.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_end_less_function.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_end_less_function.skip.typing.txt
new file mode 100644
index 0000000000..c73ba6717e
--- /dev/null
+++
b/tests/test-matlab-ts-mode-indent-files/indent_end_less_function.skip.typing.txt
@@ -0,0 +1 @@
+Some items not indented correctly.
diff --git a/tests/test-matlab-ts-mode-indent-files/indent_enum.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_enum.skip.typing.txt
new file mode 100644
index 0000000000..5184c64fb2
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_enum.skip.typing.txt
@@ -0,0 +1 @@
+enum's not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_fcn_calls.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_fcn_calls.skip.typing.txt
new file mode 100644
index 0000000000..3307417a73
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_fcn_calls.skip.typing.txt
@@ -0,0 +1 @@
+Function arguments not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_fcn_ellipsis.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_fcn_ellipsis.skip.typing.txt
new file mode 100644
index 0000000000..7d3e18125c
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_fcn_ellipsis.skip.typing.txt
@@ -0,0 +1 @@
+Items not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_if_continued.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_if_continued.skip.typing.txt
new file mode 100644
index 0000000000..ebe6ed2ee5
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_if_continued.skip.typing.txt
@@ -0,0 +1 @@
+Items not indented correctly
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_keywords.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_keywords.skip.typing.txt
new file mode 100644
index 0000000000..7d3e18125c
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_keywords.skip.typing.txt
@@ -0,0 +1 @@
+Items not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_line_continuation.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_line_continuation.skip.typing.txt
new file mode 100644
index 0000000000..7d3e18125c
--- /dev/null
+++
b/tests/test-matlab-ts-mode-indent-files/indent_line_continuation.skip.typing.txt
@@ -0,0 +1 @@
+Items not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-files/indent_nested.skip.typing.txt
b/tests/test-matlab-ts-mode-indent-files/indent_nested.skip.typing.txt
new file mode 100644
index 0000000000..7d3e18125c
--- /dev/null
+++ b/tests/test-matlab-ts-mode-indent-files/indent_nested.skip.typing.txt
@@ -0,0 +1 @@
+Items not indented correctly.
diff --git
a/tests/test-matlab-ts-mode-indent-xr-files/indent_xr_switch_expected.org
b/tests/test-matlab-ts-mode-indent-xr-files/indent_xr_switch_expected.org
index fc310ced69..1dd3bd4aef 100644
--- a/tests/test-matlab-ts-mode-indent-xr-files/indent_xr_switch_expected.org
+++ b/tests/test-matlab-ts-mode-indent-xr-files/indent_xr_switch_expected.org
@@ -105,28 +105,28 @@
- Invoking : "C-m" = newline
Start point : 171
- Moved to point: 172
- : 6:0:
- : ^
+ Moved to point: 174
+ : 6:2:
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
+++ end_contents
-@@ -5,6 +5,7 @@
+@@ -3,6 +3,7 @@
+ switch fcn1(a)
+ case 1
disp('1');
++
-+
-
-
#+end_src diff
- Invoking : (insert "end")
- Start point : 172
- Moved to point: 175
- : 6:3: end
- : ^
+ Start point : 174
+ Moved to point: 177
+ : 6:5: end
+ : ^
Buffer modified:
#+begin_src diff
--- start_contents
@@ -135,15 +135,15 @@
switch fcn1(a)
case 1
disp('1');
--
-+end
+-
++ end
#+end_src diff
- Invoking : "C-m" = newline
- Start point : 175
+ Start point : 177
Moved to point: 176
: 7:0:
: ^
@@ -151,12 +151,14 @@
#+begin_src diff
--- start_contents
+++ end_contents
-@@ -6,6 +6,7 @@
- end
-
-
+@@ -3,7 +3,8 @@
+ switch fcn1(a)
+ case 1
+ disp('1');
+- end
++end
+
-
+
#+end_src diff