Changeset 845cb34 in git


Ignore:
Timestamp:
Jul 28, 1998, 8:54:33 AM (26 years ago)
Author:
Jens Schmidt <schmidt@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
ecd512f0023781ac9df0e4e7c7b4683d0da950ad
Parents:
d8cc2a7cea0a2cbf24ab556a355de8a20e298df6
Message:
	* singular.el (singular-simple-sec-clear-type): new variable
	  (singular-simple-sec-init): new function
	  (singular-emacs-simple-sec-create,
 	  singular-emacs-simple-sec-reset-last,
 	  singular-emacs-simple-sec-start, singular-emacs-simple-sec-end,
 	  singular-emacs-simple-sec-type, singular-emacs-simple-sec-at,
 	  singular-emacs-simple-sec-before, singular-emacs-simple-sec-in
 	  ): new functions.  `fset's for the flavor-independent functions
	  added.

	* singular.el (singular-output-filter): new function
	  (singular-send-input): new function
	  (singular-interactive-mode-map): `singular-send-input' bound to
	  `"\C-m"'

	* singular.el (singular-debug-input-filter,
	  singular-debug-output-filter):  completely rewritten.  Bogus
	  call counting removed.  Debug checks added.
	  (singular-debug-bogus-output-filter-cnt): variable removed

	* singular.el (singular): code for creation of new singular
	  process moved to `singular-exec'
	  (singular-exec): new function

	* singular.el (singular-process-mark): new macro
	  (singular-exit-sentinel): debug message fix
	  (singular): arguments names changed
	  (singular-set-version): message fix
	  (singular-bogus-output-filter-calls): variable removed
	  (singular-debug): optional argument `else-form' added
	  (singular-debug-format): uses `replace-match' to replace
	  newlines

	* singular.el (singular-folding-ellipsis): new variable
	  (singular-interactive-mode): selective display stuff added

	* singular.el (singular-input-face, singular-output-face): new
	  variables
	  (singular-lookup-face): new function


