branch: externals/matlab-mode commit 52c6d5ede078c232a30c7f190126e76d3eb0206a Author: John Ciolfi <john.ciolfi...@gmail.com> Commit: John Ciolfi <john.ciolfi...@gmail.com>
matlab-ts-mode: add electric ends --- matlab-ts-mode.el | 217 +++- .../electric_ends_cases.m | 39 + .../electric_ends_cases_expected.org | 1241 ++++++++++++++++++++ .../electric_ends_classdef.m | 14 + .../electric_ends_classdef_expected.org | 143 +++ .../electric_ends_if_continued.m | 19 + .../electric_ends_if_continued_expected.org | 164 +++ tests/test-matlab-ts-mode-electric-ends.el | 72 ++ 8 files changed, 1855 insertions(+), 54 deletions(-) diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el index bb00427a85..61a598e328 100644 --- a/matlab-ts-mode.el +++ b/matlab-ts-mode.el @@ -147,16 +147,18 @@ Then restart Emacs and run You can also install via use-package or other methods." :type 'boolean) -;; TODO -;; (defcustom matlab-ts-mode-electric-ends t -;; "*If t, insert end keywords to complete statements. -;; For example, if you type -;; classdef foo<RET> -;; an end statement will be inserted resulting in: -;; classdef foo<RET> -;; ^ <== point here -;; end" -;; :type 'boolean) +(defcustom matlab-ts-mode-electric-ends t + "*If t, insert end keywords to complete statements. +For example, if you type + classdef foo<RET> +an end statement will be inserted resulting in: + classdef foo<RET> + ^ <== point here + end +Insertion of end keywords works well when the code is +indented. If you are editing code that is not indented, +you may wish to turn this off." + :type 'boolean) ;;; Global variables used in multiple code ";;; sections" @@ -1301,8 +1303,8 @@ Returns indent-level relative to ANCHOR-NODE." (when (> (point) 1) (goto-char (1- (point))) (looking-at "%"))) - ;; Ancored under a block comment: %{ - ;; ^ <== TAB to here + ;; Anchored under a block comment: %{ + ;; ^ <== TAB to here, one more than the "{" 1 matlab-ts-mode--array-indent-level)) @@ -1563,16 +1565,6 @@ Prev-siblings: last-child-of-error-node)))) (setq matlab-ts-mode--i-next-line-pair (cons (treesit-node-start anchor-node) indent-level)) - - ;; TODO Rough sketch of electric-ends - ;; We need to look at the parse tree to see if we should insert it. - ;; Also, we should verify this doesn't happen with indent-region, only on RET. - ;; (when matlab-ts-mode-electric-ends - ;; (save-excursion - ;; (let ((insert-column (save-excursion - ;; (goto-char (treesit-node-start anchor-node)) - ;; (current-column)))) - ;; (insert "\n" (make-string insert-column ?\ ) "end\n"))) t))))))) (defun matlab-ts-mode--i-next-line-anchor (&rest _) @@ -2422,17 +2414,144 @@ THERE-END MISMATCH) or nil." (list here-begin here-end there-begin there-end mismatch) (funcall #'show-paren--default)))) -;;; post-command-hook +;;; post-self-command-hook + +(defun matlab-ts-mode--is-electric-end-missing (node) + "Is statement NODE missing an \"end\"." + (let ((last-child (treesit-node-child (treesit-node-parent node) -1))) + (cond + ;; Case: no end keyword for the node in the parse tree + ((not (equal (treesit-node-type last-child) "end")) + t) + + ;; Case: see if this is an end for a different statement. Consider: + ;; function foo(a) + ;; if a > 0 <== When RET typed, we want the electric end to be inserted + ;; end + ;; The parse tree is: + ;; (function_definition function name: (identifier) + ;; (function_arguments ( arguments: (identifier) )) + ;; \n + ;; (block + ;; (if_statement if + ;; condition: (comparison_operator (identifier) > (number)) + ;; \n end) + ;; \n)) + ;; Notice the end is attached to the if_statement. Therefore, we use indent level + ;; to see if it is really attached. + ;; This works well assuming that the code is indented when one is editing it. + ((let ((node-indent-level (save-excursion + (goto-char (treesit-node-start node)) + (current-indentation))) + (end-indent-level (save-excursion + (goto-char (treesit-node-start last-child)) + (current-indentation)))) + (not (= node-indent-level end-indent-level))) + t) + + ;; Case: newely added statement casues a parse error, so it's missing the end, Consider: + ;; classdef foo + ;; properties <== properties typed, followed by RET + ;; methods + ;; end + ;; end + ;; which gives us parse tree: + ;; (source_file + ;; (class_definition classdef name: (identifier) \n + ;; (properties properties \n + ;; (ERROR , methods) + ;; \n end) + ;; end) + ;; \n) + ((let* ((statement-node (treesit-node-parent node)) + (child-idx 0) + (child (treesit-node-child statement-node child-idx)) + (node-type (treesit-node-type node))) + + (while (and child + (string-match-p (rx-to-string `(seq bos (or ,node-type "\n" "comment") eos) t) + (treesit-node-type child))) + (setq child-idx (1+ child-idx)) + (setq child (treesit-node-child statement-node child-idx))) + (and child (string= (treesit-node-type child) "ERROR"))) + ;; An ERROR immediately after node + t) + + ;; Otherwise: statement has an end + (t + nil + )))) + +(defun matlab-ts-mode--insert-electric-ends () + "A RET was type, insert the electric \"end\" if needed." + + (let (end-indent-level + extra-insert + move-point-to-extra-insert) -(defun matlab-ts-mode--post-command-newline () - "Ensure buffer always has a newline. -The matlab tree-sitter requires a newline, see -https://github.com/acristoffers/tree-sitter-matlab/issues/34" - (when (eq major-mode 'matlab-ts-mode) (save-excursion - (goto-char (point-max)) - (when (not (= (char-before) ?\n)) - (insert "\n"))))) + (forward-line -1) + (back-to-indentation) + (let* ((node (treesit-node-at (point))) + (node-type (treesit-node-type node))) + (when (and node + ;; AND: Was a statement entered that requires and end? + (string-match-p + (rx bos (or "function" "arguments" "if" "switch" "while" "for" "parfor" + "spmd" "try" "classdef" "enumeration" "properties" "methods" + "events") + eos) + node-type) + ;; AND: Is the statement missing an end? + (matlab-ts-mode--is-electric-end-missing node)) + + ;; Statement for the RET doesn't have an end, so add one at end-indent-level + (setq end-indent-level (current-indentation)) + + ;; Extra insert, e.g. case for the switch statement. + (pcase node-type + ("switch" + (setq extra-insert " case " + move-point-to-extra-insert t)) + ("try" + (setq extra-insert "catch me")) + )))) + + (when end-indent-level + (let ((indent-level-spaces (make-string end-indent-level ? ))) + (save-excursion + (when extra-insert + (when (not move-point-to-extra-insert) + (insert "\n")) + (insert indent-level-spaces extra-insert)) + (insert "\n" indent-level-spaces "end\n")) + )))) + +(defun matlab-ts-mode--post-insert-callback () + "Callback attached to `post-self-insert-hook'. + +The matlab tree-sitter requires a final newline. Setting +`require-final-newline' to \\='visit-save doesn't guarantee we have a newline +when typing code into the buffer, so we leverage `post-self-command-hook' +to insert a newline if needed. + + https://github.com/acristoffers/tree-sitter-matlab/issues/34 + +This callback also implements `matlab-ts-mode-electric-ends'." + + (when (eq major-mode 'matlab-ts-mode) + (let ((ret-typed (eq last-command-event ?\n))) + + ;; Add final newline to the buffer? + (save-excursion + (goto-char (point-max)) + (when (not (= (char-before) ?\n)) + (insert "\n"))) + + ;; Add "end" (for `matlab-ts-mode-electric-ends') + (when (and ret-typed + matlab-ts-mode-electric-ends) + (matlab-ts-mode--insert-electric-ends))))) ;;; MLint Flycheck @@ -2696,21 +2815,6 @@ mark at the beginning of the \"%% section\" and point at the end of the section" :help "When MATLAB debugger is active, stop debugging"] ) - ;; TODO - how to autoload these? Do we want this menu? - ;; ("Insert" - ;; ["Complete Symbol" matlab-complete-symbol t] - ;; ["Comment" matlab-comment t] - ;; ["if end" tempo-template-matlab-if t] - ;; ["if else end" tempo-template-matlab-if-else t] - ;; ["for end" tempo-template-matlab-for t] - ;; ["switch otherwise end" tempo-template-matlab-switch t] - ;; ["Next case" matlab-insert-next-case t] - ;; ["try catch end" tempo-template-matlab-try t] - ;; ["while end" tempo-template-matlab-while t] - ;; ["End of block" matlab-insert-end-block t] - ;; ["Function" tempo-template-matlab-function t] - ;; ["Stringify Region" matlab-stringify-region t] - ;; ) "----" ["View mlint code analyzer messages" (flycheck-list-errors) :help "View mlint code analyzer messages. @@ -2847,12 +2951,9 @@ is t, add the following to an Init File (e.g. `user-init-file' or ;; See: tests/test-matlab-ts-mode-show-paren.el (setq-local show-paren-data-function #'matlab-ts-mode--show-paren-or-block) - ;; Final newline. The matlab tree-sitter requires a final newline, see - ;; https://github.com/acristoffers/tree-sitter-matlab/issues/34 - ;; Setting require-final-newline to 'visit-save doesn't guarantee we have a newline when typing - ;; code into the buffer, so we also setup a post-command-hook to insert a newline if needed. + ;; Final newline and electric ends. (setq-local require-final-newline 'visit-save) - (add-hook 'post-self-insert-hook #'matlab-ts-mode--post-command-newline -99 t) + (add-hook 'post-self-insert-hook #'matlab-ts-mode--post-insert-callback -99 t) ;; give each file it's own parameter history (setq-local matlab-shell-save-and-go-history '("()")) @@ -2860,13 +2961,21 @@ is t, add the following to an Init File (e.g. `user-init-file' or ;; Activate MATLAB script ";; heading" matlab-sections-minor-mode if needed (matlab-sections-auto-enable-on-mfile-type-fcn (matlab-ts-mode--mfile-type)) + ;; TODO indent + ;; if a > 1 && ... + ;; ^ <== TAB or RET on prior line to here + ;; end + ;; + ;; TODO indent + ;; if (a > 1 && ... + ;; x > 1) ... + ;; ^ <== TAB or RET on prior line to here (e.g. to enter "&& y") + ;; end + ;; ;; TODO font-lock when errors ;; can we add light error indicator somewhere, e.g. put an underline marker on the error ;; region? ;; - ;; TODO create defcustom matlab-ts-mode-electric-ends that inserts end statements - ;; when a function, switch, while, for, etc. is entered. This should handle continuations. - ;; ;; TODO on load enter matlab-ts-mode when file contains mcode and ;; (add-to-list 'major-mode-remap-alist '(matlab-mode . matlab-ts-mode)) ;; is active. Also look at matlab-mode magic-mode-alist setup. diff --git a/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_cases.m b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_cases.m new file mode 100644 index 0000000000..498a62e8f9 --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_cases.m @@ -0,0 +1,39 @@ +% -*- matlab-ts -*- + +classdef electric_ends_cases + + %(t-utils-xr "C-n" "C-i" (insert "properties") "C-m" (insert "p1")) + + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + + methods + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + + function foo(a) + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + + end + end + +end + +%(t-utils-xr (t-utils-xr-print-code (point-min) (point-max))) + diff --git a/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_cases_expected.org b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_cases_expected.org new file mode 100644 index 0000000000..50bf633144 --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_cases_expected.org @@ -0,0 +1,1241 @@ +#+startup: showall + +* Executing commands from electric_ends_cases.m:5:5: + + (t-utils-xr "C-n" "C-i" (insert "properties") "C-m" (insert "p1")) + +- Invoking : "C-n" = next-line + Start point : 123 + Moved to point: 124 + : 6:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 124 + Moved to point: 128 + : 6:4: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -3,7 +3,7 @@ + classdef electric_ends_cases + + %(t-utils-xr "C-n" "C-i" (insert "properties") "C-m" (insert "p1")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + #+end_src diff + +- Invoking : (insert "properties") + Start point : 128 + Moved to point: 138 + : 6:14: properties + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -3,7 +3,7 @@ + classdef electric_ends_cases + + %(t-utils-xr "C-n" "C-i" (insert "properties") "C-m" (insert "p1")) +- ++ properties + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 138 + Moved to point: 147 + : 7:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -4,6 +4,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "properties") "C-m" (insert "p1")) + properties ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + #+end_src diff + +- Invoking : (insert "p1") + Start point : 147 + Moved to point: 149 + : 7:10: p1 + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -4,7 +4,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "properties") "C-m" (insert "p1")) + properties +- ++ p1 + end + + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:10:5: + + (t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + +- Invoking : "C-n" = next-line + Start point : 242 + Moved to point: 243 + : 11:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 243 + Moved to point: 247 + : 11:4: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -8,7 +8,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + + methods + #+end_src diff + +- Invoking : (insert "methods") + Start point : 247 + Moved to point: 254 + : 11:11: methods + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -8,7 +8,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) +- ++ methods + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + + methods + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 254 + Moved to point: 263 + : 12:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -9,6 +9,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + methods ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + + methods + #+end_src diff + +- Invoking : (insert "% methods-comment") + Start point : 263 + Moved to point: 280 + : 12:25: % methods-comment + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -9,7 +9,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "methods") "C-m" (insert "% methods-comment")) + methods +- ++ % methods-comment + end + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:15:5: + + (t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + +- Invoking : "C-n" = next-line + Start point : 371 + Moved to point: 372 + : 16:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 372 + Moved to point: 376 + : 16:4: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -13,7 +13,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) +- ++ + methods + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + #+end_src diff + +- Invoking : (insert "events") + Start point : 376 + Moved to point: 382 + : 16:10: events + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -13,7 +13,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) +- ++ events + methods + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 382 + Moved to point: 391 + : 17:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -14,6 +14,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + events ++ ++ end ++ + methods + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + #+end_src diff + +- Invoking : (insert "% events-comment") + Start point : 391 + Moved to point: 407 + : 17:24: % events-comment + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -14,7 +14,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "events") "C-m" (insert "% events-comment")) + events +- ++ % events-comment + end + + methods + #+end_src diff + +* Executing commands from electric_ends_cases.m:22:9: + + (t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + +- Invoking : "C-n" = next-line + Start point : 516 + Moved to point: 517 + : 23:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 517 + Moved to point: 525 + : 23:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -20,7 +20,7 @@ + methods + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) +- ++ + function foo(a) + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + #+end_src diff + +- Invoking : (insert "function bar") + Start point : 525 + Moved to point: 537 + : 23:20: function bar + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -20,7 +20,7 @@ + methods + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) +- ++ function bar + function foo(a) + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 537 + Moved to point: 550 + : 24:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -21,6 +21,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + function bar ++ ++ end ++ + function foo(a) + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + #+end_src diff + +- Invoking : (insert "disp('bar')") + Start point : 550 + Moved to point: 561 + : 24:23: disp('bar') + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -21,7 +21,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "function bar") "C-m" (insert "disp('bar')")) + function bar +- ++ disp('bar') + end + + function foo(a) + #+end_src diff + +* Executing commands from electric_ends_cases.m:29:13: + + (t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + +- Invoking : "C-n" = next-line + Start point : 677 + Moved to point: 678 + : 30:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 678 + Moved to point: 690 + : 30:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -27,7 +27,7 @@ + function foo(a) + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + #+end_src diff + +- Invoking : (insert "arguments") + Start point : 690 + Moved to point: 699 + : 30:21: arguments + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -27,7 +27,7 @@ + function foo(a) + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) +- ++ arguments + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 699 + Moved to point: 716 + : 31:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -28,6 +28,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + arguments ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + #+end_src diff + +- Invoking : (insert "a") + Start point : 716 + Moved to point: 717 + : 31:17: a + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -28,7 +28,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "arguments") "C-m" (insert "a")) + arguments +- ++ a + end + + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:34:13: + + (t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + +- Invoking : "C-n" = next-line + Start point : 816 + Moved to point: 817 + : 35:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 817 + Moved to point: 829 + : 35:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -32,7 +32,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + #+end_src diff + +- Invoking : (insert "if a") + Start point : 829 + Moved to point: 833 + : 35:16: if a + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -32,7 +32,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) +- ++ if a + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 833 + Moved to point: 850 + : 36:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -33,6 +33,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + if a ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + #+end_src diff + +- Invoking : (insert "disp('if')") + Start point : 850 + Moved to point: 860 + : 36:26: disp('if') + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -33,7 +33,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "if a") "C-m" (insert "disp('if')")) + if a +- ++ disp('if') + end + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:39:13: + + (t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + +- Invoking : "C-n" = next-line + Start point : 992 + Moved to point: 993 + : 40:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 993 + Moved to point: 1005 + : 40:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -37,7 +37,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +- Invoking : (insert "switch a") + Start point : 1005 + Moved to point: 1013 + : 40:20: switch a + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -37,7 +37,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) +- ++ switch a + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1013 + Moved to point: 1028 + : 41:14: case + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -38,6 +38,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + switch a ++ case ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +- Invoking : "C-e" = move-end-of-line + Start point : 1028 + Moved to point: 1033 + : 41:19: case + : ^ + No buffer modifications + +- Invoking : (insert "1") + Start point : 1033 + Moved to point: 1034 + : 41:20: case 1 + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -38,7 +38,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + switch a +- case ++ case 1 + end + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1034 + Moved to point: 1051 + : 42:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -39,6 +39,7 @@ + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + switch a + case 1 ++ + end + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + #+end_src diff + +- Invoking : (insert "disp('case 1')") + Start point : 1051 + Moved to point: 1065 + : 42:30: disp('case 1') + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -39,7 +39,7 @@ + %(t-utils-xr "C-n" "C-i" (insert "switch a") "C-m" "C-e" (insert "1") "C-m" (insert "disp('case 1')")) + switch a + case 1 +- ++ disp('case 1') + end + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:45:13: + + (t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + +- Invoking : "C-n" = next-line + Start point : 1165 + Moved to point: 1166 + : 46:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 1166 + Moved to point: 1178 + : 46:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -43,7 +43,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +- Invoking : (insert "while true") + Start point : 1178 + Moved to point: 1188 + : 46:22: while true + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -43,7 +43,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) +- ++ while true + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1188 + Moved to point: 1205 + : 47:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -44,6 +44,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + while true ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +- Invoking : (insert "break") + Start point : 1205 + Moved to point: 1210 + : 47:21: break + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -44,7 +44,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "while true") "C-m" (insert "break")) + while true +- ++ break + end + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:50:13: + + (t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + +- Invoking : "C-n" = next-line + Start point : 1315 + Moved to point: 1316 + : 51:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 1316 + Moved to point: 1328 + : 51:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -48,7 +48,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + #+end_src diff + +- Invoking : (insert "for idx=1:a") + Start point : 1328 + Moved to point: 1339 + : 51:23: for idx=1:a + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -48,7 +48,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) +- ++ for idx=1:a + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1339 + Moved to point: 1356 + : 52:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -49,6 +49,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + for idx=1:a ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + #+end_src diff + +- Invoking : (insert "disp(idx)") + Start point : 1356 + Moved to point: 1365 + : 52:25: disp(idx) + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -49,7 +49,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "for idx=1:a") "C-m" (insert "disp(idx)")) + for idx=1:a +- ++ disp(idx) + end + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:55:13: + + (t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + +- Invoking : "C-n" = next-line + Start point : 1473 + Moved to point: 1474 + : 56:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 1474 + Moved to point: 1486 + : 56:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -53,7 +53,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + #+end_src diff + +- Invoking : (insert "parfor idx=1:a") + Start point : 1486 + Moved to point: 1500 + : 56:26: parfor idx=1:a + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -53,7 +53,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) +- ++ parfor idx=1:a + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1500 + Moved to point: 1517 + : 57:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -54,6 +54,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + parfor idx=1:a ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + #+end_src diff + +- Invoking : (insert "disp(idx)") + Start point : 1517 + Moved to point: 1526 + : 57:25: disp(idx) + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -54,7 +54,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "parfor idx=1:a") "C-m" (insert "disp(idx)")) + parfor idx=1:a +- ++ disp(idx) + end + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:60:13: + + (t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + +- Invoking : "C-n" = next-line + Start point : 1639 + Moved to point: 1640 + : 61:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 1640 + Moved to point: 1652 + : 61:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -58,7 +58,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) +- ++ + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + + end + #+end_src diff + +- Invoking : (insert "spmd") + Start point : 1652 + Moved to point: 1656 + : 61:16: spmd + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -58,7 +58,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) +- ++ spmd + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + + end + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1656 + Moved to point: 1673 + : 62:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -59,6 +59,9 @@ + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + spmd ++ ++ end ++ + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + + end + #+end_src diff + +- Invoking : (insert "q = magic(spmdIndex + 2)") + Start point : 1673 + Moved to point: 1697 + : 62:40: q = magic(spmdIndex + 2) + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -59,7 +59,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "spmd") "C-m" (insert "q = magic(spmdIndex + 2)")) + spmd +- ++ q = magic(spmdIndex + 2) + end + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + #+end_src diff + +* Executing commands from electric_ends_cases.m:65:13: + + (t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + +- Invoking : "C-n" = next-line + Start point : 1796 + Moved to point: 1797 + : 66:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 1797 + Moved to point: 1809 + : 66:12: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -63,7 +63,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) +- ++ + end + end + + #+end_src diff + +- Invoking : (insert "try") + Start point : 1809 + Moved to point: 1812 + : 66:15: try + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -63,7 +63,7 @@ + end + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) +- ++ try + end + end + + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 1812 + Moved to point: 1829 + : 67:16: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -64,6 +64,10 @@ + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + try ++ ++ catch me ++ end ++ + end + end + + #+end_src diff + +- Invoking : (insert "disp('try')") + Start point : 1829 + Moved to point: 1840 + : 67:27: disp('try') + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -64,7 +64,7 @@ + + %(t-utils-xr "C-n" "C-i" (insert "try") "C-m" (insert "disp('try')")) + try +- ++ disp('try') + catch me + end + + #+end_src diff + +* Executing commands from electric_ends_cases.m:76:1: + + (t-utils-xr (t-utils-xr-print-code (point-min) (point-max))) + +- Invoking : (t-utils-xr-print-code (point-min) (point-max)) + Start point : 1966 + No point movement + standard-output: + #+begin_src matlab-ts +% -*- matlab-ts -*- + +classdef electric_ends_cases + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"properties\") \"C-m\" (insert \"p1\")) + properties + p1 + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"methods\") \"C-m\" (insert \"% methods-comment\")) + methods + % methods-comment + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"events\") \"C-m\" (insert \"% events-comment\")) + events + % events-comment + end + + methods + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"function bar\") \"C-m\" (insert \"disp('bar')\")) + function bar + disp('bar') + end + + function foo(a) + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"arguments\") \"C-m\" (insert \"a\")) + arguments + a + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"if a\") \"C-m\" (insert \"disp('if')\")) + if a + disp('if') + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"switch a\") \"C-m\" \"C-e\" (insert \"1\") \"C-m\" (insert \"disp('case 1')\")) + switch a + case 1 + disp('case 1') + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"while true\") \"C-m\" (insert \"break\")) + while true + break + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"for idx=1:a\") \"C-m\" (insert \"disp(idx)\")) + for idx=1:a + disp(idx) + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"parfor idx=1:a\") \"C-m\" (insert \"disp(idx)\")) + parfor idx=1:a + disp(idx) + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"spmd\") \"C-m\" (insert \"q = magic(spmdIndex + 2)\")) + spmd + q = magic(spmdIndex + 2) + end + + %(t-utils-xr \"C-n\" \"C-i\" (insert \"try\") \"C-m\" (insert \"disp('try')\")) + try + disp('try') + catch me + end + + end + end + +end + +%(t-utils-xr (t-utils-xr-print-code (point-min) (point-max))) + + #+end_src + No buffer modifications diff --git a/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_classdef.m b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_classdef.m new file mode 100644 index 0000000000..9ebe43bc3a --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_classdef.m @@ -0,0 +1,14 @@ +% -*- matlab-ts -*- + +%{ + (t-utils-xr + (re-search-forward "%}") "C-n" + + (insert "classdef electric_ends_classdef") "C-m" + (insert "enumeration") "C-m" + (insert "red") + + (re-search-backward "^classdef") + (t-utils-xr-print-code (point) (point-max)) + ) +%} diff --git a/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_classdef_expected.org b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_classdef_expected.org new file mode 100644 index 0000000000..72b88ab71c --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_classdef_expected.org @@ -0,0 +1,143 @@ +#+startup: showall + +* Executing commands from electric_ends_classdef.m:4:2: + + (t-utils-xr + (re-search-forward "%}") "C-n" + + (insert "classdef electric_ends_classdef") "C-m" + (insert "enumeration") "C-m" + (insert "red") + + (re-search-backward "^classdef") + (t-utils-xr-print-code (point) (point-max)) + ) + +- Invoking : (re-search-forward "%}") + Start point : 292 + Moved to point: 295 + : 14:2: %} + : ^ + No buffer modifications + +- Invoking : "C-n" = next-line + Start point : 295 + Moved to point: 296 + : 15:0: + : ^ + No buffer modifications + +- Invoking : (insert "classdef electric_ends_classdef") + Start point : 296 + Moved to point: 327 + : 15:31: classdef electric_ends_classdef + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -12,3 +12,4 @@ + (t-utils-xr-print-code (point) (point-max)) + ) + %} ++classdef electric_ends_classdef +\ No newline at end of file + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 327 + Moved to point: 332 + : 16:4: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -12,4 +12,6 @@ + (t-utils-xr-print-code (point) (point-max)) + ) + %} +-classdef electric_ends_classdef +\ No newline at end of file ++classdef electric_ends_classdef ++ ++end + #+end_src diff + +- Invoking : (insert "enumeration") + Start point : 332 + Moved to point: 343 + : 16:15: enumeration + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -13,5 +13,5 @@ + ) + %} + classdef electric_ends_classdef +- ++ enumeration + end + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 343 + Moved to point: 352 + : 17:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -14,4 +14,7 @@ + %} + classdef electric_ends_classdef + enumeration ++ ++ end ++ + end + #+end_src diff + +- Invoking : (insert "red") + Start point : 352 + Moved to point: 355 + : 17:11: red + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -14,7 +14,7 @@ + %} + classdef electric_ends_classdef + enumeration +- ++ red + end + + end + #+end_src diff + +- Invoking : (re-search-backward "^classdef") + Start point : 355 + Moved to point: 296 + : 15:0: classdef electric_ends_classdef + : ^ + No buffer modifications + +- Invoking : (t-utils-xr-print-code (point) (point-max)) + Start point : 296 + No point movement + standard-output: + #+begin_src matlab-ts +classdef electric_ends_classdef + enumeration + red + end + +end + #+end_src + No buffer modifications diff --git a/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_if_continued.m b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_if_continued.m new file mode 100644 index 0000000000..83cd4d8181 --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_if_continued.m @@ -0,0 +1,19 @@ +% -*- matlab-ts -*- + +function electric_ends_if_statement(a) + + %{ + (t-utils-xr + (re-search-forward "%}") "C-n" + + "C-i" + (insert "if (a > 1 && ...") "C-m" + (insert "a < 10)") "C-m" + (insert "disp('a > 1 && a < 10')") + + (re-search-backward "^ if") + (t-utils-xr-print-code (point) (re-search-forward "end")) + ) + %} + +end diff --git a/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_if_continued_expected.org b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_if_continued_expected.org new file mode 100644 index 0000000000..453c87a89e --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends-files/electric_ends_if_continued_expected.org @@ -0,0 +1,164 @@ +#+startup: showall + +* Executing commands from electric_ends_if_continued.m:6:6: + + (t-utils-xr + (re-search-forward "%}") "C-n" + + "C-i" + (insert "if (a > 1 && ...") "C-m" + (insert "a < 10)") "C-m" + (insert "disp('a > 1 && a < 10')") + + (re-search-backward "^ if") + (t-utils-xr-print-code (point) (re-search-forward "end")) + ) + +- Invoking : (re-search-forward "%}") + Start point : 395 + Moved to point: 402 + : 17:6: %} + : ^ + No buffer modifications + +- Invoking : "C-n" = next-line + Start point : 402 + Moved to point: 403 + : 18:0: + : ^ + No buffer modifications + +- Invoking : "C-i" = indent-for-tab-command + Start point : 403 + Moved to point: 407 + : 18:4: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -15,5 +15,5 @@ + (t-utils-xr-print-code (point) (re-search-forward "end")) + ) + %} +- ++ + end + #+end_src diff + +- Invoking : (insert "if (a > 1 && ...") + Start point : 407 + Moved to point: 423 + : 18:20: if (a > 1 && ... + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -15,5 +15,5 @@ + (t-utils-xr-print-code (point) (re-search-forward "end")) + ) + %} +- ++ if (a > 1 && ... + end + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 423 + Moved to point: 432 + : 19:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -16,4 +16,7 @@ + ) + %} + if (a > 1 && ... ++ ++ end ++ + end + #+end_src diff + +- Invoking : (insert "a < 10)") + Start point : 432 + Moved to point: 439 + : 19:15: a < 10) + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -16,7 +16,7 @@ + ) + %} + if (a > 1 && ... +- ++ a < 10) + end + + end + #+end_src diff + +- Invoking : "C-m" = newline + Start point : 439 + Moved to point: 448 + : 20:8: + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -17,6 +17,7 @@ + %} + if (a > 1 && ... + a < 10) ++ + end + + end + #+end_src diff + +- Invoking : (insert "disp('a > 1 && a < 10')") + Start point : 448 + Moved to point: 471 + : 20:31: disp('a > 1 && a < 10') + : ^ + Buffer modified: + #+begin_src diff +--- start_contents ++++ end_contents +@@ -17,7 +17,7 @@ + %} + if (a > 1 && ... + a < 10) +- ++ disp('a > 1 && a < 10') + end + + end + #+end_src diff + +- Invoking : (re-search-backward "^ if") + Start point : 471 + Moved to point: 403 + : 18:0: if (a > 1 && ... + : ^ + No buffer modifications + +- Invoking : (t-utils-xr-print-code (point) (re-search-forward "end")) + Start point : 403 + Moved to point: 479 + : 21:7: end + : ^ + standard-output: + #+begin_src matlab-ts + if (a > 1 && ... + a < 10) + disp('a > 1 && a < 10') + end + #+end_src + No buffer modifications diff --git a/tests/test-matlab-ts-mode-electric-ends.el b/tests/test-matlab-ts-mode-electric-ends.el new file mode 100644 index 0000000000..0256585782 --- /dev/null +++ b/tests/test-matlab-ts-mode-electric-ends.el @@ -0,0 +1,72 @@ +;;; test-matlab-ts-mode-electric-ends.el --- -*- lexical-binding: t -*- +;; +;; Copyright 2025 Free Software Foundation, Inc. +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; + +;;; Commentary: +;; +;; Validate matlab-ts-mode indent. +;; Load ../matlab-ts-mode.el via require and run indent tests using +;; ./test-matlab-ts-mode-electric-ends-files/NAME.m comparing against +;; ./test-matlab-ts-mode-electric-ends-files/NAME_expected.org +;; + +;;; Code: + +(require 't-utils) +(require 'matlab-ts-mode) + +(defvar test-matlab-ts-mode-electric-ends--file nil) + +(defun test-matlab-ts-mode-electric-ends--file (m-file) + "Test an individual M-FILE. +This is provided for debugging. + M-: (test-matlab-ts-mode-electric-ends--file + \"test-matlab-ts-mode-electric-ends-files/M-FILE\")" + (let ((test-matlab-ts-mode-electric-ends--file m-file)) + (ert-run-tests-interactively "test-matlab-ts-mode-electric-ends"))) + +(ert-deftest test-matlab-ts-mode-electric-ends () + "Test electric ends using ./test-matlab-ts-mode-electric-ends-files/NAME.m. +Using ./test-matlab-ts-mode-electric-ends-files/NAME.m, +exercise `matlab-ts-mode-electric-ends' automatic insertion +of ends by looping over the + ./test-matlab-ts-mode-electric-ends-files/NAME.m files +which insert statements that cause `matlab-ts-mode-electric-ends' to +insert end keywords. The results are compared against baseline: + ./test-matlab-ts-mode-electric-ends-files/NAME_expected.org + +To add a test, create + ./test-matlab-ts-mode-electric-ends-files/NAME.m +and run this function. The baseline is saved for you as + ./test-matlab-ts-mode-electric-ends-files/NAME_expected.org~ +after validating it, rename it to + ./test-matlab-ts-mode-electric-ends-files/NAME_expected.org" + + (let* ((test-name "test-matlab-ts-mode-electric-ends") + (m-files (t-utils-get-files + test-name + (rx ".m" eos) + nil + test-matlab-ts-mode-electric-ends--file))) + (t-utils-error-if-no-treesit-for 'matlab test-name) + (t-utils-test-xr test-name m-files))) + +(provide 'test-matlab-ts-mode-electric-ends) +;;; test-matlab-ts-mode-electric-ends.el ends here + +;; LocalWords: utils defun eos treesit xr