branch: externals/matlab-mode
commit f744cc2bd2fa2b8402a5d3d4229274304033a1d5
Author: John Ciolfi <john.ciolfi...@gmail.com>
Commit: John Ciolfi <john.ciolfi...@gmail.com>

    matlab-sections: display message when running sections
    
    Also add help on sections.
---
 README.org                   | 14 ++--------
 doc/matlab-code-sections.org | 66 ++++++++++++++++++++++++++++++++++++++++++++
 matlab-sections.el           | 43 +++++++++++++++++++++++------
 matlab.el                    | 10 ++++---
 toolbox/emacsrunregion.m     | 32 +++++++++++++++++----
 5 files changed, 137 insertions(+), 28 deletions(-)

diff --git a/README.org b/README.org
index abd4df2ea0..b1c2b34292 100644
--- a/README.org
+++ b/README.org
@@ -44,21 +44,13 @@
 
    #+end_example
    
-5. *Code sections* support for MATLAB script files. Script files contain one 
or more commands, such
-   as variable assignements, function calls, etc.  Script files differ from 
declaration files such
-   as those declaring function's or classdef's.  You typically focus your 
efforts on a single part
-   of your code at a time, working with the code and related text in sections. 
 You demarcate
-   sections using /"%% description"/ header comments.
+5. *Code sections* support for MATLAB script files. See 
[[file:doc/matlab-code-sections.org][doc/matlab-code-sections.org]].
 
-   - After visiting a MATLAB script, you have the *"MATLAB -> Code Sections"* 
menu and key
-     bindings which lets you can navigate, run, and move code sections.
+   - After visiting a MATLAB script, you have a *"MATLAB -> Code Sections"* 
menu and key bindings
+     which lets you navigate, run, and move code sections.
 
    - Try out code sections using: 
[[file:examples/matlab-sections/tryout_matlabsection.m][./examples/matlab-sections/tryout_matlabsection.m]].
 
-   - The default keybindings for code sections are ~C-c C-<KEY>~ and ~C-c 
M-<KEY>~. You can add
-     super key bindings for code sections. After visiting a file.m, see menu 
*"MATLAB -> Code
-     Sections -> Help"*.
-
 6. *Creation of scientific papers, theses, and documents* using MATLAB and 
