Annotation of GNUtools/emacs/lisp/xscheme.el, revision 1.1.1.1

1.1       root        1: ;; Run Scheme under Emacs
                      2: ;; Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
                      3: 
                      4: ;; This file is part of GNU Emacs.
                      5: 
                      6: ;; GNU Emacs is free software; you can redistribute it and/or modify
                      7: ;; it under the terms of the GNU General Public License as published by
                      8: ;; the Free Software Foundation; either version 1, or (at your option)
                      9: ;; any later version.
                     10: 
                     11: ;; GNU Emacs is distributed in the hope that it will be useful,
                     12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: ;; GNU General Public License for more details.
                     15: 
                     16: ;; You should have received a copy of the GNU General Public License
                     17: ;; along with GNU Emacs; see the file COPYING.  If not, write to
                     18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     19: 
                     20: ;;; Requires C-Scheme release 5 or later
                     21: ;;; Changes to Control-G handler require runtime version 13.85 or later
                     22: 
                     23: ;;; $Header: xscheme.el,v 1.23 89/04/28 22:59:40 GMT cph Rel $
                     24: 
                     25: (require 'scheme)
                     26: 
                     27: (defvar scheme-program-name "scheme"
                     28:   "*Program invoked by the `run-scheme' command.")
                     29: 
                     30: (defvar scheme-band-name nil
                     31:   "*Band loaded by the `run-scheme' command.")
                     32: 
                     33: (defvar scheme-program-arguments nil
                     34:   "*Arguments passed to the Scheme program by the `run-scheme' command.")
                     35: 
                     36: (defvar xscheme-allow-pipelined-evaluation t
                     37:   "If non-nil, an expression may be transmitted while another is evaluating.
                     38: Otherwise, attempting to evaluate an expression before the previous expression
                     39: has finished evaluating will signal an error.")
                     40: 
                     41: (defvar xscheme-startup-message
                     42:   "This is the Scheme process buffer.
                     43: Type \\[advertised-xscheme-send-previous-expression] to evaluate the expression before point.
                     44: Type \\[xscheme-send-control-g-interrupt] to abort evaluation.
                     45: Type \\[describe-mode] for more information.
                     46: 
                     47: "
                     48:   "String to insert into Scheme process buffer first time it is started.
                     49: Is processed with `substitute-command-keys' first.")
                     50: 
                     51: (defvar xscheme-signal-death-message nil
                     52:   "If non-nil, causes a message to be generated when the Scheme process dies.")
                     53: 
                     54: (defun xscheme-evaluation-commands (keymap)
                     55:   (define-key keymap "\e\C-x" 'xscheme-send-definition)
                     56:   (define-key keymap "\C-x\C-e" 'advertised-xscheme-send-previous-expression)
                     57:   (define-key keymap "\eo" 'xscheme-send-buffer)
                     58:   (define-key keymap "\ez" 'xscheme-send-definition)
                     59:   (define-key keymap "\e\C-m" 'xscheme-send-previous-expression)
                     60:   (define-key keymap "\e\C-z" 'xscheme-send-region))
                     61: 
                     62: (defun xscheme-interrupt-commands (keymap)
                     63:   (define-key keymap "\C-c\C-s" 'xscheme-select-process-buffer)
                     64:   (define-key keymap "\C-c\C-b" 'xscheme-send-breakpoint-interrupt)
                     65:   (define-key keymap "\C-c\C-c" 'xscheme-send-control-g-interrupt)
                     66:   (define-key keymap "\C-c\C-u" 'xscheme-send-control-u-interrupt)
                     67:   (define-key keymap "\C-c\C-x" 'xscheme-send-control-x-interrupt))
                     68: 
                     69: (xscheme-evaluation-commands scheme-mode-map)
                     70: (xscheme-interrupt-commands scheme-mode-map)
                     71: 
                     72: (defun run-scheme (command-line)
                     73:   "Run an inferior Scheme process.
                     74: Output goes to the buffer `*scheme*'.
                     75: With argument, asks for a command line."
                     76:   (interactive
                     77:    (list (let ((default
                     78:                 (or xscheme-process-command-line
                     79:                     (xscheme-default-command-line))))
                     80:           (if current-prefix-arg
                     81:               (read-string "Run Scheme: " default)
                     82:               default))))
                     83:   (setq xscheme-process-command-line command-line)
                     84:   (switch-to-buffer (xscheme-start-process command-line)))
                     85: 
                     86: (defun reset-scheme ()
                     87:   "Reset the Scheme process."
                     88:   (interactive)
                     89:   (let ((process (get-process "scheme")))
                     90:     (cond ((or (not process)
                     91:               (not (eq (process-status process) 'run))
                     92:               (yes-or-no-p
                     93: "The Scheme process is running, are you SURE you want to reset it? "))
                     94:           (message "Resetting Scheme process...")
                     95:           (if process (kill-process process t))
                     96:           (xscheme-start-process xscheme-process-command-line)
                     97:           (message "Resetting Scheme process...done")))))
                     98: 
                     99: (defun xscheme-default-command-line ()
                    100:   (concat scheme-program-name " -emacs"
                    101:          (if scheme-program-arguments
                    102:              (concat " " scheme-program-arguments)
                    103:              "")
                    104:          (if scheme-band-name
                    105:              (concat " -band " scheme-band-name)
                    106:              "")))
                    107: 
                    108: ;;;; Interaction Mode
                    109: 
                    110: (defun scheme-interaction-mode ()
                    111:   "Major mode for interacting with the inferior Scheme process.
                    112: Like  scheme-mode  except that:
                    113: 
                    114: \\[advertised-xscheme-send-previous-expression] sends the expression before point to the Scheme process as input
                    115: \\[xscheme-yank-previous-send] yanks the expression most recently sent to Scheme
                    116: 
                    117: All output from the Scheme process is written in the Scheme process
                    118: buffer, which is initially named \"*scheme*\".  The result of
                    119: evaluating a Scheme expression is also printed in the process buffer,
                    120: preceded by the string \";Value: \" to highlight it.  If the process
                    121: buffer is not visible at that time, the value will also be displayed
                    122: in the minibuffer.  If an error occurs, the process buffer will
                    123: automatically pop up to show you the error message.
                    124: 
                    125: While the Scheme process is running, the modelines of all buffers in
                    126: scheme-mode are modified to show the state of the process.  The
                    127: possible states and their meanings are:
                    128: 
                    129: input          waiting for input
                    130: run            evaluating
                    131: gc             garbage collecting
                    132: 
                    133: The process buffer's modeline contains additional information where
                    134: the buffer's name is normally displayed: the command interpreter level
                    135: and type.
                    136: 
                    137: Scheme maintains a stack of command interpreters.  Every time an error
                    138: or breakpoint occurs, the current command interpreter is pushed on the
                    139: command interpreter stack, and a new command interpreter is started.
                    140: One example of why this is done is so that an error that occurs while
                    141: you are debugging another error will not destroy the state of the
                    142: initial error, allowing you to return to it after the second error has
                    143: been fixed.
                    144: 
                    145: The command interpreter level indicates how many interpreters are in
                    146: the command interpreter stack.  It is initially set to one, and it is
                    147: incremented every time that stack is pushed, and decremented every
                    148: time it is popped.  The following commands are useful for manipulating
                    149: the command interpreter stack:
                    150: 
                    151: \\[xscheme-send-breakpoint-interrupt]  pushes the stack once
                    152: \\[xscheme-send-control-u-interrupt]   pops the stack once
                    153: \\[xscheme-send-control-g-interrupt]   pops everything off
                    154: \\[xscheme-send-control-x-interrupt]   aborts evaluation, doesn't affect stack
                    155: 
                    156: Some possible command interpreter types and their meanings are:
                    157: 
                    158: [Evaluator]    read-eval-print loop for evaluating expressions
                    159: [Debugger]     single character commands for debugging errors
                    160: [Where]                single character commands for examining environments
                    161: 
                    162: Starting with release 6.2 of Scheme, the latter two types of command
                    163: interpreters will change the major mode of the Scheme process buffer
                    164: to scheme-debugger-mode , in which the evaluation commands are
                    165: disabled, and the keys which normally self insert instead send
                    166: themselves to the Scheme process.  The command character ? will list
                    167: the available commands.
                    168: 
                    169: For older releases of Scheme, the major mode will be be
                    170: scheme-interaction-mode , and the command characters must be sent as
                    171: if they were expressions.
                    172: 
                    173: Commands:
                    174: Delete converts tabs to spaces as it moves back.
                    175: Blank lines separate paragraphs.  Semicolons start comments.
                    176: \\{scheme-interaction-mode-map}
                    177: 
                    178: Entry to this mode calls the value of scheme-interaction-mode-hook
                    179: with no args, if that value is non-nil."
                    180:   (interactive)
                    181:   (kill-all-local-variables)
                    182:   (scheme-interaction-mode-initialize)
                    183:   (scheme-mode-variables)
                    184:   (make-local-variable 'xscheme-previous-send)
                    185:   (run-hooks 'scheme-interaction-mode-hook))
                    186: 
                    187: (defun scheme-interaction-mode-initialize ()
                    188:   (use-local-map scheme-interaction-mode-map)
                    189:   (setq major-mode 'scheme-interaction-mode)
                    190:   (setq mode-name "Scheme Interaction"))
                    191: 
                    192: (defun scheme-interaction-mode-commands (keymap)
                    193:   (define-key keymap "\C-c\C-m" 'xscheme-send-current-line)
                    194:   (define-key keymap "\C-c\C-p" 'xscheme-send-proceed)
                    195:   (define-key keymap "\C-c\C-y" 'xscheme-yank-previous-send))
                    196: 
                    197: (defvar scheme-interaction-mode-map nil)
                    198: (if (not scheme-interaction-mode-map)
                    199:     (progn
                    200:       (setq scheme-interaction-mode-map (make-keymap))
                    201:       (scheme-mode-commands scheme-interaction-mode-map)
                    202:       (xscheme-interrupt-commands scheme-interaction-mode-map)
                    203:       (xscheme-evaluation-commands scheme-interaction-mode-map)
                    204:       (scheme-interaction-mode-commands scheme-interaction-mode-map)))
                    205: 
                    206: (defun xscheme-enter-interaction-mode ()
                    207:   (save-excursion
                    208:     (set-buffer (xscheme-process-buffer))
                    209:     (if (not (eq major-mode 'scheme-interaction-mode))
                    210:        (if (eq major-mode 'scheme-debugger-mode)
                    211:            (scheme-interaction-mode-initialize)
                    212:            (scheme-interaction-mode)))))
                    213: 
                    214: (fset 'advertised-xscheme-send-previous-expression
                    215:       'xscheme-send-previous-expression)
                    216: 
                    217: ;;;; Debugger Mode
                    218: 
                    219: (defun scheme-debugger-mode ()
                    220:   "Major mode for executing the Scheme debugger.
                    221: Like  scheme-mode  except that the evaluation commands
                    222: are disabled, and characters that would normally be self inserting are
                    223: sent to the Scheme process instead.  Typing ?  will show you which
                    224: characters perform useful functions.
                    225: 
                    226: Commands:
                    227: \\{scheme-debugger-mode-map}"
                    228:   (error "Illegal entry to scheme-debugger-mode"))
                    229: 
                    230: (defun scheme-debugger-mode-initialize ()
                    231:   (use-local-map scheme-debugger-mode-map)
                    232:   (setq major-mode 'scheme-debugger-mode)
                    233:   (setq mode-name "Scheme Debugger"))
                    234: 
                    235: (defun scheme-debugger-mode-commands (keymap)
                    236:   (let ((char ? ))
                    237:     (while (< char 127)
                    238:       (define-key keymap (char-to-string char) 'scheme-debugger-self-insert)
                    239:       (setq char (1+ char)))))
                    240: 
                    241: (defvar scheme-debugger-mode-map nil)
                    242: (if (not scheme-debugger-mode-map)
                    243:     (progn
                    244:       (setq scheme-debugger-mode-map (make-keymap))
                    245:       (scheme-mode-commands scheme-debugger-mode-map)
                    246:       (xscheme-interrupt-commands scheme-debugger-mode-map)
                    247:       (scheme-debugger-mode-commands scheme-debugger-mode-map)))
                    248: 
                    249: (defun scheme-debugger-self-insert ()
                    250:   "Transmit this character to the Scheme process."
                    251:   (interactive)
                    252:   (xscheme-send-char last-command-char))
                    253: 
                    254: (defun xscheme-enter-debugger-mode (prompt-string)
                    255:   (save-excursion
                    256:     (set-buffer (xscheme-process-buffer))
                    257:     (if (not (eq major-mode 'scheme-debugger-mode))
                    258:        (progn
                    259:          (if (not (eq major-mode 'scheme-interaction-mode))
                    260:              (scheme-interaction-mode))
                    261:          (scheme-debugger-mode-initialize)))))
                    262: 
                    263: (defun xscheme-debugger-mode-p ()
                    264:   (let ((buffer (xscheme-process-buffer)))
                    265:     (and buffer
                    266:         (save-excursion
                    267:           (set-buffer buffer)
                    268:           (eq major-mode 'scheme-debugger-mode)))))
                    269: 
                    270: ;;;; Evaluation Commands
                    271: 
                    272: (defun xscheme-send-string (&rest strings)
                    273:   "Send the string arguments to the Scheme process.
                    274: The strings are concatenated and terminated by a newline."
                    275:   (cond ((not (xscheme-process-running-p))
                    276:         (if (yes-or-no-p "The Scheme process has died.  Reset it? ")
                    277:             (progn
                    278:               (reset-scheme)
                    279:               (xscheme-wait-for-process)
                    280:               (goto-char (point-max))
                    281:               (apply 'insert-before-markers strings)
                    282:               (xscheme-send-string-1 strings))))
                    283:        ((xscheme-debugger-mode-p) (error "No sends allowed in debugger mode"))
                    284:        ((and (not xscheme-allow-pipelined-evaluation)
                    285:              xscheme-running-p)
                    286:         (error "No sends allowed while Scheme running"))
                    287:        (t (xscheme-send-string-1 strings))))
                    288: 
                    289: (defun xscheme-send-string-1 (strings)
                    290:   (let ((string (apply 'concat strings)))
                    291:     (xscheme-send-string-2 string)
                    292:     (if (eq major-mode 'scheme-interaction-mode)
                    293:        (setq xscheme-previous-send string))))
                    294: 
                    295: (defun xscheme-send-string-2 (string)
                    296:   (let ((process (get-process "scheme")))
                    297:     (send-string process (concat string "\n"))
                    298:     (if (xscheme-process-buffer-current-p)
                    299:        (set-marker (process-mark process) (point)))))
                    300: 
                    301: (defun xscheme-yank-previous-send ()
                    302:   "Insert the most recent expression at point."
                    303:   (interactive)
                    304:   (push-mark)
                    305:   (insert xscheme-previous-send))
                    306: 
                    307: (defun xscheme-select-process-buffer ()
                    308:   "Select the Scheme process buffer and move to its output point."
                    309:   (interactive)
                    310:   (let ((process (or (get-process "scheme") (error "No scheme process"))))
                    311:     (let ((buffer (or (process-buffer process) (error "No process buffer"))))
                    312:       (let ((window (get-buffer-window buffer)))
                    313:        (if window
                    314:            (select-window window)
                    315:            (switch-to-buffer buffer))
                    316:        (goto-char (process-mark process))))))
                    317: 
                    318: (defun xscheme-send-region (start end)
                    319:   "Send the current region to the Scheme process.
                    320: The region is sent terminated by a newline."
                    321:   (interactive "r")
                    322:   (if (xscheme-process-buffer-current-p)
                    323:       (progn (goto-char end)
                    324:             (set-marker (process-mark (get-process "scheme")) end)))
                    325:   (xscheme-send-string (buffer-substring start end)))
                    326: 
                    327: (defun xscheme-send-definition ()
                    328:   "Send the current definition to the Scheme process.
                    329: If the current line begins with a non-whitespace character,
                    330: parse an expression from the beginning of the line and send that instead."
                    331:   (interactive)
                    332:   (let ((start nil) (end nil))
                    333:     (save-excursion
                    334:       (end-of-defun)
                    335:       (setq end (point))
                    336:       (if (re-search-backward "^\\s(" nil t)
                    337:          (setq start (point))
                    338:          (error "Can't find definition")))
                    339:     (xscheme-send-region start end)))
                    340: 
                    341: (defun xscheme-send-next-expression ()
                    342:   "Send the expression to the right of `point' to the Scheme process."
                    343:   (interactive)
                    344:   (let ((start (point)))
                    345:     (xscheme-send-region start (save-excursion (forward-sexp) (point)))))
                    346: 
                    347: (defun xscheme-send-previous-expression ()
                    348:   "Send the expression to the left of `point' to the Scheme process."
                    349:   (interactive)
                    350:   (let ((end (point)))
                    351:     (xscheme-send-region (save-excursion (backward-sexp) (point)) end)))
                    352: 
                    353: (defun xscheme-send-current-line ()
                    354:   "Send the current line to the Scheme process.
                    355: Useful for working with debugging Scheme under adb."
                    356:   (interactive)
                    357:   (let ((line
                    358:         (save-excursion
                    359:           (beginning-of-line)
                    360:           (let ((start (point)))
                    361:             (end-of-line)
                    362:             (buffer-substring start (point))))))
                    363:     (end-of-line)
                    364:     (insert ?\n)
                    365:     (xscheme-send-string-2 line)))
                    366: 
                    367: (defun xscheme-send-buffer ()
                    368:   "Send the current buffer to the Scheme process."
                    369:   (interactive)
                    370:   (if (xscheme-process-buffer-current-p)
                    371:       (error "Not allowed to send this buffer's contents to Scheme"))
                    372:   (xscheme-send-region (point-min) (point-max)))
                    373: 
                    374: (defun xscheme-send-char (char)
                    375:   "Prompt for a character and send it to the Scheme process."
                    376:   (interactive "cCharacter to send: ")
                    377:   (send-string "scheme" (char-to-string char)))
                    378: 
                    379: ;;;; Interrupts
                    380: 
                    381: (defun xscheme-send-breakpoint-interrupt ()
                    382:   "Cause the Scheme process to enter a breakpoint."
                    383:   (interactive)
                    384:   (xscheme-send-interrupt ?b nil))
                    385: 
                    386: (defun xscheme-send-proceed ()
                    387:   "Cause the Scheme process to proceed from a breakpoint."
                    388:   (interactive)
                    389:   (send-string "scheme" "(proceed)\n"))
                    390: 
                    391: (defun xscheme-send-control-g-interrupt ()
                    392:   "Cause the Scheme processor to halt and flush input.
                    393: Control returns to the top level rep loop."
                    394:   (interactive)
                    395:   (let ((inhibit-quit t))
                    396:     (cond ((not xscheme-control-g-synchronization-p)
                    397:           (interrupt-process "scheme"))
                    398:          (xscheme-control-g-disabled-p
                    399:           (message "Relax..."))
                    400:          (t
                    401:           (setq xscheme-control-g-disabled-p t)
                    402:           (message "Sending C-G interrupt to Scheme...")
                    403:           (interrupt-process "scheme")
                    404:           (send-string "scheme" (char-to-string 0))))))
                    405: 
                    406: (defun xscheme-send-control-u-interrupt ()
                    407:   "Cause the Scheme process to halt, returning to previous rep loop."
                    408:   (interactive)
                    409:   (xscheme-send-interrupt ?u t))
                    410: 
                    411: (defun xscheme-send-control-x-interrupt ()
                    412:   "Cause the Scheme process to halt, returning to current rep loop."
                    413:   (interactive)
                    414:   (xscheme-send-interrupt ?x t))
                    415: 
                    416: ;;; This doesn't really work right -- Scheme just gobbles the first
                    417: ;;; character in the input.  There is no way for us to guarantee that
                    418: ;;; the argument to this procedure is the first char unless we put
                    419: ;;; some kind of marker in the input stream.
                    420: 
                    421: (defun xscheme-send-interrupt (char mark-p)
                    422:   "Send a ^A type interrupt to the Scheme process."
                    423:   (interactive "cInterrupt character to send: ")
                    424:   (quit-process "scheme")
                    425:   (send-string "scheme" (char-to-string char))
                    426:   (if (and mark-p xscheme-control-g-synchronization-p)
                    427:       (send-string "scheme" (char-to-string 0))))
                    428: 
                    429: ;;;; Internal Variables
                    430: 
                    431: (defvar xscheme-process-command-line nil
                    432:   "Command used to start the most recent Scheme process.")
                    433: 
                    434: (defvar xscheme-previous-send ""
                    435:   "Most recent expression transmitted to the Scheme process.")
                    436: 
                    437: (defvar xscheme-process-filter-state 'idle
                    438:   "State of scheme process escape reader state machine:
                    439: idle                   waiting for an escape sequence
                    440: reading-type           received an altmode but nothing else
                    441: reading-string         reading prompt string")
                    442: 
                    443: (defvar xscheme-running-p nil
                    444:   "This variable, if nil, indicates that the scheme process is
                    445: waiting for input.  Otherwise, it is busy evaluating something.")
                    446: 
                    447: (defconst xscheme-control-g-synchronization-p t
                    448:   "If non-nil, insert markers in the scheme input stream to indicate when
                    449: control-g interrupts were signalled.  Do not allow more control-g's to be
                    450: signalled until the scheme process acknowledges receipt.")
                    451: 
                    452: (defvar xscheme-control-g-disabled-p nil
                    453:   "This variable, if non-nil, indicates that a control-g is being processed
                    454: by the scheme process, so additional control-g's are to be ignored.")
                    455: 
                    456: (defvar xscheme-allow-output-p t
                    457:   "This variable, if nil, prevents output from the scheme process
                    458: from being inserted into the process-buffer.")
                    459: 
                    460: (defvar xscheme-prompt ""
                    461:   "The current scheme prompt string.")
                    462: 
                    463: (defvar xscheme-string-accumulator ""
                    464:   "Accumulator for the string being received from the scheme process.")
                    465: 
                    466: (defvar xscheme-string-receiver nil
                    467:   "Procedure to send the string argument from the scheme process.")
                    468: 
                    469: (defvar xscheme-start-hook nil
                    470:   "If non-nil, a procedure to call when the Scheme process is started.
                    471: When called, the current buffer will be the Scheme process-buffer.")
                    472: 
                    473: (defvar xscheme-runlight-string nil)
                    474: (defvar xscheme-mode-string nil)
                    475: (defvar xscheme-filter-input nil)
                    476: 
                    477: ;;;; Basic Process Control
                    478: 
                    479: (defun xscheme-start-process (command-line)
                    480:   (let ((buffer (get-buffer-create "*scheme*")))
                    481:     (let ((process (get-buffer-process buffer)))
                    482:       (save-excursion
                    483:        (set-buffer buffer)
                    484:        (if (and process (memq (process-status process) '(run stop)))
                    485:            (set-marker (process-mark process) (point-max))
                    486:            (progn (if process (delete-process process))
                    487:                   (goto-char (point-max))
                    488:                   (scheme-interaction-mode)
                    489:                   (if (bobp)
                    490:                       (insert-before-markers
                    491:                        (substitute-command-keys xscheme-startup-message)))
                    492:                   (setq process
                    493:                         (let ((process-connection-type nil))
                    494:                           (apply 'start-process
                    495:                                  (cons "scheme"
                    496:                                        (cons buffer
                    497:                                              (xscheme-parse-command-line
                    498:                                               command-line))))))
                    499:                   (set-marker (process-mark process) (point-max))
                    500:                   (xscheme-process-filter-initialize t)
                    501:                   (xscheme-modeline-initialize)
                    502:                   (set-process-sentinel process 'xscheme-process-sentinel)
                    503:                   (set-process-filter process 'xscheme-process-filter)
                    504:                   (run-hooks 'xscheme-start-hook)))))
                    505:     buffer))
                    506: 
                    507: (defun xscheme-parse-command-line (string)
                    508:   (setq string (substitute-in-file-name string))
                    509:   (let ((start 0)
                    510:        (result '()))
                    511:     (while start
                    512:       (let ((index (string-match "[ \t]" string start)))
                    513:        (setq start
                    514:              (cond ((not index)
                    515:                     (setq result
                    516:                           (cons (substring string start)
                    517:                                 result))
                    518:                     nil)
                    519:                    ((= index start)
                    520:                     (string-match "[^ \t]" string start))
                    521:                    (t
                    522:                     (setq result
                    523:                           (cons (substring string start index)
                    524:                                 result))
                    525:                     (1+ index))))))
                    526:     (nreverse result)))
                    527: 
                    528: (defun xscheme-wait-for-process ()
                    529:   (sleep-for 2)
                    530:   (while xscheme-running-p
                    531:     (sleep-for 1)))
                    532: 
                    533: (defun xscheme-process-running-p ()
                    534:   "True iff there is a Scheme process whose status is `run'."
                    535:   (let ((process (get-process "scheme")))
                    536:     (and process
                    537:         (eq (process-status process) 'run))))
                    538: 
                    539: (defun xscheme-process-buffer ()
                    540:   (let ((process (get-process "scheme")))
                    541:     (and process (process-buffer process))))
                    542: 
                    543: (defun xscheme-process-buffer-window ()
                    544:   (let ((buffer (xscheme-process-buffer)))
                    545:     (and buffer (get-buffer-window buffer))))
                    546: 
                    547: (defun xscheme-process-buffer-current-p ()
                    548:   "True iff the current buffer is the Scheme process buffer."
                    549:   (eq (xscheme-process-buffer) (current-buffer)))
                    550: 
                    551: ;;;; Process Filter
                    552: 
                    553: (defun xscheme-process-sentinel (proc reason)
                    554:   (xscheme-process-filter-initialize (eq reason 'run))
                    555:   (if (eq reason 'run)
                    556:       (xscheme-modeline-initialize)
                    557:       (progn
                    558:        (setq scheme-mode-line-process "")
                    559:        (setq xscheme-mode-string "no process")))
                    560:   (if (and (not (memq reason '(run stop)))
                    561:           xscheme-signal-death-message)
                    562:       (progn (beep)
                    563:             (message
                    564: "The Scheme process has died!  Do M-x reset-scheme to restart it"))))
                    565: 
                    566: (defun xscheme-process-filter-initialize (running-p)
                    567:   (setq xscheme-process-filter-state 'idle)
                    568:   (setq xscheme-running-p running-p)
                    569:   (setq xscheme-control-g-disabled-p nil)
                    570:   (setq xscheme-allow-output-p t)
                    571:   (setq xscheme-prompt "")
                    572:   (setq scheme-mode-line-process '(": " xscheme-runlight-string)))
                    573: 
                    574: (defun xscheme-process-filter (proc string)
                    575:   (let ((xscheme-filter-input string))
                    576:     (while xscheme-filter-input
                    577:       (cond ((eq xscheme-process-filter-state 'idle)
                    578:             (let ((start (string-match "\e" xscheme-filter-input)))
                    579:               (if start
                    580:                   (progn
                    581:                     (xscheme-process-filter-output
                    582:                      (substring xscheme-filter-input 0 start))
                    583:                     (setq xscheme-filter-input
                    584:                           (substring xscheme-filter-input (1+ start)))
                    585:                     (setq xscheme-process-filter-state 'reading-type))
                    586:                   (let ((string xscheme-filter-input))
                    587:                     (setq xscheme-filter-input nil)
                    588:                     (xscheme-process-filter-output string)))))
                    589:            ((eq xscheme-process-filter-state 'reading-type)
                    590:             (if (zerop (length xscheme-filter-input))
                    591:                 (setq xscheme-filter-input nil)
                    592:                 (let ((char (aref xscheme-filter-input 0)))
                    593:                   (setq xscheme-filter-input
                    594:                         (substring xscheme-filter-input 1))
                    595:                   (let ((entry (assoc char xscheme-process-filter-alist)))
                    596:                     (if entry
                    597:                         (funcall (nth 2 entry) (nth 1 entry))
                    598:                         (progn
                    599:                           (xscheme-process-filter-output ?\e char)
                    600:                           (setq xscheme-process-filter-state 'idle)))))))
                    601:            ((eq xscheme-process-filter-state 'reading-string)
                    602:             (let ((start (string-match "\e" xscheme-filter-input)))
                    603:               (if start
                    604:                   (let ((string
                    605:                          (concat xscheme-string-accumulator
                    606:                                  (substring xscheme-filter-input 0 start))))
                    607:                     (setq xscheme-filter-input
                    608:                           (substring xscheme-filter-input (1+ start)))
                    609:                     (setq xscheme-process-filter-state 'idle)
                    610:                     (funcall xscheme-string-receiver string))
                    611:                   (progn
                    612:                     (setq xscheme-string-accumulator
                    613:                           (concat xscheme-string-accumulator
                    614:                                   xscheme-filter-input))
                    615:                     (setq xscheme-filter-input nil)))))
                    616:            (t
                    617:             (error "Scheme process filter -- bad state"))))))
                    618: 
                    619: ;;;; Process Filter Output
                    620: 
                    621: (defun xscheme-process-filter-output (&rest args)
                    622:   (if xscheme-allow-output-p
                    623:       (let ((string (apply 'concat args)))
                    624:        (save-excursion
                    625:          (xscheme-goto-output-point)
                    626:          (while (string-match "\\(\007\\|\f\\)" string)
                    627:            (let ((start (match-beginning 0))
                    628:                  (end (match-end 0)))
                    629:              (insert-before-markers (substring string 0 start))
                    630:              (if (= ?\f (aref string start))
                    631:                  (progn
                    632:                    (if (not (bolp))
                    633:                        (insert-before-markers ?\n))
                    634:                    (insert-before-markers ?\f))
                    635:                  (beep))
                    636:              (setq string (substring string (1+ start)))))
                    637:          (insert-before-markers string)))))
                    638: 
                    639: (defun xscheme-guarantee-newlines (n)
                    640:   (if xscheme-allow-output-p
                    641:       (save-excursion
                    642:        (xscheme-goto-output-point)
                    643:        (let ((stop nil))
                    644:          (while (and (not stop)
                    645:                      (bolp))
                    646:            (setq n (1- n))
                    647:            (if (bobp)
                    648:                (setq stop t)
                    649:                (backward-char))))
                    650:        (xscheme-goto-output-point)
                    651:        (while (> n 0)
                    652:          (insert-before-markers ?\n)
                    653:          (setq n (1- n))))))
                    654: 
                    655: (defun xscheme-goto-output-point ()
                    656:   (let ((process (get-process "scheme")))
                    657:     (set-buffer (process-buffer process))
                    658:     (goto-char (process-mark process))))
                    659: 
                    660: (defun xscheme-modeline-initialize ()
                    661:   (setq xscheme-runlight-string "")
                    662:   (setq xscheme-mode-string "")
                    663:   (setq mode-line-buffer-identification '("Scheme: " xscheme-mode-string)))
                    664: 
                    665: (defun xscheme-set-runlight (runlight)
                    666:   (setq xscheme-runlight-string runlight)
                    667:   (xscheme-modeline-redisplay))
                    668: 
                    669: (defun xscheme-modeline-redisplay ()
                    670:   (save-excursion (set-buffer (other-buffer)))
                    671:   (set-buffer-modified-p (buffer-modified-p))
                    672:   (sit-for 0))
                    673: 
                    674: ;;;; Process Filter Operations
                    675: 
                    676: (defvar xscheme-process-filter-alist
                    677:   '((?D xscheme-enter-debugger-mode
                    678:        xscheme-process-filter:string-action)
                    679:     (?P xscheme-set-prompt-variable
                    680:        xscheme-process-filter:string-action)
                    681:     (?R xscheme-enter-interaction-mode
                    682:        xscheme-process-filter:simple-action)
                    683:     (?b xscheme-start-gc
                    684:        xscheme-process-filter:simple-action)
                    685:     (?e xscheme-finish-gc
                    686:        xscheme-process-filter:simple-action)
                    687:     (?f xscheme-exit-input-wait
                    688:        xscheme-process-filter:simple-action)
                    689:     (?g xscheme-enable-control-g
                    690:        xscheme-process-filter:simple-action)
                    691:     (?i xscheme-prompt-for-expression
                    692:        xscheme-process-filter:string-action)
                    693:     (?m xscheme-message
                    694:        xscheme-process-filter:string-action)
                    695:     (?n xscheme-prompt-for-confirmation
                    696:        xscheme-process-filter:string-action)
                    697:     (?o xscheme-output-goto
                    698:        xscheme-process-filter:simple-action)
                    699:     (?p xscheme-set-prompt
                    700:        xscheme-process-filter:string-action)
                    701:     (?s xscheme-enter-input-wait
                    702:        xscheme-process-filter:simple-action)
                    703:     (?v xscheme-write-value
                    704:        xscheme-process-filter:string-action)
                    705:     (?w xscheme-cd
                    706:        xscheme-process-filter:string-action)
                    707:     (?z xscheme-display-process-buffer
                    708:        xscheme-process-filter:simple-action)
                    709:     (?c xscheme-unsolicited-read-char
                    710:        xscheme-process-filter:simple-action))
                    711:   "Table used to decide how to handle process filter commands.
                    712: Value is a list of entries, each entry is a list of three items.
                    713: 
                    714: The first item is the character that the process filter dispatches on.
                    715: The second item is the action to be taken, a function.
                    716: The third item is the handler for the entry, a function.
                    717: 
                    718: When the process filter sees a command whose character matches a
                    719: particular entry, it calls the handler with two arguments: the action
                    720: and the string containing the rest of the process filter's input
                    721: stream.  It is the responsibility of the handler to invoke the action
                    722: with the appropriate arguments, and to reenter the process filter with
                    723: the remaining input.")
                    724: 
                    725: (defun xscheme-process-filter:simple-action (action)
                    726:   (setq xscheme-process-filter-state 'idle)
                    727:   (funcall action))
                    728: 
                    729: (defun xscheme-process-filter:string-action (action)
                    730:   (setq xscheme-string-receiver action)
                    731:   (setq xscheme-string-accumulator "")
                    732:   (setq xscheme-process-filter-state 'reading-string))
                    733: 
                    734: (defconst xscheme-runlight:running "run"
                    735:   "The character displayed when the Scheme process is running.")
                    736: 
                    737: (defconst xscheme-runlight:input "input"
                    738:   "The character displayed when the Scheme process is waiting for input.")
                    739: 
                    740: (defconst xscheme-runlight:gc "gc"
                    741:   "The character displayed when the Scheme process is garbage collecting.")
                    742: 
                    743: (defun xscheme-start-gc ()
                    744:   (xscheme-set-runlight xscheme-runlight:gc))
                    745: 
                    746: (defun xscheme-finish-gc ()
                    747:   (xscheme-set-runlight
                    748:    (if xscheme-running-p xscheme-runlight:running xscheme-runlight:input)))
                    749: 
                    750: (defun xscheme-enter-input-wait ()
                    751:   (xscheme-set-runlight xscheme-runlight:input)
                    752:   (setq xscheme-running-p nil))
                    753: 
                    754: (defun xscheme-exit-input-wait ()
                    755:   (xscheme-set-runlight xscheme-runlight:running)
                    756:   (setq xscheme-running-p t))
                    757: 
                    758: (defun xscheme-enable-control-g ()
                    759:   (setq xscheme-control-g-disabled-p nil))
                    760: 
                    761: (defun xscheme-display-process-buffer ()
                    762:   (let ((window (or (xscheme-process-buffer-window)
                    763:                    (display-buffer (xscheme-process-buffer)))))
                    764:     (save-window-excursion
                    765:       (select-window window)
                    766:       (xscheme-goto-output-point)
                    767:       (if (xscheme-debugger-mode-p)
                    768:          (xscheme-enter-interaction-mode)))))
                    769: 
                    770: (defun xscheme-unsolicited-read-char ()
                    771:   nil)
                    772: 
                    773: (defun xscheme-message (string)
                    774:   (if (not (zerop (length string)))
                    775:       (xscheme-write-message-1 string (format ";%s" string))))
                    776: 
                    777: (defun xscheme-write-value (string)
                    778:   (if (zerop (length string))
                    779:       (xscheme-write-message-1 "(no value)" ";No value")
                    780:       (xscheme-write-message-1 string (format ";Value: %s" string))))
                    781: 
                    782: (defun xscheme-write-message-1 (message-string output-string)
                    783:   (let* ((process (get-process "scheme"))
                    784:         (window (get-buffer-window (process-buffer process))))
                    785:     (if (or (not window)
                    786:            (not (pos-visible-in-window-p (process-mark process)
                    787:                                          window)))
                    788:        (message "%s" message-string)))
                    789:   (xscheme-guarantee-newlines 1)
                    790:   (xscheme-process-filter-output output-string))
                    791: 
                    792: (defun xscheme-set-prompt-variable (string)
                    793:   (setq xscheme-prompt string))
                    794: 
                    795: (defun xscheme-set-prompt (string)
                    796:   (setq xscheme-prompt string)
                    797:   (xscheme-guarantee-newlines 2)
                    798:   (setq xscheme-mode-string (xscheme-coerce-prompt string))
                    799:   (xscheme-modeline-redisplay))
                    800: 
                    801: (defun xscheme-output-goto ()
                    802:   (xscheme-goto-output-point)
                    803:   (xscheme-guarantee-newlines 2))
                    804: 
                    805: (defun xscheme-coerce-prompt (string)
                    806:   (if (string-match "^[0-9]+ " string)
                    807:       (let ((end (match-end 0)))
                    808:        (concat (substring string 0 end)
                    809:                (let ((prompt (substring string end)))
                    810:                  (let ((entry (assoc prompt xscheme-prompt-alist)))
                    811:                    (if entry
                    812:                        (cdr entry)
                    813:                        prompt)))))
                    814:       string))
                    815: 
                    816: (defvar xscheme-prompt-alist
                    817:   '(("[Normal REPL]" . "[Evaluator]")
                    818:     ("[Error REPL]" . "[Evaluator]")
                    819:     ("[Breakpoint REPL]" . "[Evaluator]")
                    820:     ("[Debugger REPL]" . "[Evaluator]")
                    821:     ("[Visiting environment]" . "[Evaluator]")
                    822:     ("[Environment Inspector]" . "[Where]"))
                    823:   "An alist which maps the Scheme command interpreter type to a print string.")
                    824: 
                    825: (defun xscheme-cd (directory-string)
                    826:   (save-excursion
                    827:     (set-buffer (xscheme-process-buffer))
                    828:     (cd directory-string)))
                    829: 
                    830: (defun xscheme-prompt-for-confirmation (prompt-string)
                    831:   (xscheme-send-char (if (y-or-n-p prompt-string) ?y ?n)))
                    832: 
                    833: (defun xscheme-prompt-for-expression (prompt-string)
                    834:   (xscheme-send-string-2
                    835:    (read-from-minibuffer prompt-string nil xscheme-prompt-for-expression-map)))
                    836: 
                    837: (defvar xscheme-prompt-for-expression-map nil)
                    838: (if (not xscheme-prompt-for-expression-map)
                    839:     (progn
                    840:       (setq xscheme-prompt-for-expression-map
                    841:            (copy-keymap minibuffer-local-map))
                    842:       (substitute-key-definition 'exit-minibuffer
                    843:                                 'xscheme-prompt-for-expression-exit
                    844:                                 xscheme-prompt-for-expression-map)))
                    845: 
                    846: (defun xscheme-prompt-for-expression-exit ()
                    847:   (interactive)
                    848:   (if (eq (xscheme-region-expression-p (point-min) (point-max)) 'one)
                    849:       (exit-minibuffer)
                    850:       (error "input must be a single, complete expression")))
                    851: 
                    852: (defun xscheme-region-expression-p (start end)
                    853:   (save-excursion
                    854:     (let ((old-syntax-table (syntax-table)))
                    855:       (unwind-protect
                    856:          (progn
                    857:            (set-syntax-table scheme-mode-syntax-table)
                    858:            (let ((state (parse-partial-sexp start end)))
                    859:              (and (zerop (car state))  ;depth = 0
                    860:                   (nth 2 state)        ;last-sexp exists, i.e. >= 1 sexps
                    861:                   (let ((state (parse-partial-sexp start (nth 2 state))))
                    862:                     (if (nth 2 state) 'many 'one)))))
                    863:        (set-syntax-table old-syntax-table)))))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.