@@ -330,22 +330,29 @@ otherwise an error is signaled."
330
330
; ; Case: "matlab" (or something similar), locate it on the executable path
331
331
; ; else locate in standard install locations.
332
332
(t
333
- (setq abs-matlab-exe (executable-find matlab-shell-command))
334
- (when (not abs-matlab-exe)
335
- (if (string= matlab-shell-command " matlab" )
336
- ; ; Get latest matlab command exe from the default installation location.
337
- (let* ((default-loc (cdr (assoc system-type matlab-shell--default-command)))
338
- (default-matlab (when default-loc
339
- (car (last (sort
340
- (file-expand-wildcards default-loc)
341
- #'string< ))))))
342
- (when (not default-matlab)
343
- (matlab-shell--matlab-not-found no-error default-loc))
344
- (when (not (file-executable-p default-matlab))
345
- (user-error " %s is not executable" default-matlab))
346
- (setq abs-matlab-exe default-matlab))
347
- ; ; else unable to locate it
348
- (matlab-shell--matlab-not-found no-error)))))
333
+ (let ((remote (file-remote-p default-directory)))
334
+ (if remote
335
+ (if (setq abs-matlab-exe (executable-find matlab-shell-command t ))
336
+ (setq abs-matlab-exe (concat remote abs-matlab-exe))
337
+ (user-error " Unable to locate matlab executable on %s
338
+ See https://github.com/mathworks/Emacs-MATLAB-Mode/doc/remote-matlab-emacs.org for tips" remote))
339
+ ; ; else look local
340
+ (setq abs-matlab-exe (executable-find matlab-shell-command))
341
+ (when (not abs-matlab-exe)
342
+ (if (string= matlab-shell-command " matlab" )
343
+ ; ; Get latest matlab command exe from the default installation location.
344
+ (let* ((default-loc (cdr (assoc system-type matlab-shell--default-command)))
345
+ (default-matlab (when default-loc
346
+ (car (last (sort
347
+ (file-expand-wildcards default-loc)
348
+ #'string< ))))))
349
+ (when (not default-matlab)
350
+ (matlab-shell--matlab-not-found no-error default-loc))
351
+ (when (not (file-executable-p default-matlab))
352
+ (user-error " %s is not executable" default-matlab))
353
+ (setq abs-matlab-exe default-matlab))
354
+ ; ; else unable to locate it
355
+ (matlab-shell--matlab-not-found no-error)))))))
349
356
350
357
; ; Return existing absolute path to the MATLAB command executable
351
358
abs-matlab-exe)
@@ -596,9 +603,12 @@ Try C-h f matlab-shell RET"))
596
603
(let* ((windowid (frame-parameter (selected-frame ) 'outer-window-id ))
597
604
(newvar (concat " WINDOWID=" windowid))
598
605
(process-environment (cons newvar process-environment))
599
- (abs-matlab-exe (matlab-shell--abs-matlab-exe)))
606
+ (abs-matlab-exe (matlab-shell--abs-matlab-exe))
607
+ (matlab-exe (if (file-remote-p abs-matlab-exe)
608
+ matlab-shell-command
609
+ abs-matlab-exe)))
600
610
(message " Running: %s " abs-matlab-exe)
601
- (apply #'make-comint matlab-shell-buffer-name abs- matlab-exe
611
+ (apply #'make-comint matlab-shell-buffer-name matlab-exe
602
612
nil matlab-shell-command-switches))
603
613
604
614
; ; Enable GUD
@@ -1065,30 +1075,102 @@ system."
1065
1075
(and mlfile (file-exists-p dir)))
1066
1076
" Add the `matlab-shell' MATLAB toolbox to the MATLAB path on startup." )
1067
1077
1068
-
1069
- (defun matlab-shell-first-prompt-fcn ()
1078
+ (defun matlab--shell-toolbox-and-bin-sha1 (matlab-dir &optional recursive-call )
1079
+ " Compute the SHA1 of the Emacs MATLAB-DIR toolbox and bin directories.
1080
+ RECURSIVE-CALL should be nil when called from top-level."
1081
+ (let (sha1-all)
1082
+ (when (not (directory-name-p matlab-dir))
1083
+ (error " Directory, %s , does not end in a / " matlab-dir))
1084
+ (when (not (file-directory-p matlab-dir))
1085
+ (error " Directory, %s , does not exist " matlab-dir))
1086
+ (setq matlab-dir (file-truename matlab-dir))
1087
+ (let ((dirs (if recursive-call
1088
+ (list matlab-dir)
1089
+ (list (concat matlab-dir " toolbox/" )
1090
+ (concat matlab-dir " bin/" )))))
1091
+ (dolist (dir dirs)
1092
+ (when (not (file-directory-p dir))
1093
+ (error " Directory, %s , does not exist " dir))
1094
+ (dolist (file-name (sort (directory-files dir) #'string< ))
1095
+ (when (and (not (string-match " ~$" file-name))
1096
+ (not (string-match " ^\\ (?:#\\ |\\ .\\ )" file-name)))
1097
+ ; ; Not a: backup~, #backup, ".", ".., or .hidden file.
1098
+ (let ((abs-file (concat dir file-name)))
1099
+ (if (file-directory-p abs-file)
1100
+ (setq sha1-all
1101
+ (concat sha1-all
1102
+ (matlab--shell-toolbox-and-bin-sha1 (concat abs-file " /" ) t )))
1103
+ ; ; Plain file to add to sha1-all.
1104
+ (with-temp-buffer
1105
+ (insert-file-contents-literally abs-file)
1106
+ (setq sha1-all (concat sha1-all (secure-hash 'sha1 (current-buffer )))))))))))
1107
+ (when (not recursive-call)
1108
+ ; ; sha1-all contains a long list of the individual hash's, reduce to one hash.
1109
+ (when (not sha1-all)
1110
+ (error " Directory, %s , contains no plain files " matlab-dir))
1111
+ (setq sha1-all (secure-hash 'sha1 sha1-all)))
1112
+ sha1-all))
1113
+
1114
+ (defun matlab--shell-remote-toolbox-dir (local-toolbox-dir )
1115
+ " Return matlab-emacs toolbox directory path on the remote system.
1116
+ This will be a copy the LOCAL-TOOLBOX-DIR toolbox and ../bin directories
1117
+ to the remote system. This will copy files to the remote system if the
1118
+ remote directory is missing or out of date. Returns:
1119
+ ~/.emacs-matlab-mode/toolbox/"
1120
+ (let* ((matlab-dir (file-name-as-directory
1121
+ (file-name-directory (directory-file-name local-toolbox-dir))))
1122
+ (sha1 (matlab--shell-toolbox-and-bin-sha1 matlab-dir))
1123
+ (local-dir-on-remote " ~/.emacs-matlab-mode/" )
1124
+ (remote (if (file-remote-p default-directory) (file-remote-p default-directory)
1125
+ (error " %s is not remote" default-directory)))
1126
+ (remote-dir (concat remote local-dir-on-remote))
1127
+ (remote-sha1-file (concat remote-dir " .sha1.txt" )))
1128
+ (when (or (not (file-exists-p remote-sha1-file))
1129
+ (not (string= sha1 (with-temp-buffer
1130
+ (insert-file-contents-literally remote-sha1-file)
1131
+ (buffer-substring (point-min ) (point-max ))))))
1132
+ (delete-directory remote-dir t )
1133
+ (copy-directory local-toolbox-dir remote-dir t t )
1134
+ (copy-directory (concat local-toolbox-dir " ../bin/" ) remote-dir t t )
1135
+ ; ; Save SHA1. This is used to avoid future copies when remote is up to date.
1136
+ (write-region sha1 nil remote-sha1-file))
1137
+ ; ; result
1138
+ (concat local-dir-on-remote " toolbox/" )))
1139
+
1140
+ (cl-defun matlab-shell-first-prompt-fcn ()
1070
1141
" Hook run when the first prompt is seen.
1071
1142
Sends commands to the MATLAB shell to initialize the MATLAB process."
1072
1143
; ; Don't do this again
1073
1144
(remove-hook 'matlab-shell-prompt-appears-hook #'matlab-shell-first-prompt-fcn )
1074
1145
1075
- ; ; Init this session of MATLAB.
1076
- (if matlab-shell-use-emacs-toolbox
1077
- ; ; Use our local toolbox directory.
1078
- (let* ((path (expand-file-name " toolbox" (file-name-directory
1079
- (locate-library " matlab" ))))
1080
- (initcmd (expand-file-name " emacsinit" path))
1081
- (nsa (if matlab-shell-autostart-netshell " emacs.set('netshell', true);" " " ))
1082
- (ecc (matlab-shell--get-emacsclient-command))
1083
- (ecca (if ecc (format " emacs.set('clientcmd', '%s '); " ecc) " " ))
1084
- (args (list nsa ecca))
1085
- (cmd (format " run('%s ');%s " initcmd (apply #'concat args))))
1086
- (matlab-shell-send-command (string-replace (expand-file-name " ~/" ) " ~/" cmd))
1087
- )
1088
-
1146
+ (when (not matlab-shell-use-emacs-toolbox)
1089
1147
; ; Setup is misconfigured - we need emacsinit because it tells us how to debug
1090
1148
(error " Unable to initialize matlab, emacsinit.m and other files missing " ))
1091
1149
1150
+ ; ; Run emacsinit.m which sets up the MATLAB environment to include the matlab-mode
1151
+ ; ; "toolbox". This is used for items like debugging, e.g. ebstop.m.
1152
+ ; ; Also setup emacsclient such that ">> edit file" works.
1153
+ (let* ((local-toolbox-dir (expand-file-name " toolbox/"
1154
+ (file-name-directory (locate-library " matlab" ))))
1155
+ (toolbox-dir (if (file-remote-p default-directory)
1156
+ ; ; Case: Remote matlab-shell via tramp
1157
+ (matlab--shell-remote-toolbox-dir local-toolbox-dir)
1158
+ local-toolbox-dir))
1159
+ (emacs-init (concat toolbox-dir " emacsinit" ))
1160
+ (e-client-command (matlab-shell--get-emacsclient-command))
1161
+ (remote-location (file-remote-p default-directory))
1162
+ (e-set-args (replace-regexp-in-string
1163
+ " ^, " " " ; ; strip leading ", "
1164
+ (concat (when matlab-shell-autostart-netshell " , 'netshell', true" )
1165
+ (when e-client-command (format " , 'clientcmd', '%s ' "
1166
+ e-client-command))
1167
+ (when remote-location (format " , 'remoteLocation', '%s ' "
1168
+ remote-location)))))
1169
+ (cmd (format " run('%s ');%s " emacs-init (if e-set-args
1170
+ (format " emacs.set(%s ); " e-set-args)
1171
+ " " ))))
1172
+ (matlab-shell-send-command (string-replace (expand-file-name " ~/" ) " ~/" cmd)))
1173
+
1092
1174
; ; Init any user commands
1093
1175
(if matlab-custom-startup-command
1094
1176
; ; Wait for next prompt, then send.
@@ -2039,21 +2121,26 @@ a file name, or nil if no conversion done.")
2039
2121
; ; (matlab-shell-mref-to-filename "eltest.utils.testme>localfcn")
2040
2122
2041
2123
(defun matlab-shell-mref-to-filename (fileref )
2042
- " Convert the MATLAB file reference FILEREF into an actual file name .
2124
+ " Convert MATLAB file reference FILEREF into an file Emacs can load .
2043
2125
MATLAB can refer to functions on the path by a short name, or by a .p
2044
2126
extension, and a host of different ways. Convert this reference into
2045
- something Emacs can load."
2127
+ something Emacs can load. If matlab-shell is running remote via tramp,
2128
+ returned file will be prefixed with the remote location."
2046
2129
(interactive " sFileref: " )
2047
2130
(with-current-buffer (matlab-shell-active-p)
2048
- (let ((C matlab-shell-mref-converters)
2049
- (ans nil ))
2131
+ (let ((remote-location (file-remote-p default-directory))
2132
+ (C matlab-shell-mref-converters)
2133
+ ans)
2050
2134
(while (and C (not ans))
2051
2135
(let ((tmp (funcall (car C) fileref)))
2052
- (when (and tmp (file-exists-p tmp))
2053
- (setq ans tmp))
2054
- )
2136
+ (when tmp
2137
+ (when (and remote-location (not (file-remote-p tmp)))
2138
+ (setq tmp (concat remote-location tmp)))
2139
+ (when (file-exists-p tmp)
2140
+ (setq ans tmp))))
2055
2141
(setq C (cdr C)))
2056
- (when (called-interactively-p 'any ) (message " Found: %S " ans))
2142
+ (when (called-interactively-p 'any )
2143
+ (message " Found: %S " ans))
2057
2144
ans)))
2058
2145
2059
2146
(defun matlab-find-other-window-file-line-column (ef el ec &optional debug )
@@ -2601,10 +2688,10 @@ Argument FNAME specifies if we should echo the region to the command line."
2601
2688
; ; LocalWords: keymap subjob kbd emacscd featurep fboundp EDU msbn pc Thx Chappaz windowid tcp lang
2602
2689
; ; LocalWords: postoutput capturetext EMACSCAP captext STARTCAP progn eol dbhot erroexamples cdr
2603
2690
; ; LocalWords: ENDPT dolist overlaystack mref deref errortext ERRORTXT shellerror Emacsen iq nt buf
2604
- ; ; LocalWords: auth mlfile emacsinit initcmd nsa ecc ecca clientcmd EMAACSCAP buffname showbuff
2691
+ ; ; LocalWords: auth mlfile EMAACSCAP buffname showbuff symlink'd emacsinit sha dirs ebstop
2605
2692
; ; LocalWords: evalforms Histed pmark memq promptend numchars integerp emacsdocomplete mycmd ba
2606
2693
; ; LocalWords: nreverse emacsdocompletion byteswap stringp cbuff mapcar bw FCN's alist substr usr
2607
2694
; ; LocalWords: BUILTINFLAG dired bol bobp numberp princ minibuffer fn matlabregex lastcmd notimeout
2608
2695
; ; LocalWords: stacktop eltest testme localfcn LF fileref funcall ef ec basec sk nondirectory utils
2609
2696
; ; LocalWords: ignoredups boundp edir sexp Fixup mapc emacsrun noshow cnt ellipsis newf bss noselect
2610
- ; ; LocalWords: fname mlx xemacs linux darwin truename
2697
+ ; ; LocalWords: fname mlx xemacs linux darwin truename clientcmd
0 commit comments