Support running a cell from script w/ local functions.
matlab-shell.el: (gud-matlab-marker-regexp-plain-prompt): New regexp. (matlab-shell-prompt-appears-hook): New hook (used below) (gud-matlab-marker-filter): When returning output, if a prompt is included, call the matlab-shell-prompt-appears-hook. (matlab-shell-run-cell, matlab-shell-run-region-or-line): Move (matlab-shell-run-region): Extract inline code to find 'command' to new fcn. (matlab-shell-region-command): Function to extract code to run as cmd. (matlab-shell-region->commandline): Copy from run-region as new fcn. Fix up to better clean up blank lines, and excessive whitespace. (matlab-shell-extract-region-to-tmp-file): NEW. This is like region->commandline but puts content into a speicially named m file. If any functions are needed from the script, pull those along. (matlab-shell-cleanup-extracted-region): Delete files created by above. Called from the new hook.
This commit is contained in:
parent
1734085cbc
commit
1ff16e4ade
1 changed files with 186 additions and 60 deletions
246
matlab-shell.el
246
matlab-shell.el
|
@ -118,7 +118,6 @@ When nil, complete against file names."
|
|||
:group 'matlab-shell
|
||||
:type 'boolean)
|
||||
|
||||
|
||||
;;; Font Lock
|
||||
;;
|
||||
;; Extra font lock keywords for the MATLAB shell.
|
||||
|
@ -646,6 +645,9 @@ Argument STR is the text that might have errors in it."
|
|||
;; MATLAB's process filter handles output from the MATLAB process and
|
||||
;; inteprets it for formatting text, and for running the debugger.
|
||||
|
||||
(defvar gud-matlab-marker-regexp-plain-prompt "^K?>>"
|
||||
"Regular expression for finding a prompt.")
|
||||
|
||||
(defvar gud-matlab-marker-regexp-1 "^K>>"
|
||||
"Regular expression for finding a file line-number.")
|
||||
|
||||
|
@ -680,6 +682,10 @@ FILE is ignored, and ARGS is returned."
|
|||
(gud-make-debug-menu))
|
||||
buf)))
|
||||
|
||||
(defvar matlab-shell-prompt-appears-hook nil
|
||||
"Hooks run each time a prompt is seen and sent to display.
|
||||
If multiple prompts are seen together, only call this once.")
|
||||
|
||||
(defun gud-matlab-marker-filter (string)
|
||||
"Filters STRING for the Unified Debugger based on MATLAB output."
|
||||
(if matlab-prompt-seen
|
||||
|
@ -716,8 +722,7 @@ FILE is ignored, and ARGS is returned."
|
|||
(let ((output "") (frame nil))
|
||||
|
||||
(when (string-match gud-matlab-marker-regexp-1 gud-marker-acc)
|
||||
;; If there is a debug prompt, and no frame currently set,
|
||||
;; go find one.
|
||||
;; Look for any frames for case of a debug prompt.
|
||||
(let ((url gud-marker-acc)
|
||||
ef el)
|
||||
(cond
|
||||
|
@ -815,6 +820,15 @@ FILE is ignored, and ARGS is returned."
|
|||
(if frame (setq gud-last-frame frame))
|
||||
|
||||
;;(message "[%s] [%s]" output gud-marker-acc)
|
||||
|
||||
;; (string-match gud-matlab-marker-regexp-plain-prompt ">>")
|
||||
|
||||
(when (string-match gud-matlab-marker-regexp-plain-prompt output)
|
||||
;; Now that we are about to dump this, run our prompt hook.
|
||||
;;(message "PROMPT!")
|
||||
(run-hooks 'matlab-shell-prompt-appears-hook)
|
||||
)
|
||||
|
||||
|
||||
output))
|
||||
|
||||
|
@ -1674,63 +1688,9 @@ Similar to `comint-send-input'."
|
|||
(matlab-shell-add-to-input-history cmd)
|
||||
(matlab-shell-send-string (concat cmd "\n"))))))
|
||||
|
||||
(defun matlab-shell-run-region (beg end &optional noshow)
|
||||
"Run region from BEG to END and display result in MATLAB shell.
|
||||
If NOSHOW is non-nil, replace newlines with commas to suppress output.
|
||||
This command requires an active MATLAB shell."
|
||||
(interactive "r")
|
||||
(if (> beg end) (let (mid) (setq mid beg beg end end mid)))
|
||||
|
||||
(let ((command
|
||||
(let ((str (concat (buffer-substring beg end) "\n")))
|
||||
;; Remove comments
|
||||
(with-temp-buffer
|
||||
(insert str)
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "%" nil t)
|
||||
(when (not (matlab-cursor-in-string))
|
||||
(delete-region (1- (point)) (matlab-point-at-eol))))
|
||||
(setq str (buffer-substring-no-properties (point-min) (point-max))))
|
||||
(while (string-match "\n\\s-*\n" str)
|
||||
(setq str (concat (substring str 0 (match-beginning 0))
|
||||
"\n"
|
||||
(substring str (match-end 0)))))
|
||||
(when noshow
|
||||
;; Remove continuations
|
||||
(while (string-match
|
||||
(concat "\\s-*"
|
||||
(regexp-quote matlab-elipsis-string)
|
||||
"\\s-*\n")
|
||||
str)
|
||||
(setq str (replace-match " " t t str)))
|
||||
(while (string-match "\n" str)
|
||||
(setq str (replace-match ", " t t str)))
|
||||
(setq str (concat str "\n")))
|
||||
str))
|
||||
(msbn nil)
|
||||
(lastcmd)
|
||||
(inhibit-field-text-motion t))
|
||||
(if (matlab-with-emacs-link)
|
||||
;; Run the region w/ Emacs Link
|
||||
(when (fboundp 'matlab-eei-eval-region) (matlab-eei-eval-region beg end))
|
||||
|
||||
(save-excursion
|
||||
(setq msbn (matlab-shell-buffer-barf-not-running))
|
||||
(set-buffer msbn)
|
||||
(if (not (matlab-on-prompt-p))
|
||||
(error "MATLAB shell must be non-busy to do that"))
|
||||
;; Save the old command
|
||||
(beginning-of-line)
|
||||
(re-search-forward comint-prompt-regexp)
|
||||
(setq lastcmd (buffer-substring (point) (matlab-point-at-eol)))
|
||||
(delete-region (point) (matlab-point-at-eol))
|
||||
;; We are done error checking, run the command.
|
||||
(matlab-shell-send-string command)
|
||||
(insert lastcmd))
|
||||
(set-buffer msbn)
|
||||
(goto-char (point-max))
|
||||
(display-buffer msbn nil "visible"))
|
||||
))
|
||||
;;; Running buffer subset
|
||||
;;
|
||||
;; Run some subset of the buffer in matlab-shell.
|
||||
|
||||
(defun matlab-shell-run-cell ()
|
||||
"Run the cell the cursor is in."
|
||||
|
@ -1761,6 +1721,172 @@ This command requires an active MATLAB shell."
|
|||
(matlab-shell-run-region (matlab-point-at-bol) (matlab-point-at-eol))))
|
||||
|
||||
|
||||
(defun matlab-shell-run-region (beg end &optional noshow)
|
||||
"Run region from BEG to END and display result in MATLAB shell.
|
||||
If NOSHOW is non-nil, replace newlines with commas to suppress output.
|
||||
This command requires an active MATLAB shell."
|
||||
(interactive "r")
|
||||
(if (> beg end) (let (mid) (setq mid beg beg end end mid)))
|
||||
|
||||
(let ((command (matlab-shell-region-command beg end noshow))
|
||||
(msbn nil)
|
||||
(lastcmd)
|
||||
(inhibit-field-text-motion t))
|
||||
(if (matlab-with-emacs-link)
|
||||
;; Run the region w/ Emacs Link
|
||||
(when (fboundp 'matlab-eei-eval-region) (matlab-eei-eval-region beg end))
|
||||
|
||||
(save-excursion
|
||||
(setq msbn (matlab-shell-buffer-barf-not-running))
|
||||
(set-buffer msbn)
|
||||
(if (not (matlab-on-prompt-p))
|
||||
(error "MATLAB shell must be non-busy to do that"))
|
||||
;; Save the old command
|
||||
(beginning-of-line)
|
||||
(re-search-forward comint-prompt-regexp)
|
||||
(setq lastcmd (buffer-substring (point) (matlab-point-at-eol)))
|
||||
(delete-region (point) (matlab-point-at-eol))
|
||||
;; We are done error checking, run the command.
|
||||
(matlab-shell-send-string command)
|
||||
(insert lastcmd))
|
||||
(set-buffer msbn)
|
||||
(goto-char (point-max))
|
||||
(display-buffer msbn nil "visible"))
|
||||
))
|
||||
|
||||
;;; Convert regions to runnable text
|
||||
;;
|
||||
;; There are two techniques.
|
||||
;; Option 1: Convert the region into a single command line, suppress output, and eval.
|
||||
;; Option 2: Copy into a script, and run the script.
|
||||
(defun matlab-shell-region-command (beg end &optional noshow)
|
||||
"Convert the region between BEG and END into a MATLAB command.
|
||||
Picks between different options for running the commands."
|
||||
;; OLD WAY
|
||||
;;(matlab-shell-region->commandline beg end noshow)
|
||||
|
||||
;; NEW WAY
|
||||
(matlab-shell-extract-region-to-tmp-file beg end noshow)
|
||||
|
||||
;; TODO - if we just have a simple line of code, don't extract
|
||||
;; into a new file, just do it. How to decide?
|
||||
)
|
||||
|
||||
(defun matlab-shell-region->commandline (beg end &optional noshow)
|
||||
"Convert the region between BEG and END into a MATLAB command.
|
||||
Squeeze out newlines.
|
||||
When NOSHOW is non-nil, supress output by adding ; to commands."
|
||||
;; Assume beg & end are in the right order.
|
||||
(let ((str (concat (buffer-substring beg end) "\n")))
|
||||
;; Remove comments
|
||||
(with-temp-buffer
|
||||
(insert str)
|
||||
(goto-char (point-min))
|
||||
;; Delete all the comments
|
||||
(while (search-forward "%" nil t)
|
||||
(when (not (matlab-cursor-in-string))
|
||||
(delete-region (1- (point)) (matlab-point-at-eol))))
|
||||
(setq str (buffer-substring-no-properties (point-min) (point-max))))
|
||||
|
||||
;; Strip out blank lines
|
||||
(while (string-match "^\\s-*\n" str)
|
||||
(setq str (concat (substring str 0 (match-beginning 0))
|
||||
(substring str (match-end 0)))))
|
||||
;; Strip out large chunks of whitespace
|
||||
(while (string-match "\\s-\\s-+" str)
|
||||
(setq str (concat (substring str 0 (match-beginning 0))
|
||||
(substring str (match-end 0)))))
|
||||
(when noshow
|
||||
;; Remove continuations
|
||||
(while (string-match
|
||||
(concat "\\s-*"
|
||||
(regexp-quote matlab-elipsis-string)
|
||||
"\\s-*\n")
|
||||
str)
|
||||
(setq str (replace-match " " t t str)))
|
||||
(while (string-match "\n" str)
|
||||
(setq str (replace-match ", " t t str)))
|
||||
(setq str (concat str "\n")))
|
||||
str))
|
||||
|
||||
|
||||
(defun matlab-shell-extract-region-to-tmp-file (beg end &optional noshow)
|
||||
"Extract region between BEG & END into a temporary M file.
|
||||
The tmp file name is based on the name of the current buffer.
|
||||
The extracted region is unmodifed from src buffer unless NOSHOW is non-nil,
|
||||
in which case ; are added to quiece the buffer.
|
||||
Scan the extracted region for any functions that are in the original
|
||||
buffer,and include them.
|
||||
Return the name of the temporary file."
|
||||
(interactive "r")
|
||||
(let* ((start (count-lines (point-min) beg))
|
||||
(len (count-lines beg end))
|
||||
(stem (file-name-sans-extension (file-name-nondirectory
|
||||
(buffer-file-name))))
|
||||
(orig (current-buffer))
|
||||
(newf (concat stem "_" (number-to-string start) "_"
|
||||
(number-to-string len)))
|
||||
(bss (buffer-substring-no-properties beg end))
|
||||
(buff (find-file-noselect (concat newf ".m")))
|
||||
(intro "%% Automatically craeted temporary file created to run-region")
|
||||
;; These variables are for script / fcn tracking
|
||||
(functions (semantic-find-tags-by-class 'function (current-buffer)))
|
||||
)
|
||||
|
||||
;; TODO : if the directory in which the current buffer is in is READ ONLY
|
||||
;; we should write our tmp buffer to /tmp instead.
|
||||
|
||||
(save-excursion
|
||||
|
||||
(set-buffer buff)
|
||||
(goto-char (point-min))
|
||||
|
||||
;; Clean up old extracted regions.
|
||||
(when (looking-at intro) (delete-region (point-min) (point-max)))
|
||||
;; Don't stomp on old code.
|
||||
(when (not (= (point-min) (point-max)))
|
||||
(error "Region extract to tmp file: Temp file not empty!"))
|
||||
|
||||
(insert intro "\n\n" bss "\n%%\n")
|
||||
|
||||
;; Some scripts call local functions from the script. Find them
|
||||
;; and copy those local scripts over.
|
||||
(goto-char (point-min))
|
||||
(dolist (F functions)
|
||||
(save-excursion
|
||||
(when (re-search-forward (semantic-tag-name F) nil t)
|
||||
;; Found, copy it in.
|
||||
(let ((ft (with-current-buffer orig
|
||||
(buffer-substring-no-properties (semantic-tag-start F)
|
||||
(semantic-tag-end F)))))
|
||||
(goto-char (point-max))
|
||||
(insert "% Copy of " (semantic-tag-name F) "\n\n")
|
||||
(insert ft)
|
||||
(insert "\n%%\n"))))
|
||||
)
|
||||
|
||||
;; Save buffer, and setup ability to run this new script.
|
||||
(save-buffer)
|
||||
|
||||
;; This sets us up to cleanup our file after it's done running.
|
||||
(add-hook 'matlab-shell-prompt-appears-hook `(lambda () (matlab-shell-cleanup-extracted-region ,(buffer-file-name buff))))
|
||||
|
||||
(kill-buffer)
|
||||
)
|
||||
|
||||
;; Return the command.
|
||||
(concat "run('" (expand-file-name newf) "')\n")))
|
||||
|
||||
(defun matlab-shell-cleanup-extracted-region (fname)
|
||||
"Cleanup the file created when we previously extracted a region."
|
||||
(condition-case nil
|
||||
(delete-file fname)
|
||||
(error nil))
|
||||
|
||||
(remove-hook 'matlab-shell-prompt-appears-hook
|
||||
;; The below needs to be a perfect match to the setter.
|
||||
`(lambda () (matlab-shell-cleanup-extracted-region ,fname)))
|
||||
)
|
||||
|
||||
;;; M File path stuff =========================================================
|
||||
|
||||
|
|
Loading…
Reference in a new issue