home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / modes / maple.el < prev    next >
Encoding:
Text File  |  1990-07-22  |  19.0 KB  |  607 lines

  1. ;From salvy@inria.inria.fr Mon Jul 23 14:54:00 1990
  2. ;Date: Mon, 23 Jul 90 09:17:27 +0200
  3. ;From: salvy@inria.inria.fr (Bruno Salvy)
  4. ;Sender: salvy@rully.inria.fr
  5. ;To: de5@stc06.ctd.ornl.gov
  6. ;In-Reply-To: SILL D E's message of Fri, 20 Jul 90 15:14:27 EDT <9007201914.AA16543@stc06.CTD.ORNL.GOV>
  7. ;Subject: Maple mode
  8. ;
  9. ;    Date: Fri, 20 Jul 90 15:14:27 EDT
  10. ;    From: SILL D E <de5@stc06.ctd.ornl.gov>
  11. ;
  12. ;    If your Maple mode for GNU Emacs is available, I'd like a copy for the
  13. ;    elisp archives on tut.cis.ohio-state.edu.  If there's already an ftp
  14. ;    site, I could just leave a pointer to that.
  15. ;
  16. ;    -Dave Sill (de5@ornl.gov)
  17. ;     elisp archive coordinator
  18. ;
  19. ;It is available, I just did not think it could interest enough people
  20. ;to be put on a site. Anyway, here it is:
  21.  
  22. ;;;;;;;;;;;;;;;;;;;;;;;; maple-mode.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23. ; Maple editing support package
  24. ; B. Salvy (salvy@inria.inria.fr)
  25. ; (borrows heavily from modula2.el, ada.el and tex-mode.el)
  26. ; modified 03/05/90: C-p and C-n in maple-shell. B.S.
  27. ; modified 29/05/90: maple-prompt-regexp B.S.
  28.  
  29. (provide 'maple)
  30.  
  31. (defvar maple-mode-syntax-table nil
  32.   "Syntax table in use in maple-mode buffers.")
  33.  
  34. (if maple-mode-syntax-table
  35.     ()
  36.   (let ((table (make-syntax-table)))
  37.     (modify-syntax-entry ?\\ "\\" table)
  38.     (modify-syntax-entry ?\{ "(}" table)
  39.     (modify-syntax-entry ?\[ "(]" table)
  40.     (modify-syntax-entry ?\( "()" table)
  41.     (modify-syntax-entry ?\} "){" table)
  42.     (modify-syntax-entry ?\] ")[" table)
  43.     (modify-syntax-entry ?\) ")(" table)
  44.     (modify-syntax-entry ?* "." table)
  45.     (modify-syntax-entry ?+ "." table)
  46.     (modify-syntax-entry ?- "." table)
  47.     (modify-syntax-entry ?/ "." table)
  48.     (modify-syntax-entry ?= "." table)
  49.     (modify-syntax-entry ?< "." table)
  50.     (modify-syntax-entry ?> "." table)
  51.     (modify-syntax-entry ?\' "\"" table)
  52.     (modify-syntax-entry ?\` "\"" table)
  53.     (modify-syntax-entry ?\" "." table)
  54.      (modify-syntax-entry ?#  "<" table)
  55. ;     (modify-syntax-entry ?\n ">" table)
  56. ;     (modify-syntax-entry ?\f ">" table)
  57.     (setq maple-mode-syntax-table table)))
  58.  
  59. (defvar maple-mode-map nil
  60.   "Keymap used in Maple mode.")
  61.  
  62. (if maple-mode-map ()
  63.   (let ((map (make-sparse-keymap)))
  64.      (define-key map "\C-m" 'maple-newline)
  65.      (define-key map "\C-?" 'maple-untab)
  66.      (define-key map "\C-i" 'maple-tab)
  67.      (define-key map "\C-c<" 'maple-backward-to-same-indent)
  68.      (define-key map "\C-c>" 'maple-forward-to-same-indent)
  69.     (define-key map "\C-c#" 'maple-inline-comment)
  70.     (define-key map "\C-ce" 'maple-else)
  71.     (define-key map "\C-cf" 'maple-for)
  72.      (define-key map "\C-ch" 'maple-help)
  73.     (define-key map "\C-ci" 'maple-if)
  74.     (define-key map "\C-cl" 'maple-local)
  75.      (define-key map "\C-cm" 'maple-modify)
  76.     (define-key map "\C-cp" 'maple-procedure)
  77.     (define-key map "\C-ct" 'maple-title)
  78.     (define-key map "\C-cw" 'maple-while)
  79.      (define-key map "\C-c\C-i" 'maple-make-library)
  80.      (define-key map "\C-c\C-r" 'maple-region)
  81.      (define-key map "\C-c\C-b" 'maple-buffer)
  82.      (define-key map "\C-c\C-m" 'mint-buffer)
  83.      (define-key map "\C-c\C-l" 'maple-recenter-output-buffer)
  84.     (define-key map "\C-c\C-z" 'suspend-emacs)
  85.     (setq maple-mode-map map)))
  86.  
  87. (defvar maple-indent 3 "*This variable gives the indentation in Maple-Mode")
  88.   
  89. (defun maple-mode ()
  90. "This is a mode intended to support program development in Maple.
  91. All control constructs of Maple can be reached by typing
  92. Control-C followed by the first character of the construct.
  93. Use \\[maple-region] to run Maple on the current region under
  94. a special subshell.  \\[maple-buffer] does the whole buffer.
  95.  
  96.   Control-c f for           Control-c e else
  97.   Control-c i if            Control-c l local
  98.   Control-c w while         Control-c p proc
  99.   Control-c # comment       Control-c h help
  100.   Control-c m modify        Control-c t title
  101.   Control-c ( paired parens
  102.   Control-c Control-z suspend-emacs
  103.  
  104.   C-c < and C-c > move backward and forward respectively to the next line
  105.   having the same (or lesser) level of indentation.
  106.  
  107.    maple-indent controls the number of spaces for each indentation.
  108.  
  109. \\{maple-mode-map}
  110. "
  111.   (interactive)
  112.   (kill-all-local-variables)
  113.   (maple-define-common-keys maple-mode-map)
  114.   (use-local-map maple-mode-map)
  115.   (setq major-mode 'maple-mode)
  116.   (setq mode-name "Maple")
  117.   (make-local-variable 'comment-column)
  118.   (setq comment-column 41)
  119.   (make-local-variable 'end-comment-column)
  120.   (setq end-comment-column 72)
  121.   (set-syntax-table maple-mode-syntax-table)
  122.   (make-local-variable 'paragraph-start)
  123.   (setq paragraph-start (concat "^$\\|" page-delimiter))
  124.   (make-local-variable 'paragraph-separate)
  125.   (setq paragraph-separate paragraph-start)
  126.   (make-local-variable 'paragraph-ignore-fill-prefix)
  127.   (setq paragraph-ignore-fill-prefix t)
  128. ;  (make-local-variable 'indent-line-function)
  129. ;  (setq indent-line-function 'c-indent-line)
  130.   (make-local-variable 'require-final-newline)
  131.   (setq require-final-newline t)
  132.   (make-local-variable 'comment-start)
  133.   (setq comment-start "#")
  134.   (make-local-variable 'comment-end)
  135.   (setq comment-end "\n")
  136.   (make-local-variable 'comment-column)
  137.   (setq comment-column 41)
  138. ;  (make-local-variable 'comment-start-skip)
  139. ;  (setq comment-start-skip "/\\*+ *")
  140.   (make-local-variable 'comment-indent-hook)
  141.   (setq comment-indent-hook 'c-comment-indent)
  142.   (make-local-variable 'parse-sexp-ignore-comments)
  143.   (setq parse-sexp-ignore-comments t)
  144.   (run-hooks 'maple-mode-hook))
  145.  
  146. (defun maple-newline ()
  147.   "Insert a newline and indent following line like previous line."
  148.   (interactive)
  149.   (let ((hpos (current-indentation)))
  150.     (newline)
  151.     (indent-to hpos)))
  152.  
  153. (defun maple-tab ()
  154.   "Indent to next tab stop."
  155.   (interactive)
  156.   (if (< (current-indentation)
  157.             (- (point)
  158.                 (save-excursion (beginning-of-line)(point))))
  159.         (insert "\t")
  160.      (back-to-indentation)
  161.      (indent-to (* (1+ (/ (current-indentation) maple-indent)) maple-indent))))
  162.  
  163. (defun maple-tabsize (s)
  164.   "changes spacing used for indentation. Reads spacing from minibuffer."
  165.   (interactive "new indentation spacing: ")
  166.   (setq maple-indent s))
  167.  
  168. (defun maple-untab ()
  169.   "Delete backwards to previous tab stop."
  170.   (interactive)
  171.   (backward-delete-char 1))
  172.  
  173. (defun maple-go-to-this-indent (step indent-level)
  174.   "Move point repeatedly by <step> lines till the current line
  175. has given indent-level or less, or the start/end of the buffer is hit.
  176. Ignore blank lines and comments."
  177.   (while (and
  178.       (zerop (forward-line step))
  179.       (or (looking-at "^[     ]*$")
  180.           (looking-at "^[     ]*#")
  181.           (looking-at "^<<[A-Za-z0-9_]+>>")
  182.           (looking-at "^[A-Za-z0-9_]+:")
  183.           (> (current-indentation) indent-level)))
  184.     nil))
  185.  
  186. (defun maple-backward-to-same-indent ()
  187.   "Move point backwards to nearest line with same indentation or less.
  188. If not found, point is left at top of buffer."
  189.   (interactive)
  190.   (maple-go-to-this-indent -1 (current-indentation))
  191.   (back-to-indentation))
  192.  
  193. (defun maple-forward-to-same-indent ()
  194.   "Move point forwards to nearest line with same indentation or less.
  195. If not found, point is left at start of last line in buffer."
  196.   (interactive)
  197.   (maple-go-to-this-indent 1 (current-indentation))
  198.   (back-to-indentation))
  199.  
  200. (defun maple-for ()
  201.   "Build skeleton for-loop statment, prompting for the loop parameters."
  202.   (interactive)
  203.   (let ((for (read-string "var: ")))
  204.      (if (string-equal for "")
  205.           (let ((to (read-string "to: ")))
  206.              (if (not (string-equal to ""))
  207.                   (insert " to " to)))
  208.           (insert "for " for)
  209.           (let ((in (read-string "in: ")))
  210.              (if (not (string-equal in ""))
  211.                   (insert " in " in)
  212.                 (let ((from (read-string "from: ")))
  213.                   (if (not (string-equal from ""))
  214.                         (insert " from " from)))
  215.                 (let ((by (read-string "by: ")))
  216.                   (if (not (string-equal by ""))
  217.                         (insert " by " by)))
  218.                 (let ((to (read-string "to: ")))
  219.                   (if (not (string-equal to ""))
  220.                         (insert " to " to)))))))
  221.   (let ((while (read-string "while: ")))
  222.     (if (not (string-equal while ""))
  223.           (insert " while " while)))
  224.   (insert " do")
  225.   (maple-newline)
  226.   (maple-newline)
  227.   (insert "od;")
  228.   (end-of-line 0)
  229.   (maple-tab))
  230.  
  231. (defun maple-while ()
  232.   "Build skeleton while-loop statment, prompting for the loop parameters."
  233.   (interactive)
  234.   (insert "while " (read-string "cond: "))
  235.   (insert " do")
  236.   (maple-newline)
  237.   (maple-newline)
  238.   (insert "od;")
  239.   (end-of-line 0)
  240.   (maple-tab))
  241.  
  242. (defun maple-title ()
  243.   "Insert a comment block containing the module title, author, etc."
  244.   (interactive)
  245.   (if (eq (point) (point-min))
  246.         nil
  247.      (set-mark (point))
  248.      (goto-line 1))
  249.   (insert "\n\n")
  250.   (previous-line 2)
  251.   (insert "##\n##    Title: \t")
  252.   (insert (read-string "Title: "))
  253.   (insert "\n##    Created:\t")
  254.   (insert (current-time-string))
  255.   (insert "\n##    Author: \t")
  256.   (insert (user-full-name))
  257.   (insert (concat "\n##\t\t<" (user-login-name) "@" (system-name) ">\n"))
  258.   (insert "##\n## Description: ")
  259.   (end-of-line nil))
  260.  
  261. (defun maple-modify ()
  262.   "Insert a comment block containing the modification, author, etc."
  263.   (interactive)
  264.   (set-mark (point))
  265.   (goto-line 1)
  266.   (while (char-equal (char-after (point)) 35)
  267.                 (forward-line 1))                                        
  268.   (insert "##\n##    Modified: \t")
  269.   (insert (current-time-string))
  270.   (insert "\n##    Author: \t")
  271.   (insert (user-full-name))
  272.   (insert "\n##    Modification: ")
  273.   (insert (read-string "Modification: "))
  274.   (insert "\n##\n"))
  275.  
  276. (defun maple-if ()
  277.   "Insert skeleton if statment, prompting for <boolean-expression>."
  278.   (interactive)
  279.   (insert "if " (read-string "cond: ") " then")
  280.   (maple-newline)
  281.   (maple-newline)
  282.   (insert "fi;")
  283.   (end-of-line 0)
  284.   (maple-tab))
  285.  
  286. (defun maple-else ()
  287.   "Add an elif clause to an if statement, prompting for the condition.
  288.    When no condition is given, put an else."
  289.   (interactive)
  290.   (maple-untab)
  291.   (let ((condition (read-string "elif: ")))
  292.      (if (not (string-equal condition ""))
  293.           (insert "elif " condition " then")
  294.         (insert "else")))
  295.   (maple-newline)
  296.   (maple-tab))
  297.  
  298. (defun maple-local ()
  299.    "Add a new local variable, inserting the word local if necessary."
  300.     (interactive)
  301.     (save-excursion
  302.       (set-mark (point))
  303.       (while (or (> (current-indentation) 0)
  304.                      (looking-at "#")
  305.                      (looking-at "end")
  306.                      (looking-at "option"))
  307.          (forward-line -1))
  308.       (let ((first-time))
  309.          (if (looking-at "local")
  310.               (setq first-time nil)
  311.             (forward-line 1)
  312.             (insert "local ;\n")
  313.             (forward-line -1)
  314.             (setq first-time t))
  315.          (search-forward ";")
  316.          (backward-char)
  317.          (let ((newvar (read-string "New variable: ")))
  318.             (if first-time (insert newvar)
  319.               (insert ", " newvar))))))
  320.  
  321. (defun maple-procedure ()
  322.   (interactive)
  323.   (let ((name (read-string "Name: " ))
  324.     args)
  325.     (insert name ":=proc (")
  326.     (insert (read-string "Arguments: ") ")")
  327.      (let ((options (read-string "Options: ")))
  328.         (if (not (string-equal options ""))
  329.              (progn (maple-newline)
  330.                       (insert "options " options ";"))))
  331.     (maple-newline)
  332.     (maple-newline)
  333.     (insert "end: # ")
  334.     (insert name)
  335.     (end-of-line 0)
  336.     (maple-tab)))
  337.  
  338. (defun maple-paired-parens ()
  339.   "Insert a pair of round parentheses, placing point between them."
  340.   (interactive)
  341.   (insert "()")
  342.   (backward-char))
  343.  
  344. (defun maple-inline-comment ()
  345.   "Start a comment after the end of the line, indented at least COMMENT-COLUMN.
  346. If starting after END-COMMENT-COLUMN, start a new line."
  347.   (interactive)
  348.   (end-of-line)
  349.   (if (> (current-column) end-comment-column) (newline))
  350.   (if (< (current-column) comment-column) (indent-to comment-column))
  351.   (insert "#  "))
  352.  
  353. (defun maple-display-comment ()
  354. "Inserts 3 comment lines, making a display comment."
  355.   (interactive)
  356.   (insert "#\n# \n#")
  357.   (end-of-line 0))
  358.  
  359. (defvar maple-lib-directory "/net/bandol/V4.3/lib")
  360.  
  361. (defun maple-help ()
  362.   "Like describe-function in lisp-mode, tries to guess which function is
  363. interesting for the user and prompts for confirmation, then displays help.
  364. This could be much better if we called Maple to find the file, but I do not
  365. see how it could be as fast."
  366.   (interactive)
  367.   (save-excursion
  368.      (let ((orig (point))
  369.              eow bow)
  370.         (forward-word -1)
  371.         (setq bow (point))
  372.         (forward-word 1)
  373.         (setq eow (point))
  374.         (let* ((posfuncname (buffer-substring bow eow))
  375.                  (funcname (read-string
  376.                                 (if (string-equal posfuncname "")
  377.                                      "Help about: "
  378.                                      (concat "Help about [" posfuncname "]: ")))))
  379.           (and (string-equal funcname "")
  380.                 (setq funcname posfuncname))
  381.           (or (file-exists-p (concat maple-lib-directory "/help/text/" funcname))
  382.                 (error "Cannot find help for this function"))
  383.           (with-output-to-temp-buffer "*Maple Help*"
  384.              (buffer-flush-undo standard-output)
  385.              (save-excursion
  386.                 (set-buffer standard-output)
  387.                 (insert-file-contents
  388.                  (concat maple-lib-directory "/help/text/" funcname))))))))
  389.  
  390. ;;; Invoking Maple in an inferior shell.
  391.  
  392. (defvar maple-command "maple"
  393.   "The command to run maple on a file.")
  394.  
  395. (defvar maple-args ""
  396.   "Arguments passed to maple. For old versions of Maple, -q could be useful")
  397.  
  398. (defvar maple-prompt-regexp "^[^>\n]*>+ +" "\
  399. *Regexp defining the prompt in Maple sessions.")
  400.  
  401. (defvar mint-command "mint"
  402.   "The command to run mint on a file.  The name of the file will be appended
  403. to this string, separated by <.")
  404.  
  405. (defun maple-define-common-keys (keymap)
  406.   "Define the keys that we want defined both in maple-mode
  407. and in the maple-shell."
  408.   (define-key keymap "\C-c\C-k" 'maple-kill-job))
  409.  
  410. (defvar maple-shell-map nil
  411.   "Keymap for the maple shell.  A shell-mode-map with a few additions")
  412.  
  413. (defvar maple-temp-directory "/tmp/"
  414.   "*Directory in which to create temporary files.")
  415.  
  416. (defvar zap-file nil
  417.   "Temporary file name used for text being sent as input to Maple.")
  418.  
  419. (defun maple ()
  420.   "Run maple in a buffer, without shell. Exiting maple will kill the buffer.
  421. The buffer is called *Maple*, and the program used comes from variable
  422. maple-command (default maple). The buffer is put in shell-mode with
  423. a maple-syntax-table."
  424.    (interactive)
  425.     (if (get-buffer "*Maple*")
  426.          nil
  427.       (maple-start-shell "*Maple*"))
  428.     (switch-to-buffer "*Maple*"))
  429.  
  430. (defun maple-start-shell (name)
  431.   (require 'shell)
  432.   (save-excursion
  433.         (set-process-sentinel
  434.          (if (not (string-equal maple-args ""))
  435.               (start-process "maple" name
  436.                                   (concat exec-directory "env")
  437.                                   "TERM=emacs"  ; so that the process may know it 
  438.                                                      ; is called by emacs
  439.                                   "PAGER=cat"   ; because of 4.3 help
  440. ;                                  "PAGER=emacsclient"   ; because of 4.3 help
  441.                                   "-"
  442.                                   maple-command
  443.                                   maple-args)
  444.             (start-process "maple" name
  445.                                 (concat exec-directory "env")
  446.                                 "TERM=emacs"  ; so that the process may know it 
  447.                                                      ; is called by emacs
  448.                                 "PAGER=cat"   ; because of 4.3 help
  449. ;                                "PAGER=emacsclient"   ; because of 4.3 help
  450.                                 "-"
  451.                                 maple-command))
  452.          'maple-process-sentinel)
  453.         (set-buffer name)
  454.         (shell-mode)
  455.         (make-local-variable 'shell-prompt-pattern)
  456.         (setq shell-prompt-pattern maple-prompt-regexp)
  457.         (set-syntax-table maple-mode-syntax-table)
  458.         (setq maple-shell-map (copy-keymap shell-mode-map))
  459.         (maple-define-common-keys maple-shell-map)
  460.         (define-key maple-shell-map "\C-p" 'maple-previous-command)
  461.         (define-key maple-shell-map "\C-n" 'maple-next-command)
  462.         (use-local-map maple-shell-map)))
  463.  
  464. (defun maple-process-sentinel (proc mesg)
  465.   (let ((stat (process-status proc))
  466.           (name (process-buffer proc)))
  467.      (cond ((eq stat 'run) nil)
  468.              ((eq stat 'stop)
  469.               (continue-process proc)
  470.               (if (and (not (eq (process-status proc) 'run))
  471.                           name
  472.                           (save-excursion
  473.                              (kill-buffer name)))))
  474.              (t (if (not name) nil
  475.                     (save-excursion
  476.                       (kill-buffer name)))))))
  477.  
  478. (defun maple-region (beg end)
  479.   "Run Maple on the current region.  A temporary file (zap-file) is
  480. written in directory maple-temp-directory, but Maple is run in the current
  481. directory."
  482.   (interactive "r")
  483.   (let ((name (concat "*" (buffer-name) "-Maple*")))
  484.      (if (get-buffer name)
  485.           nil
  486.         (maple-start-shell name))
  487.      (if zap-file
  488.           (if (file-exists-p zap-file)
  489.                 (delete-file zap-file))
  490.         (setq zap-file
  491.                 (expand-file-name
  492.                  (concat maple-temp-directory
  493.                             (make-temp-name "#mz")))))
  494.      (save-excursion
  495.         (save-restriction
  496.           (widen)
  497.           (goto-char (point-min))
  498.           (write-region beg end zap-file t nil))
  499.         (send-string (get-buffer-process name)
  500.                          (concat "read \`" zap-file "\`;\n")))
  501.      (sit-for 1)
  502.      (maple-recenter-output-buffer nil)))
  503.  
  504. (defun mint-shell (name)
  505.   (require 'shell)
  506.   (save-excursion
  507.      (set-process-sentinel
  508.       (start-process "mint" "*Mint*" mint-command "<" name)
  509.       'mint-process-sentinel)
  510.      (set-buffer "*Mint*")
  511.      (shell-mode)))
  512.  
  513. (defun mint-process-sentinel (proc mesg)
  514.   (let ((stat (process-status proc))
  515.           (name (process-buffer proc)))
  516.      (cond ((eq stat 'run) nil)
  517.              ((eq stat 'stop)
  518.               (continue-process proc))
  519.              (t nil))))
  520.  
  521. (defun mint-region (beg end)
  522.   "Run Mint on the current region.  A temporary file (zap-file) is
  523. written in directory maple-temp-directory, but Mint is run in the current
  524. directory."
  525.   (interactive "r")
  526.   (let ((name "*Mint*"))
  527.      (if (get-buffer name)
  528.           (save-excursion (kill-buffer name)))
  529.      (if zap-file
  530.           (if (file-exists-p zap-file)
  531.                 (delete-file zap-file))
  532.         (setq zap-file
  533.                 (expand-file-name
  534.                  (concat maple-temp-directory
  535.                             (make-temp-name "#mz")))))
  536.      (save-excursion
  537.         (save-restriction
  538.           (widen)
  539.           (goto-char (point-min))
  540.           (write-region beg end zap-file t nil))
  541.         (mint-shell zap-file))
  542.      (pop-to-buffer "*Mint*")))
  543.  
  544. (defun maple-buffer ()
  545.   "Run Maple on current buffer.  See \\[maple-region] for more information."
  546.   (interactive)
  547.   (maple-region (point-min) (point-max)))
  548.  
  549. (defun maple-make-library ()
  550.   "Run Maple on current buffer, with option -s."
  551.   (interactive)
  552.   (let ((maple-args "-s"))
  553.      (maple-region (point-min) (point-max))))
  554.  
  555. (defun mint-buffer ()
  556.   "Run Mint on current buffer.  See \\[mint-region] for more information."
  557.   (interactive)
  558.   (mint-region (point-min) (point-max)))
  559.  
  560. (defun maple-kill-job ()
  561.   "Kill the currently running Maple job."
  562.   (interactive)
  563.   (if (get-buffer-process (current-buffer))
  564.         (kill-buffer (current-buffer))
  565.      (let ((name (concat "*" (buffer-name) "-Maple*")))
  566.         (and (get-buffer name)
  567.               (kill-buffer name)))))
  568.  
  569. (defun maple-recenter-output-buffer (linenum)
  570.   "Redisplay buffer of Maple job output so that most recent output can be seen.
  571. The last line of the buffer is displayed on
  572. line LINE of the window, or centered if LINE is nil."
  573.   (interactive "P")
  574.   (let ((old-buffer (current-buffer))
  575.           (maple-shell(if (get-buffer-process (current-buffer))
  576.                                 (current-buffer)
  577.                              (or (get-buffer (concat "*" (buffer-name) "-Maple*"))
  578.                                   (get-buffer "*Maple*")))))
  579.     (if (null maple-shell)
  580.           (message "No Maple output buffer")
  581.       (pop-to-buffer maple-shell)
  582.         (goto-char (point-max))
  583.         (recenter (if linenum
  584.                           (prefix-numeric-value linenum)
  585.                         (/(window-height) 2)))
  586.         (pop-to-buffer old-buffer))))
  587.  
  588. (defun maple-previous-command ()
  589.   "Recall previous maple command."
  590.   (interactive)
  591.   (maple-relative-command -1))
  592.  
  593. (defun maple-next-command ()
  594.   "Step to maple next command line."
  595.   (interactive)
  596.   (maple-relative-command 1))
  597.  
  598. (defun maple-relative-command (dir)
  599.   "Step to previous or next command line according to the first argument
  600. being 1 or -1."
  601.   (while (and (zerop (forward-line dir))
  602.                   (not (looking-at maple-prompt-regexp))
  603.                   (looking-at "^"))); forward-line at the end of a buffer
  604.   (end-of-line))
  605.  
  606.  
  607.