From: rdong@playmate.mat.jhu.edu (Rui-Tao Dong ~{6-HpLN~})
Subject: Emacs mode
Organization: Source only  Discussion and requests in gnu.emacs.help.
Distribution: gnu
Date: Wed, 7 Oct 1992 07:46:54 GMT


	I have hacked a matlab shell mode. It does a few intelligent
things reasonably well.

	1) Has a history mechanism. (M-p and M-n. Built on top of comint.el)

	2) Does command completion. (TAB. Build a command alist by sending
help help at initialization. It takes only a couple of seconds)

	3) Does help in a separate buffer (C-c C-h)

	4) If matlab is licensed for another machine, it logins to
matlab-host and then start it automatically. (Use a shell script xrlogin to
pass DISPLAY. I happened to have it handy. Otherwise it should be easy to
do it in Emacs-Lisp.)

	I need your suggestions for the name of the code. It will be silly
to call it matlab-shell.el. Therefore, I re-named the current matlab m-file
editing mode to matlab-m-mode.el (I changed function names accordingly) and
named my code matlab.el.


Regards,

    Rui-Tao Dong ~{6-HpLN~}		    Department of Mathematics
    rdong@playmate.mat.jhu.edu		    The Johns Hopkins University
    (410)516-7406(O) (410)516-5549(Fax)	    Baltimore, Maryland 21218

-----------------------------------------				

;;; $Id: matlab.el,v 1.7 1992/10/07 15:29:34 rdong Exp $