[[http://orgmode.org]].
 
    - Org enables 
[[https://en.wikipedia.org/wiki/Literate_programming][literate programming]] 
which directly supports reproducible research by allowing
diff --git a/doc/matlab-code-sections.org b/doc/matlab-code-sections.org
new file mode 100644
index 0000000000..8524367862
--- /dev/null
+++ b/doc/matlab-code-sections.org
@@ -0,0 +1,66 @@
+# File: doc/matlab-code-sections.org
+
+#+startup: showall
+#+options: toc:nil
+
+# Copyright 2025 Free Software Foundation, Inc.
+
+* MATLAB Code Sections in Script *.m Files
+
+MATLAB script files contain one or more commands, such as variable 
assignments, function calls, etc.
+Script files differ from declaration files such as those declaring function's 
or classdef's.  When
+working with script files, you typically focus your efforts on a single part 
of your code at a time,
+working with the code and related text in sections.  You demarcate sections 
using /"%% description"/
+header comments.
+
+An example of a script file is ~basic_script.m~:
+
+#+begin_src matlab
+  %% First section
+
+  a = 1;
+  b = 2;
+
+  %% Second section
+
+  c = a + b;
+  disp(['c = ', num2str(c)]);
+#+end_src
+
+When you visit a script.m file, you will have a *MATLAB -> Code Sections* 
menu.  Help from within
+Emacs is available from *"MATLAB -> Code Sections -> Help"* menu item.  You 
can use the menu or key
+bindings to modify or run your script.
+
+#+begin_example
+  C-c C-SPC        Mark/select section.
+
+  C-c C-<up>       Move point backward to the prior "% section"
+  C-c C-<down>     Move point forward to the next "% section"
+  C-c C-<left>     Move point to the beginning of the current "%% section"
+  C-c C-<right>    Move point to the end of the current "%% section"
+
+  C-c M-<up>       Move the current "%% section" up
+  C-c M-<down>     Move the current "%% section" down
+
+  C-c C-<return>   Run the current "%% section"
+  C-c M-<return>   Run all "%% sections" prior to the current section
+#+end_example
+
+Sections are run using the =*MATLAB*= shell buffer created using =M-x 
matlab-shell= on Unix and the
+attached MATLAB using the [[file:matlab-netshell-for-windows.org][matlab 
netshell on Windows]]. When a section is run, you will see in the
+MATLAB Command Window:
+
+#+begin_example
+  emacsrunregion('/path/to/your/script.m', startChar, endChar)
+
+  <text displayed by your script.m>
+#+end_example
+
+The sections are run asynchronously. After sending the emacsrunregion command 
to MATLAB, control is
+returned to Emacs.  In MATLAB, you'll see the ">>" prompt reappear when 
emacsrunregion is complete.
+
+** Customizations
+
+If you'd like to use super (aka Windows) key bindings instead of the above key 
bindings, you can
+
+ : M-x customize-variable RET matlab-sections-use-super-key RET
diff --git a/matlab-sections.el b/matlab-sections.el
index 2be88ba82d..ed88dfe8fe 100644
--- a/matlab-sections.el
+++ b/matlab-sections.el
@@ -132,6 +132,25 @@ the command `matlab-sections-minor-mode' to turn 
matlab-sections mode on."
 
 ;; Function to obtain range of current code section
 
+(defun matlab-sections--get-heading (&optional range)
+  "Return the \"%% descrition\" heading or nil if not in a code section.
+RANGE is (START-PT . END-PT) of the section or nil.  If nil, we'll
+determine the RANGE."
+  (when (not range)
+    (setq range (matlab-sections-range-function)))
+  (save-excursion
+    (save-restriction
+      (widen)
+      (goto-char (car range))
+      (when (not (looking-at "^[[:blank:]]*%%[[:blank:]]*\\(.*\\)$"))
+        (error "Assert - failed to match section heading at point %S" (point)))
+      (let ((heading (string-trim (match-string-no-properties 1))))
+        (when (string= heading "")
+          (setq heading "Empty section heading"))
+        (setq heading (concat heading (format " (line %d)"
+                                              (line-number-at-pos)))))
+      )))
+
 (defun matlab-sections-range-function ()
   "Return range (START-PT . END-PT) of current MATLAB code section.
 nil is returned if there is no code section."
@@ -293,11 +312,14 @@ Return `point'."
   "Run the current \"%% section\" in `matlab-shell'."
   (interactive)
   (let ((rng (matlab-sections-range-function)))
-    (save-excursion
-      (save-restriction
-        (widen)
-        (save-window-excursion
-          (matlab-shell-run-region (car rng) (cdr rng)))))))
+    (if rng
+        (save-excursion
+          (save-restriction
+            (widen)
+            (save-window-excursion
+              (message "Running section: %s" (matlab-sections--get-heading 
rng))
+              (matlab-shell-run-region (car rng) (cdr rng)))))
+      (message "Not in a \"%% code section\""))))
 
 (define-obsolete-function-alias 'matlab-sections-run-till-point
   #'matlab-sections-run-prior-sections "6.3")
@@ -312,9 +334,14 @@ Does not run the section the point is in."
       (let ((current-section-start-point 
(matlab-sections-beginning-of-section)))
         (goto-char (point-min))
         (matlab-sections-beginning-of-section)
-        (when (< (point) current-section-start-point)
-          (save-window-excursion
-            (matlab-shell-run-region (point) current-section-start-point)))))))
+        (if (< (point) current-section-start-point)
+            (progn
+              (save-excursion
+                (goto-char current-section-start-point)
+                (message "Running sections prior to: %s" 
(matlab-sections--get-heading)))
+              (save-window-excursion
+                (matlab-shell-run-region (point) current-section-start-point)))
+          (message "No prior \"%% code sections\""))))))
 
 (declare-function matlab-mode "matlab.el")
 
