|
|
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)))))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.