(require 'comint)

(provide 'matlab)

(defvar matlab-program "matlab"
  "*The matlab program.")

(defvar matlab-prompt-regexp "^>> "
       "Matlab prompt.")

(defvar matlab-program-args nil
  "*Args passed matlab program. Value is a list of strings, which may be
nil.")

(defvar matlab-host nil
  "*Host to run matlab if non-nil and is different from (system-name).")

(defvar matlab-buffer "*Matlab*"
  "Name of matlab buffer.")

(defvar matlab-help-buffer "*Matlab-help*"
  "Name of matlab help buffer.")

(setq matlab-mode-map (full-copy-sparse-keymap comint-mode-map))
(define-key matlab-mode-map "\C-c\C-h" 'matlab-help)
(define-key matlab-mode-map "\t" 'matlab-command-completion)

(defun matlab-mode ()
  "Major mode for running matlab.

\\{matlab-mode-map}
Customization: Entry to this mode runs the hooks on comint-mode-hook and
matlab-mode-hook (in that order)."
  (interactive)
  (comint-mode)
  (setq comint-prompt-regexp matlab-prompt-regexp)
  (setq major-mode 'matlab-mode)
  (setq mode-name "Matlab")
  (setq comint-input-sentinel
      '(lambda (arg)
	 (let ((proc (get-buffer-process matlab-buffer)))
	   (delete-region (process-mark proc) (point)))))
  (use-local-map matlab-mode-map)
  (run-hooks 'matlab-mode-hook))

(defun matlab ()
  "Run matlab, with I/O through buffer *Matlab*. 
If buffer exists but matlab process is not running, start new matlab
process. If buffer exists and process is running, just switch to buffer
*Matlab*. Program used comes from variable matlab-program.

\(Type \\[describe-mode] in matlab buffer for a list of commands.)"
  (interactive)
  (cond ((comint-check-proc matlab-buffer))
	((or (not matlab-host) (equal matlab-host (system-name)))
	 (set-buffer (apply 'make-comint "Matlab" matlab-program nil
			    matlab-program-args))
	 (matlab-mode)
	 (matlab-init))
	(t (let* ((bf (make-comint "Matlab" "xrlogin" nil matlab-host))
		  (proc (get-buffer-process bf)))
	     (set-process-filter proc 'ignore)
	     (sleep-for 2)
	     (process-send-string proc
				  (concat "unset edit; stty -onlcr; "
				  "exec " matlab-program " "
					  matlab-program-args "\n"))
	     (set-buffer bf)
	     (matlab-mode)
	     (matlab-init))))
  (switch-to-buffer matlab-buffer))

(defun matlab-help (command)
  "Get help in matlab. It sends help on current word to the running matlab
process."
  (interactive			;Read a word.
   (let ((enable-recursive-minibuffers t)
	 (try-word (matlab-command-around-point))
	 val)
     (if (string-equal try-word "")
	 (setq val (read-string "Matlab command: "))
       (setq val (read-string (format "Matlab command (default %s): "
				      try-word)))
       (if (string-equal val "")
	   (setq val try-word)))
     (if (string-equal val "")
	 (error "No symbol read"))
     (list val)))
  (let 	((proc (get-buffer-process (current-buffer)))
	 (hbf (get-buffer-create matlab-help-buffer)))
    (display-buffer hbf)
    (save-excursion
      (set-buffer hbf)
      (erase-buffer))
    (set-process-filter proc 'matlab-help-filter)
    (process-send-string proc (concat "help " command "\n"))))

(defun matlab-help-filter (proc string)
  (save-excursion
    (set-buffer matlab-help-buffer)
    (goto-char (point-max))
    (if (string-match matlab-prompt-regexp string)
	(progn 
	  (insert (substring string 0 (1- (match-beginning 0))))
	  (set-process-filter proc nil))
      (insert string))))

(defun matlab-command-around-point ()
 "Return the matlab command around the point as a string."
 (save-excursion
   (let (beg)
     (if (not (eobp)) (forward-char 1))
     (if (not (re-search-backward "\\w\\|\\s_" nil t))
	 ""
       (forward-char 1)
       (backward-sexp)
       (setq beg (point))
       (forward-sexp)
       (buffer-substring beg (point))))))

(defun matlab-init ()
  ""
  (interactive)
  (setq matlab-commands-buffer (get-buffer-create " *Matlab-Commands*"))
  (let ((proc (get-buffer-process (current-buffer))))
    (save-excursion
      (set-buffer matlab-commands-buffer)
      (erase-buffer))
    (message "Matlab initializing....")
    (setq matlab-init t)
    (set-process-filter proc 'matlab-init-filter)))
    
(defun matlab-init-filter (proc str)
  (let ((cbf (current-buffer)))
    (if matlab-init
	(progn
	  (set-buffer matlab-buffer)
	  (goto-char (process-mark proc))
	  (insert str)
	  (set-marker (process-mark proc) (point))	   
	  (set-buffer cbf)
	  (if (string-match matlab-prompt-regexp str)
	      (progn
		(setq matlab-init nil)
		(process-send-string proc "help\n"))))
      (save-excursion
	(set-buffer matlab-commands-buffer)
	(goto-char (point-max))
	(insert str)
	(if (string-match "^Strike any key to continue " str)
	    (process-send-string proc "\n"))
	(if (string-match matlab-prompt-regexp str)
	    (progn
	      (message "done.")
	      (set-process-filter proc nil)
	      (matlab-build-command-alist)))))))

(defun matlab-build-command-alist ()
  (setq matlab-command-alist nil)
  (set-buffer matlab-commands-buffer)
  (goto-char (point-min))
  (while
      (re-search-forward
       "\\(built-in functions:.*\n*\\)\\|\\(Directory of M-files.*\n*\\)"
       nil t)
    (let ((beg (match-end 0))
	  end)
      (if (search-forward "\n\n")
	  (progn
	    (setq end (match-beginning 0))
	    (goto-char beg)
	    (while
		(re-search-forward "[^ \n]+" end t)
	      (setq matlab-command-alist
		    (cons (list (buffer-substring
			   (match-beginning 0)
			   (match-end 0)) 0)
			  matlab-command-alist))))))))

(defun matlab-command-completion ()
  (interactive)
  (let* ((cmd (matlab-command-around-point))
	(completion (all-completions cmd matlab-command-alist)))
    (cond ((eq (length completion) 0) (message "[No match]"))
	  ((eq (length completion) 1)
	   (delete-region (- (point) (length cmd)) (point))
	   (insert (car completion) " "))
	   (t (save-window-excursion
		(with-output-to-temp-buffer " *Completions*"
		  (display-completion-list
		   completion))
		 (sit-for 32767))))))


			       
Newsgroups: gnu.emacs.sources