branch: externals/matlab-mode
commit 3de24154f09854745a1ba415e74497b36900a645
Author: John Ciolfi <[email protected]>
Commit: John Ciolfi <[email protected]>
matlab-ts-mode: improve beginning of command, end of command
---
matlab-ts-mode.el | 147 +++++++++++++--------
.../movement_statements.m | 13 ++
.../movement_statements_expected.org | 117 ++++++++++++++++
3 files changed, 223 insertions(+), 54 deletions(-)
diff --git a/matlab-ts-mode.el b/matlab-ts-mode.el
index baf5cb697e..bc674f8550 100644
--- a/matlab-ts-mode.el
+++ b/matlab-ts-mode.el
@@ -255,8 +255,9 @@ content can crash Emacs via the matlab tree-sitter parser."
(when bad-char-point
(fundamental-mode)
(goto-char bad-char-point)
- (user-error "Not entering matlab-ts-mode due to non-printable utf8
character \"%c\" at point %d"
- (char-before) bad-char-point ))))
+ (user-error
+ "Not entering matlab-ts-mode due to non-printable utf8 character \"%c\"
at point %d"
+ (char-before) bad-char-point ))))
;;; Syntax table
@@ -713,7 +714,8 @@ Example, disp variable is overriding the disp builtin
function:
;; F-Rule: Constant literal numbers, e.g. 1234, 12.34, 10e10
;; We could use this for items like true, false, pi, etc. See some of these
numbers in:
- ;;
https://www.mathworks.com/content/dam/mathworks/fact-sheet/matlab-basic-functions-reference.pdf
+ ;; https://www.mathworks.com/content/dam/mathworks/fact-sheet/
+ ;; matlab-basic-functions-reference.pdf
;; however, they do show up as builtins, which to me seems more accurate.
;; This rule needs to come before the "F-Rule: keywords: if, else, end,
etc." because
;; we want the end_keyword when used as a number index into a cell/matrix
to be a number font.
@@ -918,7 +920,6 @@ Example, disp variable is overriding the disp builtin
function:
)
"The matlab-ts-mode font-lock settings.")
-
;;; Indent
;; MATLAB Indent Standard
@@ -2290,7 +2291,6 @@ Example:
eos))
parent ,matlab-ts-mode--indent-level)
-
;; I-Rule: case 10<RET>
((n-p-gp nil ,(rx bos "\n" eos) ,(rx bos (or "switch_statement"
"case_clause"
"otherwise_clause")
@@ -2405,7 +2405,9 @@ Example:
;; I-Rule: someNamespace1.subNamespace2.myFunction( ...
;; TAB> a, ... % comment for param1
;; See:
tests/test-matlab-ts-mode-indent-files/indent_namespace_fcn_continued.m
- ((n-p-gp ,(rx bos "arguments" eos) ,(rx bos "function_call" eos) ,(rx bos
"field_expression" eos))
+ ((n-p-gp ,(rx bos "arguments" eos)
+ ,(rx bos "function_call" eos)
+ ,(rx bos "field_expression" eos))
grand-parent ,matlab-ts-mode--indent-level)
;; I-Rule: my_function( ...
@@ -2481,7 +2483,6 @@ Example:
;;; Thing settings for movement, etc.
-
(defvar matlab-ts-mode--statements-type-re
(rx (seq
bos
@@ -2505,14 +2506,17 @@ Example:
eos))
"MATLAB command statements.")
-(cl-defun matlab-ts-mode-beginning-of-statement (&optional goto-end
statement-type-re)
+(cl-defun matlab-ts-mode-beginning-of-statement (&optional
+ goto-end statement-type-re
+ find-outermost-statement
+ no-message)
"Move to the beginning of a statement.
If optional GOTO-END is \\='end, move to end of the current statement.
We define a command statement to be a complete syntactic unit that has
a start and end. For example, if point is in an assignment statement
var = ...
- 1;
+ 1;
move point to the \"v\" when GOTO-END is nil, otherwise move to the
point after \";\". Likewise for other command statements.
@@ -2531,9 +2535,18 @@ current assignment statement, use
If STATEMENT-TYPE-RE is not specified, `matlab-ts-mode--statements-type-re'
is used.
-Returns nil if not in a statement, otherwise the `point' which
-will be a new point if the starting point was not at the start
-or end of the command statement."
+Optional FIND-OUTERMOST-STATEMENT, if t locates the outermost statement.
+For example, if point is on the 11 below will move to the beginning of
+the assignment and not the inner function_call statement.
+
+ var = ...
+ fun(11, ...
+ 22);
+
+Optional NO-MESSAGE if non-nil will prevent messages from being displayed.
+
+Returns nil if not in a statement, otherwise the anchor node
+used to do the movement."
(interactive)
(cl-assert (or (not goto-end) (eq goto-end 'end)))
@@ -2542,52 +2555,68 @@ or end of the command statement."
(setq statement-type-re matlab-ts-mode--statements-type-re))
(let ((start-point (point))
- (node (treesit-node-at (point))))
+ (search-node (treesit-node-at (point)))
+ statement-node)
;; When on a newline, back up to prior statement
(when (and (> (point) 1)
- (equal (treesit-node-type node) "\n")
+ (equal (treesit-node-type search-node) "\n")
(re-search-backward "[^ \t\n\r]" nil t))
- (setq node (treesit-node-at (point))))
+ (setq search-node (treesit-node-at (point))))
;; When at ";" use prev-sibling
- (when (equal (treesit-node-type node) ";")
- (setq node (treesit-node-prev-sibling node)))
+ (when (equal (treesit-node-type search-node) ";")
+ (setq search-node (treesit-node-prev-sibling search-node)))
;; find nearest ancestor that matches statement-type-re
- (while (and node
- (let ((type (treesit-node-type node)))
- (when (equal type "ERROR")
- ;; No movement if we have a syntax error
- (message "Not in statement due to syntax error.")
- (cl-return-from matlab-ts-mode-beginning-of-statement))
- (not (string-match-p statement-type-re type))))
- (setq node (treesit-node-parent node)))
-
- (when (not node)
- (message "Not in a statement")
+ (while search-node
+
+ ;; Find inner statement node
+ (while (and search-node
+ (let ((type (treesit-node-type search-node)))
+ (when (equal type "ERROR")
+ ;; No movement if we have a syntax error
+ (unless no-message
+ (message "Not in statement due to syntax error"))
+ (cl-return-from matlab-ts-mode-beginning-of-statement))
+ (not (string-match-p statement-type-re type))))
+ (setq search-node (treesit-node-parent search-node)))
+
+ (when search-node
+ (setq statement-node search-node)
+ (if find-outermost-statement
+ (setq search-node (treesit-node-parent search-node))
+ (setq search-node nil))))
+
+ (when (not statement-node)
+ (unless no-message
+ (message "Not in a statement"))
(cl-return-from matlab-ts-mode-beginning-of-statement))
- (when node
- (let* ((statement-start-point (treesit-node-start node))
- (end-node (or
- ;; Use next sibling node if it's a ";" for the an
- ;; assignment or function_call.
- (and (string-match-p (rx (seq bos (or "assignment"
- "function_call")
- eos))
- (treesit-node-type node))
- (let ((next-node (treesit-node-next-sibling
node)))
- (when (and next-node
- (string= ";" (treesit-node-type
next-node)))
- next-node)))
- node))
- (statement-end-point (treesit-node-end end-node)))
- (when (and (>= start-point statement-start-point)
- (<= start-point statement-end-point))
- (goto-char (if (eq goto-end 'end)
- statement-end-point
- statement-start-point)))))))
+ (let* ((statement-start-point (treesit-node-start statement-node))
+ (end-node (or
+ ;; Use next sibling node if it's a ";" for the an
+ ;; assignment or function_call.
+ (and (string-match-p (rx (seq bos (or "assignment"
+ "function_call"
+ "field_expression")
+ eos))
+ (treesit-node-type statement-node))
+ (let ((next-node (treesit-node-next-sibling
statement-node)))
+ (when (and next-node
+ (string= ";" (treesit-node-type
next-node)))
+ next-node)))
+ statement-node))
+ (statement-end-point (treesit-node-end end-node)))
+ (when (and (>= start-point statement-start-point)
+ (<= start-point statement-end-point))
+ (cond
+ ((eq goto-end 'end)
+ (goto-char statement-end-point)
+ end-node)
+ (t
+ (goto-char statement-start-point)
+ statement-node))))))
(defun matlab-ts-mode-end-of-statement (&optional statement-type)
"Move to the end of a command statement.
@@ -2597,15 +2626,21 @@ not specified statement in
`matlab-ts-mode--statements-ht' are used."
(interactive)
(matlab-ts-mode-beginning-of-statement 'end statement-type))
+;; TODO - use these for M-a, M-e?
+
(defun matlab-ts-mode-beginning-of-command ()
"Move to the beginning of the command at point.
Commands are either assignment or function_call statements that can be
evaluated at the matlab prompt. Movement occurs only if the point is in
an assignment or function call. Note array indexing is considered a
function call."
- (matlab-ts-mode-beginning-of-statement nil (rx (seq bos (or "assignment"
- "function_call")
- eos))))
+ (when (matlab-ts-mode-beginning-of-statement nil
+ (rx (seq bos (or "assignment"
+ "function_call"
+
"field_expression")
+ eos))
+ t)
+ (point)))
(defun matlab-ts-mode-end-of-command ()
"Move to the end of the command at point.
@@ -2613,9 +2648,13 @@ Commands are either assignment or function_call
statements that can be
evaluated at the matlab prompt. Movement occurs only if the point is in
an assignment or function call. Note array indexing is considered a
function call."
- (matlab-ts-mode-beginning-of-statement 'end (rx (seq bos (or "assignment"
- "function_call")
- eos))))
+ (when (matlab-ts-mode-beginning-of-statement 'end
+ (rx (seq bos (or "assignment"
+ "function_call"
+
"field_expression")
+ eos))
+ t)
+ (point)))
;; matlab-ts-mode--thing-settings used for:
;; C-M-a - M-x beginning-of-defun
diff --git a/tests/test-matlab-ts-mode-movement-files/movement_statements.m
b/tests/test-matlab-ts-mode-movement-files/movement_statements.m
index 3395e13ef9..44109db676 100644
--- a/tests/test-matlab-ts-mode-movement-files/movement_statements.m
+++ b/tests/test-matlab-ts-mode-movement-files/movement_statements.m
@@ -19,4 +19,17 @@ v=1:10;
% Case5: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
v(2:3)
+% Case6: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
+dependencies.internal.widget.foobar( ...
+ this.UniqueName);
+
+% Case7: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
+this.foo3 = 1 + dependencies.internal.widget.someFunction( ...
+ this.UniqueName2);
+
+% Case8: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
+this.foo3 = 1 + dependencies.internal.widget.someFunction2( ...
+ a + foo(1 + 2 + ...
+ 3) + ...
+ this.UniqueName3);
diff --git
a/tests/test-matlab-ts-mode-movement-files/movement_statements_expected.org
b/tests/test-matlab-ts-mode-movement-files/movement_statements_expected.org
index 603e88c481..37dadb3b62 100644
--- a/tests/test-matlab-ts-mode-movement-files/movement_statements_expected.org
+++ b/tests/test-matlab-ts-mode-movement-files/movement_statements_expected.org
@@ -233,3 +233,120 @@
: 20:6: v(2:3)
: ^
No buffer modifications
+
+* Executing commands from movement_statements.m:22:9:
+
+ Case6: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
+
+- Invoking : "C-n" = next-line
+ Start point : 881
+ Moved to point: 922
+ : 23:40: dependencies.internal.widget.foobar( ...
+ : ^
+ No buffer modifications
+
+- Invoking : "C-a" = move-beginning-of-line
+ Start point : 922
+ Moved to point: 882
+ : 23:0: dependencies.internal.widget.foobar( ...
+ : ^
+ No buffer modifications
+
+- Invoking : "C-f" = forward-char
+ Start point : 882
+ Moved to point: 883
+ : 23:1: dependencies.internal.widget.foobar( ...
+ : ^
+ No buffer modifications
+
+- Invoking : (matlab-ts-mode-beginning-of-command)
+ Start point : 883
+ Moved to point: 882
+ : 23:0: dependencies.internal.widget.foobar( ...
+ : ^
+ No buffer modifications
+
+- Invoking : (matlab-ts-mode-end-of-command)
+ Start point : 882
+ Moved to point: 944
+ : 24:21: this.UniqueName);
+ : ^
+ No buffer modifications
+
+* Executing commands from movement_statements.m:26:9:
+
+ Case7: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
+
+- Invoking : "C-n" = next-line
+ Start point : 1055
+ Moved to point: 1118
+ : 27:62: this.foo3 = 1 + dependencies.internal.widget.someFunction( ...
+ : ^
+ No buffer modifications
+
+- Invoking : "C-a" = move-beginning-of-line
+ Start point : 1118
+ Moved to point: 1056
+ : 27:0: this.foo3 = 1 + dependencies.internal.widget.someFunction( ...
+ : ^
+ No buffer modifications
+
+- Invoking : "C-f" = forward-char
+ Start point : 1056
+ Moved to point: 1057
+ : 27:1: this.foo3 = 1 + dependencies.internal.widget.someFunction( ...
+ : ^
+ No buffer modifications
+
+- Invoking : (matlab-ts-mode-beginning-of-command)
+ Start point : 1057
+ Moved to point: 1056
+ : 27:0: this.foo3 = 1 + dependencies.internal.widget.someFunction( ...
+ : ^
+ No buffer modifications
+
+- Invoking : (matlab-ts-mode-end-of-command)
+ Start point : 1056
+ Moved to point: 1141
+ : 28:22: this.UniqueName2);
+ : ^
+ No buffer modifications
+
+* Executing commands from movement_statements.m:30:9:
+
+ Case8: (t-utils-xr "C-n" "C-a" "C-f" (matlab-ts-mode-beginning-of-command)
(matlab-ts-mode-end-of-command))
+
+- Invoking : "C-n" = next-line
+ Start point : 1252
+ Moved to point: 1316
+ : 31:63: this.foo3 = 1 + dependencies.internal.widget.someFunction2( ...
+ : ^
+ No buffer modifications
+
+- Invoking : "C-a" = move-beginning-of-line
+ Start point : 1316
+ Moved to point: 1253
+ : 31:0: this.foo3 = 1 + dependencies.internal.widget.someFunction2( ...
+ : ^
+ No buffer modifications
+
+- Invoking : "C-f" = forward-char
+ Start point : 1253
+ Moved to point: 1254
+ : 31:1: this.foo3 = 1 + dependencies.internal.widget.someFunction2( ...
+ : ^
+ No buffer modifications
+
+- Invoking : (matlab-ts-mode-beginning-of-command)
+ Start point : 1254
+ Moved to point: 1253
+ : 31:0: this.foo3 = 1 + dependencies.internal.widget.someFunction2( ...
+ : ^
+ No buffer modifications
+
+- Invoking : (matlab-ts-mode-end-of-command)
+ Start point : 1253
+ Moved to point: 1384
+ : 34:22: this.UniqueName3);
+ : ^
+ No buffer modifications