diff --git a/matlab.el b/matlab.el
index dd8235b9b4..3b73f54775 100644
--- a/matlab.el
+++ b/matlab.el
@@ -602,16 +602,18 @@ point, but it will be restored for them."
     ("Code Sections"
      ["Run section" matlab-sections-run-section
       :active matlab-sections-minor-mode
-      :help "Run the current \"%% section\" in `matlab-shell'."]
+      :help "Run the current \"%% section\" in
+matlab-shell (Unix) or matlab-netshell (Windows)"]
      ["Run prior sections" matlab-sections-run-prior-sections
       :active matlab-sections-minor-mode
-      :help "Run all \"%% sections\" prior to the current section in 
`matlab-shell'"]
+      :help "Run all \"%% sections\" prior to the current section in
+matlab-shell (Unix) or matlab-netshell (Windows)"]
      ["Move to beginning" matlab-sections-beginning-of-section
       :active matlab-sections-minor-mode
-      :help "Move `point' to the beginning of the current \"%% section\""]
+      :help "Move point to the beginning of the current \"%% section\""]
      ["Move to end" matlab-sections-end-of-section
       :active matlab-sections-minor-mode
-      :help "Move `point' to the end of the current \"%% section\""]
+      :help "Move point to the end of the current \"%% section\""]
      ["Backward section" matlab-sections-backward-section
       :active matlab-sections-minor-mode
       :help "Move point backward to the prior \"%% section\""]
diff --git a/toolbox/emacsrunregion.m b/toolbox/emacsrunregion.m
index cce7e2d1ee..5517cd8f81 100644
--- a/toolbox/emacsrunregion.m
+++ b/toolbox/emacsrunregion.m
@@ -25,7 +25,7 @@ function emacsrunregion(file, startchar, endchar)
     end
 
     % Now figure out if shortFileName is on the path.
-    [ fullFilePath, shortFileName ] = fileparts(file);
+    [fullFilePath, shortFileName, extension] = fileparts(file);
     onpath = ~isempty(which(shortFileName));
 
     % If not on the path, temporarily switch to that directory so it and an 
files it references are
@@ -36,9 +36,31 @@ function emacsrunregion(file, startchar, endchar)
         cleanup = onCleanup(@()cd(oldpath));
     end
 
-    txt = fileread(file);
-    evalTxt = txt(startchar:min(endchar,length(txt)));
-    evalin('base',evalTxt);
+    fileContents = fileread(file);
+
+    endchar = min(endchar, length(fileContents));
+    evalTxt = fileContents(startchar:endchar);
+    evalin('base', evalTxt);
+
+    % See if startchar and endchar are on the first column of a lines and if 
so display that. Note,
+    % fileContents can contain POSIX newlines (LF) or be Windows CRFL (13, 10) 
line endings.
+    if (startchar == 1 || fileContents(startchar-1) == newline) && ...
+            regexp(fileContents(endchar), '[\r\n]', 'once')
+        startLineNum = length(strfind(fileContents(1:startchar), newline)) + 1;
+        endLineNum = length(strfind(fileContents(1:endchar), newline));
+        if fileContents(endchar) == 13 || endchar == length(fileContents)
+            % Looking at CR or end-of-file
+            endLineNum = endLineNum + 1;
+        end
+
+        regionInfo = sprintf('lines %d to %d', startLineNum, endLineNum);
+    else
+        regionInfo = sprintf('chars %d to %d', startchar, endchar);
+    end
+
+    % TODO - enable this display after updating tests to pass on Unix.
+    % fprintf(1, 'emacsrunregion: finished running %s%s %s\n', ...
+    %         shortFileName, extension, regionInfo);
 end
 
-% LocalWords:  Ludlam STARTCHAR ENDCHAR
+% LocalWords:  STARTCHAR ENDCHAR

Reply via email to