git-svn-id: file:///usr/local/Singular/svn/trunk@2377 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • emacs/singular.el

    rd8cc2a r845cb34  
    11;;; singular.el --- Emacs support for Computer Algebra System Singular
    22
    3 ;; $Id: singular.el,v 1.5 1998-07-23 15:57:22 schmidt Exp $
     3;; $Id: singular.el,v 1.6 1998-07-28 06:54:33 schmidt Exp $
    44
    55;;; Commentary:
     
    2323;; - folding-marks are `;;{{{' and `;;}}}' resp., for sake of standard
    2424;;   conformity
     25;; - mark incomplete doc strings or code with `NOT READY' (optionally
     26;;   followed by an explanation what exactly is missing)
    2527;;
    2628;; - use `singular' as prefix for all global symbols
     
    2931;;
    3032;; - mark dependencies on Emacs flavor/version with a comment of the form
    31 ;;   `;; Emacs[ version]' resp.  `;; XEmacs[ version]'
     33;;   `;; Emacs[ <version>]'     resp.
     34;;   `;; XEmacs[ <version>][ <nasty comment>]' (in that order, if
     35;;   possible)
    3236;; - use a `cond' statement to execute Emacs flavor/version-dependent code,
    3337;;   not `if'.  This is to make such checks more extensible.
     
    5559(defun singular-debug-format (string)
    5660  "Return STRING in a nicer format."
    57 
    58   ;; is there any better way to replace in strings??
    5961  (while (string-match "\n" string)
    60     (setq string (concat (substring string 0 (match-beginning 0))
    61                          "^J"
    62                          (substring string (match-end 0)))))
     62    (setq string (replace-match "^J" nil nil string)))
    6363
    6464  (if (> (length string) 16)
     
    6666    (concat "<" string ">")))
    6767
    68 (defmacro singular-debug (mode form)
     68(defmacro singular-debug (mode form &optional else-form)
    6969  "Major debugging hook for singular.el.
    70 Evaluates FORM if and only if `singular-debug' equals `all' or if MODE
    71 is an element of `singular-debug'."
     70Evaluates FORM if `singular-debug' equals `all' or if MODE is an
     71element of `singular-debug', othwerwise ELSE-FORM"
    7272  `(if (or (eq singular-debug 'all)
    7373           (memq ,mode singular-debug))
    74        ,form))
     74       ,form
     75     ,else-form))
    7576;;}}}
    7677
     
    120121"You seem to have quite an old Emacs or XEmacs version.  Some of the
    121122features from singular.el will not work properly.  Consider upgrading to a
    122 more recent version of Emaxs or XEmacs.  singular.el is guaranteed to run
     123more recent version of Emacs or XEmacs.  singular.el is guaranteed to run
    123124on Emacs 19.34, Emacs 20.2, and XEmacs 20.2."))
    124125    ;; assume the oldest version we support
     
    133134(singular-set-version)
    134135;;}}}
     136
     137;;{{{ Faces
     138(make-face 'singular-input-face)
     139(set-face-background 'singular-input-face "peach puff")
     140(defvar singular-input-face 'singular-input-face
     141  "Face for user input.
     142This face should have set background only.")
     143
     144(make-face 'singular-output-face)
     145(set-face-background 'singular-output-face "blanched almond")
     146(defvar singular-output-face 'singular-output-face
     147  "Face for Singular output.
     148This face should have set background only.")
     149
     150(defun singular-lookup-face (face-type)
     151  "Return face belonging to FACE-TYPE.
     152NOT READY [should be rewritten completely]!"
     153  (cond ((eq face-type 'input) singular-input-face)
     154        ((eq face-type 'output) singular-output-face)))
     155;;}}}
    135156;;}}}
    136157
     
    141162
    142163(if (not singular-interactive-mode-map)
    143     (cond
    144      ;; Emacs
    145      ((eq singular-emacs-flavor 'emacs)
    146       (setq singular-interactive-mode-map
    147             (nconc (make-sparse-keymap) comint-mode-map)))
    148      ;; XEmacs
    149      (t
    150       (setq singular-interactive-mode-map (make-keymap))
    151       (set-keymap-parents singular-interactive-mode-map (list comint-mode-map))
    152       (set-keymap-name singular-interactive-mode-map
    153                        'singular-interactive-mode-map))))
     164    (progn
     165      (cond
     166       ;; Emacs
     167       ((eq singular-emacs-flavor 'emacs)
     168        (setq singular-interactive-mode-map
     169              (nconc (make-sparse-keymap) comint-mode-map)))
     170       ;; XEmacs
     171       (t
     172        (setq singular-interactive-mode-map (make-keymap))
     173        (set-keymap-parents singular-interactive-mode-map (list comint-mode-map))
     174        (set-keymap-name singular-interactive-mode-map
     175                         'singular-interactive-mode-map)))
     176      (define-key singular-interactive-mode-map "\C-m" 'singular-send-input)))
    154177;;}}}
    155178
     
    172195The buffer name is the process name with surrounding `*'."
    173196  (concat "*" process-name "*"))
    174 ;;}}}
    175  
     197
     198(defmacro singular-process-mark ()
     199  "Return process mark of current buffer."
     200  (process-mark (get-buffer-process (current-buffer))))
     201;;}}}
     202
    176203;;{{{ Customizing variables of comint
    177204
     
    234261;;}}}
    235262
    236 ;;{{{ Input and output filters
     263;;{{{ Simple section stuff for both Emacs and XEmacs
     264
     265;; Note:
     266;;
     267;; NOT READY[was sind und wollen simple sections]!
     268
     269(defvar singular-simple-sec-clear-type 'input
     270  "Type of clear simple sections.")
     271
     272(defun singular-simple-sec-init (pos)
     273  "Initialize global variables belonging to simple section management.
     274Creates the buffer-local marker `singular-simple-sec-last-end' and
     275initializes it to POS."
     276  (make-local-variable 'singular-simple-sec-last-end)
     277  (if (not (and (boundp 'singular-simple-sec-last-end)
     278                singular-simple-sec-last-end))
     279      (setq singular-simple-sec-last-end (make-marker)))
     280  (set-marker singular-simple-sec-last-end pos))
     281
     282;; Note:
     283;;
     284;; The rest of the folding is either marked as
     285;; Emacs
     286;; or
     287;; XEmacs
     288
     289(singular-fset 'singular-simple-sec-create
     290               'singular-emacs-simple-sec-create
     291               'singular-emacs-simple-sec-create)
     292
     293(singular-fset 'singular-simple-sec-reset-last
     294               'singular-emacs-simple-sec-reset-last
     295               'singular-emacs-simple-sec-reset-last)
     296
     297(singular-fset 'singular-simple-sec-start
     298               'singular-emacs-simple-sec-start
     299               'singular-emacs-simple-sec-start)
     300
     301(singular-fset 'singular-simple-sec-end
     302               'singular-emacs-simple-sec-end
     303               'singular-emacs-simple-sec-end)
     304
     305(singular-fset 'singular-simple-sec-type
     306               'singular-emacs-simple-sec-type
     307               'singular-emacs-simple-sec-type)
     308
     309(singular-fset 'singular-simple-sec-at
     310               'singular-emacs-simple-sec-at
     311               'singular-emacs-simple-sec-at)
     312
     313(singular-fset 'singular-simple-sec-before
     314               'singular-emacs-simple-sec-before
     315               'singular-emacs-simple-sec-before)
     316
     317(singular-fset 'singular-simple-sec-in
     318               'singular-emacs-simple-sec-in
     319               'singular-emacs-simple-sec-in)
     320;;}}}
     321
     322;;{{{ Simple section stuff for Emacs
     323(defun singular-emacs-simple-sec-create (type end)
     324  "Create a new simple section of type TYPE.
     325Creates the section from end of previous simple section up to END.
     326Returns the new simple section or `empty' if no simple section has
     327been created.
     328Updates `singular-simple-sec-last-end'."
     329  (let ((last-end (marker-position singular-simple-sec-last-end))
     330        ;; `simple-sec' is the new simple section or `empty'
     331        simple-sec)
     332
     333    ;; get beginning of line before END
     334    (setq end (let ((save-point (point)))
     335                (goto-char end) (beginning-of-line)
     336                (prog1 (point) (goto-char save-point))))
     337
     338    (cond
     339     ;; do not create empty sections
     340     ((eq end last-end) (setq simple-sec 'empty))
     341     ;; create only non-clear simple sections
     342     ((not (eq type singular-simple-sec-clear-type))
     343      ;; if type has not changed we only have to extend the previous
     344      ;; simple section
     345      (setq simple-sec (singular-emacs-simple-sec-before last-end))
     346      (if (eq type (singular-emacs-simple-sec-type simple-sec))
     347          ;; move existing overlay
     348          (setq simple-sec (move-overlay simple-sec (overlay-start simple-sec) end))
     349        ;; create new overlay
     350        (setq simple-sec (make-overlay last-end end))
     351        ;; set type property
     352        (overlay-put simple-sec 'singular-type type)
     353        ;; set face
     354        (overlay-put simple-sec 'face (singular-lookup-face type))
     355        ;; evaporate empty sections
     356        (overlay-put simple-sec 'evaporate t))))
     357           
     358    ;; update end of last simple section
     359    (set-marker singular-simple-sec-last-end end)
     360    simple-sec))
     361
     362(defun singular-emacs-simple-sec-reset-last ()
     363  "Reset end of last simple section after accidental extension."
     364  (let ((simple-sec (singular-emacs-simple-sec-at singular-simple-sec-last-end)))
     365    (if simple-sec
     366        (move-overlay simple-sec (overlay-start simple-sec)
     367                      singular-simple-sec-last-end))))
     368
     369(defun singular-emacs-simple-sec-start (simple-sec)
     370  "Return start of non-clear simple section SIMPLE-SEC."
     371  (overlay-start simple-sec))
     372
     373(defun singular-emacs-simple-sec-end (simple-sec)
     374  "Return end of non-clear simple section SIMPLE-SEC."
     375  (overlay-end simple-sec))
     376
     377(defun singular-emacs-simple-sec-type (simple-sec)
     378  "Return type of SIMPLE-SEC."
     379  (if simple-sec
     380      (overlay-get simple-sec 'singular-type)
     381    singular-simple-sec-clear-type))
     382
     383(defun singular-emacs-simple-sec-at (pos)
     384  "Return simple section at position POS."
     385  (let ((overlays (overlays-at pos)) simple-sec)
     386    ;; be careful, there may be other overlays!
     387    (while (and overlays (not simple-sec))
     388      (if (singular-emacs-simple-sec-type (car overlays))
     389          (setq simple-sec (car overlays)))
     390      (setq overlays (cdr overlays)))
     391    simple-sec))
     392
     393(defun singular-emacs-simple-sec-before (pos)
     394  "Return simple section before position POS.
     395This is the same as `singular-emacs-section-at' except if POS falls on
     396a section border.  In this case `singular-emacs-section-before'
     397returns the previous simple section instead of the current one."
     398  (singular-emacs-simple-sec-at (max 1 (1- pos))))
     399
     400(defun singular-emacs-simple-sec-in (beg end)
     401  "Return a list of all simple sections intersecting with the region from BEG to END.
     402A simple section intersects the region if the section and the region
     403have at least one character in common.
     404The result contains both clear and non-clear simple sections in the
     405order in that the appear in the region."
     406  ;; NOT READY
     407  nil)
     408;;}}}
     409
     410;;{{{ Folding sections
     411(defvar singular-folding-ellipsis "Singular I/O ..."
     412  "Ellipsis to show for folded input or output.")
     413;;}}}
     414 
     415;;{{{ Debugging input and output filters
     416(defun singular-debug-input-filter (string)
     417  "Echo STRING in mini-buffer."
     418  (singular-debug 'interactive-filter
     419                  (message "Input filter: %s"
     420                           (singular-debug-format string))))
     421
     422(defun singular-debug-output-filter (string)
     423  "Echo STRING in mini-buffer."
     424  (singular-debug 'interactive-filter
     425                  (message "Output filter: %s"
     426                           (singular-debug-format string))))
     427;;}}}
     428
     429;;{{{ Sending input and receiving output
    237430
    238431;;{{{ Some lengthy notes on filters
     
    300493;; - `comint-last-input-start' <= `comint-last-input-end'
    301494;;                              = `comint-last-output-start' (!)
    302 ;;                              = process marker = `(point)'.
     495;;                              = process mark = `(point)'.
    303496;;   The region between the first of them is what has been inserted by the
    304497;;   user.
     
    317510;;}}}
    318511
    319 (defconst singular-bogus-output-filter-calls
    320   (cond
    321    ;; XEmacs
    322    ((eq singular-emacs-flavor 'xemacs) 2)
    323    ;; Emacs
    324    (t 1))
    325   "Number of bogus runs of hooks on `comint-output-filter-functions'.")
    326 
    327 ;; debugging filters
    328 (defvar singular-debug-bogus-output-filter-cnt 0
    329   "Number of bogus runs of hooks on `comint-output-filter-functions' yet to do.
    330 This variable is set to `singular-bogus-output-filter-calls' in
    331 `singular-debug-input-filter' and decremented for each bogus run of
    332 `singular-debug-output-filter' until it becomes zero.")
    333 
    334 (defun singular-debug-input-filter (string)
    335   "Echo STRING and reset `singular-debug-bogus-output-filter-cnt'."
    336   (message "Input filter: %s" (singular-debug-format string))
    337   (setq singular-debug-bogus-output-filter-cnt
    338         singular-bogus-output-filter-calls))
    339 
    340 (defun singular-debug-output-filter (string)
    341   "Echo STRING and `singular-debug-bogus-output-filter-cnt'.
    342 Decrement `singular-debug-bogus-output-filter-cnt' until it becomes zero."
    343   (if (zerop singular-debug-bogus-output-filter-cnt)
    344       (message "Output filter (real): %s"
    345                (singular-debug-format string))
    346     (message "Output filter (bogus %d): %s"
    347              singular-debug-bogus-output-filter-cnt
    348              (singular-debug-format string))
    349     (setq singular-debug-bogus-output-filter-cnt
    350           (1- singular-debug-bogus-output-filter-cnt))))
     512(defun singular-send-input (string)
     513  "NOT READY!!"
     514  ;; STRING is always nil when called interactively
     515  (interactive (list nil))
     516
     517  (let ((process (get-buffer-process (current-buffer)))
     518        pmark)
     519    ;; some checks and initializations
     520    (or process (error "Current buffer has no process"))
     521    (setq pmark (marker-position (process-mark process)))
     522
     523    ;; NOT READY[history expansion, handling of STRING]!
     524
     525    ;; note that the input string does not include its terminal newline
     526    (let* ((raw-input (buffer-substring pmark (point)))
     527           (input raw-input)
     528           (history raw-input))
     529
     530      ;; insert newline into buffer
     531      (insert-before-markers ?\n)
     532
     533      ;; insert input into history
     534      (if (and (funcall comint-input-filter history)
     535               (or (null comint-input-ignoredups)
     536                   (not (ring-p comint-input-ring))
     537                   (ring-empty-p comint-input-ring)
     538                   (not (string-equal (ring-ref comint-input-ring 0) history))))
     539          (ring-insert comint-input-ring history))
     540
     541      ;; run hooks and reset index into history
     542      (run-hook-with-args 'comint-input-filter-functions (concat input "\n"))
     543      (setq comint-input-ring-index nil)
     544
     545      ;; update markers and create a new simple section
     546      (set-marker comint-last-input-start pmark)
     547      (set-marker comint-last-input-end (point))
     548      (set-marker (process-mark process) (point))
     549      (singular-debug 'interactive-simple-secs
     550                      (message "Simple input section: %S"
     551                               (singular-simple-sec-create 'input (point)))
     552                      (singular-simple-sec-create 'input (point)))
     553
     554      ;; do it !!
     555      (send-string process input)
     556      (send-string process "\n"))))
     557
     558(defun singular-output-filter (process string)
     559  "Insert STRING containing output from PROCESS into its associated buffer.
     560
     561Takes care off:
     562- current buffer, even in case of non-local exits;
     563- point and restriction in buffer associated with process;
     564- markers which should not be advanced when inserting output.
     565Updates:
     566- process mark;
     567- `comint-last-output-start';
     568- simple sections;
     569- mode line.
     570Runs the hooks on `comint-output-filter-functions'.
     571
     572For a more detailed descriptions of the output filter, the markers it
     573sets, and output filter functions refer to the section \"Some lengthy
     574notes on filters\" in singular.el."
     575  (let ((process-buffer (process-buffer process))
     576        (save-buffer (current-buffer)))
     577
     578    ;; check whether buffer is still alive
     579    (if (and process-buffer (buffer-name process-buffer))
     580        (unwind-protect
     581            (progn
     582              (set-buffer process-buffer)
     583              (let ((save-point (point))
     584                    (save-point-min (point-min))
     585                    (save-point-max (point-max))
     586                    (save-pmark (marker-position (process-mark process)))
     587                    (buffer-read-only nil)
     588                    (n (length string)))
     589                (widen)
     590                (goto-char save-pmark)
     591
     592                ;; adjust point and narrowed region borders
     593                (if (<= (point) save-point) (setq save-point (+ save-point n)))
     594                (if (< (point) save-point-min) (setq save-point-min (+ save-point-min n)))
     595                (if (<= (point) save-point-max) (setq save-point-max (+ save-point-max n)))
     596
     597                ;; do it !!
     598                (insert-before-markers string)
     599
     600                ;; reset markers and simple sections which may have
     601                ;; been advanced by above insertion.  We rely on the
     602                ;; fact that `set-marker' always returns some non-nil
     603                ;; value.  Looks nicer this way.
     604                (and (= comint-last-input-end (point))
     605                     (set-marker comint-last-input-end save-pmark)
     606                     ;; this may happen only on startup and only if
     607                     ;; `comint-last-input-end' has been modified,
     608                     ;; too.  Hence, we check for it after the first
     609                     ;; test.
     610                     (= comint-last-input-start (point))
     611                     (set-marker comint-last-input-start save-pmark))
     612                (and (= singular-simple-sec-last-end (point))
     613                     (set-marker singular-simple-sec-last-end save-pmark)
     614                     (singular-simple-sec-reset-last))
     615
     616                ;; set new markers and create/extend new simple section
     617                (set-marker comint-last-output-start save-pmark)
     618                (singular-debug 'interactive-simple-secs
     619                                (message "Simple output section: %S"
     620                                         (singular-simple-sec-create 'output (point)))
     621                                (singular-simple-sec-create 'output (point)))
     622
     623                ;; restore old values, run hooks, and force mode line update
     624                (narrow-to-region save-point-min save-point-max)
     625                (goto-char save-point)
     626                (run-hook-with-args 'comint-output-filter-functions string)
     627                (force-mode-line-update)))
     628
     629          ;; this is unwind-protected
     630          (set-buffer save-buffer)))))
    351631;;}}}
    352632
    353633;;{{{ Singular interactive mode
    354 
    355 ;; Note:
    356 ;;
    357 ;; In contrast to shell.el, `singular' does not run
    358 ;; `singular-interactive-mode' every time a new Singular process is
    359 ;; started, but only when a new buffer is created.  This behaviour seems
    360 ;; more intuitive w.r.t. local variables and hooks.
    361 
    362634(defun singular-interactive-mode ()
    363635  "Major mode for interacting with Singular.
     
    412684      (setq comint-input-ring-file-name nil))
    413685
    414   ;; marking of input and output
     686  ;; selective display
     687  (setq selective-display t)
     688  (setq selective-display-ellipses t)
     689  (cond
     690   ;; Emacs
     691   ((eq singular-emacs-flavor 'emacs)
     692    (setq buffer-display-table (or (copy-sequence standard-display-table)
     693                                   (make-display-table)))
     694    (set-display-table-slot buffer-display-table
     695     'selective-display (vconcat singular-folding-ellipsis)))
     696    ;; XEmacs
     697   (t
     698    (set-glyph-image invisible-text-glyph singular-folding-ellipsis (current-buffer))))
     699
     700  ;; input and output filters
    415701  (singular-debug 'interactive-filter
    416702                  (add-hook 'comint-input-filter-functions
     
    448734  (save-excursion
    449735    (singular-debug 'interactive
    450                     (message "Sentinel message: %s" (substring message 0 -1)))
     736                    (message "Sentinel: %s" (substring message 0 -1)))
    451737    (if (string-match "finished\\|exited" message)
    452738        (let ((process-buffer (process-buffer process)))
     
    458744                (comint-write-input-ring)))))))
    459745
    460 (defun singular (&optional singular-executable singular-name singular-switches)
     746(defun singular-exec (buffer name executable start-file switches)
     747  "Start a new Singular process NAME in BUFFER, running EXECUTABLE.
     748EXECUTABLE should be a string denoting an executable program.
     749SWITCHES should be a list of strings that are passed as command line
     750switches.  START-FILE should be the name of a file which contents is
     751sent to the process.
     752
     753Deletes any old processes running in that buffer.
     754Moves point to the end of BUFFER.
     755Initializes all important markers and the simple sections.
     756Runs `comint-exec-hook' and `singular-exec-hook' (in that order).
     757Returns BUFFER."
     758  (let ((save-buffer (current-buffer)))
     759    (unwind-protect
     760        (progn
     761          (set-buffer buffer)
     762
     763          ;; delete any old processes
     764          (let ((process (get-buffer-process buffer)))
     765            (if process (delete-process process)))
     766
     767          ;; create new process
     768          (singular-debug 'interactive (message "Starting new Singular"))
     769          (let ((process (comint-exec-1 name buffer executable switches)))
     770
     771            ;; set process filter and sentinel
     772            (set-process-filter process 'singular-output-filter)
     773            (set-process-sentinel process 'singular-exit-sentinel)
     774            (make-local-variable 'comint-ptyp)
     775            (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe.
     776
     777            ;; go to the end of the buffer, set up markers, and
     778            ;; initialize simple sections
     779            (goto-char (point-max))
     780            (set-marker comint-last-input-start (point))
     781            (set-marker comint-last-input-end (point))
     782            (set-marker comint-last-output-start (point))
     783            (set-marker (process-mark process) (point))
     784            (singular-simple-sec-init (point))
     785
     786            ;; feed process with start file and read input ring
     787            (if start-file
     788                (progn
     789                  (singular-debug 'interactive (message "Feeding start file"))
     790                  (sleep-for 1)                 ; try to avoid timing errors
     791                  (insert-file-contents start-file)
     792                  (setq start-file (buffer-substring (point) (point-max)))
     793                  (delete-region (point) (point-max))
     794                  (comint-send-string process start-file)))
     795            (singular-debug 'interactive (message "Reading input ring"))
     796            (comint-read-input-ring t)
     797
     798            ;; execute hooks
     799            (run-hooks 'comint-exec-hook)
     800            (run-hooks 'singular-exec-hook))
     801         
     802          buffer)
     803      ;; this code is unwide-protected
     804      (set-buffer save-buffer))))
     805
     806;; Note:
     807;;
     808;; In contrast to shell.el, `singular' does not run
     809;; `singular-interactive-mode' every time a new Singular process is
     810;; started, but only when a new buffer is created.  This behaviour seems
     811;; more intuitive w.r.t. local variables and hooks.
     812
     813(defun singular (&optional executable name switches)
    461814  "Run an inferior Singular process, with I/O through an Emacs buffer.
    462815
     
    483836
    484837  (let* (;; get default values for optional arguments
    485          (singular-executable (or singular-executable
    486                                   singular-default-executable))
    487          (singular-name (or singular-name
    488                             singular-default-name))
    489          (singular-switches (or singular-switches
    490                                 singular-default-switches))
    491 
    492          (buffer-name (singular-process-name-to-buffer-name singular-name))
     838         (executable (or executable singular-default-executable))
     839         (name (or name singular-default-name))
     840         (switches (or switches singular-default-switches))
     841
     842         (buffer-name (singular-process-name-to-buffer-name name))
    493843         ;; buffer associated with Singular, nil if there is none
    494844         (buffer (get-buffer buffer-name)))
    495845
    496     ;; create new buffer if there has been none and call
    497     ;; `singular-interactive-mode'
    498846    (if (not buffer)
    499847        (progn
     848          ;; create new buffer and call `singular-interactive-mode'
    500849          (singular-debug 'interactive (message "Creating new buffer"))
    501850          (setq buffer (get-buffer-create buffer-name))
     
    504853          (singular-interactive-mode)))
    505854
    506     ;; create new process if there has been none
    507855    (if (not (comint-check-proc buffer))
    508         (progn
    509           ;; initialize markers.  process-marker is initialized by
    510           ;; `comint-exec'.
    511           (set-marker comint-last-input-start nil)
    512           (set-marker comint-last-input-end nil)
    513           (set-marker comint-last-output-start nil)
    514 
    515           ;; note that `comint-exec' may result in some process output already!
    516           ;; Note furthermore that we use `comint-exec' instead of
    517           ;; `make-comint' to avoid double calls of `comint-mode'.
    518           (singular-debug 'interactive (message "Starting new Singular"))
    519           (setq buffer (funcall 'comint-exec buffer singular-name singular-executable
    520                                 (if (file-exists-p singular-start-file) singular-start-file)
    521                                 singular-switches))
    522           (set-process-sentinel (get-buffer-process buffer) 'singular-exit-sentinel)
    523           (set-buffer buffer)
    524           (singular-debug 'interactive (message "Reading input ring"))
    525           (comint-read-input-ring t)
    526 
    527           ;; go to end of buffer and run hooks
    528           (goto-char (point-max))
    529           (run-hooks 'singular-exec-hook)))
     856        ;; create new process if there is none
     857        (singular-exec buffer name executable
     858                       (if (file-exists-p singular-start-file)
     859                           singular-start-file)
     860                       switches))
    530861
    531862    ;; pop to buffer
Note: See TracChangeset for help on using the changeset viewer.