Mercurial > hg > xemacs-beta
diff lisp/comint/inf-lisp.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 0293115a14e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/comint/inf-lisp.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,635 @@ +;;; inf-lisp.el --- an inferior-lisp mode +;;; Copyright (C) 1988, 1993, 1994 Free Software Foundation, Inc. + +;; Author: Olin Shivers <shivers@cs.cmu.edu> +;; Keywords: processes, lisp + +;; This file is part of XEmacs. + +;; XEmacs is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; XEmacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with XEmacs; see the file COPYING. If not, write to the Free +;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +;;; Synched up with: FSF 19.30. + +;;; Commentary: + +;;; Hacked from tea.el by Olin Shivers (shivers@cs.cmu.edu). 8/88 + +;;; This file defines a a lisp-in-a-buffer package (inferior-lisp +;;; mode) built on top of comint mode. This version is more +;;; featureful, robust, and uniform than the Emacs 18 version. The +;;; key bindings are also more compatible with the bindings of Hemlock +;;; and Zwei (the Lisp Machine emacs). + +;;; Since this mode is built on top of the general command-interpreter-in- +;;; a-buffer mode (comint mode), it shares a common base functionality, +;;; and a common set of bindings, with all modes derived from comint mode. +;;; This makes these modes easier to use. + +;;; For documentation on the functionality provided by comint mode, and +;;; the hooks available for customizing it, see the file comint.el. +;;; For further information on inferior-lisp mode, see the comments below. + +;;; Needs fixin: +;;; The load-file/compile-file default mechanism could be smarter -- it +;;; doesn't know about the relationship between filename extensions and +;;; whether the file is source or executable. If you compile foo.lisp +;;; with compile-file, then the next load-file should use foo.bin for +;;; the default, not foo.lisp. This is tricky to do right, particularly +;;; because the extension for executable files varies so much (.o, .bin, +;;; .lbin, .mo, .vo, .ao, ...). +;;; +;;; It would be nice if inferior-lisp (and inferior scheme, T, ...) modes +;;; had a verbose minor mode wherein sending or compiling defuns, etc. +;;; would be reflected in the transcript with suitable comments, e.g. +;;; ";;; redefining fact". Several ways to do this. Which is right? +;;; +;;; When sending text from a source file to a subprocess, the process-mark can +;;; move off the window, so you can lose sight of the process interactions. +;;; Maybe I should ensure the process mark is in the window when I send +;;; text to the process? Switch selectable? + +;;; Code: + +(require 'comint) +(require 'lisp-mode) + + +;;;jwz: ilisp is better, don't ###autoload +(defvar inferior-lisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'" + "*What not to save on inferior Lisp's input history. +Input matching this regexp is not saved on the input history in Inferior Lisp +mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword +\(as in :a, :c, etc.)") + +(defvar inferior-lisp-mode-map nil) +(cond ((not inferior-lisp-mode-map) + (setq inferior-lisp-mode-map (make-sparse-keymap)) + (set-keymap-name inferior-lisp-mode-map 'inferior-lisp-mode-map) + (set-keymap-parents inferior-lisp-mode-map + (list comint-mode-map shared-lisp-mode-map)) + (define-key inferior-lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp) + (define-key inferior-lisp-mode-map "\C-c\C-l" 'lisp-load-file) + (define-key inferior-lisp-mode-map "\C-c\C-k" 'lisp-compile-file) + (define-key inferior-lisp-mode-map "\C-c\C-a" 'lisp-show-arglist) + (define-key inferior-lisp-mode-map "\C-c\C-d" 'lisp-describe-sym) + (define-key inferior-lisp-mode-map "\C-c\C-f" + 'lisp-show-function-documentation) + (define-key inferior-lisp-mode-map "\C-c\C-v" + 'lisp-show-variable-documentation))) + +;;; These commands augment Lisp mode, so you can process Lisp code in +;;; the source files. +(define-key lisp-mode-map "\M-\C-x" 'lisp-eval-defun) ; Gnu convention +(define-key lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp) ; Gnu convention +(define-key lisp-mode-map "\C-c\C-e" 'lisp-eval-defun) +(define-key lisp-mode-map "\C-c\C-r" 'lisp-eval-region) +(define-key lisp-mode-map "\C-c\C-c" 'lisp-compile-defun) +(define-key lisp-mode-map "\C-c\C-z" 'switch-to-lisp) +(define-key lisp-mode-map "\C-c\C-l" 'lisp-load-file) +(define-key lisp-mode-map "\C-c\C-k" 'lisp-compile-file) ; "kompile" file +(define-key lisp-mode-map "\C-c\C-a" 'lisp-show-arglist) +(define-key lisp-mode-map "\C-c\C-d" 'lisp-describe-sym) +(define-key lisp-mode-map "\C-c\C-f" 'lisp-show-function-documentation) +(define-key lisp-mode-map "\C-c\C-v" 'lisp-show-variable-documentation) + +;;; This function exists for backwards compatibility. +;;; Previous versions of this package bound commands to C-c <letter> +;;; bindings, which is not allowed by the gnumacs standard. + +;;; "This function binds many inferior-lisp commands to C-c <letter> bindings, +;;;where they are more accessible. C-c <letter> bindings are reserved for the +;;;user, so these bindings are non-standard. If you want them, you should +;;;have this function called by the inferior-lisp-load-hook: +;;; (setq inferior-lisp-load-hook '(inferior-lisp-install-letter-bindings)) +;;;You can modify this function to install just the bindings you want." +(defun inferior-lisp-install-letter-bindings () + (define-key lisp-mode-map "\C-ce" 'lisp-eval-defun-and-go) + (define-key lisp-mode-map "\C-cr" 'lisp-eval-region-and-go) + (define-key lisp-mode-map "\C-cc" 'lisp-compile-defun-and-go) + (define-key lisp-mode-map "\C-cz" 'switch-to-lisp) + (define-key lisp-mode-map "\C-cl" 'lisp-load-file) + (define-key lisp-mode-map "\C-ck" 'lisp-compile-file) + (define-key lisp-mode-map "\C-ca" 'lisp-show-arglist) + (define-key lisp-mode-map "\C-cd" 'lisp-describe-sym) + (define-key lisp-mode-map "\C-cf" 'lisp-show-function-documentation) + (define-key lisp-mode-map "\C-cv" 'lisp-show-variable-documentation) + + (define-key inferior-lisp-mode-map "\C-cl" 'lisp-load-file) + (define-key inferior-lisp-mode-map "\C-ck" 'lisp-compile-file) + (define-key inferior-lisp-mode-map "\C-ca" 'lisp-show-arglist) + (define-key inferior-lisp-mode-map "\C-cd" 'lisp-describe-sym) + (define-key inferior-lisp-mode-map "\C-cf" 'lisp-show-function-documentation) + (define-key inferior-lisp-mode-map "\C-cv" + 'lisp-show-variable-documentation)) + + +;;;jwz: ilisp is better, don't ###autoload +(defvar inferior-lisp-program "lisp" + "*Program name for invoking an inferior Lisp with for Inferior Lisp mode.") + +;;;jwz: ilisp is better, don't ###autoload +(defvar inferior-lisp-load-command "(load \"%s\")\n" + "*Format-string for building a Lisp expression to load a file. +This format string should use `%s' to substitute a file name +and should result in a Lisp expression that will command the inferior Lisp +to load that file. The default works acceptably on most Lisps. +The string \"(progn (load \\\"%s\\\" :verbose nil :print t) (values))\\n\" +produces cosmetically superior output for this application, +but it works only in Common Lisp.") + +;;;jwz: ilisp is better, don't ###autoload +(defvar inferior-lisp-prompt "^[^> \n]*>+:? *" + "Regexp to recognise prompts in the Inferior Lisp mode. +Defaults to \"^[^> \\n]*>+:? *\", which works pretty good for Lucid, kcl, +and franz. This variable is used to initialize `comint-prompt-regexp' in the +Inferior Lisp buffer. + +More precise choices: +Lucid Common Lisp: \"^\\\\(>\\\\|\\\\(->\\\\)+\\\\) *\" +franz: \"^\\\\(->\\\\|<[0-9]*>:\\\\) *\" +kcl: \"^>+ *\" + +This is a fine thing to set in your .emacs file.") + +(defvar inferior-lisp-buffer nil "*The current inferior-lisp process buffer. + +MULTIPLE PROCESS SUPPORT +=========================================================================== +To run multiple Lisp processes, you start the first up +with \\[inferior-lisp]. It will be in a buffer named `*inferior-lisp*'. +Rename this buffer with \\[rename-buffer]. You may now start up a new +process with another \\[inferior-lisp]. It will be in a new buffer, +named `*inferior-lisp*'. You can switch between the different process +buffers with \\[switch-to-buffer]. + +Commands that send text from source buffers to Lisp processes -- +like `lisp-eval-defun' or `lisp-show-arglist' -- have to choose a process +to send to, when you have more than one Lisp process around. This +is determined by the global variable `inferior-lisp-buffer'. Suppose you +have three inferior Lisps running: + Buffer Process + foo inferior-lisp + bar inferior-lisp<2> + *inferior-lisp* inferior-lisp<3> +If you do a \\[lisp-eval-defun] command on some Lisp source code, +what process do you send it to? + +- If you're in a process buffer (foo, bar, or *inferior-lisp*), + you send it to that process. +- If you're in some other buffer (e.g., a source file), you + send it to the process attached to buffer `inferior-lisp-buffer'. +This process selection is performed by function `inferior-lisp-proc'. + +Whenever \\[inferior-lisp] fires up a new process, it resets +`inferior-lisp-buffer' to be the new process's buffer. If you only run +one process, this does the right thing. If you run multiple +processes, you can change `inferior-lisp-buffer' to another process +buffer with \\[set-variable].") + +;;;jwz: ilisp is better, don't ###autoload +(defvar inferior-lisp-mode-hook '() + "*Hook for customizing Inferior Lisp mode.") + +(defun inferior-lisp-mode () + "Major mode for interacting with an inferior Lisp process. +Runs a Lisp interpreter as a subprocess of Emacs, with Lisp I/O through an +Emacs buffer. Variable `inferior-lisp-program' controls which Lisp interpreter +is run. Variables `inferior-lisp-prompt', `inferior-lisp-filter-regexp' and +`inferior-lisp-load-command' can customize this mode for different Lisp +interpreters. + +For information on running multiple processes in multiple buffers, see +documentation for variable `inferior-lisp-buffer'. + +\\{inferior-lisp-mode-map} + +Customization: Entry to this mode runs the hooks on `comint-mode-hook' and +`inferior-lisp-mode-hook' (in that order). + +You can send text to the inferior Lisp process from other buffers containing +Lisp source. + switch-to-lisp switches the current buffer to the Lisp process buffer. + lisp-eval-defun sends the current defun to the Lisp process. + lisp-compile-defun compiles the current defun. + lisp-eval-region sends the current region to the Lisp process. + lisp-compile-region compiles the current region. + + Prefixing the lisp-eval/compile-defun/region commands with + a \\[universal-argument] causes a switch to the Lisp process buffer after sending + the text. + +Commands: +Return after the end of the process' output sends the text from the + end of process to point. +Return before the end of the process' output copies the sexp ending at point + to the end of the process' output, and sends it. +Delete converts tabs to spaces as it moves back. +Tab indents for Lisp; with argument, shifts rest + of expression rigidly with the current line. +C-M-q does Tab on each line starting within following expression. +Paragraphs are separated only by blank lines. Semicolons start comments. +If you accidentally suspend your process, use \\[comint-continue-subjob] +to continue it." + (interactive) + (comint-mode) + (setq comint-prompt-regexp inferior-lisp-prompt) + (setq major-mode 'inferior-lisp-mode) + (setq mode-name "Inferior Lisp") + (setq mode-line-process '(":%s")) + (lisp-mode-variables t) + (use-local-map inferior-lisp-mode-map) ;c-c c-k for "kompile" file + (setq comint-get-old-input (function lisp-get-old-input)) + (setq comint-input-filter (function lisp-input-filter)) + (setq comint-input-sentinel 'ignore) + (run-hooks 'inferior-lisp-mode-hook)) + +(defun lisp-get-old-input () + "Return a string containing the sexp ending at point." + (save-excursion + (let ((end (point))) + (backward-sexp) + (buffer-substring (point) end)))) + +(defun lisp-input-filter (str) + "t if STR does not match `inferior-lisp-filter-regexp'." + (not (string-match inferior-lisp-filter-regexp str))) + +;;;jwz: ilisp is better, don't ###autoload +(defun inferior-lisp (cmd) + "Run an inferior Lisp process, input and output via buffer `*inferior-lisp*'. +If there is a process already running in `*inferior-lisp*', just switch +to that buffer. +With argument, allows you to edit the command line (default is value +of `inferior-lisp-program'). Runs the hooks from +`inferior-lisp-mode-hook' (after the `comint-mode-hook' is run). +\(Type \\[describe-mode] in the process buffer for a list of commands.)" + (interactive (list (if current-prefix-arg + (read-string "Run lisp: " inferior-lisp-program) + inferior-lisp-program))) + (if (not (comint-check-proc "*inferior-lisp*")) + (let ((cmdlist (inferior-lisp-args-to-list cmd))) + (set-buffer (apply (function make-comint) + "inferior-lisp" (car cmdlist) nil (cdr cmdlist))) + (inferior-lisp-mode))) + (setq inferior-lisp-buffer "*inferior-lisp*") + (pop-to-buffer "*inferior-lisp*")) +;;;###autoload (add-hook 'same-window-buffer-names "*inferior-lisp*") + +;;;jwz: ilisp is better, don't ###autoload +(define-function 'run-lisp 'inferior-lisp) + +;;; Break a string up into a list of arguments. +;;; This will break if you have an argument with whitespace, as in +;;; string = "-ab +c -x 'you lose'". +(defun inferior-lisp-args-to-list (string) + (let ((where (string-match "[ \t]" string))) + (cond ((null where) (list string)) + ((not (= where 0)) + (cons (substring string 0 where) + (inferior-lisp-args-to-list (substring string (+ 1 where) + (length string))))) + (t (let ((pos (string-match "[^ \t]" string))) + (if (null pos) + nil + (inferior-lisp-args-to-list (substring string pos + (length string))))))))) + +(defun lisp-eval-region (start end &optional and-go) + "Send the current region to the inferior Lisp process. +Prefix argument means switch to the Lisp buffer afterwards." + (interactive "r\nP") + (comint-send-region (inferior-lisp-proc) start end) + (comint-send-string (inferior-lisp-proc) "\n") + (if and-go (switch-to-lisp t))) + +(defun lisp-eval-defun (&optional and-go) + "Send the current defun to the inferior Lisp process. +Prefix argument means switch to the Lisp buffer afterwards." + (interactive "P") + (save-excursion + (end-of-defun) + (skip-chars-backward " \t\n\r\f") ; Makes allegro happy + (let ((end (point))) + (beginning-of-defun) + (lisp-eval-region (point) end))) + (if and-go (switch-to-lisp t))) + +(defun lisp-eval-last-sexp (&optional and-go) + "Send the previous sexp to the inferior Lisp process. +Prefix argument means switch to the Lisp buffer afterwards." + (interactive "P") + (lisp-eval-region (save-excursion (backward-sexp) (point)) (point) and-go)) + +;;; Common Lisp COMPILE sux. +(defun lisp-compile-region (start end &optional and-go) + "Compile the current region in the inferior Lisp process. +Prefix argument means switch to the Lisp buffer afterwards." + (interactive "r\nP") + (comint-send-string + (inferior-lisp-proc) + (format "(funcall (compile nil `(lambda () (progn 'compile %s))))\n" + (buffer-substring start end))) + (if and-go (switch-to-lisp t))) + +(defun lisp-compile-defun (&optional and-go) + "Compile the current defun in the inferior Lisp process. +Prefix argument means switch to the Lisp buffer afterwards." + (interactive "P") + (save-excursion + (end-of-defun) + (skip-chars-backward " \t\n\r\f") ; Makes allegro happy + (let ((e (point))) + (beginning-of-defun) + (lisp-compile-region (point) e))) + (if and-go (switch-to-lisp t))) + +(defun switch-to-lisp (eob-p) + "Switch to the inferior Lisp process buffer. +With argument, positions cursor at end of buffer." + (interactive "P") + (if (get-buffer inferior-lisp-buffer) + (pop-to-buffer inferior-lisp-buffer) + (error "No current inferior Lisp buffer")) + (cond (eob-p + (push-mark) + (goto-char (point-max))))) + + +;;; Now that lisp-compile/eval-defun/region takes an optional prefix arg, +;;; these commands are redundant. But they are kept around for the user +;;; to bind if he wishes, for backwards functionality, and because it's +;;; easier to type C-c e than C-u C-c C-e. + +(defun lisp-eval-region-and-go (start end) + "Send the current region to the inferior Lisp, and switch to its buffer." + (interactive "r") + (lisp-eval-region start end t)) + +(defun lisp-eval-defun-and-go () + "Send the current defun to the inferior Lisp, and switch to its buffer." + (interactive) + (lisp-eval-defun t)) + +(defun lisp-compile-region-and-go (start end) + "Compile the current region in the inferior Lisp, and switch to its buffer." + (interactive "r") + (lisp-compile-region start end t)) + +(defun lisp-compile-defun-and-go () + "Compile the current defun in the inferior Lisp, and switch to its buffer." + (interactive) + (lisp-compile-defun t)) + +;;; A version of the form in H. Shevis' soar-mode.el package. Less robust. +;;; (defun lisp-compile-sexp (start end) +;;; "Compile the s-expression bounded by START and END in the inferior lisp. +;;; If the sexp isn't a DEFUN form, it is evaluated instead." +;;; (cond ((looking-at "(defun\\s +") +;;; (goto-char (match-end 0)) +;;; (let ((name-start (point))) +;;; (forward-sexp 1) +;;; (process-send-string "inferior-lisp" +;;; (format "(compile '%s #'(lambda " +;;; (buffer-substring name-start +;;; (point))))) +;;; (let ((body-start (point))) +;;; (goto-char start) (forward-sexp 1) ; Can't use end-of-defun. +;;; (process-send-region "inferior-lisp" +;;; (buffer-substring body-start (point)))) +;;; (process-send-string "inferior-lisp" ")\n")) +;;; (t (lisp-eval-region start end))))) +;;; +;;; (defun lisp-compile-region (start end) +;;; "Each s-expression in the current region is compiled (if a DEFUN) +;;; or evaluated (if not) in the inferior lisp." +;;; (interactive "r") +;;; (save-excursion +;;; (goto-char start) (end-of-defun) (beginning-of-defun) ; error check +;;; (if (< (point) start) (error "region begins in middle of defun")) +;;; (goto-char start) +;;; (let ((s start)) +;;; (end-of-defun) +;;; (while (<= (point) end) ; Zip through +;;; (lisp-compile-sexp s (point)) ; compiling up defun-sized chunks. +;;; (setq s (point)) +;;; (end-of-defun)) +;;; (if (< s end) (lisp-compile-sexp s end))))) +;;; +;;; End of HS-style code + + +(defvar lisp-prev-l/c-dir/file nil + "Record last directory and file used in loading or compiling. +This holds a cons cell of the form `(DIRECTORY . FILE)' +describing the last `lisp-load-file' or `lisp-compile-file' command.") + +(defvar lisp-source-modes '(lisp-mode) + "*Used to determine if a buffer contains Lisp source code. +If it's loaded into a buffer that is in one of these major modes, it's +considered a Lisp source file by `lisp-load-file' and `lisp-compile-file'. +Used by these commands to determine defaults.") + +(defun lisp-load-file (file-name) + "Load a Lisp file into the inferior Lisp process." + (interactive (comint-get-source "Load Lisp file: " lisp-prev-l/c-dir/file + lisp-source-modes nil)) ; NIL because LOAD + ; doesn't need an exact name + (comint-check-source file-name) ; Check to see if buffer needs saved. + (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name) + (file-name-nondirectory file-name))) + (comint-send-string (inferior-lisp-proc) + (format inferior-lisp-load-command file-name)) + (switch-to-lisp t)) + +(defun lisp-compile-file (file-name) + "Compile a Lisp file in the inferior Lisp process." + (interactive (comint-get-source "Compile Lisp file: " lisp-prev-l/c-dir/file + lisp-source-modes nil)) ; NIL = don't need + ; suffix .lisp + (comint-check-source file-name) ; Check to see if buffer needs saved. + (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name) + (file-name-nondirectory file-name))) + (comint-send-string (inferior-lisp-proc) (concat "(compile-file \"" + file-name + "\"\)\n")) + (switch-to-lisp t)) + + + +;;; Documentation functions: function doc, var doc, arglist, and +;;; describe symbol. +;;; =========================================================================== + +;;; Command strings +;;; =============== + +(defvar lisp-function-doc-command + "(let ((fn '%s)) + (format t \"Documentation for ~a:~&~a\" + fn (documentation fn 'function)) + (values))\n" + "Command to query inferior Lisp for a function's documentation.") + +(defvar lisp-var-doc-command + "(let ((v '%s)) + (format t \"Documentation for ~a:~&~a\" + v (documentation v 'variable)) + (values))\n" + "Command to query inferior Lisp for a variable's documentation.") + +(defvar lisp-arglist-command + "(let ((fn '%s)) + (format t \"Arglist for ~a: ~a\" fn (arglist fn)) + (values))\n" + "Command to query inferior Lisp for a function's arglist.") + +(defvar lisp-describe-sym-command + "(describe '%s)\n" + "Command to query inferior Lisp for a variable's documentation.") + + +;;; Ancillary functions +;;; =================== + +;;; Reads a string from the user. +(defun lisp-symprompt (prompt default) + (list (let* ((prompt (if default + (format "%s (default %s): " prompt default) + (concat prompt ": "))) + (ans (read-string prompt))) + (if (zerop (length ans)) default ans)))) + + +;;; Adapted from function-called-at-point in help.el. +(defun lisp-fn-called-at-pt () + "Returns the name of the function called in the current call. +The value is nil if it can't find one." + (condition-case nil + (save-excursion + (save-restriction + (narrow-to-region (max (point-min) (- (point) 1000)) (point-max)) + (backward-up-list 1) + (forward-char 1) + (let ((obj (read (current-buffer)))) + (and (symbolp obj) obj)))) + (error nil))) + + +;;; Adapted from variable-at-point in help.el. +(defun lisp-var-at-pt () + (condition-case () + (save-excursion + (forward-sexp -1) + (skip-chars-forward "'") + (let ((obj (read (current-buffer)))) + (and (symbolp obj) obj))) + (error nil))) + + +;;; Documentation functions: fn and var doc, arglist, and symbol describe. +;;; ====================================================================== + +(defun lisp-show-function-documentation (fn) + "Send a command to the inferior Lisp to give documentation for function FN. +See variable `lisp-function-doc-command'." + (interactive (lisp-symprompt "Function doc" (lisp-fn-called-at-pt))) + (comint-proc-query (inferior-lisp-proc) + (format lisp-function-doc-command fn))) + +(defun lisp-show-variable-documentation (var) + "Send a command to the inferior Lisp to give documentation for function FN. +See variable `lisp-var-doc-command'." + (interactive (lisp-symprompt "Variable doc" (lisp-var-at-pt))) + (comint-proc-query (inferior-lisp-proc) (format lisp-var-doc-command var))) + +(defun lisp-show-arglist (fn) + "Send a query to the inferior Lisp for the arglist for function FN. +See variable `lisp-arglist-command'." + (interactive (lisp-symprompt "Arglist" (lisp-fn-called-at-pt))) + (comint-proc-query (inferior-lisp-proc) (format lisp-arglist-command fn))) + +(defun lisp-describe-sym (sym) + "Send a command to the inferior Lisp to describe symbol SYM. +See variable `lisp-describe-sym-command'." + (interactive (lisp-symprompt "Describe" (lisp-var-at-pt))) + (comint-proc-query (inferior-lisp-proc) + (format lisp-describe-sym-command sym))) + + +;; "Returns the current inferior Lisp process. +;; See variable `inferior-lisp-buffer'." +(defun inferior-lisp-proc () + (let ((proc (get-buffer-process (if (eq major-mode 'inferior-lisp-mode) + (current-buffer) + inferior-lisp-buffer)))) + (or proc + (error "No Lisp subprocess; see variable `inferior-lisp-buffer'")))) + + +;;; Do the user's customization... +;;;=============================== +(defvar inferior-lisp-load-hook nil + "This hook is run when the library `inf-lisp' is loaded. +This is a good place to put keybindings.") + +(run-hooks 'inferior-lisp-load-hook) + +;;; CHANGE LOG +;;; =========================================================================== +;;; 7/21/92 Jim Blandy +;;; - Changed all uses of the cmulisp name or prefix to inferior-lisp; +;;; this is now the official inferior lisp package. Use the global +;;; ChangeLog from now on. +;;; 5/24/90 Olin +;;; - Split cmulisp and cmushell modes into separate files. +;;; Not only is this a good idea, it's apparently the way it'll be rel 19. +;;; - Upgraded process sends to use comint-send-string instead of +;;; process-send-string. +;;; - Explicit references to process "cmulisp" have been replaced with +;;; (cmulisp-proc). This allows better handling of multiple process bufs. +;;; - Added process query and var/function/symbol documentation +;;; commands. Based on code written by Douglas Roberts. +;;; - Added lisp-eval-last-sexp, bound to C-x C-e. +;;; +;;; 9/20/90 Olin +;;; Added a save-restriction to lisp-fn-called-at-pt. This bug and fix +;;; reported by Lennart Staflin. +;;; +;;; 3/12/90 Olin +;;; - lisp-load-file and lisp-compile-file no longer switch-to-lisp. +;;; Tale suggested this. +;;; - Reversed this decision 7/15/91. You need the visual feedback. +;;; +;;; 7/25/91 Olin +;;; Changed all keybindings of the form C-c <letter>. These are +;;; supposed to be reserved for the user to bind. This affected +;;; mainly the compile/eval-defun/region[-and-go] commands. +;;; This was painful, but necessary to adhere to the gnumacs standard. +;;; For some backwards compatibility, see the +;;; cmulisp-install-letter-bindings +;;; function. +;;; +;;; 8/2/91 Olin +;;; - The lisp-compile/eval-defun/region commands now take a prefix arg, +;;; which means switch-to-lisp after sending the text to the Lisp process. +;;; This obsoletes all the -and-go commands. The -and-go commands are +;;; kept around for historical reasons, and because the user can bind +;;; them to key sequences shorter than C-u C-c C-<letter>. +;;; - If M-x cmulisp is invoked with a prefix arg, it allows you to +;;; edit the command line. + +(provide 'inf-lisp) + +;;; inf-lisp.el ends here