home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / lisp / ilisp / ilisp.el < prev    next >
Encoding:
Text File  |  1992-12-13  |  133.8 KB  |  3,685 lines

  1. ;;; -*-Emacs-Lisp-*-
  2. ;;;%Header
  3. ;;; Inferior LISP interaction package for GNU Emacs.  Version 4.12
  4. ;;; Copyright (C) 1990, 1991, 1992 Chris McConnell, ccm@cs.cmu.edu.
  5. ;;; Hacked for Lucid GNU Emacs
  6.  
  7. ;;; This file is part of GNU Emacs.
  8.  
  9. ;;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;;; but WITHOUT ANY WARRANTY.  No author or distributor
  11. ;;; accepts responsibility to anyone for the consequences of using it
  12. ;;; or for whether it serves any particular purpose or works at all,
  13. ;;; unless he says so in writing.  Refer to the GNU Emacs General Public
  14. ;;; License for full details.
  15.  
  16. ;;; Everyone is granted permission to copy, modify and redistribute
  17. ;;; GNU Emacs, but only under the conditions described in the
  18. ;;; GNU Emacs General Public License.   A copy of this license is
  19. ;;; supposed to have been given to you along with GNU Emacs so you
  20. ;;; can know your rights and responsibilities.  It should be in a
  21. ;;; file named COPYING.  Among other things, the copyright notice
  22. ;;; and this notice must be preserved on all copies.
  23.  
  24. ;;; ILISP replaces the standard inferior LISP mode. It is based on
  25. ;;; comint mode and derived from a number of different interfaces
  26. ;;; including Symbolics, cmulisp, and Thinking Machines.  There are
  27. ;;; many people that have taken the time to report bugs, make
  28. ;;; suggestions and even better send code to fix bugs or implement new
  29. ;;; features.  Special thanks to Todd Kaufmann for the texinfo file,
  30. ;;; work on bridge, epoch-pop and for really exercising everything.
  31. ;;; Thanks to Neil Smithline, David Braunegg, Fred White, Jim Healy,
  32. ;;; Larry Stead, Hans Chalupsky, Michael Ernst, Frank Ritter, Tom
  33. ;;; Emerson, David Duff, Dan Pierson, Michael Kashket, Jamie Zawinski,
  34. ;;; Bjorn Victor and Brian Dennis for bug reports, suggestions and
  35. ;;; code.  Please send bug reports, fixes and extensions to
  36. ;;; ccm@cs.cmu.edu so I can merge them into the master source.
  37.  
  38. ;;; This file defines a generic LISP interface that can be customized
  39. ;;; to match a specific LISP dialect.  Support is already provided for
  40. ;;; a number of common LISP dialects.  Lucid, Allegro and CMU are
  41. ;;; fully supported.  Other LISP dialects are missing features like
  42. ;;; arglist and find-source.
  43.  
  44. ;;; Since this is built on top of the general command-interpreter-in-
  45. ;;; a-buffer mode (comint mode), it shares a common base
  46. ;;; functionality, and a common set of bindings, with all modes
  47. ;;; derived from comint mode.  This makes it easier to use.
  48.  
  49. ;;; For documentation on the functionality provided by comint mode,
  50. ;;; and the hooks available for customizing it, see the file
  51. ;;; comint.el.
  52.  
  53. ;;; Throughout this file you will find comment lines with %'s on them.
  54. ;;; These lines define sections for outline mode which I use while
  55. ;;; programming to temporarily hide code.
  56.  
  57. ;;;%%SITE INFORMATION
  58. ;;; The files you need to use ilisp are:
  59. ;;;  ilisp.emacs     File with sample .emacs code for ILISP.
  60. ;;;  symlink.el      Expand pathnames resolving links.
  61. ;;;  completer.el    Partial completion code.
  62. ;;;  completion.el   Completion package from TMC.
  63. ;;;  popper.el       Shrink-wrapped temporary windows.
  64. ;;;  epoch-pop.el    Popper for epoch.
  65. ;;;  bridge.el       Process to process communication.
  66. ;;;  comint.el       The basic comint abstraction.
  67. ;;;  comint-ipc.el   Extensions for sending commands and getting results.
  68. ;;;  ilisp-ext.el    Standalone lisp-mode extensions.
  69. ;;;  ilisp-src.el    Ilisp source code module.
  70. ;;;  ilisp-bat.el    Ilisp batch code module.
  71. ;;;  ilisp.el        Actual ilisp definitions.
  72. ;;;  ilisp.texi      Texinfo file.
  73. ;;;  ilisp.ps        Postscript version of the manual.
  74. ;;;  ilisp.info      Info file.
  75. ;;;  *.lcd           Descriptors for the Lisp Code Directory.
  76. ;;;  *.lisp          Each dialect will have one of these files.
  77. ;;;
  78. ;;; All of the .el files in the ilisp directory should be
  79. ;;; byte-compiled by typing C-u M-x byte-recompile-directory.  Before
  80. ;;; compiling, make sure that load-path has the location of the files
  81. ;;; on it.  If you plan to use epoch, you must make sure that the
  82. ;;; epoch EMACS code is loaded before compiling epoch-pop.  If you do
  83. ;;; not plan to use epoch, you should rename the epoch-pop.el file to
  84. ;;; epoch-pop so that it will not get compiled.  The first time a
  85. ;;; dialect is started, the interface files will complain about not
  86. ;;; being compiled, just hit 'i' to ignore the message.  Once a lisp
  87. ;;; dialect is started up, you should execute the EMACS command M-x
  88. ;;; ilisp-compile-inits which will compile the *.lisp files and write
  89. ;;; them to the same directory as the ilisp files.  The binary files
  90. ;;; should have a unique extension for each different combination of
  91. ;;; architecture and LISP dialect.  You will need to change
  92. ;;; ilisp-init-binary-extension/command to get additional extensions.
  93. ;;; The binary for each different architecture should be different.
  94. ;;; If you want to build the interface files into a LISP world, you
  95. ;;; will also need to set ilisp-load-inits to nil in the same place
  96. ;;; that you change ilisp-program to load the LISP world.
  97. ;;;
  98. ;;; There is an ilisp-site-hook for initializing site specific stuff
  99. ;;; like program locations when ilisp is first loaded.  You may want
  100. ;;; to define appropriate autoloads in your system Emacs start up
  101. ;;; file.
  102. ;;;
  103. ;;; ;;; CMU site
  104. ;;; (setq ilisp-site-hook
  105. ;;;       '(lambda ()
  106. ;;;         (setq ilisp-motd "CMU ILISP V%s")
  107. ;;;         (setq expand-symlinks-rfs-exists t)
  108. ;;;         (setq allegro-program "/usr/misc/.allegro/bin/cl")
  109. ;;;         (setq lucid-program "/usr/misc/.lucid/bin/lisp")))
  110.  
  111. ;;;%%CUSTOMIZING DIALECTS
  112. ;;;
  113. ;;; ILISP is already set up with support for a number of dialects.
  114. ;;; Each dialect has a command NAME that will start an inferior LISP
  115. ;;; of that dialect.  NAME-hook is a hook that will run after the
  116. ;;; default settings for NAME are set up.  NAME-program is the default
  117. ;;; program for NAME. A prefix when starting a dialect will cause you
  118. ;;; to be prompted for the buffer name and the program.  When setting
  119. ;;; something in a hook, you should use the most general dialect that
  120. ;;; makes sense. Dialect definitions and their hooks are executed from
  121. ;;; least specific to most specific.  They will be executed before the
  122. ;;; inferior LISP is started.
  123. ;;;
  124. ;;; These are the currently supported dialects.  The dialects
  125. ;;; are listed so that the indentation correponds to the hierarchical
  126. ;;; relationship between dialects.
  127. ;;; clisp
  128. ;;;   allegro
  129. ;;;   lucid
  130. ;;;   cmulisp
  131. ;;;   kcl
  132. ;;;     akcl
  133. ;;;     ibcl
  134. ;;; scheme
  135. ;;;   oaklisp
  136. ;;;
  137. ;;; If anyone figures out support for other dialects I would be happy
  138. ;;; to include it in future releases.
  139. ;;;
  140. ;;; ;;; Example of local changes and extensions to ilisp mode
  141. ;;; (setq ilisp-load-hook
  142. ;;;       '(lambda ()
  143. ;;;         ;; Change the allegro lisp program
  144. ;;;         (setq allegro-program "/usr/misc/bin/lisp")
  145. ;;;         ;; Add a new key binding
  146. ;;;         (defkey-ilisp "\C-\M-a" 'arglist-lisp)
  147. ;;;         ;; Define a new subdialect to run on another machine.
  148. ;;;         (defdialect cmlisp "Connection Machine LISP."
  149. ;;;           lucid
  150. ;;;           (setq ilisp-program
  151. ;;;            "rsh power /usr/local/cm/bin/starlisp"))))
  152. ;;;
  153. ;;; ;;; Automatically load a new subdialect
  154. ;;; (autoload 'cmlisp "ilisp" "Run an inferior CM lisp." t)
  155. ;;;
  156. ;;; To define a new dialect use the macro defdialect.  For examples,
  157. ;;; look at the dialect definitions in this file.  There are hooks and
  158. ;;; variables for almost anything that you are likely to need to
  159. ;;; change.  The relationship between dialects is hierarchical with
  160. ;;; the root values being defined in setup-ilisp.  For a new dialect,
  161. ;;; you only need to change the variables that are different than in
  162. ;;; the parent dialect.
  163. ;;;
  164. ;;; ILISP Mode Hooks:
  165. ;;; ilisp-site-hook         Executed when file is loaded
  166. ;;; ilisp-load-hook          Executed when file is loaded
  167. ;;; ilisp-mode-hook         Executed when an ilisp buffer is created
  168. ;;; ilisp-init-hook         Executed after inferior LISP is initialized
  169. ;;; DIALECT-hook            Executed when dialect is set
  170. ;;;
  171. ;;; Variables you might want to set in a hook or dialect:
  172. ;;; ilisp-prefix          Keys to prefix ilisp key bindings
  173. ;;; ilisp-program         Program to start for inferior LISP
  174. ;;; ilisp-motd            String printed on startup with version
  175. ;;; lisp-wait-p           Set to T for synchronous sends
  176. ;;; lisp-no-popper        Set to T to have all output in inferior LISP
  177. ;;; lisp-show-status      Set to nil to stop showing process status
  178. ;;; ilisp-prefix-match    Set to T if you do not want partial completion
  179. ;;; ilisp-filter-regexp      Input history filter 
  180. ;;; ilisp-filter-length   Input history minimum length
  181. ;;; ilisp-other-prompt    Prompt for non top level read-eval print loops
  182.  
  183. ;;; %%WRITING NEW COMMANDS
  184. ;;;
  185. ;;; Basic tools for creating new commands:
  186. ;;; deflocal -- Define a new buffer local variable.
  187. ;;; ilisp-dialect -- List of dialect types.  For specific dialect clauses.
  188. ;;; lisp-symbol -- Create a symbol.
  189. ;;; lisp-symbol-name -- Return a symbol's name
  190. ;;; lisp-symbol-delimiter -- Return a symbol's qualification
  191. ;;; lisp-symbol-package -- Return a symbol's package
  192. ;;; lisp-string-to-symbol -- Convert string to symbol
  193. ;;; lisp-symbol-to-string -- Convert symbol to string
  194. ;;; lisp-buffer-symbol -- Convert symbol to string qualified for buffer
  195. ;;; lisp-previous-symbol -- Return previous symbol 
  196. ;;; lisp-previous-sexp -- Return previous sexp
  197. ;;; lisp-def-name -- Return name of current definition
  198. ;;; lisp-function-name -- Return previous function symbol
  199. ;;; ilisp-read -- Read an sexp with completion, arglist, etc
  200. ;;; ilisp-read-symbol -- Read a symbol or list with completion
  201. ;;; ilisp-completing-read -- Read from choices or list with completion
  202. ;;;
  203. ;;; Special commands like arglist should use ilisp-send to send a
  204. ;;; message to the inferior LISP.
  205. ;;;
  206. ;;; Eval/compile commands should use eval-region-lisp or compile-region-lisp.
  207. ;;;
  208.  
  209. ;;; See the documentation for ILISP mode, or read the rest of this
  210. ;;; file for more information.  All of the EMACS function names begin
  211. ;;; or end with lisp or ilisp to separate ilisp functions from
  212. ;;; functions in other packages.  Functions that work only in lisp
  213. ;;; buffers or that work in both lisp buffers and inferior lisp
  214. ;;; buffers use lisp, all other functions use ilisp.  If a function is
  215. ;;; intended to be used interactively, then the lisp or ilisp comes at
  216. ;;; the end of the function name, otherwise at the start.
  217.  
  218. ;;;%%KNOWN BUGS
  219. ;;; 
  220. ;;; If you type multiple things to the top level before you get a
  221. ;;; prompt, the LISP may be running with the status light indicating
  222. ;;; ready.  This is because I have no way to distinguish between input
  223. ;;; to a program and that to the top level.
  224. ;;;
  225. ;;; When running a lisp on Ultrix, you need to set ilisp-program to
  226. ;;; "/bin/sh -c your/path/your-lisp-image".
  227. ;;; 
  228. ;;; If you get lisp output breaking up in weird places it almost
  229. ;;; certainly means that comint-prompt-regexp is not precise enough.
  230. ;;;
  231. ;;; I would like to eat Lucid's return from break in the process
  232. ;;; filter, but I can't tell how many newlines to eat after.
  233.  
  234. ;;;%Requirements
  235. (require 'symlink)
  236. (require 'comint)
  237. (require 'comint-ipc)
  238. (require 'ilisp-ext)
  239.  
  240. ;;;%Variables
  241. ;;;%%Deflocal
  242. (defvar ilisp-locals '(comint-prompt-regexp 
  243.                input-ring-size
  244.                comint-get-old-input
  245.                comint-input-sentinel
  246.                comint-input-filter
  247.                comint-input-sender
  248.                comint-eol-on-send
  249.                comint-send-newline
  250.                comint-always-scroll
  251.                comint-fix-error
  252.                comint-continue
  253.                comint-interrupt-regexp
  254.                comint-error-regexp
  255.                comint-output-filter
  256.                comint-interrupt-start
  257.                comint-handler
  258.                comint-update-status
  259.                comint-prompt-status
  260.                comint-abort-hook)
  261.   "List of ilisp local variables.")
  262. (defun lisp-deflocal (local)
  263.   (if (not (memq local ilisp-locals))
  264.       (setq ilisp-locals (cons local ilisp-locals))))
  265.  
  266. ;;;
  267. (defmacro deflocal (variable default &optional documentation)
  268.   "Define an ilisp local variable."
  269.   (` (progn (lisp-deflocal '(, variable))
  270.         (defvar (, variable) (, default) (, documentation)))))
  271.  
  272. ;;;%%Simple customization
  273. (defvar ilisp-prefix "\C-z" "Prefix sequence for ilisp commands.")
  274.  
  275. (deflocal ilisp-program nil
  276.   "*Program and arguments for invoking an inferior LISP.  The program
  277. can be an rsh to run on a remote machine.  If there is not a common
  278. file system, the interface files will be sent down the pipe instead.
  279. The value of this variable is set from DIALECT-program, or inherited
  280. from a less specific dialect if DIALECT-program is nil.")
  281.  
  282. (defvar ilisp-motd 
  283.   "ILISP V%s  Use M-x ilisp-bug for problems and suggestions."
  284.   "*Message of the day format string for ILISP given VERSION. To
  285. prevent any message from being printed, set this to nil.")
  286.  
  287. (defvar lisp-wait-p nil
  288.   "*T if LISP eval/compile commands should wait for the result.  A
  289. minus prefix to the command will change the sense of this switch for
  290. just the next command.")
  291.  
  292. (defvar lisp-no-popper nil
  293.   "*T if you want all output in the inferior LISP rather than in a
  294. pop-up window.  You should probably also set comint-always-scroll to T
  295. as well so that output is always visible.")
  296.  
  297. (defvar lisp-show-status t 
  298.   "*Set to nil to stop showing process status in lisp-mode buffers.")
  299.  
  300. (defvar ilisp-prefix-match nil
  301.   "*Set to T to match only as a prefix when completing through the
  302. inferior LISP.  This will speed up completion, but you no longer get
  303. partial completion.") 
  304.  
  305. (deflocal ilisp-filter-regexp nil
  306.   "*What not to save on an inferior LISP's input history.
  307. Input matching this regexp is not saved on the input history in ilisp
  308. mode.")
  309.  
  310. (deflocal ilisp-filter-length 3
  311.   "*Do not save strings less than this in the command history.")
  312.  
  313. (deflocal ilisp-other-prompt nil
  314.   "*Regexp to recognise prompts in the inferior LISP that are prompts
  315. of non-(read/eval/print) top-levels so that bol-ilisp skips them.")
  316.  
  317. (deflocal ilisp-raw-echo nil
  318.   "*Set this to T to cause echoing in raw keyboard mode.")
  319.  
  320. (deflocal ilisp-load-no-compile-query nil
  321.   "*Set this to T to stop load querying about compile.")
  322.  
  323. ;;;%%%Hooks
  324. (defvar ilisp-site-hook nil
  325.   "Hook for site customization of ilisp mode when it is loaded.")
  326.  
  327. (defvar ilisp-load-hook '()
  328.   "Hook for customizing ilisp mode when it is loaded.")
  329.  
  330. (defvar ilisp-mode-hook '()
  331.   "Hook for customizing ilisp mode.")
  332.  
  333. (deflocal ilisp-init-hook nil
  334.   "Hook of functions to call on first prompt in inferior LISP.")
  335.  
  336. ;;;%%Advanced customization
  337. ;;;%%%Commands
  338. (deflocal ilisp-reset nil
  339.   "String for resetting the top-level of the inferior LISP.")
  340.  
  341. (deflocal ilisp-load-or-send-command nil
  342.   "Format string for loading BINARY if possible otherwise loading
  343. FILE.  If you can't load either, return NIL.")
  344.  
  345. (deflocal ilisp-package-regexp nil
  346.   "Regular expression for finding a package specification in a buffer.
  347. The entire sexp starting with this pattern will be passed to
  348. ilisp-package-command to find the package.")
  349.  
  350. (deflocal ilisp-package-command nil
  351.   "Format string to find the package given PACKAGE.")
  352.  
  353. (deflocal ilisp-package-name-command nil
  354.   "Format string to return the name of the current package.")
  355.  
  356. (deflocal ilisp-in-package-command nil
  357.   "Format string to set the package given PACKAGE.")
  358.  
  359. (deflocal ilisp-last-command nil
  360.   "Format string for getting the last returned value.")
  361.  
  362. (deflocal ilisp-save-command nil
  363.   "Format string for saving result history given FORM.")
  364.  
  365. (deflocal ilisp-restore-command nil
  366.   "Format string for restoring result history.")
  367.  
  368. (deflocal ilisp-block-command nil
  369.   "Format string for grouping FORMS into one.")
  370.  
  371. (deflocal ilisp-eval-command nil
  372.   "Format string for evaluating FORM in PACKAGE from FILE.")
  373.  
  374. (deflocal ilisp-defvar-regexp nil
  375.   "Regular expression for identifying a defvar form.")
  376.  
  377. (deflocal ilisp-defvar-command nil
  378.   "Format string for re-evaluating DEFVAR in PACKAGE from FILE.")
  379.  
  380. (deflocal ilisp-describe-command nil
  381.   "Format string for describing FORM in PACKAGE.")
  382.  
  383. (deflocal ilisp-inspect-command nil
  384.   "Format string for inspecting FORM in PACKAGE.")
  385.  
  386. (deflocal ilisp-arglist-command nil
  387.   "Format string for arglist of SYMBOL in PACKAGE.")
  388.  
  389. (deflocal ilisp-documentation-types nil
  390.   "((\"type\") ...) possible LISP documentation types.")
  391.  
  392. (deflocal ilisp-documentation-command nil
  393.   "Format string for documentation given SYMBOL in PACKAGE and TYPE.")
  394.  
  395. (deflocal ilisp-macroexpand-1-command nil
  396.   "Format string for top-level macroexpand given FORM and PACKAGE.")
  397.  
  398. (deflocal ilisp-macroexpand-command  nil
  399.   "Format string for macroexpand given FORM and PACKAGE.")
  400.  
  401. (deflocal ilisp-complete-command nil
  402.   "Format string for finding possibly matching symbols given SYMBOL,
  403. PACKAGE, FUNCTIONP, EXTERNALP and PARTIAL-MATCHP.  It should print
  404. ((string) (string) ...).")
  405.  
  406. (deflocal ilisp-callers-command nil
  407.   "Format for finding the callers of SYMBOL in PACKAGE.  The function
  408. should print out callers with one per line.")
  409.  
  410. (deflocal ilisp-trace-command nil
  411.   "Format for tracing SYMBOL in PACKAGE.")
  412. (deflocal ilisp-untrace-command nil
  413.   "Format for untracing SYMBOL in PACKAGE.")
  414.  
  415. (deflocal ilisp-directory-command nil
  416.   "Format for getting default DIRECTORY.")
  417. (deflocal ilisp-set-directory-command nil
  418.   "Format for setting default DIRECTORY.")
  419.  
  420. (deflocal ilisp-binary-command nil
  421.   "Command to return the extension for binary files.")
  422.  
  423. (deflocal ilisp-binary-extension nil
  424.   "*The extension to use for LISP binaries.  If there is an
  425. ilisp-binary-command, this string will be determined at initilization time.")
  426.  
  427. (deflocal ilisp-init-binary-command nil
  428.   "Command to return the extension for initialization binary files.")
  429.  
  430. (deflocal ilisp-init-binary-extension nil
  431.   "The extension for initialization binary files.  If there is an
  432. ilisp-init-binary-command, this string will be determined at
  433. initilization time.")
  434.  
  435. (deflocal ilisp-load-command nil
  436.   "Format string for loading a file in LISP given FILE.")
  437.  
  438. (deflocal ilisp-compile-file-command nil
  439.   "Format string for compiling a file in LISP given FILE and EXTENSION.")
  440.  
  441. ;;;%%%%Source
  442. (deflocal ilisp-source-types nil
  443.   "Alist of strings for source types.  The strings can be either
  444. symbols or list expressions since the input accepts symbols or open
  445. ended lists as type specifiers.")
  446.  
  447. (deflocal ilisp-find-source-command nil
  448.   "Format string for finding the source file that defined SYMBOL in
  449. PACKAGE.  It should return NIL if no source is found.")
  450.  
  451. (deflocal ilisp-locator nil
  452.   "Function \(SYMBOL TYPE FIRST-P BACK-P) that finds the next SYMBOL TYPE
  453. definition in the current buffer.  FIRST-P is T the first time it is
  454. called in a buffer.  BACK-P is T to move backwards.")
  455.  
  456. (deflocal ilisp-calls-locator nil
  457.   "Function \(SYMBOL TYPE FIRST-P BACK-P ) that finds calls to SYMBOL
  458. in the current buffer.  FIRST-P is T the first time it is called in a
  459. buffer.  BACK-P is T to move backwards.")
  460.  
  461. ;;;%%%Misc
  462. (deflocal ilisp-use-map nil "Keymap to use in ILISP mode.")
  463.  
  464. (defvar ilisp-bugs-to "ccm@cs.cmu.edu" "Who to send bug reports to.")
  465.  
  466. (defvar ilisp-modes '(ilisp-mode) "List of all inferior ilisp modes.")
  467. (defvar lisp-source-modes '(lisp-mode scheme-mode)
  468.   "Used to determine if a buffer contains Lisp source code.
  469. If it's loaded into a buffer that is in one of these major modes, it's
  470. considered a lisp source file by find-file-lisp, load-file-lisp and
  471. compile-file-lisp. Used by these commands to determine defaults.")
  472.  
  473. (deflocal ilisp-no-newline nil
  474.   "Set to T to stop ilisp from inserting a newline after a command.")
  475.  
  476. (deflocal ilisp-error-filter nil "Function to filter error output.")
  477. (deflocal ilisp-error-regexp nil "Regular expression to match error.")
  478.  
  479. (deflocal ilisp-symbol-delimiters nil
  480.   "Delimiters found around symbols.")
  481.  
  482. ;;;%%Program
  483. (defvar ilisp-epoch-running (and (boundp 'epoch::version) epoch::version)
  484.   "Non-nil if epoch is running.")
  485. (defvar ilisp-version "4.12" "Interface version.")
  486. (defvar ilisp-directory nil "The directory that ilisp is found in.")
  487. (defvar ilisp-mode-map nil "Key map for ILISP.")
  488. (defvar ilisp-raw-map  nil
  489.   "Keyboard map for sending characters directly to the inferior LISP.")
  490. (defvar ilisp-raw-message "Raw keyboard mode until C-g"
  491.   "Message for how to stop raw mode.")
  492. (defvar ilisp-buffer nil "Name of selected ilisp buffer.")
  493. (defvar ilisp-status nil "Status string for selected ilisp buffer.")
  494. (defvar ilisp-buffers nil "List of ILISP buffers.")
  495. (defvar ilisp-dialects nil "List of ILISP dialects.")
  496.  
  497. (deflocal ilisp-load-inits nil
  498.   "Alist of dialect files to load when initializing an inferior LISP.
  499. By default the file will be loaded from the ilisp-directory.")
  500.  
  501. ;;; This is useful to have a clause in ilisp code like:
  502. ;;; (if (memq 'allegro (ilisp-value 'ilisp-dialect)) 
  503. ;;;     allegro-code
  504. ;;;     normal-code)
  505. (deflocal ilisp-dialect nil
  506.   "List of the dialects that defined the current inferior LISP.")
  507.  
  508. (defvar ilisp-initialized nil
  509.   "List of buffer names that have been initialized.")
  510. (deflocal ilisp-initializing nil
  511.   "Set to T while waiting for inferior LISP to get initialized.")
  512.  
  513. (deflocal ilisp-load-files nil "List of files being loaded.")
  514.  
  515. (defvar lisp-changes nil
  516.   "List of markers for changed forms.")
  517. (deflocal ilisp-pending-changes nil
  518.   "List of changes that are pending, but have not been confirmed yet.")
  519.  
  520. ;;;%%%Completion
  521. ;;; Dynamically bound variables for controlling reading
  522. (defvar ilisp-complete nil "T if in minibuffer completion mode.")
  523. (defvar ilisp-no-complete nil "T if incomplete symbols are allowed.")
  524. (defvar ilisp-table nil "Completion table for ilisp readers.")
  525. (defvar ilisp-paren nil "T if paren is allowed in ilisp readers.")
  526. (defvar ilisp-completion-package nil 
  527.   "Package of buffer requesting completion.")
  528. (defvar ilisp-completion-function-p nil
  529.   "T if only symbols with function values are allowed.")
  530.  
  531. ;;; State variables for ilisp reading
  532. (defvar ilisp-mini-prefix nil "Package and qualification from minibuffer.")
  533. (defvar ilisp-original nil "Original string for ilisp completion.")
  534. (defvar ilisp-original-function-p nil "Function-p for ilisp completion.")
  535. (defvar ilisp-original-table nil "Completion table for ilisp-original.")
  536.  
  537. ;;;%Utilities
  538. ;;;%%Misc
  539. (defun lisp-memk (item list key)
  540.   "Test to see if ITEM is in LIST using KEY on each item in LIST
  541. before comparing it to ITEM."
  542.   (lisp-mem item list (function (lambda (x y)
  543.             (equal x (funcall key y))))))
  544.  
  545. ;;; This should be in emacs, but it isn't.
  546. (defun lisp-del (item list &optional test)
  547.   "Delete ITEM from LIST using TEST comparison and return the result.
  548. Default test is equal."
  549.   (let ((test (or test (function equal)))
  550.     (element list)
  551.     (prev nil)
  552.     (done nil))
  553.     (while (and element (not done))
  554.       (if (funcall test item (car element))
  555.       (progn
  556.         (setq done t)
  557.         (if prev
  558.         (rplacd prev (cdr element))
  559.         (setq list (cdr list))))
  560.       (setq prev element
  561.         element (cdr element))))
  562.     list))
  563.  
  564. ;;;
  565. (defun lisp-last (list)
  566.   "Return the last element of LIST."
  567.   (while (cdr list)
  568.     (setq list (cdr list)))
  569.   (car list))
  570.  
  571. ;;;
  572. (defun lisp-pop-to-buffer (buffer)
  573.   "Like pop-to-buffer, but select a screen that buffer was shown in."
  574.   (let ((ilisp-window (if ilisp-epoch-running
  575.               (epoch::get-buffer-window buffer)
  576.               (get-buffer-window buffer))))
  577.     (if ilisp-window
  578.     (select-window ilisp-window)
  579.     ;; It is not currently displayed, so find some place to display
  580.     ;; it.
  581.     (if ilisp-epoch-running
  582.         ;; Select a screen that the buffer has been displayed in before
  583.         ;; or the current screen otherwise.
  584.         (epoch::select-screen
  585.          ;; allowed-screens in epoch 3.2, was called screens before that
  586.          (or (car (symbol-buffer-value 'allowed-screens buffer))
  587.          (epoch::current-screen))))
  588.     (pop-to-buffer buffer)))
  589.   (set-buffer buffer))
  590.  
  591. ;;;%%Symbol
  592. (defun lisp-symbol (package delimiter name)
  593.   "Create a LISP symbol."
  594.   (list package (if package (or delimiter "::")) name))
  595. (defun lisp-symbol-name (symbol)
  596.   "Return the name of SYMBOL."
  597.   (car (cdr (cdr symbol))))
  598. (defun lisp-symbol-package (symbol)
  599.   "Return the package of SYMBOL."
  600.   (car symbol))
  601. (defun lisp-symbol-delimiter (symbol)
  602.   "Return the qualifier of SYMBOL."
  603.   (car (cdr symbol)))
  604.  
  605. ;;;
  606. (defun lisp-symbol= (symbol1 symbol2)
  607.   "Return T is SYMBOL1 is equal to SYMBOL2."
  608.   (and (string= (lisp-symbol-name symbol1) (lisp-symbol-name symbol2))
  609.        (string= (lisp-symbol-package symbol1) (lisp-symbol-package symbol2))
  610.        (string= (lisp-symbol-delimiter symbol1)
  611.         (lisp-symbol-delimiter symbol2))))
  612.  
  613. ;;;%%String
  614. (defun lisp-prefix-p (s1 s2)
  615.   "Returns t if S1 is a prefix of S2 considering all non alphanumerics
  616. as word delimiters."
  617.   (let ((len1 (length s1)))
  618.     (and (<= len1 (length s2))
  619.      (let ((start 0)
  620.            (start2 0) 
  621.            end
  622.            (match t))
  623.        (while
  624.            (if (setq end (string-match "[^a-zA-Z0-9]" s1 start))
  625.            ;; Found delimiter
  626.            (if (string= (substring s1 start end)
  627.                 (substring s2 start2 (+ start2 (- end start))))
  628.                ;; Words are the same
  629.                (progn (setq start (match-end 0))
  630.                   (if (string-match
  631.                    (regexp-quote (substring s1 end start))
  632.                    s2 start2)
  633.                   (setq start2 (match-end 0)) ;OK
  634.                   (setq match nil))) ;Can't find delimiter
  635.                (setq match nil)) ;Words don't match 
  636.            nil))        ;Ran out of delimiters in s1
  637.        (and match
  638.         (string= (substring s1 start len1)
  639.              (substring s2 start2 (+ start2 (- len1 start)))))))))
  640.  
  641. ;;;
  642. (defun lisp-last-line (string)
  643.   "Return the last line of STRING with everything else."
  644.   (let* ((position 0))
  645.     (while (string-match "\\(\n+\\)[^\n]" string position)
  646.       (setq position (match-end 1)))
  647.     (cons (substring string position)
  648.       (substring string 0 position))))
  649.  
  650. ;;;
  651. (defun lisp-show-send (string)
  652.   "Show STRING in the *ilisp-send* buffer."
  653.   (save-excursion
  654.     (if (ilisp-buffer)
  655.     (set-buffer "*ilisp-send*")
  656.     (error "You must start an inferior LISP with run-ilisp."))
  657.     (erase-buffer)
  658.     (insert string)
  659.     string))
  660.  
  661. ;;;
  662. (defun lisp-slashify (string)
  663.   "Put string in the *ilisp-send* buffer, put backslashes before
  664. quotes and backslashes and return the resulting string."
  665.   (save-excursion
  666.     (lisp-show-send string)
  667.     (set-buffer "*ilisp-send*")
  668.     (goto-char (point-min))
  669.     (while (search-forward "\\" nil t)
  670.       (delete-char -1)
  671.       (insert "\\\\"))
  672.     (goto-char (point-min))
  673.     (while (search-forward "\"" nil t)
  674.       (backward-char)
  675.       (insert ?\\)
  676.       (forward-char))
  677.     (buffer-substring (point-min) (point-max))))
  678.  
  679. ;;;%%File
  680. (defun ilisp-directory (file &optional dirs)
  681.   "Return the directory of DIRS that FILE is found in.  By default
  682. load-path is used for the directories."
  683.   (let* ((dirs (or dirs (cons "" load-path)))
  684.      (dir (car dirs)))
  685.     (while (and dir (not (file-exists-p (expand-file-name file dir))))
  686.       (setq dirs (cdr dirs)
  687.         dir (car dirs)))
  688.     dir))
  689.  
  690. ;;;
  691. (defun lisp-file-extension (file extension)
  692.   "Return FILE with new EXTENSION."
  693.   (concat (substring file 0 (string-match ".[^.]*$" file))
  694.       "." extension))
  695.  
  696. ;;;%Buffer and process selection
  697. (defun ilisp-buffer ()
  698.   "Return the current ILISP buffer."
  699.   (if (memq major-mode ilisp-modes)
  700.       (current-buffer)
  701.       (let ((buffer 
  702.          (if ilisp-buffer 
  703.          (or (get-buffer ilisp-buffer)
  704.              (get-buffer
  705.               (setq ilisp-buffers
  706.                 (lisp-del (substring ilisp-buffer 1 
  707.                          (1- (length ilisp-buffer)))
  708.                       ilisp-buffers 
  709.                       (function (lambda (s1 s2)
  710.                     (string= s1 (car s2)))))
  711.                 ilisp-buffer 
  712.                 (format "*%s*" (car (car ilisp-buffers)))))))))
  713.     (or buffer
  714.         (error "You must start an inferior LISP with run-ilisp.")))))
  715.  
  716. ;;;
  717. (defun ilisp-process ()
  718.   "Return the current ILISP process."
  719.   (get-buffer-process (ilisp-buffer)))
  720.  
  721. ;;;
  722. (defun ilisp-value (variable &optional no-error-p)
  723.   "Return the value of VARIABLE in the ILISP buffer.
  724. If NO-ERROR-P is NIL, then an error will be signalled if VARIABLE is nil."
  725.   (save-excursion
  726.     (set-buffer (ilisp-buffer))
  727.     (let ((value (eval variable)))
  728.       (if value
  729.       value
  730.       (if no-error-p
  731.           nil
  732.           (error "%s is not defined." variable))))))
  733.  
  734. ;;;
  735. (defun set-ilisp-value (variable value)
  736.   "Set the value of VARIABLE in the ILISP buffer."
  737.   (save-excursion
  738.     (set-buffer (ilisp-buffer))
  739.     (set variable value)))
  740.  
  741. ;;;
  742. (defun select-ilisp ()
  743.   "Select the current ILISP buffer."
  744.   (interactive)
  745.   (let ((new (completing-read
  746.           (if ilisp-buffer
  747.           (format "Buffer [%s]: "
  748.               (substring ilisp-buffer 1
  749.                      (1- (length ilisp-buffer))))
  750.           "Buffer: ")
  751.           ilisp-buffers nil t)))
  752.     (if (not (zerop (length new)))
  753.     (setq ilisp-buffer (format "*%s*" new)))))
  754.  
  755. ;;;
  756. (defvar ilisp-last-buffer nil
  757.   "The last used LISP buffer.")
  758. (defun switch-to-lisp (eob-p &optional ilisp-only)
  759.   "If in an ILISP buffer, switch to the buffer that last switched to
  760. an ILISP otherwise, switch to the current ILISP buffer.  With
  761. argument, positions cursor at end of buffer.  If you don't want to
  762. split windows, set pop-up-windows to NIL."
  763.   (interactive "P")
  764.   (if (and (not ilisp-only) ilisp-last-buffer (memq major-mode ilisp-modes))
  765.       (lisp-pop-to-buffer ilisp-last-buffer)
  766.       (if (not (memq major-mode ilisp-modes))
  767.       (setq ilisp-last-buffer (current-buffer)))
  768.       (lisp-pop-to-buffer (ilisp-buffer))
  769.       (cond (eob-p (goto-char (point-max))))))
  770.  
  771. ;;;
  772. (defun abort-commands-lisp (&optional message)
  773.   "Abort the commands sent to the current ilisp."
  774.   (interactive)
  775.   (if (ilisp-value comint-aborting t)
  776.       (message "Already aborted commands")
  777.       (beep)
  778.       (message (or message "Aborted commands"))
  779.       (comint-abort-sends (ilisp-process))))
  780.  
  781. ;;;
  782. (defun panic-lisp ()
  783.   "Panic reset for the inferior LISP."
  784.   (interactive)
  785.   (save-excursion
  786.     (if (y-or-n-p "Panic reset LISP? ")
  787.     (save-excursion
  788.       (set-buffer (ilisp-buffer))
  789.       (comint-setup-ipc t)
  790.       (message "LISP is reset, state is unknown"))
  791.     (message ""))))
  792.  
  793. ;;;
  794. (defun interrupt-subjob-ilisp ()
  795.   "Interrupt the current top level command in the inferior LISP."
  796.   (interactive)
  797.   (if (not (eq comint-send-queue comint-end-queue))
  798.       (if (y-or-n-p "Abort commands before interrupting top level? ")
  799.       (abort-commands-lisp)
  800.       (message "Waiting for commands to finish")
  801.       (while (not (eq comint-send-queue comint-end-queue))
  802.         (accept-process-output)
  803.         (sit-for 0))))
  804.   (message "Interrupted top level")
  805.   (comint-interrupt-subjob))
  806.  
  807. ;;;
  808. (defun status-lisp (showp)
  809.   "Show the message of the current command being executed in the
  810. inferior LISP.  With a prefix show pending sends as well."  
  811.   (interactive "P")
  812.   (save-excursion
  813.     (set-buffer (ilisp-buffer))
  814.     (comint-current-send showp)))
  815.  
  816. ;;;%Buffer
  817. ;;;%%Packages
  818. (defvar buffer-package 'not-yet-computed "Cached package name.")
  819. (defvar buffer-mode-name nil "Original mode name.")
  820. (defvar lisp-buffer-package nil "T if in lisp-buffer-package.")
  821.  
  822. ;;;
  823. (defun lisp-buffer-package ()
  824.   "Return the package for this buffer.  The package name is a string.
  825. If there is none, return NIL.  This caches the package, so calling
  826. this more than once is cheap."
  827.   (cond ((not (eq buffer-package 'not-yet-computed)) buffer-package)
  828.     (ilisp-completion-package ilisp-completion-package)
  829.     ((or lisp-buffer-package 
  830.          (memq major-mode ilisp-modes)
  831.          (not (memq major-mode lisp-source-modes)))
  832.      nil)
  833.     (t
  834.      (make-local-variable 'buffer-package)
  835.      (make-local-variable 'buffer-mode-name)
  836.      (setq mode-line-process 'ilisp-status)
  837.      ;; go search for the first package in the current buffer
  838.      (let* ((lisp-buffer-package t)
  839.         (case-fold-search t)
  840.         (regexp (ilisp-value 'ilisp-package-regexp t))
  841.         (spec
  842.          (if regexp
  843.              (save-excursion
  844.                (goto-char (point-min))
  845.                (if (re-search-forward regexp nil t)
  846.                (buffer-substring (match-beginning 0)
  847.                          (progn 
  848.                            (goto-char (match-beginning 0))
  849.                            (forward-sexp)
  850.                            (point)))))))
  851.         (package
  852.          (if spec
  853.              (ilisp-send 
  854.               (format (ilisp-value 'ilisp-package-command) spec)
  855.               "Finding buffer package"
  856.               'pkg))))
  857.        (if (ilisp-value 'comint-errorp t)
  858.            (progn
  859.          (lisp-display-output package)
  860.          (error "No package"))
  861.            (if (and package 
  862.             (string-match "[ \n\t:\"]*\\([^ \n\t\"]\\)*" package))
  863.            (setq package
  864.              (substring package
  865.                     (match-beginning 1) (match-end 1)))))
  866.        (message "")
  867.        (setq buffer-package package)
  868.        ;; Display package in mode line
  869.        (if package 
  870.            (setq mode-name
  871.              (concat (or buffer-mode-name
  872.                  (setq buffer-mode-name mode-name))
  873.                  ":" buffer-package)))
  874.        buffer-package))))
  875.  
  876. ;;;
  877. (defun package-lisp ()
  878.   "Show current inferior LISP package."
  879.   (interactive)
  880.   (message "Inferior LISP package is %s"
  881.        (ilisp-send (ilisp-value 'ilisp-package-name-command)
  882.                "Finding inferior LISP package" 'pkg)))
  883.  
  884. ;;;
  885. (defun set-package-lisp (package)
  886.   "Set inferior LISP to package of buffer or a named package with prefix."
  887.   (interactive 
  888.    (let ((default (lisp-buffer-package)))
  889.      (if (or current-prefix-arg (null default))
  890.      (let ((name
  891.         (read-string ;; read-no-blanks-input is obsolete
  892.          (format "Package [%s]: " (lisp-buffer-package)) "")))
  893.        (list (if (equal name "") default name)))
  894.      (list default))))
  895.   (if package
  896.       (ilisp-send (format (ilisp-value 'ilisp-in-package-command) package)
  897.           (format "Set %s's package to %s" 
  898.               (buffer-name (ilisp-buffer))
  899.               package)
  900.           'pkg 'dispatch)
  901.       (error "No package")))
  902.  
  903. ;;;
  904. (defun set-buffer-package-lisp (package)
  905.   "Reset the current package of the current buffer.  With prefix
  906. specify manually."
  907.   (interactive (if current-prefix-arg
  908.            (list (read-from-minibuffer "Package: " ))
  909.            (list nil)))
  910.   (if package
  911.       (setq buffer-package package
  912.         mode-name (concat (or buffer-mode-name mode-name) ":" package))
  913.       (setq buffer-package 'not-yet-computed)
  914.       (lisp-buffer-package)))
  915.  
  916. ;;;%Process interface
  917. ;;;%%Comint 
  918. (defun ilisp-get-old-input ()
  919.   "Snarf the sexp starting at the nearest previous prompt, or NIL if none."
  920.   (save-excursion
  921.     (let* ((begin (lisp-defun-begin))
  922.        (pmark (process-mark (get-buffer-process (current-buffer))))
  923.        (once (if (< (point) pmark)
  924.              (save-excursion (end-of-line) (point))))
  925.        (end nil)
  926.        (done nil))
  927.       (condition-case ()
  928.       (while (and (not done) (< (point) (point-max)))
  929.         (forward-sexp)
  930.         (setq end (point))
  931.         (skip-chars-forward " \t\n")
  932.         (if (and once (>= (point) once)) (setq done t)))
  933.     (error (setq end nil)))
  934.       (if end (buffer-substring begin end)))))
  935.  
  936. ;;;
  937. (defun ilisp-input-filter (str)
  938.   "Don't save anything matching ilisp-filter-regexp or less than
  939. ilisp-filter-length long."
  940.   (and (not (string-match ilisp-filter-regexp str))
  941.        (> (length str) ilisp-filter-length)))
  942.  
  943. ;;;
  944. (defun ilisp-error-filter (output)
  945.   "Keep from OUTPUT only what matches ilisp-error-regexp or everything
  946. if there is no match."
  947.   (if (string-match (ilisp-value 'ilisp-error-regexp) output)
  948.       (substring output (match-beginning 0) (match-end 0))
  949.       output))
  950.  
  951. ;;;
  952. (defvar ilisp-last-message nil)
  953. (defvar ilisp-last-prompt nil)
  954. (defun lisp-display-output (output)
  955.   "Display OUTPUT in a popper window unless lisp-no-popper is T."
  956.   (if output
  957.       (progn
  958.     (if (ilisp-value 'comint-errorp t)
  959.         (setq output (funcall (ilisp-value 'ilisp-error-filter) output)))
  960.     (if lisp-no-popper
  961.         (let ((buffer (current-buffer))
  962.           (window (selected-window)))
  963.           (unwind-protect
  964.            (progn
  965.              (lisp-pop-to-buffer (ilisp-buffer))
  966.              (if (not (eq (current-buffer) buffer))
  967.              (setq ilisp-last-buffer buffer))
  968.              (comint-insert 
  969.               (concat (if ilisp-last-message
  970.                   (concat ";;; " ilisp-last-message "\n"))
  971.                   (comint-remove-whitespace output)
  972.                   "\n"
  973.                   ilisp-last-prompt))
  974.              (setq ilisp-last-message nil))
  975.         (if (window-point window)
  976.             (progn (select-window window)
  977.                (set-buffer buffer)))))
  978.         (comint-display-output output)))))
  979.  
  980. ;;;
  981. (defun ilisp-handler (error-p wait-p message output prompt)
  982.   "Given ERROR-P, WAIT-P, MESSAGE, OUTPUT and PROMPT, show the message
  983. and output if there is an error or the output is multiple lines and
  984. let the user decide what to do."
  985.   (if lisp-no-popper
  986.       (progn
  987.     (if message
  988.         (progn
  989.           (setq ilisp-last-message message
  990.             ilisp-last-prompt prompt)
  991.           (if (not wait-p) (lisp-display-output output))))
  992.     nil)
  993.       (if (and (not wait-p)
  994.            (setq output (comint-remove-whitespace output))
  995.            (or error-p (string-match "\n" output)))
  996.       (let* ((buffer (popper-output-buffer))
  997.          (out (if error-p 
  998.               (funcall ilisp-error-filter output)
  999.               output))
  1000.          (key
  1001.           (if (and error-p (not (comint-interrupted)))
  1002.               (comint-handle-error
  1003.                out
  1004.                "SPC-scroll, I-ignore, K-keep, A-abort sends and keep or B-break: "
  1005.                '(?i ?k ?a ?b))
  1006.               (comint-handle-error 
  1007.                out 
  1008.                "SPC-scroll, I-ignore, K-keep or A-abort sends and keep: "
  1009.                '(?i ?k ?a))))
  1010.          (clear comint-queue-emptied))
  1011.         (if (= key ?i)
  1012.         (progn
  1013.           (message "Ignore message")
  1014.           (if buffer 
  1015.               (funcall (if (boundp 'temp-buffer-show-function)
  1016.                    temp-buffer-show-function
  1017.                  temp-buffer-show-hook)
  1018.                    buffer)
  1019.               (popper-bury-output))
  1020.           t)
  1021.         (save-excursion
  1022.           (set-buffer (get-buffer-create "*Errors*"))
  1023.           (if clear (delete-region (point-min) (point-max)))
  1024.           (goto-char (point-max))
  1025.           (insert message)
  1026.           (insert ?\n)
  1027.           (insert out) 
  1028.           (insert "\n\n"))
  1029.         (if clear (setq comint-queue-emptied nil))
  1030.         (if (= key ?a)
  1031.             (progn 
  1032.               (message "Abort pending commands and keep in *Errors*")
  1033.               (comint-abort-sends)
  1034.               t)
  1035.             (if (= key ?b)
  1036.             (progn 
  1037.               (comint-insert
  1038.                (concat comment-start comment-start comment-start
  1039.                    message "\n"
  1040.                    output "\n" prompt))
  1041.               (message "Preserve break") nil)
  1042.             (message "Keep error in *Errors* and continue")
  1043.             t))))
  1044.       t)))
  1045.  
  1046. ;;;
  1047. (defun ilisp-update-status (status)
  1048.   "Update process STATUS of the current buffer and let all lisp mode
  1049. buffers know as well."
  1050.   (setq ilisp-status (if lisp-show-status (format " :%s" status)))
  1051.   (comint-update-status status))
  1052.  
  1053. ;;;
  1054. (defun ilisp-abort-handler ()
  1055.   "Handle when the user aborts commands."
  1056.   (setq ilisp-initializing nil
  1057.     ilisp-load-files nil)
  1058.   (let ((add nil))
  1059.     (while ilisp-pending-changes
  1060.       (if (not (memq (car ilisp-pending-changes) lisp-changes))
  1061.       (setq add (cons (car ilisp-pending-changes) add)))
  1062.       (setq ilisp-pending-changes (cdr ilisp-pending-changes)))
  1063.     (setq lisp-changes (nconc lisp-changes add))))
  1064.  
  1065. ;;;%%Ilisp stuff
  1066. (defun ilisp-initialized ()
  1067.   "Return T if the current inferior LISP has been initialized."
  1068.   (memq (buffer-name (ilisp-buffer)) ilisp-initialized))
  1069.  
  1070. ;;;
  1071. (defun ilisp-compile-inits ()
  1072.   "Compile the initialization files for the current inferior LISP
  1073. dialect."
  1074.   (interactive)
  1075.   (ilisp-init t)
  1076.   (let ((files (ilisp-value 'ilisp-load-inits t)))
  1077.     (while files
  1078.       (compile-file-lisp (expand-file-name (cdr (car files)) ilisp-directory)
  1079.              (ilisp-value 'ilisp-init-binary-extension t))
  1080.       (setq files (cdr files)))))
  1081.  
  1082. ;;;
  1083. (defun ilisp-load-or-send (file)
  1084.   "Try to load FILE into the inferior LISP.  If the file is not
  1085. accessible in the inferior LISP as determined by
  1086. ilisp-load-or-send-command, then visit the file and send the file over
  1087. the process interface."
  1088.   (let* ((command
  1089.       (format (ilisp-value 'ilisp-load-or-send-command) 
  1090.           (lisp-file-extension
  1091.            file 
  1092.            (ilisp-value 'ilisp-init-binary-extension t))
  1093.           file)))
  1094.     (set-ilisp-value 'ilisp-load-files 
  1095.              (nconc (ilisp-value 'ilisp-load-files t) (list file)))
  1096.     (comint-send
  1097.      (ilisp-process) command t nil 'load
  1098.      (format "Loading %s" file)
  1099.      (function (lambda (error wait message output last)
  1100.        (let* ((file (lisp-last ilisp-load-files))
  1101.           (process (get-buffer-process (current-buffer)))
  1102.           (case-fold-search t))
  1103.      (if (and output 
  1104.           (string-match "nil" (car (lisp-last-line output))))
  1105.          (let* ((old-buffer (get-file-buffer file))
  1106.             (buffer (find-file-noselect file))
  1107.             (string (save-excursion
  1108.                   (set-buffer buffer)
  1109.                   (buffer-string))))
  1110.            (if (not old-buffer) (kill-buffer buffer))
  1111.            (if (string= "" string)
  1112.            (abort-commands-lisp (format "Can't find file %s" file))
  1113.            (comint-send
  1114.             process
  1115.             (format ilisp-block-command string)
  1116.             t nil 'send (format "Sending %s" file)
  1117.             (function (lambda (error wait message output last)
  1118.               (if error
  1119.               (progn 
  1120.                 (comint-display-error output)
  1121.                 (abort-commands-lisp
  1122.                  (format "Error sending %s"
  1123.                      (lisp-last ilisp-load-files))))
  1124.               (setq ilisp-load-files
  1125.                 (delq (lisp-last ilisp-load-files)
  1126.                       ilisp-load-files))))))))
  1127.            (if error (ilisp-handler error wait message output last))
  1128.            (setq ilisp-load-files (delq file ilisp-load-files)))))))))
  1129.  
  1130. ;;;
  1131. (defun ilisp-load-init (dialect file)
  1132.   "Add FILE to the files to be loaded into the inferior LISP when
  1133. dialect is initialized.  If FILE is NIL, the entry will be removed."
  1134.   (let ((old (assoc dialect ilisp-load-inits)))
  1135.     (if file
  1136.     (if old
  1137.         (rplacd old file)
  1138.         (setq ilisp-load-inits (nconc ilisp-load-inits 
  1139.                       (list (cons dialect file)))))
  1140.     (if old (setq ilisp-load-inits (delq old ilisp-load-inits))))))
  1141.  
  1142. ;;;
  1143. (defun ilisp-binary (init var)
  1144.   "Initialize VAR to the result of INIT if VAR is NIL."
  1145.   (if (not (ilisp-value var t))
  1146.       (let ((binary (ilisp-value init t)))
  1147.     (if binary
  1148.         (comint-send 
  1149.          (ilisp-process) binary
  1150.          t nil 'binary nil 
  1151.          (` (lambda (error wait message output last)
  1152.           (if (or error
  1153.               (not (string-match "\"[^\"]*\"" output)))
  1154.               (progn
  1155.             (lisp-display-output output)
  1156.             (abort-commands-lisp "No binary"))
  1157.               (setq (, var)
  1158.                 (substring output
  1159.                        (1+ (match-beginning 0))
  1160.                        (1- (match-end 0))))))))))))
  1161.  
  1162. ;;;
  1163. (defun ilisp-done-init ()
  1164.   "Make sure that initialization is done and if not dispatch another check."
  1165.   (if ilisp-load-files
  1166.       (comint-send-code (get-buffer-process (current-buffer))
  1167.             'ilisp-done-init)
  1168.       (if ilisp-initializing
  1169.       (progn
  1170.         (message "Finished initializing %s" (car ilisp-dialect))
  1171.         (setq ilisp-initializing nil
  1172.           ilisp-initialized
  1173.           (cons (buffer-name (current-buffer)) ilisp-initialized))))))
  1174.  
  1175. ;;;
  1176. (defun ilisp-init-internal (&optional sync)
  1177.   "Send all of the stuff necessary to initialize."
  1178.   (unwind-protect
  1179.        (progn
  1180.      (if sync
  1181.          (comint-sync
  1182.           (ilisp-process)
  1183.           "\"Start sync\""  "[ \t\n]*\"Start sync\""
  1184.           "\"End sync\""    "\"End sync\""))
  1185.      (ilisp-binary 'ilisp-binary-command 'ilisp-binary-extension)
  1186.      (ilisp-binary 'ilisp-init-binary-command 'ilisp-init-binary-extension)
  1187.      ;; This gets executed in the process buffer
  1188.      (comint-send-code
  1189.       (ilisp-process)
  1190.       (function (lambda ()
  1191.         (let ((files ilisp-load-inits)
  1192.           (done nil))
  1193.           (unwind-protect
  1194.            (progn
  1195.              (if (not ilisp-init-binary-extension)
  1196.              (setq ilisp-init-binary-extension 
  1197.                    ilisp-binary-extension))
  1198.              (while files
  1199.                (ilisp-load-or-send
  1200.             (expand-file-name 
  1201.              (cdr (car files)) ilisp-directory))
  1202.                (setq files (cdr files)))
  1203.              (comint-send-code (ilisp-process)
  1204.                        'ilisp-done-init)
  1205.              (setq done t))
  1206.         (if (not done)
  1207.             (progn
  1208.               (setq ilisp-initializing nil)
  1209.               (abort-commands-lisp))))))))
  1210.      (set-ilisp-value 'ilisp-initializing t))
  1211.     (if (not (ilisp-value 'ilisp-initializing t))
  1212.     (abort-commands-lisp))))
  1213.  
  1214. ;;;
  1215. (defun ilisp-init (&optional waitp forcep sync)
  1216.   "Initialize the current inferior LISP if necessary by loading the
  1217. files in ilisp-load-inits.  Optional WAITP waits for initialization to
  1218. finish.  When called interactively, force reinitialization.  With a
  1219. prefix, get the binary extensions again."  
  1220.   (interactive 
  1221.    (list (if current-prefix-arg
  1222.          (progn
  1223.            (set-ilisp-value 'ilisp-init-binary-extension nil)
  1224.            (set-ilisp-value 'ilisp-binary-extension nil)
  1225.            nil))
  1226.      t))
  1227.   (if (or forcep (not (ilisp-initialized)))
  1228.       (progn
  1229.     (message "Started initializing ILISP")
  1230.     (if (not ilisp-directory)
  1231.         (setq ilisp-directory (or (ilisp-directory "ilisp.elc" load-path)
  1232.                       (ilisp-directory "ilisp.el" load-path))))
  1233.     (if (not (ilisp-value 'ilisp-initializing t))
  1234.         (ilisp-init-internal sync))
  1235.     (if waitp
  1236.         (while (ilisp-value 'ilisp-initializing t)
  1237.           (accept-process-output)
  1238.           (sit-for 0))))))
  1239.  
  1240. ;;;
  1241. (defun ilisp-init-and-sync ()
  1242.   "Synchronize with the inferior LISP and then initialize."
  1243.   (ilisp-init nil nil t))
  1244.  
  1245. ;;;
  1246. (defun ilisp-send (string &optional message status and-go handler)
  1247.   "Send STRING to the ILISP buffer, print MESSAGE set STATUS and
  1248. return the result if AND-GO is NIL, otherwise switch to ilisp if
  1249. and-go is T and show message and results.  If AND-GO is 'dispatch,
  1250. then the command will be executed without waiting for results.  If
  1251. AND-GO is 'call, then a call will be generated. If this is the first
  1252. time an ilisp command has been executed, the lisp will also be
  1253. initialized from the files in ilisp-load-inits.  If there is an error,
  1254. comint-errorp will be T and it will be handled by HANDLER."
  1255.   (ilisp-init t)
  1256.   (let ((process (ilisp-process))
  1257.     (dispatch (eq and-go 'dispatch)))
  1258.     (if message
  1259.     (message "%s" (if dispatch
  1260.               (concat "Started " message)
  1261.               message)))
  1262.     ;; No completion table
  1263.     (setq ilisp-original nil)
  1264.     (if (memq and-go '(t call))
  1265.     (progn (comint-send process string nil nil status message handler)
  1266.            (if (eq and-go 'call)
  1267.            (call-defun-lisp nil)
  1268.            (switch-to-lisp t t))
  1269.            nil)
  1270.     (let* ((save (ilisp-value 'ilisp-save-command t))
  1271.            (result
  1272.         (comint-send 
  1273.          process
  1274.          (if save (format save string) string)
  1275.          ;; Interrupt without waiting
  1276.          t (if (not dispatch) 'wait) status message handler)))
  1277.       (if save 
  1278.           (comint-send
  1279.            process
  1280.            (ilisp-value 'ilisp-restore-command t)
  1281.            t nil 'restore "Restore" t t))
  1282.       (if (not dispatch)
  1283.           (progn
  1284.         (while (not (cdr result))
  1285.           (sit-for 0)
  1286.           (accept-process-output))
  1287.         (comint-remove-whitespace (car result))))))))
  1288.  
  1289. ;;;
  1290. (defun return-ilisp ()
  1291.   "Grab the current expression with comint-get-old-input.  If we have
  1292. a complete sexp, send it.  Otherwise, indent appropriately."
  1293.   (interactive)
  1294.   (let ((proc (get-buffer-process (current-buffer))))
  1295.     (if (not proc)
  1296.     (error "Current buffer has no process")
  1297.     (let* ((pmark (process-mark proc))
  1298.            (input (ilisp-get-old-input)))
  1299.       (if input
  1300.           (let ((input-ring (get-input-ring)))
  1301.         (if (>= (point) pmark)
  1302.             (goto-char (point-max))
  1303.             (goto-char pmark)
  1304.             (insert input))
  1305.         (if (not ilisp-no-newline) (insert ?\n))
  1306.         (if (and (funcall comint-input-filter input)
  1307.              (or (ring-empty-p input-ring)
  1308.                  (not (string= (ring-ref input-ring 0) input))))
  1309.             (ring-insert-new input-ring input))
  1310.         (funcall comint-input-sentinel input)
  1311.         ;; Nuke symbol table
  1312.         (setq ilisp-original nil)
  1313.         (funcall comint-input-sender proc input)
  1314.         (set-marker (process-mark proc) (point))
  1315.         (set-marker comint-last-input-end (point))
  1316.         (goto-char (point-max)))
  1317.           (if (= pmark (point-max)) 
  1318.           (let ((comint-send-newline t))
  1319.             (if (not ilisp-no-newline) (insert ?\n))
  1320.             (set-marker (process-mark proc) (point))
  1321.             (funcall comint-input-sender proc ""))
  1322.           (insert ?\n)
  1323.           (save-restriction
  1324.             (narrow-to-region pmark (point-max))
  1325.             (funcall indent-line-function))))))))
  1326.  
  1327. ;;;
  1328. (defun close-and-send-lisp ()
  1329.   "Close and indent the current sexp then send it to the inferior
  1330. LISP." 
  1331.   (interactive)
  1332.   (reindent-lisp)
  1333.   (if (memq major-mode ilisp-modes)
  1334.       (return-ilisp)
  1335.       (eval-defun-lisp)))
  1336.  
  1337. ;;;%%Keyboard mode
  1338. (defun raw-keys-ilisp ()
  1339.   "Start using raw keyboard mode to send each character typed to the
  1340. inferior LISP until a key bound to interactive-keys-ilisp is
  1341. encountered.  See also io-bridge-ilisp." 
  1342.   (interactive)
  1343.   (if (not ilisp-raw-map)
  1344.       (let ((map (make-keymap)))
  1345.     (if (vectorp map)
  1346.         (fillarray map 'ilisp-send-char)
  1347.       ;; Lucid GNU Emacs keymaps
  1348.       (let ((i 0))
  1349.         (while (< i 128)
  1350.           (define-key map (make-string 1 i) 'ilisp-send-char)
  1351.           (setq i (1+ i)))))
  1352.     (define-key map "\C-g" 'interactive-keys-ilisp)
  1353.     (setq ilisp-raw-map map)))
  1354.   (use-local-map ilisp-raw-map)
  1355.   (message ilisp-raw-message))
  1356.  
  1357. ;;;
  1358. (defun interactive-keys-ilisp ()
  1359.   "Go back to interactive keyboard interactions in the inferior LISP."
  1360.   (interactive)
  1361.   (use-local-map ilisp-use-map)
  1362.   (message "Interactive keyboard mode"))
  1363.  
  1364. ;;;
  1365. (defun ilisp-send-char ()
  1366.   "Send the last typed character to the current inferior LISP echoing
  1367. if ilisp-raw-echo is T."
  1368.   (interactive)
  1369.   (if (ilisp-value 'ilisp-raw-echo t)
  1370.       (progn
  1371.     (goto-char (point-max))
  1372.     (insert last-input-char)
  1373.     (set-marker (process-mark (ilisp-process)) (point))
  1374.     (set-marker comint-last-input-end (point))))
  1375.   (process-send-string (ilisp-process) 
  1376.                (make-string 1 last-input-char))
  1377.   (message ilisp-raw-message))
  1378.  
  1379. ;;;
  1380. (defun ilisp-raw-handler (process output)
  1381.   "Turn on raw keyboard mode."
  1382.   (raw-keys-ilisp))
  1383. (defun ilisp-interactive-handler (process output)
  1384.   "Turn on interactive keyboard mode."
  1385.   (interactive-keys-ilisp))
  1386.  
  1387. ;;;
  1388. (defun io-bridge-ilisp ()
  1389.   "Set up so that the inferior LISP can turn on EMACS raw mode by
  1390. sending ^[1^] and turn it off by sending ^[0^]."
  1391.   (interactive)
  1392.   (require 'bridge)
  1393.   (install-bridge)
  1394.   (setq bridge-handlers (cons '("1" . ilisp-raw-handler)
  1395.                   (cons '("0" . ilisp-interactive-handler)
  1396.                     bridge-handlers))))
  1397.  
  1398. ;;;%%Debugger interface
  1399. (defun delete-char-or-pop-ilisp (arg &optional killflag)
  1400.   "Delete ARG characters, or pop break level if at end of buffer.  
  1401. Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).
  1402. Interactively, ARG is the prefix arg, and KILLFLAG is set if
  1403. ARG was explicitly specified."
  1404.   (interactive "p")
  1405.   (if (eobp)
  1406.       (progn
  1407.     (message "Pop LISP one level")
  1408.     (comint-simple-send (ilisp-process) (ilisp-value 'comint-fix-error)))
  1409.       (call-interactively 'delete-char (list arg killflag))))
  1410.  
  1411. ;;;
  1412. (defun reset-ilisp ()
  1413.   "Reset the inferior LISP top level."
  1414.   (interactive)
  1415.   (message "Reset LISP to top level")
  1416.   (comint-simple-send (ilisp-process) (ilisp-value 'ilisp-reset)))
  1417.  
  1418. ;;;%Completion
  1419. ;;; The basic idea behind the completion stuff is to use as much of
  1420. ;;; the standard Emacs stuff as possible.  The extensions here go out
  1421. ;;; to the inferior LISP to complete symbols if necessary.  
  1422. ;;; 
  1423. (defun ilisp-display-choices (symbol choices)
  1424.   "Display the possible choices for SYMBOL in alist CHOICES."
  1425.   (with-output-to-temp-buffer " *Completions*"
  1426.     (display-completion-list
  1427.      (sort 
  1428.       (all-completions (lisp-symbol-name symbol) choices)
  1429.       'string-lessp))))
  1430.  
  1431. ;;;%%ilisp-can-complete
  1432. (defun ilisp-can-complete (symbol function-p)
  1433.   "Return T if ilisp completion can complete SYMBOL from the current table."
  1434.   (and ilisp-original 
  1435.        (string= (lisp-symbol-package ilisp-original) 
  1436.         (lisp-symbol-package symbol))
  1437.        (string= (lisp-symbol-delimiter ilisp-original)
  1438.         (lisp-symbol-delimiter symbol))
  1439.        (lisp-prefix-p (lisp-symbol-name ilisp-original)
  1440.               (lisp-symbol-name symbol))
  1441.        (eq function-p ilisp-original-function-p)))
  1442.  
  1443. ;;;%%ilisp-complete
  1444. (defun ilisp-complete (symbol &optional function-p)
  1445.   "Return a list of the possible completions for symbol from the
  1446. inferior LISP.  If FUNCTION-P is T, only symbols with function
  1447. bindings will be considered.  If no package is specified the buffer
  1448. package will be used."
  1449.   (let* ((choices 
  1450.       (ilisp-send 
  1451.        (format  (ilisp-value 'ilisp-complete-command) 
  1452.             (lisp-symbol-name symbol) (lisp-symbol-package symbol)
  1453.             function-p
  1454.             (string= (lisp-symbol-delimiter symbol) ":")
  1455.             ilisp-prefix-match)
  1456.        (if (not ilisp-complete)
  1457.            (concat "Complete " 
  1458.                (if function-p "function ")
  1459.                (lisp-buffer-symbol symbol)))
  1460.        'complete)))
  1461.     (if (ilisp-value 'comint-errorp t)
  1462.     (progn (lisp-display-output choices)
  1463.            (error "Error completing %s" (lisp-buffer-symbol symbol)))
  1464.     (setq choices (read choices)
  1465.           choices (if (eq choices 'NIL) nil choices)))
  1466.     (setq ilisp-original symbol
  1467.       ilisp-original-function-p function-p
  1468.       ilisp-original-table choices)))
  1469.  
  1470. ;;;%%ilisp-completion-table
  1471. (defun ilisp-completion-table (symbol function-p)
  1472.   "Return the completion table for SYMBOL trying to use the current
  1473. one.  If FUNCTION-P is T, only symbols with function cells will be
  1474. returned."
  1475.   (if (ilisp-can-complete symbol function-p) 
  1476.       ilisp-original-table
  1477.       (ilisp-complete symbol function-p)))
  1478.  
  1479. ;;;%%Minibuffer completion
  1480. (defun ilisp-restore-prefix ()
  1481.   "Restore the prefix from ilisp-mini-prefix at the start of the
  1482. minibuffer."
  1483.   (if ilisp-mini-prefix
  1484.       (save-excursion
  1485.     (goto-char (point-min))
  1486.     (insert ilisp-mini-prefix)
  1487.     (setq ilisp-mini-prefix nil))))
  1488.  
  1489. ;;;
  1490. (defun ilisp-current-choice ()
  1491.   "Set up the minibuffer completion table for the current symbol.
  1492. If there is a paren at the start of the minibuffer, or there is not an
  1493. ilisp-table, this will be from the inferior LISP.  Otherwise, it will
  1494. be the ilisp-table."
  1495.   (if (or (null ilisp-table) (eq (char-after 1) ?\())
  1496.       (progn
  1497.     (let* ((symbol-info (lisp-previous-symbol))
  1498.            (symbol (car symbol-info)))
  1499.       (setq minibuffer-completion-table 
  1500.         (ilisp-completion-table symbol ilisp-completion-function-p)))
  1501.     (save-excursion 
  1502.       (skip-chars-backward "^: \(")
  1503.       (setq ilisp-mini-prefix (buffer-substring (point-min) (point)))
  1504.       (delete-region (point-min) (point)))
  1505.     ;; Nothing can match this table
  1506.     (if (not minibuffer-completion-table)
  1507.         (setq minibuffer-completion-table '((" ")))))
  1508.       (setq minibuffer-completion-table ilisp-table
  1509.         minibuffer-completion-predicate nil)))
  1510.  
  1511. ;;;%%Commands
  1512. (defvar ilisp-completion-help
  1513.   (lookup-key minibuffer-local-must-match-map "?"))
  1514. (defun ilisp-completion-help ()
  1515.   "Inferior LISP minibuffer completion help."
  1516.   (interactive)
  1517.   (ilisp-current-choice) 
  1518.   (funcall ilisp-completion-help)
  1519.   (ilisp-restore-prefix))
  1520.  
  1521. ;;;
  1522. (defvar ilisp-completion
  1523.   (lookup-key minibuffer-local-must-match-map "\t"))
  1524. (defun ilisp-completion ()
  1525.   "Inferior LISP minibuffer complete."
  1526.   (interactive)
  1527.   (ilisp-current-choice)
  1528.   (funcall ilisp-completion)
  1529.   (ilisp-restore-prefix))
  1530.  
  1531. ;;;
  1532. (defvar ilisp-completion-word
  1533.   (lookup-key minibuffer-local-must-match-map " "))
  1534. (defun ilisp-completion-word ()
  1535.   "Inferior LISP minibuffer complete word."
  1536.   (interactive)
  1537.   (if (eq (char-after 1) ?\()
  1538.       (insert " ")
  1539.       (ilisp-current-choice)
  1540.       (funcall ilisp-completion-word)
  1541.       (ilisp-restore-prefix)))
  1542.  
  1543. ;;;
  1544. (defun ilisp-completion-paren ()
  1545.   "Only allow a paren if ilisp-paren is T."
  1546.   (interactive)
  1547.   (if ilisp-paren 
  1548.       (if (or (eq last-input-char ?\() (eq (char-after 1) ?\())
  1549.       (insert last-input-char)
  1550.       (beep))
  1551.       (beep)))
  1552.       
  1553. ;;; 
  1554. (defvar ilisp-completion-exit 
  1555.   (lookup-key minibuffer-local-must-match-map "\n"))
  1556. (defun ilisp-completion-exit ()
  1557.   "Inferior LISP completion complete and exit."
  1558.   (interactive)
  1559.   (if (eq (char-after 1) ?\()
  1560.       (progn (find-unbalanced-lisp nil)
  1561.          (exit-minibuffer))
  1562.       (if ilisp-no-complete
  1563.       (exit-minibuffer)
  1564.       (if (= (point-min) (point-max))
  1565.           (exit-minibuffer)
  1566.           (ilisp-current-choice)
  1567.           (unwind-protect (funcall ilisp-completion-exit)
  1568.         (ilisp-restore-prefix))))))
  1569.  
  1570. ;;;%%ilisp-completer
  1571. (defun ilisp-completer (symbol function-p)
  1572.   "Complete SYMBOL from the inferior LISP using only function symbols
  1573. if FUNCTION-P is T.  Return (SYMBOL LCS-SYMBOL CHOICES UNIQUEP)."
  1574.   (let* ((name (lisp-symbol-name symbol))
  1575.      (table (ilisp-completion-table symbol function-p))
  1576.      (choice (and table (try-completion name table))))
  1577.     (cond ((eq choice t)        ;Name is it
  1578.        (list symbol symbol nil t))
  1579.       ((string= name choice)    ;Name is LCS
  1580.        (list symbol symbol (all-completions name table) nil))
  1581.       (choice            ;New LCS
  1582.        (let ((symbol
  1583.           (lisp-symbol (lisp-symbol-package symbol) 
  1584.                    (lisp-symbol-delimiter symbol)
  1585.                    choice)))
  1586.          (list symbol symbol (all-completions choice table) nil)))
  1587.       ((and (not ilisp-prefix-match) table)    ;Try partial matches
  1588.        (let ((matches
  1589.           (completer name table nil (regexp-quote completer-words))))
  1590.          (cons (lisp-symbol (lisp-symbol-package symbol)
  1591.                 (lisp-symbol-delimiter symbol)
  1592.                 (car matches))
  1593.            (cons  (lisp-symbol (lisp-symbol-package symbol)
  1594.                 (lisp-symbol-delimiter symbol)
  1595.                 (car (cdr matches)))
  1596.               (cdr (cdr matches)))))))))
  1597.  
  1598. ;;;%Interface functions
  1599. ;;;%%Symbols
  1600. (defun lisp-string-to-symbol (string)
  1601.   "Convert STRING to a symbol, (package delimiter symbol) where the
  1602. package is either package:symbol or from the current buffer."
  1603.   (let* ((start (string-match ":+" string))
  1604.      (end (if start (match-end 0))))
  1605.     (if start
  1606.     (lisp-symbol
  1607.      (if (= start 0)
  1608.          ""
  1609.          (substring string 0 start))
  1610.      (substring string start end)
  1611.      (substring string end))
  1612.     (let ((package (lisp-buffer-package)))
  1613.       (lisp-symbol package (if package "::") string)))))
  1614.  
  1615. ;;;
  1616. (defun lisp-symbol-to-string (symbol)
  1617.   "Convert SYMBOL to a string."
  1618.   (apply 'concat symbol))
  1619.  
  1620. ;;;
  1621. (defun lisp-buffer-symbol (symbol)
  1622.   "Return SYMBOL as a string qualified for the current buffer."
  1623.   (let ((symbol-name (lisp-symbol-name symbol))
  1624.     (pkg (lisp-symbol-package symbol))
  1625.     (delimiter (lisp-symbol-delimiter symbol)))
  1626.     (cond ((string= pkg (lisp-buffer-package)) symbol-name)
  1627.       ((string= pkg "") (concat ":" symbol-name))
  1628.       (pkg (concat pkg delimiter symbol-name))
  1629.       (t symbol-name))))
  1630.  
  1631. ;;;
  1632. (defun lisp-previous-symbol (&optional stay)
  1633.   "Return the immediately preceding symbol as ((package delimiter symbol)
  1634. function-p start end).  If STAY is T, the end of the symbol will be point."
  1635.   (save-excursion
  1636.     (if (or (and (memq major-mode ilisp-modes)
  1637.          (= (point) (process-mark (get-buffer-process
  1638.                        (current-buffer)))))
  1639.         (progn
  1640.           (skip-chars-backward " \t\n")
  1641.           (or (bobp) (memq (char-after (1- (point))) '(?\) ?\")))))
  1642.     nil
  1643.     (let* ((delimiters (ilisp-value 'ilisp-symbol-delimiters))
  1644.            (end (progn
  1645.               (if (not stay) (skip-chars-forward delimiters))
  1646.               (point)))
  1647.            (start (progn
  1648.             (skip-chars-backward delimiters)
  1649.             (point)))
  1650.            (prefix (if (not (bobp)) (1- start)))
  1651.            (function-p
  1652.         (and prefix
  1653.              (or (eq (char-after prefix) ?\()
  1654.              (and (eq (char-after prefix) ?')
  1655.                   (not (bobp))
  1656.                   (eq (char-after (1- prefix)) ?#)))
  1657.              (not (looking-at "[^: \t\n]*:*\\*[^ \t\n]")))))
  1658.       (cons (lisp-string-to-symbol (buffer-substring start end))
  1659.         (list function-p start end))))))
  1660.  
  1661. ;;;%%Sexps
  1662. (defun lisp-previous-sexp (&optional prefix)
  1663.   "Return the previous sexp.  If PREFIX is T, then prefix like ' or #'
  1664. are allowed."
  1665.   (save-excursion
  1666.     (condition-case ()
  1667.     (progn
  1668.       (if (and (memq major-mode ilisp-modes)
  1669.            (= (point)
  1670.               (process-mark (get-buffer-process (current-buffer)))))
  1671.           nil
  1672.           (if (not
  1673.            (or (eobp) (memq (char-after (point)) '(? ?\) ?\n ?\t))))
  1674.           (forward-sexp))
  1675.           (skip-chars-backward " \t\n")
  1676.           (let ((point (point)))
  1677.         (backward-sexp)
  1678.         (skip-chars-backward "^ \t\n(\",")
  1679.         (if (not prefix) (skip-chars-forward "#'"))
  1680.         (buffer-substring (point) point))))
  1681.       (error nil))))
  1682.  
  1683. ;;;
  1684. (defun lisp-def-name (&optional namep)
  1685.   "Return the name of a definition assuming that you are at the start
  1686. of the sexp.  If the form starts with DEF, the form start and the next
  1687. symbol will be returned.  Optional NAMEP will return only the name without the defining symbol."
  1688.   (let ((case-fold-search t))
  1689.     (if (looking-at
  1690.      ;; (( \( (def*) (( \( (setf)) | \(?)) | \(?) (symbol)
  1691.      ;; 12    3    3 45    6    65      42      1 7      7
  1692.      ;;0011\(22 def*        22         32 43\(54 setf54         43   \(?32 11      00 60           60
  1693.      "\\(\\((\\(def[^ \t\n]*\\)[ \t\n]+\\(\\((\\(setf\\)[ \t\n]+\\)\\|(?\\)\\)\\|(?\\)\\([^ \t\n)]*\\)")
  1694.     (let ((symbol (buffer-substring (match-beginning 7) (match-end 7))))
  1695.       (if (match-end 6)
  1696.           (concat (if (not namep) 
  1697.               (concat 
  1698.                (buffer-substring (match-beginning 3) (match-end 3))
  1699.                " "))
  1700.               "("
  1701.               (buffer-substring (match-beginning 6) (match-end 6))
  1702.               " " symbol ")")
  1703.           (if (match-end 3)
  1704.           (concat (if (not namep)
  1705.                   (concat 
  1706.                    (buffer-substring (match-beginning 3) 
  1707.                          (match-end 3))
  1708.                    " "))
  1709.               symbol)
  1710.           symbol))))))
  1711.  
  1712. ;;;
  1713. (defun lisp-function-name ()
  1714.   "Return the previous function symbol.  This is either after a #' or
  1715. at the start of the current sexp.  If there is no current sexp, return
  1716. nil."
  1717.   (save-excursion
  1718.     (let ((symbol (lisp-previous-symbol)))
  1719.       (if (car (cdr symbol))
  1720.       (car symbol)
  1721.       (condition-case ()
  1722.           (if (and (memq major-mode ilisp-modes)
  1723.                (= (point)
  1724.               (process-mark 
  1725.                (get-buffer-process (current-buffer)))))
  1726.           nil
  1727.           (backward-up-list 1)
  1728.           (down-list 1)
  1729.           (lisp-string-to-symbol
  1730.            (buffer-substring (point) 
  1731.                      (progn (forward-sexp 1) (point)))))
  1732.         (error nil))))))
  1733.  
  1734. ;;;
  1735. (defun lisp-minus-prefix ()
  1736.   "Set current-prefix-arg to its absolute value if numeric and return
  1737. T if it is a negative."
  1738.   (if current-prefix-arg
  1739.       (if (symbolp current-prefix-arg)
  1740.       (progn (setq current-prefix-arg nil) t)
  1741.       (if (< (setq current-prefix-arg
  1742.                (prefix-numeric-value current-prefix-arg))
  1743.          0)
  1744.           (progn (setq current-prefix-arg (- current-prefix-arg)) t)))))
  1745.  
  1746. ;;;%%ilisp-read
  1747. (defvar ilisp-completion-map nil "Keymap for reading ilisp readers.")
  1748. (defun ilisp-completion-map ()
  1749.   "Set up the ilisp-completion-map from lisp-mode-map for the ilisp
  1750. readers and return it."
  1751.   (if (not ilisp-completion-map)
  1752.       (progn
  1753.     (if (string-match "Lucid" emacs-version)
  1754.         ;; not necessary, but friendlier.
  1755.         (progn
  1756.           (setq ilisp-completion-map (make-keymap))
  1757.               (set-keymap-name ilisp-completion-map 'ilisp-completion-map)
  1758.           (set-keymap-parent ilisp-completion-map lisp-mode-map))
  1759.       (setq ilisp-completion-map (copy-keymap lisp-mode-map)))
  1760.     (define-key ilisp-completion-map " "  'ilisp-completion-word)
  1761.     (define-key ilisp-completion-map "\t" 'ilisp-completion)
  1762.     (define-key ilisp-completion-map "?" 'ilisp-completion-help)
  1763.     (define-key ilisp-completion-map "\M-\t" 'ilisp-completion)
  1764.     (define-key ilisp-completion-map "\n" 'ilisp-completion-exit)
  1765.     (define-key ilisp-completion-map "\r" 'ilisp-completion-exit)
  1766.     (define-key ilisp-completion-map "\C-g" 'abort-recursive-edit)
  1767.     (define-key ilisp-completion-map "(" 'ilisp-completion-paren)
  1768.     (define-key ilisp-completion-map ")" 'ilisp-completion-paren)
  1769.     (define-key ilisp-completion-map "'" nil)
  1770.     (define-key ilisp-completion-map "#" nil)
  1771.     (define-key ilisp-completion-map "\"" nil)))
  1772.   ilisp-completion-map)
  1773.  
  1774. ;;;
  1775. (defun ilisp-read (prompt &optional initial-contents)
  1776.   "PROMPT in the minibuffer with optional INITIAL-CONTENTS and return
  1777. the result.  Completion of symbols though the inferior LISP is
  1778. allowed."
  1779.   (let ((ilisp-complete t)
  1780.     (ilisp-paren t)
  1781.     (ilisp-no-complete t)
  1782.     (ilisp-completion-package (lisp-buffer-package)))
  1783.     (read-from-minibuffer prompt initial-contents
  1784.               (ilisp-completion-map))))
  1785.  
  1786. ;;;%%lisp-read-program
  1787. (defvar lisp-program-map nil
  1788.   "Minibuffer map for reading a program and arguments.")
  1789.  
  1790. ;;;
  1791. (defun lisp-read-program (prompt &optional initial)
  1792.   "Read a program with PROMPT and INITIAL.  TAB or Esc-TAB will complete
  1793. filenames."
  1794.   (if (null lisp-program-map)
  1795.       (progn 
  1796.     (setq lisp-program-map (copy-keymap minibuffer-local-map))
  1797.     (define-key lisp-program-map "\M-\t" 'comint-dynamic-complete)
  1798.     (define-key lisp-program-map "\t" 'comint-dynamic-complete)
  1799.     (define-key lisp-program-map "?" 'comint-dynamic-list-completions)))
  1800.   (read-from-minibuffer prompt initial lisp-program-map))
  1801.  
  1802. ;;;%%ilisp-read-symbol
  1803. (defun ilisp-read-symbol (prompt &optional default function-p no-complete)
  1804.   "PROMPT in the minibuffer with optional DEFAULT and return a symbol
  1805. from the inferior LISP.  If FUNCTION-P is T, only symbols with
  1806. function values will be returned.  If NO-COMPLETE is T, then
  1807. uncompleted symbols will be allowed."
  1808.   (let* ((ilisp-complete t)
  1809.      (ilisp-no-complete no-complete)
  1810.      (ilisp-completion-package (lisp-buffer-package))
  1811.      (ilisp-completion-function-p function-p)
  1812.      (string (read-from-minibuffer prompt nil (ilisp-completion-map))))
  1813.     (if (equal string "")
  1814.     default
  1815.     (lisp-string-to-symbol string))))
  1816.  
  1817. ;;;%%ilisp-completing-read
  1818. (defun ilisp-completing-read (prompt table &optional default)
  1819.   "Read with PROMPT from an alist of TABLE.  No input returns DEFAULT.
  1820. Symbols are from table, other specs are in parentheses."
  1821.   (let* ((ilisp-complete t)
  1822.      (ilisp-table table)
  1823.      (ilisp-completion-package (lisp-buffer-package))
  1824.      (ilisp-paren
  1825.       (let ((entry table) (done nil))
  1826.         (while (and entry (not done))
  1827.           (setq done (= (elt (car (car entry)) 0) ?\()
  1828.             entry (cdr entry)))
  1829.         done))
  1830.      (string (read-from-minibuffer prompt nil (ilisp-completion-map))))
  1831.     (if (string= string "") default string)))
  1832.  
  1833. ;;;%%Input 
  1834. (defun lisp-at-start ()
  1835.   "Return the point if you are at the start of an input expression in
  1836. an inferior Lisp."
  1837.   (save-excursion
  1838.     (let ((point (point)))
  1839.       (beginning-of-line)
  1840.       (comint-skip-prompt)
  1841.       (if (= point (point))
  1842.       point))))
  1843.  
  1844. ;;;
  1845. (defun lisp-input-start ()
  1846.   "Go to the start of the input region."
  1847.   (let* ((pmark (process-mark (get-buffer-process (current-buffer)))))
  1848.     (if (>= (point) pmark)
  1849.     (goto-char pmark)
  1850.     (progn 
  1851.       (end-of-line)
  1852.       (if (re-search-backward comint-prompt-regexp (point-min) 'stay)
  1853.           (comint-skip-prompt)
  1854.           (point))))))
  1855.  
  1856. ;;;%%Defuns
  1857. (defun lisp-defun-region-and-name ()
  1858.   "Return the region of the current defun and the name starting it."
  1859.   (save-excursion
  1860.     (let ((end (lisp-defun-end))
  1861.       (begin (lisp-defun-begin)))
  1862.       (list begin end (lisp-def-name)))))
  1863.   
  1864. ;;;
  1865. (defun lisp-defun-name ()
  1866.   "Return the name of the current defun."
  1867.   (save-excursion
  1868.     (lisp-defun-begin)
  1869.     (lisp-string-to-symbol (lisp-def-name t))))
  1870.  
  1871. ;;;
  1872. (defun lisp-region-name (start end)
  1873.   "Return a name for the region from START to END."
  1874.   (save-excursion
  1875.     (goto-char start)
  1876.     (if (re-search-forward "^[ \t]*[^;\n]" end t)
  1877.     (forward-char -1))
  1878.     (setq start (point))
  1879.     (goto-char end)
  1880.     (re-search-backward "^[ \t]*[^;\n]" start 'move)
  1881.     (end-of-line)
  1882.     (skip-chars-backward " \t")
  1883.     (setq end (min (point) end))
  1884.     (goto-char start)
  1885.     (let ((from
  1886.        (if (= (char-after (point)) ?\()
  1887.            (lisp-def-name)
  1888.            (buffer-substring (point) 
  1889.                  (progn (forward-sexp) (point))))))
  1890.       (goto-char end)
  1891.       (if (= (char-after (1- (point))) ?\))
  1892.       (progn
  1893.         (backward-sexp)
  1894.         (if (= (point) start)
  1895.         from
  1896.         (concat "from " from " to " (lisp-def-name))))
  1897.       (concat "from " from " to " 
  1898.           (buffer-substring (save-excursion
  1899.                       (backward-sexp)
  1900.                       (point)) 
  1901.                     (1- (point))))))))
  1902.  
  1903. ;;;%Lisp mode extensions
  1904. ;;;%%Movement
  1905. (defun bol-ilisp (arg)
  1906.   "Goes to the beginning of line, then skips past the prompt, if any.
  1907. If a prefix argument is given (\\[universal-argument]), then no prompt skip 
  1908. -- go straight to column 0.
  1909.  
  1910. The prompt skip is done by skipping text matching the regular expression
  1911. comint-prompt-regexp or ilisp-other-prompt, both buffer local variables."
  1912.   (interactive "P")
  1913.   (beginning-of-line)
  1914.   (if (null arg) 
  1915.       (or (comint-skip-prompt)
  1916.       (if ilisp-other-prompt
  1917.           (let ((comint-prompt-regexp ilisp-other-prompt))
  1918.         (comint-skip-prompt))))))
  1919.  
  1920. ;;;
  1921. (defun beginning-of-defun-lisp (&optional stay)
  1922.   "Go to the next left paren that starts at the left margin or after a
  1923. prompt in an ILISP buffer.  If optional STAY, then do not move to
  1924. prior defun if at the start of one in an ilisp mode."
  1925.   (interactive)
  1926.   (if (memq major-mode ilisp-modes)
  1927.       (let ((point (point)))
  1928.     (if (and (not stay) (= point (lisp-input-start)))
  1929.         (progn (forward-line -1) (lisp-input-start))))
  1930.       (beginning-of-defun)))
  1931.  
  1932. ;;;
  1933. (defun end-of-defun-lisp ()
  1934.   "Go to the next left paren that starts at the left margin or after a
  1935. prompt in an ILISP buffer and go to the end of the expression."
  1936.   (interactive)
  1937.   (let ((point (point)))
  1938.     (if (memq major-mode ilisp-modes)
  1939.     (beginning-of-defun-lisp t)
  1940.     (if (or (lisp-in-string)
  1941.         (progn (beginning-of-line)
  1942.                (re-search-forward "^[ \t\n]*[^; \t\n]" nil t)
  1943.                (back-to-indentation)
  1944.                (not (bolp))))
  1945.         (beginning-of-defun-lisp t)))
  1946.     (lisp-end-defun-text t)
  1947.     (if (= point (point))        ;Already at end so move to next end
  1948.     (progn
  1949.       (if (memq major-mode ilisp-modes)
  1950.           (re-search-forward comint-prompt-regexp (point-max) t)
  1951.           (lisp-skip (point-max)))
  1952.       (if (not (or (eobp)
  1953.                (= (char-after (point)) ?\n)))
  1954.           (lisp-end-defun-text t))))))
  1955.  
  1956. ;;;%%Indentation
  1957. (defun newline-and-indent-lisp ()
  1958.   "If at the end of the buffer, send the string back to the process
  1959. mark with no newline.  Otherwise, insert a newline, then indent.  In
  1960. an ilisp buffer the region is narrowed first.  See newline-and-indent
  1961. for more information."
  1962.   (interactive "*")
  1963.   (if ilisp-complete
  1964.       (exit-minibuffer)
  1965.       (let (input)
  1966.     (if (and (= (point) (point-max)) 
  1967.          (memq major-mode ilisp-modes)
  1968.          (setq input (ilisp-get-old-input)))
  1969.         (let ((process (ilisp-process))
  1970.           (comint-send-newline (not comint-send-newline)))
  1971.           (funcall comint-input-sender process input)
  1972.           (set-marker (process-mark process) (point)))
  1973.         (save-restriction
  1974.           (if (memq major-mode ilisp-modes)
  1975.           (narrow-to-region (save-excursion (lisp-input-start))
  1976.                     (point-max)))
  1977.           (newline-and-indent))))))
  1978.  
  1979. ;;;%%Call
  1980. (defun match-ring (ring regexp start)
  1981.   "Return the index in RING of REGEXP starting at START."
  1982.   (let ((n 0)
  1983.     (len (ring-length ring)))
  1984.     (while (and (< n len) 
  1985.         (not (string-match regexp (ring-ref ring n))))
  1986.       (setq n (1+ n)))
  1987.     (if (= n len)
  1988.     nil
  1989.     n)))
  1990.  
  1991. ;;;
  1992. (defun lisp-match-ring (regexp string &optional no-insert)
  1993.   "Match REGEXP in the input-ring of the current buffer and set the
  1994. ring variables to look like comint-previous-similar-input if found.
  1995. If not found insert STRING, unless NO-INSERT."
  1996.   (let ((n (if regexp (match-ring (get-input-ring) regexp 0))))
  1997.     (if n
  1998.     (let ((point (progn (comint-kill-input) (point))))
  1999.       (insert (ring-ref (get-input-ring) n))
  2000.       (save-excursion
  2001.         (goto-char (+ point (length string)))
  2002.         (skip-chars-forward "^ \t\n\)")
  2003.         (setq point (point)))
  2004.       (push-mark point)
  2005.       (setq this-command 'comint-previous-similar-input
  2006.         input-ring-index n
  2007.         comint-last-similar-string string)
  2008.       t)
  2009.     (if (and string (not no-insert))
  2010.         (progn (comint-kill-input) (insert string) t)
  2011.         nil))))
  2012.  
  2013. ;;;
  2014. (defun call-defun-lisp (arg)
  2015.   "Put a call of the current defun in the inferior LISP and go there.
  2016. If it is a \(def* name form, look up reasonable forms of name in the
  2017. input history unless called with prefix ARG. If not found, use \(name
  2018. or *name* as the call.  If is not a def* form, put the whole form in
  2019. the buffer."
  2020.   (interactive "P")
  2021.   (if (save-excursion (lisp-defun-begin) (looking-at "(def"))
  2022.       (let* ((symbol (lisp-defun-name))
  2023.          (name (lisp-symbol-name symbol))
  2024.          (package (if (lisp-symbol-package symbol)
  2025.               (concat "\\("
  2026.                   (lisp-symbol-package symbol) ":+\\)?")))
  2027.          (variablep (string-match "^\\*" name))
  2028.          (setfp (string-match "(setf \\([^\)]+\\)" name)))
  2029.     (switch-to-lisp t t)
  2030.     (cond (setfp 
  2031.            (setq name (substring name (match-beginning 1) (match-end 1)))
  2032.            (lisp-match-ring (if (not arg)
  2033.                     (concat "(setf[ \t\n]*(" 
  2034.                         package name "[ \t\n]"))
  2035.                 (concat "(setf (" name)))
  2036.           (variablep (lisp-match-ring (if (not arg) 
  2037.                           (concat package name))
  2038.                       name))
  2039.           (t
  2040.            (let ((fun (concat "(" name)))
  2041.          (setq name (regexp-quote name))
  2042.          (or (lisp-match-ring 
  2043.               (if (not arg) (concat "(" package name "[ \t\n\)]"))
  2044.               fun 
  2045.               (not arg))
  2046.              (lisp-match-ring (concat "(" package
  2047.                           "[^ \t\n]*-*" name)
  2048.                       fun))))))
  2049.       (let ((form 
  2050.          (save-excursion
  2051.            (buffer-substring (lisp-defun-begin) (lisp-end-defun-text t)))))
  2052.     (switch-to-lisp t t)
  2053.     (comint-kill-input)
  2054.     (insert form))))
  2055.  
  2056. ;;;%Special commands
  2057. (defun describe-lisp (sexp)
  2058.   "Describe the current sexp using ilisp-describe-command.  With a
  2059. negative prefix, prompt for the expression.  If in an ILISP buffer,
  2060. and there is no current sexp, describe ilisp-last-command."
  2061.   (interactive
  2062.    (list
  2063.     (if (lisp-minus-prefix)
  2064.     (ilisp-read "Describe: " (lisp-previous-sexp t))
  2065.     (if (memq major-mode ilisp-modes)
  2066.         (if (= (point)
  2067.            (process-mark (get-buffer-process (current-buffer))))
  2068.         (or (ilisp-value 'ilisp-last-command t)
  2069.             (error "No sexp to describe."))
  2070.         (lisp-previous-sexp t))
  2071.         (lisp-previous-sexp t)))))
  2072.   (let ((result
  2073.      (ilisp-send
  2074.       (format (ilisp-value 'ilisp-describe-command) 
  2075.           (lisp-slashify sexp) (lisp-buffer-package))
  2076.       (concat "Describe " sexp)
  2077.       'describe)))
  2078.     (lisp-display-output result)))
  2079.  
  2080. ;;;
  2081. (defun inspect-lisp (sexp)
  2082.   "Inspect the current sexp using ilisp-inspect-command.  With a
  2083. prefix, prompt for the expression.  If in an ILISP buffer, and there
  2084. is no current sexp, inspect ilisp-last-command."
  2085.   (interactive
  2086.    (list
  2087.     (if current-prefix-arg
  2088.     (ilisp-read "Inspect: " (lisp-previous-sexp t))
  2089.     (if (memq major-mode ilisp-modes)
  2090.         (if (= (point)
  2091.            (process-mark (get-buffer-process (current-buffer))))
  2092.         (or (ilisp-value 'ilisp-last-command t)
  2093.             (error "No sexp to inspect."))
  2094.         (lisp-previous-sexp t))
  2095.         (lisp-previous-sexp t)))))
  2096.   (ilisp-send
  2097.    (format (ilisp-value 'ilisp-inspect-command) 
  2098.        (lisp-slashify sexp) (lisp-buffer-package))
  2099.    (concat "Inspect " sexp)
  2100.    'inspect t))
  2101.  
  2102. ;;;
  2103. (defun arglist-lisp (symbol)
  2104.   "Return the arglist of the currently looked at function.  With a
  2105. numeric prefix, the arglist will be inserted.  With a negative one,
  2106. the symbol will be prompted for."
  2107.   (interactive
  2108.    (let* ((function (lisp-function-name)))
  2109.      (list (if (lisp-minus-prefix)
  2110.            (ilisp-read-symbol
  2111.         (format "Arglist [%s]: " (lisp-buffer-symbol function))
  2112.         function t)
  2113.            function))))
  2114.   (if (null symbol)
  2115.       (error "No symbol")
  2116.       (let* ((arglist
  2117.           (ilisp-send
  2118.            (format (ilisp-value 'ilisp-arglist-command)
  2119.                (lisp-symbol-name symbol) 
  2120.                (lisp-symbol-package symbol))
  2121.            (concat "Arglist " (lisp-buffer-symbol symbol))
  2122.            'args))
  2123.          (position (string-match "(" arglist)))
  2124.     (cond ((and (not (ilisp-value 'comint-errorp t))
  2125.             current-prefix-arg position)
  2126.            (let ((temp (point)))
  2127.          (insert (substring arglist (1+ position)))
  2128.          (goto-char temp)))
  2129.           (t (lisp-display-output 
  2130.           (if position
  2131.               (substring arglist position)
  2132.               arglist)))))))
  2133.  
  2134. ;;;
  2135. (defun documentation-lisp (symbol type)
  2136.   "Return the documentation of the previous symbol using
  2137. ilisp-documentation-command.  If the symbol is at the start of a list,
  2138. it is assumed to be a function, otherwise variable documentation is
  2139. searched for.  With a minus prefix, prompt for the symbol and type.
  2140. With a numeric prefix always return the current function call
  2141. documentation."
  2142.   (interactive
  2143.    (if (lisp-minus-prefix)
  2144.        (let* ((symbol-info (lisp-previous-symbol))
  2145.           (symbol (car symbol-info))
  2146.           (doc (ilisp-read-symbol 
  2147.             (format "Documentation [%s]: " 
  2148.                 (lisp-buffer-symbol symbol))
  2149.             symbol))
  2150.           (default (if (car (cdr symbol-info))
  2151.                'function
  2152.                'variable))
  2153.           (types (ilisp-value 'ilisp-documentation-types t))
  2154.           (type
  2155.            (if types
  2156.            (ilisp-completing-read
  2157.             (if default
  2158.             (format "Type [%s]: " default)
  2159.             "Type: ")
  2160.             types
  2161.             default))))
  2162.      (list doc (if (stringp type) (read type) type)))
  2163.        (if current-prefix-arg
  2164.        (list (lisp-function-name) 'function)
  2165.        (let* ((symbol-info (lisp-previous-symbol)))
  2166.          (list (car symbol-info)
  2167.            (if (car (cdr symbol-info))
  2168.                'function
  2169.                'variable))))))
  2170.   (lisp-display-output
  2171.    (ilisp-send
  2172.     (format (ilisp-value 'ilisp-documentation-command)
  2173.         (lisp-symbol-name symbol) (lisp-symbol-package symbol) type)
  2174.     (format "Documentation %s %s" type (lisp-buffer-symbol symbol))
  2175.     'doc)))
  2176.  
  2177. ;;;%%Macroexpand
  2178. (defun lisp-macroexpand-form ()
  2179.   "Return the next form for macroexpanding."
  2180.   (save-excursion
  2181.     (skip-chars-forward " \t\n")
  2182.     (let* ((begin (point))
  2183.        (end (progn (forward-sexp) (point)))
  2184.        (form (buffer-substring begin end)))
  2185.       (list
  2186.        (if (lisp-minus-prefix)
  2187.        (ilisp-read "Macroexpand: " form)
  2188.        form)))))
  2189.  
  2190. ;;;
  2191. (defun macroexpand-lisp (form &optional top)
  2192.   "Macroexpand the next sexp until it is no longer a macro.  With a
  2193. prefix, insert into buffer."
  2194.   (interactive (lisp-macroexpand-form))
  2195.   (if (string-match "(\\([^ \t\n)]*\\)" form)
  2196.       (let ((message (concat "Macroexpand"
  2197.                  (if top "-1 " " ")
  2198.                  (substring form
  2199.                     (match-beginning 1)
  2200.                     (match-end 1))))
  2201.         result)
  2202.     (setq result
  2203.           (ilisp-send
  2204.            (format
  2205.         (ilisp-value
  2206.          (if top
  2207.              'ilisp-macroexpand-1-command
  2208.              'ilisp-macroexpand-command))
  2209.         (lisp-slashify form)
  2210.         (lisp-buffer-package)
  2211.         (buffer-file-name))
  2212.            message 'expand))
  2213.     (if current-prefix-arg
  2214.         (save-excursion (forward-sexp) (insert ?\n) (insert result))
  2215.         (lisp-display-output result)))
  2216.       (error "Not a form: %s" form)))
  2217.  
  2218. (defun macroexpand-1-lisp (form)
  2219.   "Macroexpand the next sexp once.  With a prefix, insert into buffer."
  2220.   (interactive (lisp-macroexpand-form))
  2221.   (macroexpand-lisp form t))
  2222.  
  2223. ;;;%%complete-lisp
  2224. (autoload 'complete "completion" "Complete previous symbol." t)
  2225. (defun complete-lisp (mode)
  2226.   "Complete the current symbol using information from the current
  2227. ILISP buffer.  If in a string, complete as a filename.  If called with
  2228. a positive prefix force all symbols to be considered.  If called with
  2229. a negative prefix, undo the last completion.  Partial completion is
  2230. allowed unless ilisp-prefix-match is T.  If a symbol starts after a
  2231. left paren or #', then only function symbols will be considered.
  2232. Package specifications are also allowed and the distinction between
  2233. internal and exported symbols is considered."
  2234.   (interactive "P")
  2235.   (if (< (prefix-numeric-value mode) 0)
  2236.       (completer-undo)
  2237.       (let* ((filep
  2238.           (save-excursion
  2239.         (skip-chars-backward "^ \t\n")
  2240.         (= (char-after (point)) ?\"))))
  2241.     (if filep
  2242.         (comint-dynamic-complete)
  2243.         (let* ((symbol-info (lisp-previous-symbol))
  2244.            (symbol (car symbol-info))
  2245.            (name (lisp-symbol-name symbol))
  2246.            (choice (ilisp-completer 
  2247.                 symbol 
  2248.                 (if (not mode) (car (cdr symbol-info)))))
  2249.            (match (lisp-buffer-symbol (car choice)))
  2250.            (lcs (lisp-buffer-symbol (car (cdr choice))))
  2251.            (choices (car (cdr (cdr choice))))
  2252.            (unique (car (cdr (cdr (cdr choice))))))
  2253.           (skip-chars-backward " \t\n")
  2254.           (completer-goto match lcs choices unique 
  2255.                   (ilisp-value 'ilisp-symbol-delimiters)
  2256.                   completer-words)))
  2257.     (message "Completed"))))
  2258.  
  2259. ;;;%%Trace
  2260. (defun trace-defun-lisp (function)
  2261.   "Trace FUNCTION without arg, untrace with.  Prompt for function with
  2262. negative prefix.  Default function is the current defun."
  2263.   (interactive
  2264.    (let ((function (lisp-defun-name)))
  2265.      (if (lisp-minus-prefix)
  2266.      (list (ilisp-read-symbol
  2267.         (format (if current-prefix-arg 
  2268.                 "Untrace [%s]: "
  2269.                 "Trace [%s]: ")
  2270.             (lisp-buffer-symbol function))
  2271.         function
  2272.         t))
  2273.      (list function))))
  2274.   (if function
  2275.       (ilisp-send
  2276.        (format (if current-prefix-arg 
  2277.            (ilisp-value 'ilisp-untrace-command)
  2278.            (ilisp-value 'ilisp-trace-command))
  2279.            (lisp-symbol-name function)
  2280.            (lisp-symbol-package function))
  2281.        (format "%srace %s" (if current-prefix-arg "Unt" "T") 
  2282.            (lisp-buffer-symbol function))
  2283.        (if current-prefix-arg 'untrace 'trace)
  2284.        (if lisp-wait-p nil 'dispatch))
  2285.       (error "No function to %strace" (if current-prefix-arg "un" ""))))
  2286.  
  2287. ;;;%%Default-directory
  2288. (defun default-directory-lisp (&optional buffer)
  2289.   "Set the inferior LISP default directory to the default directory of
  2290. optional BUFFER.  If you are in an inferior LISP buffer, set the
  2291. default directory to the current directory of the LISP."
  2292.   (interactive)
  2293.   (if (and (not buffer) (memq major-mode ilisp-modes))
  2294.       (let ((dir
  2295.          (ilisp-send
  2296.           (ilisp-value 'ilisp-directory-command)
  2297.           (format "Getting LISP directory")
  2298.           'dir)))
  2299.     (if (ilisp-value 'comint-errorp t)
  2300.         (progn
  2301.           (lisp-display-output dir)
  2302.           (error "Error getting directory"))
  2303.         (setq default-directory (read dir)
  2304.           lisp-prev-l/c-dir/file (cons default-directory nil))
  2305.         (message "Default directory is %s" default-directory)))
  2306.       (let ((directory (save-excursion
  2307.              (set-buffer (or buffer (current-buffer)))
  2308.              default-directory)))
  2309.     (ilisp-send 
  2310.      (format (ilisp-value 'ilisp-set-directory-command) directory)
  2311.      (format "Set %s's directory to %s" 
  2312.          (buffer-name (ilisp-buffer)) directory)
  2313.      'dir
  2314.      (if lisp-wait-p nil 'dispatch)))))
  2315.   
  2316. ;;;%Source
  2317. (autoload 'lisp-directory "ilisp-src" 
  2318.       "Select directories to search." t)
  2319. (autoload 'next-definition-lisp "ilisp-src"
  2320.       "Edit the next definition." t)
  2321. (autoload 'edit-definitions-lisp "ilisp-src" 
  2322.       "Edit definitions." t)
  2323. (autoload 'search-lisp "ilisp-src" 
  2324.       "Search for pattern in source files." t)
  2325. (autoload 'replace-lisp "ilisp-src" 
  2326.       "Relace pattern in source files." t)
  2327. (autoload 'who-calls-lisp "ilisp-src"
  2328.       "Show callers of a function." t)
  2329. (autoload 'next-caller-lisp "ilisp-src" 
  2330.       "Edit the next caller of a function." t)
  2331. (autoload 'edit-callers-lisp "ilisp-src" 
  2332.       "Edit the callers of a function." t)
  2333.  
  2334. ;;;%Eval/compile
  2335. (defun lisp-send-region (start end switch message status format
  2336.                    &optional handler)
  2337.   "Given START, END, SWITCH, MESSAGE, STATUS, FORMAT and optional
  2338. HANDLER send the region between START and END to the lisp buffer and
  2339. execute the command defined by FORMAT on the region, its package and
  2340. filename.  If called with a positive prefix, the results will be
  2341. inserted at the end of the region.  If SWITCH is T, the command will
  2342. be sent and the buffer switched to the inferior LISP buffer.  if
  2343. SWITCH is 'call, a call will be inserted.  If SWITCH is 'result the
  2344. result will be returned without being displayed.  Otherwise the
  2345. results will be displayed in a popup window if lisp-wait-p is T and
  2346. the current-prefix-arg is not '- or if lisp-wait-p is nil and the
  2347. current-prefix-arg is '-.  If not displayed in a pop-up window then
  2348. comint-handler will display the results in a pop-up window if they are
  2349. more than one line long, or they are from an error.  STATUS will be
  2350. the process status when the command is actually executing.  MESSAGE is
  2351. a message to let the user know what is going on."
  2352.   (if (= start end) (error "Region is empty"))
  2353.   (let ((sexp (lisp-count-pairs start end ?\( ?\)))
  2354.     (string (buffer-substring start end)))
  2355.     (setq string
  2356.       (format (ilisp-value format)
  2357.           (lisp-slashify
  2358.            (if (= sexp 1)
  2359.                string
  2360.                (format (ilisp-value 'ilisp-block-command) string)))
  2361.           (lisp-buffer-package) (buffer-file-name)))
  2362.     (let ((result 
  2363.        (ilisp-send
  2364.         string message status
  2365.         (cond ((memq switch '(t call)) switch)
  2366.           ((or (not (eq lisp-wait-p (lisp-minus-prefix))) 
  2367.                current-prefix-arg
  2368.                (eq switch 'result)) nil)
  2369.           (t 'dispatch))
  2370.         handler)))
  2371.       (if result
  2372.       (if current-prefix-arg
  2373.           (save-excursion
  2374.         (goto-char end)
  2375.         (insert ?\n)
  2376.         (insert result))
  2377.           (if (or (ilisp-value 'comint-errorp t)
  2378.               (string-match "\n" result))
  2379.           (lisp-display-output result)
  2380.           (popper-bury-output t)
  2381.           (message "%s" result)))
  2382.       result))))
  2383.  
  2384. ;;;%%Eval
  2385. (defun eval-region-lisp (start end &optional switch message status handler)
  2386.   "Evaluate the current region."
  2387.   (interactive "r")
  2388.   (setq message (or message 
  2389.             (concat "Evaluate " (lisp-region-name start end))))
  2390.   (let ((defvar (ilisp-value 'ilisp-defvar-regexp t)))
  2391.     (if (and defvar
  2392.          (save-excursion
  2393.            (goto-char start)
  2394.            (skip-chars-forward " \t\n")
  2395.            (and (let ((case-fold-search t)) (looking-at defvar))
  2396.             (progn (forward-sexp) (skip-chars-forward " \t\n" end)
  2397.                (= (point) end)))))
  2398.     (lisp-send-region start end switch message (or status 'defvar)
  2399.               'ilisp-defvar-command handler)
  2400.     (lisp-send-region start end switch message (or status 'eval)
  2401.               'ilisp-eval-command handler))))
  2402.  
  2403. ;;;
  2404. (defun eval-next-sexp-lisp (&optional switch)
  2405.   "Evaluate the next sexp."
  2406.   (interactive)
  2407.   (let (start end)
  2408.     (save-excursion
  2409.       (setq start (point))
  2410.       (forward-sexp)
  2411.       (setq end (point)))
  2412.     (eval-region-lisp start end switch
  2413.               (format "Evaluate %s" (buffer-substring start end)))))
  2414.  
  2415. ;;;
  2416. (defun eval-defun-lisp (&optional switch)
  2417.   "Evaluate the current form."
  2418.   (interactive)
  2419.   (let ((form (lisp-defun-region-and-name)))
  2420.     (eval-region-lisp (car form) (car (cdr form)) switch
  2421.               (format "Evaluate %s" (car (cdr (cdr form)))))))
  2422.               
  2423. ;;;%%%And go
  2424. (defun eval-region-and-go-lisp (start end)
  2425.   "Evaluate the current region and switch to the current ILISP buffer."
  2426.   (interactive "r")
  2427.   (eval-region-lisp start end t))
  2428.  
  2429. (defun eval-next-sexp-and-go-lisp (&optional switch)
  2430.   "Evaluate the next sexp and switch to the current ILISP buffer."
  2431.   (interactive)
  2432.   (eval-next-sexp-lisp t))
  2433.  
  2434. (defun eval-defun-and-go-lisp ()
  2435.   "Evaluate the current defun and switch to the current ILISP buffer.
  2436. With prefix, insert a call as well."
  2437.   (interactive)
  2438.   (eval-defun-lisp (if current-prefix-arg 
  2439.                (progn
  2440.              (setq current-prefix-arg nil)
  2441.              'call)
  2442.                t)))
  2443.  
  2444. ;;;%%Compile
  2445. (defun compile-region-lisp (start end &optional switch message status handler)
  2446.   "Compile the current region."
  2447.   (interactive "r")
  2448.   (lisp-send-region
  2449.    start end switch 
  2450.    (or message (concat "Compile " (lisp-region-name start end)))
  2451.    (or status 'compile)
  2452.    'ilisp-compile-command 
  2453.    handler))
  2454.         
  2455. ;;;
  2456. (defun compile-defun-lisp (&optional switch)
  2457.   "Compile the current defun or the last command in the input-ring of
  2458. an ILISP buffer if no current defun."
  2459.   (interactive)
  2460.   (let* ((form (lisp-defun-region-and-name))
  2461.      (start (car form))
  2462.      (end (car (cdr form))))
  2463.     (if (and (= start end) (memq major-mode ilisp-modes))
  2464.     (save-excursion
  2465.       (let ((form (ring-ref (get-input-ring) input-ring-index)))
  2466.         (set-buffer "*ilisp-send*")
  2467.         (delete-region (point-min) (point-max))
  2468.         (insert form)
  2469.         (compile-defun-lisp)))
  2470.     (compile-region-lisp start end switch
  2471.                  (format "Compile %s" (car (cdr (cdr form))))))))
  2472.  
  2473. ;;;%%%And-go
  2474. (defun compile-region-and-go-lisp (start end)
  2475.   "Compile the current region and switch to the current ILISP buffer."
  2476.   (interactive "r")
  2477.   (compile-region-lisp start end t))
  2478.  
  2479. (defun compile-defun-and-go-lisp ()
  2480.   "Compile the current defun and switch to the current ILISP buffer."
  2481.   (interactive)
  2482.   (compile-defun-lisp 
  2483.    (if current-prefix-arg
  2484.        (progn
  2485.      (setq current-prefix-arg nil)
  2486.      'call)
  2487.        t)))
  2488.  
  2489. ;;;%%Changed definitions
  2490. (autoload 'mark-change-lisp "ilisp-bat" 
  2491.       "Mark the current defun as changed." t)
  2492. (autoload 'list-changes-lisp "ilisp-bat"
  2493.       "List the current LISP changes." t)
  2494. (autoload 'clear-changes-lisp "ilisp-bat"
  2495.       "Clear the list of LISP changes." t)
  2496. (autoload 'eval-changes-lisp "ilisp-bat"
  2497.       "Evaluate the list of LISP changes." t)
  2498. (autoload 'compile-changes-lisp "ilisp-bat"
  2499.       "Compile the list of LISP changes." t)
  2500.  
  2501. ;;;%File operations
  2502. (defvar lisp-prev-l/c-dir/file nil
  2503.   "Saves the (directory . file) pair used in the last find-file-lisp,
  2504. load-file-lisp or compile-file-lisp command. Used for determining the
  2505. default in the next one.")
  2506.  
  2507. ;;;
  2508. (defvar lisp-buffer-file nil 
  2509.   "Cons of buffer-file-name and the expanded name.")
  2510. (make-variable-buffer-local 'lisp-buffer-file)
  2511. (defun lisp-find-file (file &optional pop no-name)
  2512.   "Find FILE, optionally POPping.  If optional NO-NAME is nil, and
  2513. there is a buffer with a name that is the same as the final pathname
  2514. component, select that instead of reading the file associated with the
  2515. full path name.  If the expanded name of FILE and buffer match, select
  2516. that buffer."  
  2517.   (let* ((buffers (buffer-list))
  2518.      (position 0)
  2519.      (expand-symlinks t)
  2520.      (expanded (expand-file-name file))
  2521.      filename)
  2522.     (if (not no-name)
  2523.     (progn (while (string-match "/" file position)
  2524.          (setq position (match-end 0)))
  2525.            (setq filename (substring file position))))
  2526.     (while buffers
  2527.       (save-excursion 
  2528.     (set-buffer (car buffers))
  2529.     (let* ((name (and (not no-name) (buffer-name)))
  2530.            (buffer-file (buffer-file-name))
  2531.            (buffer-expanded
  2532.         (cdr 
  2533.          (if (string-equal buffer-file (car lisp-buffer-file)) 
  2534.              lisp-buffer-file
  2535.              (setq lisp-buffer-file
  2536.                (cons buffer-file 
  2537.                  (expand-file-name buffer-file)))))))
  2538.       (if (or (and name (string-equal filename name))
  2539.           (string-equal expanded buffer-expanded))
  2540.           (setq file buffer-file
  2541.             buffers nil)
  2542.           (setq buffers (cdr buffers)))))))
  2543.   (if pop
  2544.       (lisp-pop-to-buffer (find-file-noselect file))
  2545.       (find-file file)))
  2546.  
  2547. ;;;
  2548. (defun find-file-lisp (file-name)
  2549.   "Find a file.  If point is on a string that points to an existing
  2550. file, that will be the default.  If the buffer is one of
  2551. lisp-source-modes, the buffer file will be the default.  Otherwise,
  2552. the last file used in a lisp-source-mode will be used."
  2553.   (interactive
  2554.    (comint-get-source "Find file: " lisp-prev-l/c-dir/file
  2555.               lisp-source-modes nil))
  2556.   (setq lisp-prev-l/c-dir/file (cons (file-name-directory    file-name)
  2557.                      (file-name-nondirectory file-name)))
  2558.   (lisp-find-file file-name nil t))
  2559.  
  2560. ;;;
  2561. (defun load-file-lisp (file-name)
  2562.   "Load a lisp file into the current inferior LISP and go there."
  2563.   (interactive (comint-get-source "Load Lisp file: " lisp-prev-l/c-dir/file
  2564.                   lisp-source-modes nil))
  2565.   (comint-check-source file-name)    ; Check to see if buffer needs saved.
  2566.   (setq lisp-prev-l/c-dir/file (cons (file-name-directory    file-name)
  2567.                      (file-name-nondirectory file-name)))
  2568.   (ilisp-init t)
  2569.   (let* ((extension (ilisp-value 'ilisp-binary-extension t))
  2570.      (binary (lisp-file-extension file-name extension)))
  2571.     (save-excursion
  2572.       (set-buffer (ilisp-buffer))
  2573.       (if (not (eq comint-send-queue comint-end-queue))
  2574.       (if (y-or-n-p "Abort commands before loading? ")
  2575.           (abort-commands-lisp)
  2576.           (message "Waiting for commands to finish")
  2577.           (while (not (eq comint-send-queue comint-end-queue))
  2578.         (accept-process-output)
  2579.         (sit-for 0))))
  2580.       (if (and (car (comint-send-variables (car comint-send-queue)))
  2581.            (y-or-n-p "Interrupt top level? "))
  2582.       (let ((result (comint-send-results (car comint-send-queue))))
  2583.         (interrupt-subjob-ilisp)
  2584.         (while (not (cdr result))
  2585.           (accept-process-output)
  2586.           (sit-for 0)))))
  2587.     (if (file-newer-than-file-p file-name binary)
  2588.     (if (and (not ilisp-load-no-compile-query)
  2589.          extension (y-or-n-p "Compile first? "))
  2590.         ;; Load binary if just compiled
  2591.         (progn
  2592.           (message "")
  2593.           (compile-file-lisp file-name)
  2594.           (setq file-name binary)))
  2595.     ;; Load binary if it is current
  2596.     (if (file-readable-p binary) (setq file-name binary)))
  2597.     (switch-to-lisp t t)
  2598.     (comint-sender
  2599.      (ilisp-process)
  2600.      (format (ilisp-value 'ilisp-load-command) file-name))
  2601.     (message "Loading %s" file-name)))
  2602.  
  2603. ;;;
  2604. (defun compile-file-lisp (file-name &optional extension)
  2605.   "Compile a Lisp file in the current inferior LISP and go there."
  2606.   (interactive (comint-get-source
  2607.         "Compile Lisp file: " lisp-prev-l/c-dir/file
  2608.         lisp-source-modes nil))
  2609.   (comint-check-source file-name) ; Check to see if buffer needs saved.
  2610.   (setq lisp-prev-l/c-dir/file (cons (file-name-directory    file-name)
  2611.                         (file-name-nondirectory file-name)))
  2612.   (ilisp-init t)
  2613.   (ilisp-send
  2614.    (format (ilisp-value 'ilisp-compile-file-command) file-name
  2615.        (or extension (ilisp-value 'ilisp-binary-extension)))
  2616.    (concat "Compile " file-name) 'compile
  2617.    t))
  2618.  
  2619. ;;;%Dialects
  2620. (defun lisp-add-dialect (dialect)
  2621.   "Add DIALECT as a supported ILISP dialect."
  2622.   (if (not (lisp-memk dialect ilisp-dialects 'car))
  2623.       (setq ilisp-dialects
  2624.         (cons (list dialect) ilisp-dialects))))
  2625.  
  2626. ;;;
  2627. (defun ilisp-start-dialect (buffer program setup)
  2628.   ;; Allow dialects to be started from command line
  2629.   (if (eq current-prefix-arg 0) (setq current-prefix-arg nil))
  2630.   (setq ilisp-last-buffer (current-buffer)
  2631.     buffer (if current-prefix-arg
  2632.            (read-from-minibuffer "Buffer: " buffer)
  2633.            buffer))
  2634.   (funcall setup buffer)
  2635.   (setq ilisp-program
  2636.     (or program 
  2637.         (if current-prefix-arg
  2638.         (lisp-read-program "Program: " ilisp-program)
  2639.         ilisp-program)))
  2640.   (ilisp buffer))
  2641.  
  2642. ;;;
  2643. (defmacro defdialect (dialect full-name parent &rest body)
  2644.   "Define a new ILISP dialect.  DIALECT is the name of the function to
  2645. invoke the inferior LISP. The hook for that LISP will be called
  2646. DIALECT-hook.  The default program will be DIALECT-program.  FULL-NAME
  2647. is a string that describes the inferior LISP.  PARENT is the name of
  2648. the parent dialect."
  2649.   (let ((setup (read (format "setup-%s" dialect)))
  2650.     (hook (read (format "%s-hook" dialect)))
  2651.     (program (read (format "%s-program" dialect)))
  2652.     (dialects (format "%s" dialect)))
  2653.     (`
  2654.      (progn
  2655.        (defvar (, hook) nil (, (format "*Inferior %s hook." full-name)))
  2656.        (defvar (, program) nil
  2657.      (, (format "*Inferior %s default program." full-name)))
  2658.        (defun (, setup) (buffer)
  2659.      (, (format "Set up for interacting with %s." full-name))
  2660.      (, (read (format "(setup-%s buffer)" parent)))
  2661.      (,@ body)
  2662.      (setq ilisp-program (or (, program) ilisp-program)
  2663.            ilisp-dialect (cons '(, dialect) ilisp-dialect))
  2664.      (run-hooks '(, (read (format "%s-hook" dialect)))))
  2665.        (defun (, dialect) (&optional buffer program)
  2666.      (, (format "Create an inferior %s.  With prefix, prompt for buffer and program."
  2667.            full-name))
  2668.      (interactive (list nil nil))
  2669.      (ilisp-start-dialect (or buffer (, dialects)) 
  2670.                   program 
  2671.                   '(, setup))
  2672.      (setq (, program) ilisp-program))
  2673.        (lisp-add-dialect (, dialects))))))
  2674.  
  2675. ;;;%%ilisp
  2676. (defun setup-ilisp (buffer)
  2677.   "Set up for interacting with an inferior LISP."
  2678.   (set-buffer (get-buffer-create "*ilisp-send*"))
  2679.   (kill-all-local-variables)
  2680.   (lisp-mode)
  2681.   (setq ilisp-buffer (format "*%s*" buffer))
  2682.   (set-buffer (get-buffer-create ilisp-buffer))
  2683.   (setq major-mode 'ilisp-mode
  2684.     mode-name "ILISP")
  2685.   (lisp-mode-variables t)
  2686.   ;; Set variables to nil
  2687.   (let ((binary ilisp-binary-extension)
  2688.     (init ilisp-init-binary-extension)
  2689.     (vars ilisp-locals))
  2690.     (while (not (null vars))
  2691.       (make-local-variable (car vars))
  2692.       (set (car vars) nil)
  2693.       (setq vars (cdr vars)))
  2694.     ;; Preserve from initialization
  2695.     (if binary (setq ilisp-binary-extension binary))
  2696.     (if init (setq ilisp-init-binary-extension init)))
  2697.   ;; Comint defaults
  2698.   (setq comint-prompt-regexp "^[^<> ]*>+:? *"
  2699.     input-ring-size 200
  2700.     comint-get-old-input 'ilisp-get-old-input
  2701.     comint-input-sentinel (function ignore)
  2702.     comint-input-filter 'ilisp-input-filter
  2703.     comint-input-sender 'comint-default-send
  2704.     comint-eol-on-send t)
  2705. ;;  (or input-ring (set-input-ring (make-ring input-ring-size)))
  2706.   ;; Comint-ipc defaults
  2707.   (setq comint-send-newline t
  2708.     comint-always-scroll nil
  2709.     comint-output-buffer " *Output*"
  2710.     comint-error-buffer " *Error Output*"
  2711.     comint-error-regexp "^\"ILISP:"
  2712.     comint-output-filter (function identity)
  2713.     comint-interrupt-start 'comint-interrupt-start
  2714.     comint-handler 'ilisp-handler
  2715.     comint-update-status 'ilisp-update-status
  2716.     comint-prompt-status 'comint-prompt-status
  2717.     comint-abort-hook 'ilisp-abort-handler)
  2718.   (setq ilisp-use-map ilisp-mode-map
  2719.     ilisp-init-hook '((lambda () (ilisp-init nil nil t)))
  2720.     ilisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)*\\)?\\s *\\'"
  2721.     ilisp-filter-length 3
  2722.     ilisp-error-filter 'ilisp-error-filter
  2723.     ilisp-error-regexp ".*" 
  2724.     ilisp-symbol-delimiters "^ \t\n\('\"#.\)<>"
  2725.     ilisp-program "lisp"
  2726.     ilisp-locator 'lisp-locate-ilisp
  2727.     ilisp-calls-locator 'lisp-locate-calls)
  2728.   (run-hooks 'ilisp-mode-hook))
  2729.  
  2730. (defun run-ilisp ()
  2731.   "Create an inferior LISP prompting for dialect.  With prefix, prompt
  2732. for buffer name as well."
  2733.   (interactive)
  2734.   (let ((dialect (completing-read "Dialect: " ilisp-dialects nil t)))
  2735.     (if (not (zerop (length dialect)))
  2736.     (call-interactively (read dialect)))))
  2737.  
  2738. ;;;%%Common LISP
  2739. (defdialect clisp "Common LISP"
  2740.   ilisp
  2741.   (if (not (fboundp 'common-lisp-indent-function))
  2742.       (load "cl-indent"))
  2743.   (if (string-lessp "19" emacs-version)
  2744.       (setq lisp-indent-function 'common-lisp-indent-function)
  2745.     (setq lisp-indent-hook 'common-lisp-indent-function))
  2746.   (setq ilisp-load-or-send-command 
  2747.     "(or (and (load \"%s\" :if-does-not-exist nil) t)
  2748.              (and (load \"%s\" :if-does-not-exist nil) t))")
  2749.   (ilisp-load-init 'clisp "clisp.lisp")
  2750.   (setq ilisp-package-regexp "^[ \t]*(in-package[ \t\n]*"
  2751.     ilisp-package-command "(let ((*package* *package*)) %s (package-name *package*))"
  2752.     ilisp-package-name-command "(package-name *package*)"
  2753.     ilisp-in-package-command "(in-package \"%s\")"
  2754.     ilisp-last-command "*"
  2755.     ilisp-save-command "(progn (ILISP:ilisp-save) %s\n)"
  2756.     ilisp-restore-command "(ILISP:ilisp-restore)"
  2757.     ilisp-block-command "(progn %s\n)"
  2758.     ilisp-eval-command "(ILISP:ilisp-eval \"%s\" \"%s\" \"%s\")"
  2759.     ilisp-defvar-regexp "(defvar[ \t\n]")
  2760.   (setq ilisp-defvar-command 
  2761.     "(ILISP:ilisp-eval \"(let ((form '%s)) (progn (makunbound (second form)) (eval form)))\" \"%s\" \"%s\")")
  2762.   (setq ilisp-compile-command "(ILISP:ilisp-compile \"%s\" \"%s\" \"%s\")"
  2763.     ilisp-describe-command "(ILISP:ilisp-describe \"%s\" \"%s\")"
  2764.     ilisp-inspect-command "(ILISP:ilisp-inspect \"%s\" \"%s\")"
  2765.     ilisp-arglist-command "(ILISP:ilisp-arglist \"%s\" \"%s\")")
  2766.   (setq ilisp-documentation-types
  2767.     '(("function") ("variable")
  2768.       ("structure") ("type")
  2769.       ("setf") ("class")
  2770.       ("(qualifiers* (class ...))")))
  2771.   (setq ilisp-documentation-command
  2772.     "(ILISP:ilisp-documentation \"%s\" \"%s\" \"%s\")")
  2773.   (setq ilisp-macroexpand-1-command 
  2774.     "(ILISP:ilisp-macroexpand-1 \"%s\" \"%s\")")
  2775.   (setq ilisp-macroexpand-command "(ILISP:ilisp-macroexpand \"%s\" \"%s\")")
  2776.   (setq ilisp-complete-command 
  2777.     "(ILISP:ilisp-matching-symbols \"%s\" \"%s\" %s %s %s)")
  2778.   (setq ilisp-locator 'lisp-locate-clisp)
  2779.   (setq ilisp-source-types 
  2780.     '(("function") ("macro") ("variable")
  2781.       ("structure") ("type")
  2782.       ("setf") ("class")
  2783.       ("(qualifiers* (class ...))")))
  2784.   (setq ilisp-callers-command "(ILISP:ilisp-callers \"%s\" \"%s\")"
  2785.     ilisp-trace-command "(ILISP:ilisp-trace \"%s\" \"%s\")"
  2786.     ilisp-untrace-command "(ILISP:ilisp-untrace \"%s\" \"%s\")")
  2787.   (setq ilisp-directory-command "(namestring *default-pathname-defaults*)"
  2788.     ilisp-set-directory-command
  2789.     "(setq *default-pathname-defaults* (parse-namestring \"%s\"))")
  2790.   (setq ilisp-load-command "(load \"%s\")")
  2791.   (setq ilisp-compile-file-command 
  2792.     "(ILISP:ilisp-compile-file \"%s\" \"%s\")"))
  2793.  
  2794. ;;;%%%Allegro
  2795. (defun allegro-check-prompt (old new)
  2796.   "Compare the break level printed at the beginning of the prompt."
  2797.   (let* ((old-level (if (and old (eq 1 (string-match "[0-9]+" old)))
  2798.              (string-to-int (substring old 1))
  2799.              0))
  2800.       (new-level (if (eq 1 (string-match "[0-9]+" new))
  2801.              (string-to-int (substring new 1))
  2802.              0)))
  2803.     (<= new-level old-level)))
  2804.  
  2805. ;;;
  2806. (defdialect allegro "Allegro Common LISP"
  2807.   clisp
  2808.   (ilisp-load-init 'allegro "allegro.lisp")
  2809.   (setq comint-fix-error ":pop"
  2810.     ilisp-reset ":reset"
  2811.     comint-continue ":cont"
  2812.     comint-interrupt-regexp  "Error: [^\n]* interrupt\)")
  2813.   (setq comint-prompt-status 
  2814.     (function (lambda (old line)
  2815.       (comint-prompt-status old line 'allegro-check-prompt))))
  2816.   ;; <cl> or package> at top-level
  2817.   ;; [0-9c] <cl> or package> in error
  2818.   (setq comint-prompt-regexp "^\\(\\[[0-9]*c*\\] \\|\\)\\(<\\|\\)[^>]*> ")
  2819.   (setq ilisp-error-regexp
  2820.     "\\(ILISP:[^\"]*\\)\\|\\(Error:[^\n]*\\)\\|\\(Break:[^\n]*\\)")
  2821.   (setq ilisp-binary-command "excl:*fasl-default-type*")
  2822.   (setq ilisp-source-types (append ilisp-source-types '(("any"))))
  2823.   (setq ilisp-find-source-command 
  2824.     "(ILISP:ilisp-source-files \"%s\" \"%s\" \"%s\")")
  2825.   (setq ilisp-init-binary-command 
  2826.     "(let ((ext (or #+m68k \"68fasl\"
  2827.                 #+sparc \"sfasl\"
  2828.                 #+iris4d \"ifasl\"
  2829.                         #+dec3100 \"pfasl\"
  2830.                         excl:*fasl-default-type*)))
  2831.            #+allegro-v4.0 (setq ext (concatenate 'string ext \"4\"))
  2832.            ext)"))
  2833. (if (not allegro-program) (setq allegro-program "cl"))
  2834.  
  2835. ;;;%%%Lucid
  2836. (defun lucid-check-prompt (old new)
  2837.   "Compare the break level printed at the beginning of the prompt."
  2838.   (let* ((old-level (if (and old (eq 0 (string-match "\\(->\\)+" old)))
  2839.              (- (match-end 0) (match-beginning 0))
  2840.              0))
  2841.      (new-level (if (eq 0 (string-match "\\(->\\)+" new))
  2842.              (- (match-end 0) (match-beginning 0))
  2843.              0)))
  2844.     (<= new-level old-level)))
  2845.  
  2846. ;;;
  2847. (defdialect lucid "Lucid Common LISP"
  2848.   clisp
  2849.   (ilisp-load-init 'lucid "lucid.lisp")
  2850.   (setq comint-prompt-regexp "^\\(->\\)+ \\|^[^> ]*> "
  2851.     comint-fix-error ":a"
  2852.     ilisp-reset ":a :t"
  2853.     comint-continue ":c"
  2854.     comint-interrupt-regexp ">>Break: Keyboard interrupt"
  2855.     comint-prompt-status 
  2856.     (function (lambda (old line)
  2857.       (comint-prompt-status old line 'lucid-check-prompt))))
  2858.   (setq ilisp-error-regexp "ILISP:[^\"]*\\|>>[^\n]*")
  2859.   (setq ilisp-source-types (append ilisp-source-types '(("any"))))
  2860.   (setq ilisp-find-source-command 
  2861.     "(ILISP:ilisp-source-files \"%s\" \"%s\" \"%s\")")
  2862.   (setq ilisp-binary-command 
  2863.     "(first (last lucid::*load-binary-pathname-types*))"))
  2864. (if (not lucid-program) (setq lucid-program "lisp"))
  2865.  
  2866. ;;;%%%KCL--these dialects by Tom Emerson
  2867. ;;; kcl-check-prompt doesn't after the first break because the
  2868. ;;; number of ">" characters doesn't increase.
  2869.  
  2870. (defun kcl-check-prompt (old new)
  2871.   "Compare the break level printed at the beginning of the prompt."
  2872.   (let* ((was-in-break (and old (string-match ">+" old)))
  2873.       (old-level (if was-in-break
  2874.              (- (match-end 0) (match-beginning 0))
  2875.              0))
  2876.       (is-in-break (string-match ">+" new))
  2877.       (new-level (if is-in-break
  2878.              (- (match-end 0) (match-beginning 0))
  2879.              0)))
  2880.     (<= new-level old-level)))
  2881.  
  2882. ;;;
  2883. (defdialect kcl "Kyoto Common LISP" clisp
  2884.   (setq comint-prompt-regexp "^>+"
  2885.         ilisp-error-regexp "Error: "
  2886.         ilisp-binary-extension "o"
  2887.         comint-fix-error ":q"
  2888.         comint-continue ":r"
  2889.     comint-prompt-status
  2890.     (function
  2891.      (lambda (old line)
  2892.        (comint-prompt-status old line 'kcl-check-prompt)))))
  2893. (if (not kcl-program) (setq kcl-program "kcl"))
  2894.  
  2895. ;;;%%%AKCL
  2896. (defdialect akcl "Austin Kyoto Common LISP" kcl)
  2897. (if (not akcl-program) (setq akcl-program "akcl"))
  2898.  
  2899. ;;;%%%IBCL
  2900. (defdialect ibcl "Ibuki Common LISP" kcl
  2901.   (setq comint-prompt-regexp "^[-A-Z]*>+\\|^[-A-Z]* ->"
  2902.         comint-interrupt-regexp ">>Condition: Terminal Interrupt"
  2903.         comint-continue ":q"
  2904.         ilisp-reset ":q!"
  2905.         ilisp-error-regexp ">>Error:"))
  2906. (if (not ibcl-program) (setq ibcl-program "ibcl"))
  2907.  
  2908. ;;;%%%CMULisp
  2909. (defun cmulisp-check-prompt (old new)
  2910.   "Compare the break level printed at the beginning of the prompt."
  2911.   (let* ((was-in-break (and old (string-match "]+" old)))
  2912.       (old-level (if was-in-break
  2913.              (- (match-end 0) (match-beginning 0))
  2914.              0))
  2915.       (is-in-break (string-match "]+" new))
  2916.       (new-level (if is-in-break
  2917.              (- (match-end 0) (match-beginning 0))
  2918.              0)))
  2919.     (<= new-level old-level)))
  2920.  
  2921. ;;;
  2922. (defdialect cmulisp "CMU Common LISP"
  2923.   clisp
  2924.   (ilisp-load-init 'cmu "cmulisp.lisp")
  2925.   (setq comint-prompt-regexp "^\\([0-9]+\\]+\\|\\*\\) "
  2926.     comint-prompt-status 
  2927.     (function (lambda (old line)
  2928.       (comint-prompt-status old line 'cmulisp-check-prompt)))
  2929.     ilisp-error-regexp "ILISP:[^\"]*\\|Error [^\n]*"
  2930.     ilisp-arglist-command "(ILISP:arglist \"%s\" \"%s\")"
  2931.     ilisp-find-source-command "(ILISP:source-file \"%s\" \"%s\" \"%s\")"
  2932.     comint-fix-error ":pop"
  2933.     comint-continue ":go"
  2934.     ilisp-reset ":q"
  2935.     comint-interrupt-regexp "Software Interrupt"
  2936.     ilisp-binary-extension "fasl"))
  2937.  
  2938. ;;;%%Scheme
  2939. (defdialect scheme "Scheme" ilisp
  2940.   (setq ilisp-block-command "(begin \n%s)")
  2941.   (setq ilisp-load-command "(load \"%s\")")
  2942.   )
  2943. (if (not scheme-program) (setq scheme-program "scheme"))
  2944.  
  2945. ;;;Cscheme
  2946. ;;; This has a problem since interrupts cause things to crash
  2947. ;(defdialect cscheme "C Scheme"
  2948. ;  scheme
  2949. ;  (setq comint-prompt-regexp
  2950. ;   "^[0-9]+ \\([\\]=]=>\\|Error->\\|Bkpt->\\|Debug->\\|Where->\\) ")
  2951. ;  (setq ilisp-program "cscheme")
  2952. ;  (setq ilisp-binary-extension "bin")
  2953. ;  )
  2954.  
  2955. ;;;Oaklisp
  2956. (defdialect oaklisp "Oaklisp Scheme"
  2957.   scheme
  2958.   (setq comint-prompt-regexp ">+ ")
  2959.   (setq comint-fix-error "(ret 0)")
  2960.   (setq ilisp-last-command "*")
  2961.   (setq ilisp-describe-command "(describe %s)")
  2962.   )
  2963.  
  2964. ;;;%ilisp-mode
  2965. (defvar ilisp-documentation
  2966.   "Major mode for interacting with an inferior LISP process.  Runs a
  2967. LISP interpreter as a subprocess of Emacs, with LISP I/O through an
  2968. Emacs buffer.  If you have problems, use M-x ilisp-bug in the buffer
  2969. where you are having a problem to send a bug report.
  2970.  
  2971. To start a LISP use M-x run-ilisp, or a specific dialect like M-x
  2972. allegro.  If called with a prefix you will be prompted for a buffer
  2973. name and a program to run.  The default buffer name is the name of the
  2974. dialect.  The default program for a dialect will be the value of
  2975. DIALECT-program or the value of ilisp-program inherited from a less
  2976. specific dialect.  If there are multiple LISP's, use the dialect name
  2977. or select-ilisp \(\\[select-ilisp]) to select the current ILISP
  2978. buffer.
  2979.  
  2980. Currently supported LISP dialects include:
  2981.  clisp
  2982.    allegro
  2983.    lucid
  2984.    kcl
  2985.      akcl
  2986.      ibcl
  2987.    cmulisp
  2988.  scheme
  2989.    oaklisp
  2990.  
  2991. Customization: Starting a dialect runs the hooks on comint-mode-hook
  2992. and ilisp-mode-hook and then DIALECT-hooks specific to dialects in the
  2993. nesting order above.  On the very first prompt in the inferior LISP,
  2994. the hooks on ilisp-init-hook are run.  For more information on
  2995. creating a new dialect or variables to set in hooks, see ilisp.el.
  2996.  
  2997. Most of these key bindings work in both Lisp Mode and ILISP mode.
  2998. There are a few additional and-go bindings found in Lisp Mode.
  2999. \\{ilisp-use-map}
  3000. There are also a few bindings found in global-map including:
  3001.   \\[popper-bury-output] popper-bury-output
  3002.   \\[popper-scroll-output] popper-scroll-output
  3003.   \\[popper-other-window] popper-other-window
  3004.   \\[popper-grow-output] popper-grow-output
  3005.   \\[previous-buffer-lisp] previous-buffer-lisp
  3006.   \\[switch-to-lisp] switch-to-lisp
  3007.  
  3008. ILISP uses a dynamically sized pop-up window that can be buried and
  3009. scrolled from any window for displaying output.  See the file
  3010. popper.el or the ILISP info node for information on customizing popper
  3011. windows.  \(\\[popper-other-window]) skips the popper window.  If
  3012. called with a C-u prefix, the popper window will be selected.
  3013. popper-bury-output \(\\[popper-bury-output]) buries the output window.
  3014. popper-scroll-output \(\\[popper-scroll-output]) scrolls the output
  3015. window if it is already showing, otherwise it pops it up.  If it is
  3016. called with a negative prefix, it will scroll backwards.
  3017. popper-grow-output \(\\[popper-grow-output]) will grow the output
  3018. window if showing by the prefix number of lines.  Otherwise, it will
  3019. pop the window up.
  3020.  
  3021. If you are running epoch, the popper window will be in a separate
  3022. X window that is not automatically grown or shrunk.  The variable
  3023. popper-screen-properties can be used to set window properties for that
  3024. window. 
  3025.  
  3026. An alternative to popper windows is to always have the inferior LISP
  3027. buffer visible and have all output go there.  Setting lisp-no-popper
  3028. to T will cause all output to go to the inferior LISP buffer.
  3029. Setting comint-always-scroll to T will cause process output to always
  3030. be visible.  If a command gets an error, you will be left in the break
  3031. loop.
  3032.  
  3033. Each ILISP buffer has a command history associated with it.  Commands
  3034. that do not match ilisp-filter-regexp and that are longer than
  3035. ilisp-filter-length and that do not match the immediately prior
  3036. command will be added to this history.  comint-previous-input
  3037. \(\\[comint-previous-input]) and comint-next-input
  3038. \(\\[comint-next-input]) cycle through the input history.
  3039. comint-previous-similar-input \(\\[comint-previous-similar-input])
  3040. cycles through input that has the string typed so far as a prefix.
  3041.  
  3042. See comint-mode documentation for more information on comint commands.
  3043.  
  3044. A number of commands refer to \"defun\".  A \"defun\" is a list that
  3045. starts at the left margin in a LISP buffer, or after a prompt in the
  3046. ILISP buffer.  So the commands refer to the \"defun\" that contains
  3047. point.
  3048.  
  3049. There are two keyboard modes for interacting with the inferior LISP,
  3050. \"interactive\" and \"raw\".  Normally you are in interactive mode
  3051. where keys are interpreted as commands to EMACS and nothing is sent to
  3052. the inferior LISP unless a specific command does so.  In raw mode, all
  3053. characters are passed directly to the inferior LISP without any
  3054. interpretation as EMACS commands.  Keys will not be echoed unless
  3055. ilisp-raw-echo is T.  Raw mode can be turned on interactively by
  3056. raw-keys-ilisp \(\\[raw-keys-ilisp]) and will continue until you type
  3057. C-g.  Raw mode can also be turned on/off by inferior LISP functions if
  3058. io-bridge-ilisp \(\\[io-bridge-ilisp]) has been executed in the
  3059. inferior LISP interactively or on a hook.  To turn on raw mode, a
  3060. function should print ^[1^] and to turn it off should print ^[0^].
  3061.  
  3062. When you send something to LISP, the status light will reflect the
  3063. progress of the command.  If you type top-level forms ahead of the
  3064. processing, the status may indicate ready when the LISP is actually
  3065. running.  In a lisp mode buffer the light will reflect the status of
  3066. the currently selected inferior LISP unless lisp-show-status is nil.
  3067. If you want to find out what command is currently running, use the
  3068. command status-lisp \(\\[status-lisp]).  If you call it with a prefix,
  3069. the pending commands will be displayed as well.
  3070.  
  3071. If you are want to abort the last command you can use
  3072. \(\\[keyboard-quit]).  If you want to abort all commands, you should
  3073. use the command abort-commands-lisp \(\\[abort-commands-lisp]).
  3074. Commands that are aborted will be put in the buffer *Aborted Commands*
  3075. so that you can see what was aborted.  If you want to abort the
  3076. currently running top-level command, use interrupt-subjob-ilisp
  3077. \(\\[interrupt-subjob-ilisp]).  As a last resort, \\[panic-lisp] will
  3078. reset the ILISP state without affecting the inferior LISP so that you
  3079. can see what is happening.
  3080.  
  3081. bol-ilisp \(\\[bol-ilisp]) will go after the prompt as defined by
  3082. comint-prompt-regexp or ilisp-other-prompt or to the left margin with
  3083. a prefix.
  3084.  
  3085. return-ilisp \(\\[return-ilisp]) knows about prompts and sexps.  If an
  3086. sexp is not complete, it will indent properly.  When an entire sexp is
  3087. complete, it is sent to the inferior LISP together with a new line.
  3088. If you edit old input, the input will be copied to the end of the
  3089. buffer first.
  3090.  
  3091. close-and-send-lisp \(\\[close-and-send-lisp]) will close the current
  3092. sexp, indent it, then send it to the current inferior LISP.
  3093.  
  3094. indent-line-ilisp \(\\[indent-line-ilisp]) indents for LISP.  With
  3095. prefix, shifts rest of expression rigidly with the current line.
  3096.  
  3097. newline-and-indent-lisp \(\\[newline-and-indent-lisp]) will insert a
  3098. new line and then indent to the appropriate level.  If you are at the
  3099. end of the inferior LISP buffer and an sexp, the sexp will be sent to
  3100. the inferior LISP without a trailing newline.
  3101.  
  3102. indent-sexp-ilisp \(\\[indent-sexp-ilisp]) will indent each line in
  3103. the next sexp.
  3104.  
  3105. backward-delete-char-untabify \(\\[backward-delete-char-untabify])
  3106. converts tabs to spaces as it moves back.
  3107.  
  3108. delete-char-or-pop-ilisp \(\\[delete-char-or-pop-ilisp]) will delete
  3109. prefix characters unless you are at the end of an ILISP buffer in
  3110. which case it will pop one level in the break loop.
  3111.  
  3112. reset-ilisp, \(\\[reset-ilisp]) will reset the current inferior LISP's
  3113. top-level so that it will no longer be in a break loop.
  3114.  
  3115. switch-to-lisp \(\\[switch-to-lisp]) will pop to the current ILISP
  3116. buffer or if already in an ILISP buffer, it will return to the buffer
  3117. that last switched to an ILISP buffer.  With a prefix, it will also go
  3118. to the end of the buffer.  If you do not want it to pop, set
  3119. pop-up-windows to nil.  
  3120.  
  3121. call-defun-lisp \(\\[call-defun-lisp]) will put a call to the current
  3122. defun in the inferior LISP and go there.  If it is a \(def* name form,
  3123. it looks up reasonable forms of name in the input history unless
  3124. called with a prefix. If not found, \(name or *name* will be inserted.
  3125. If it is not a def* form, the whole defun will be put in the buffer.
  3126.  
  3127. reposition-window-lisp \(\\[reposition-window-lisp]) will scroll the
  3128. current window to show as much of the current defun and its
  3129. introductory comments as possible without moving the point.  If called
  3130. with a prefix, the point will be moved if necessary to show the start
  3131. of the defun.  If called more than once with the first line of the
  3132. defun showing, the introductory comments will be shown or suppressed.
  3133.  
  3134. previous-buffer-lisp \(\\[previous-buffer-lisp]) will switch to the
  3135. last visited buffer in the current window or the Nth previous buffer
  3136. with a prefix.
  3137.  
  3138. find-unbalanced-lisp \(\\[find-unbalanced-lisp]) will find unbalanced
  3139. parens in the current buffer.  When called with a prefix it will look
  3140. in the current region.
  3141.  
  3142. close-all-lisp \(\\[close-all-lisp]) will close all outstanding
  3143. parens back to the containing form, or a previous left bracket
  3144. which will be converted to a left parens.  If there are too many
  3145. parens, they will be deleted unless there is text between the
  3146. last paren and the end of the defun.  If called with a prefix,
  3147. all open left brackets will be closed.
  3148.  
  3149. reindent-lisp \(\\[reindent-lisp]) will reindent the current paragraph
  3150. if in a comment or string.  Otherwise it will close the containing
  3151. defun and reindent it.
  3152.  
  3153. comment-region-lisp \(\\[comment-region-lisp]) will put prefix copies of
  3154. comment-start before and comment-end's after the lines in region.  To
  3155. uncomment a region, use a minus prefix.
  3156.  
  3157. The very first inferior LISP command executed may send some forms to
  3158. initialize the inferior LISP.
  3159.  
  3160. Each time an inferior LISP command is executed, the last form sent can be
  3161. seen in the \*ilisp-send* buffer.
  3162.  
  3163. The first time an inferior LISP mode command is executed in a Lisp
  3164. Mode buffer, the package will be determined by using the regular
  3165. expression ilisp-package-regexp to find a package sexp and then
  3166. passing that sexp to the inferior LISP through ilisp-package-command.
  3167. For the clisp dialect, this will find the first \(in-package PACKAGE)
  3168. form in the file.  A buffer's package will be displayed in the mode
  3169. line.  set-buffer-package-lisp \(\\[set-buffer-package-lisp]) will
  3170. update the current package from the buffer.  If it is called with a
  3171. prefix, the package can be set manually.  If a buffer has no
  3172. specification, forms will be evaluated in the current inferior LISP
  3173. package.  package-lisp \(\\[package-lisp]) will show the current
  3174. package of the inferior LISP.  set-package-lisp
  3175. \(\\[set-package-lisp]) will set the inferior LISP package to the
  3176. current buffer's package or to a manually entered package with a
  3177. prefix.
  3178.  
  3179. describe-lisp, inspect-lisp, arglist-lisp, documentation-lisp,
  3180. macroexpand-1-lisp, macroexpand-lisp, edit-definitions-lisp,
  3181. who-calls-lisp, edit-callers-lisp and trace-defun-lisp will switch
  3182. whether they prompt for a response or use a default when called with a
  3183. negative prefix.  If they are prompting, there is completion through
  3184. the inferior LISP by using TAB or M-TAB.  When you are entering an
  3185. expression in the minibuffer, all of the normal ilisp commands like
  3186. arglist-lisp also work.
  3187.  
  3188. Commands that work on a function will use the nearest previous
  3189. function symbol.  This is either a symbol after a #' or the symbol at
  3190. the start of the current list.
  3191.  
  3192. describe-lisp \(\\[describe-lisp]) will describe the previous sexp.
  3193. inspect-lisp \(\\[inpsect-lisp]) will inspect the previous sexp.If
  3194. there is no previous-sexp and you are in an ILISP buffer, the previous
  3195. result will be described or inspected.
  3196.  
  3197. arglist-lisp \(\\[arglist-lisp]) will return the arglist of the
  3198. current function.  With a numeric prefix, the leading paren will be
  3199. removed and the arglist will be inserted into the buffer.
  3200.  
  3201. documentation-lisp \(\\[documentation-lisp]) infers whether function
  3202. or variable documentation is desired.  With a negative prefix, you can
  3203. specify the type of documentation as well.  With a positive prefix the
  3204. documentation of the current function call is returned.
  3205.  
  3206. If the Franz online Common LISP manual is available, fi:clman
  3207. \(\\[fi:clman]) will get information on a specific symbol.
  3208. fi:clman-apropos \(\\[fi:clman-apropos]) will get information apropos
  3209. a specific string.  Some of the documentation is specific to the
  3210. allegro dialect, but most of it is for standard Common LISP.
  3211.  
  3212. macroexpand-lisp \(\\[macroexpand-lisp]) and macroexpand-1-lisp
  3213. \(\\[macroexpand-1-lisp]) will be applied to the next sexp.  They will
  3214. insert their result into the buffer if called with a numeric prefix.
  3215.  
  3216. complete-lisp \(\\[complete-lisp]) will try to complete the previous
  3217. symbol in the current inferior LISP.  Partial completion is supported
  3218. unless ilisp-prefix-match is set to T.  \(If you set it to T, inferior
  3219. LISP completions will be faster.)  With partial completion, \"p--n\"
  3220. would complete to \"position-if-not\" in Common LISP.  If the symbol
  3221. follows a left paren or a #', only symbols with function cells will be
  3222. considered.  If the symbol starts with a \* or you call with a
  3223. positive prefix all possible completions will be considered.  Only
  3224. external symbols are considered if there is a package qualification
  3225. with only one colon.  The first time you try to complete a string the
  3226. longest common substring will be inserted and the cursor will be left
  3227. on the point of ambiguity.  If you try to complete again, you can see
  3228. the possible completions.  If you are in a string, then filename
  3229. completion will be done instead.  And if you try to complete a
  3230. filename twice, you will see a list of possible completions.  Filename
  3231. components are completed individually, so /u/mi/ could expand to
  3232. /usr/misc/.  If you complete with a negative prefix, the most recent
  3233. completion \(symbol or filename) will be undone.
  3234.  
  3235. complete \(\\[complete]) will complete the current symbol to the most
  3236. recently seen symbol in Emacs that matches what you have typed so far.
  3237. Executing it repeatedly will cycle through potential matches.  This is
  3238. from the TMC completion package and there may be some delay as it is
  3239. initially loaded.
  3240.  
  3241. trace-defun-lisp \(\\[trace-defun-lisp]) traces the current defun.
  3242. When called with a numeric prefix the function will be untraced.
  3243.  
  3244. default-directory-lisp \(\\[default-directory-lisp]\) sets the default
  3245. inferior LISP directory to the directory of the current buffer.  If
  3246. called in an inferior LISP buffer, it sets the Emacs default-directory
  3247. the LISP default directory.
  3248.  
  3249. The eval/compile commands evaluate or compile the forms specified.  If
  3250. any of the forms contain an interactive command, then the command will
  3251. never return.  To get out of this state, you need to use
  3252. abort-commands-lisp \(\\[abort-commands-lisp]).  The eval/compile
  3253. commands verify that their expressions are balanced and then send the
  3254. form to the inferior LISP.  If called with a positive prefix, the
  3255. result of the operation will be inserted into the buffer after the
  3256. form that was just sent.  If lisp-wait-p is t, then EMACS will display
  3257. the result of the command in the minibuffer or a pop-up window.  If
  3258. lisp-wait-p is nil, (the default) the send is done asynchronously and
  3259. the results will be brought up only if there is more than one line or
  3260. there is an error.  In this case, you will be given the option of
  3261. ignoring the error, keeping it in another buffer or keeping it and
  3262. aborting all pending sends.  If there is not a command already running
  3263. in the inferior LISP, you can preserve the break loop.  If called with
  3264. a negative prefix, the sense of lisp-wait-p will be inverted for the
  3265. next command.  The and-go versions will perform the operation and then
  3266. immediately switch to the ILISP buffer where you will see the results
  3267. of executing your form.  If eval-defun-and-go-lisp
  3268. \(\\[eval-defun-and-go-lisp]) or compile-defun-and-go-lisp
  3269. \(\\[compile-defun-and-go-lisp]) is called with a prefix, a call for
  3270. the form will be inserted as well.
  3271.  
  3272. When an eval is done of a single form matching ilisp-defvar-regexp,
  3273. the corresponding symbol will be unbound and the value assigned again.
  3274.  
  3275. When compile-defun-lisp \(\\[compile-defun-lisp]) is called in an
  3276. inferior LISP buffer with no current form, the last form typed to the
  3277. top-level will be compiled.
  3278.  
  3279. The following commands all deal with finding things in source code.
  3280. The first time that one of these commands is used, there may be some
  3281. delay while the source module is loaded.  When searching files, the
  3282. first applicable rule is used: 1) try the inferior LISP, 2) try a tags
  3283. file if defined, 3) try all buffers in one of lisp-source-modes or all
  3284. files defined using lisp-directory.
  3285.  
  3286. lisp-directory \(\\[lisp-directory]) defines a set of files to be
  3287. searched by the source code commands.  It prompts for a directory and
  3288. sets the source files to be those in the directory that match entries
  3289. in auto-mode-alist for modes in lisp-source-modes.  With a positive
  3290. prefix, the files are appended.  With a negative prefix, all current
  3291. buffers that are in one of lisp-source-modes will be searched.  This
  3292. is also what happens by default.  Using this command stops using a
  3293. tags file.
  3294.  
  3295. edit-definitions-lisp \(\\[edit-definitions-lisp]) will find a
  3296. particular type of definition for a symbol.  It tries to use the rules
  3297. described above.  The files to be searched are listed in the buffer
  3298. \*Edit-Definitions*.  If lisp-edit-files is nil, no search will be
  3299. done if not found through the inferior LISP.  The variable
  3300. ilisp-locator contains a function that when given the name and type
  3301. should be able to find the appropriate definition in the file.  There
  3302. is often a flag to cause your LISP to record source files that you
  3303. will need to set in the initialization file for your LISP.  The
  3304. variable is \*record-source-files* in both allegro and lucid.  Once a
  3305. definition has been found, next-definition-lisp
  3306. \(\\[next-definition-lisp]) will find the next definition.  \(Or the
  3307. previous definition with a prefix.)
  3308.  
  3309. edit-callers-lisp \(\\[edit-callers-lisp]) will generate a list of all
  3310. of the callers of a function in the current inferior LISP and edit the
  3311. first caller using edit-definitions-lisp.  Each successive call to
  3312. next-caller-lisp \(\\[next-caller-lisp]) will edit the next caller.
  3313. \(Or the previous caller with a prefix.)  The list is stored in the
  3314. buffer \*All-Callers*.  You can also look at the callers by doing
  3315. who-calls-lisp \(\\[who-calls-lisp]).
  3316.  
  3317. search-lisp \(\\[search-lisp]) will search the current tags files,
  3318. lisp directory files or buffers in one of lisp-source-modes for a
  3319. string or a regular expression when called with a prefix.
  3320. \(\\[next-definition-lisp]) will find the next definition.  \(Or the
  3321. previous definition with a prefix.)
  3322.  
  3323. replace-lisp \(\\[replace-lisp]) will replace a string (or a regexp
  3324. with a prefix) in the current tags files, lisp directory files or
  3325. buffers in one of lisp-source-modes.
  3326.  
  3327. The following commands all deal with making a number of changes all at
  3328. once.  The first time one of these commands is used, there may be some
  3329. delay as the module is loaded.  The eval/compile versions of these
  3330. commands are always executed asynchronously.
  3331.  
  3332. mark-change-lisp \(\\[mark-change-lisp]) marks the current defun as
  3333. being changed.  A prefix causes it to be unmarked.  clear-changes-lisp
  3334. \(\\[clear-changes-lisp]) will clear all of the changes.
  3335. list-changes-lisp \(\\[list-changes-lisp]) will show the forms
  3336. currently marked. 
  3337.  
  3338. eval-changes-lisp \(\\[eval-changes-lisp]), or compile-changes-lisp
  3339. \(\\[compile-changes-lisp]) will evaluate or compile these changes as
  3340. appropriate.  If called with a positive prefix, the changes will be
  3341. kept.  If there is an error, the process will stop and show the error
  3342. and all remaining changes will remain in the list.  All of the results
  3343. will be kept in the buffer *Last-Changes*.
  3344.  
  3345. File commands in lisp-source-mode buffers keep track of the last used
  3346. directory and file.  If the point is on a string, that will be the
  3347. default if the file exists.  If the buffer is one of
  3348. lisp-source-modes, the buffer file will be the default.  Otherwise,
  3349. the last file used in a lisp-source-mode will be used.
  3350.  
  3351. find-file-lisp \(\\[find-file-lisp]) will find a file.  If it is in a
  3352. string, that will be used as the default if it matches an existing
  3353. file.  Symbolic links are expanded so that different references to the
  3354. same file will end up with the same buffer.
  3355.  
  3356. load-file-lisp \(\\[load-file-lisp]) will load a file into the inferior
  3357. LISP.  You will be given the opportunity to save the buffer if it has
  3358. changed and to compile the file if the compiled version is older than
  3359. the current version.
  3360.  
  3361. compile-file-lisp \(\\[compile-file-lisp]) will compile a file in the
  3362. current inferior LISP."
  3363.   "Documentation string for ILISP mode.")
  3364.  
  3365. ;;;
  3366. (defun ilisp-set-doc (function string)
  3367.   "Set the documentation of the symbol FUNCTION to STRING."
  3368.   (let* ((old-function (symbol-function function)))
  3369.     (if (consp old-function)  ; old-style v18 compiled-function objects
  3370.     ;; I did not use rplacd so that I can replace read-only objects
  3371.     (let ((old-doc (cdr (cdr old-function))))
  3372.       (fset function
  3373.         (nconc (list (car old-function)
  3374.                  (car (cdr old-function))
  3375.                  string)
  3376.                (if (or (stringp (car old-doc)) (numberp (car old-doc)))
  3377.                (cdr old-doc)
  3378.              old-doc))))
  3379.       ;; else, new-style compiled-code objects
  3380.       (let ((code-as-list (append old-function nil)))
  3381.     (if (nthcdr 4 code-as-list)
  3382.         (setcar (nthcdr 4 code-as-list) string)
  3383.       (setcdr (nthcdr 3 code-as-list) (cons string nil)))
  3384.     (fset function (apply 'make-byte-code code-as-list))))))
  3385.  
  3386. ;;;
  3387. (defun ilisp-mode ()
  3388.   (interactive)
  3389.   (run-ilisp))
  3390. (ilisp-set-doc 'ilisp-mode ilisp-documentation)
  3391. (ilisp-set-doc 'lisp-mode ilisp-documentation)
  3392.  
  3393. ;;;%%ILISP
  3394. (defun lisp-command-args (string)
  3395.   "Break up STRING into (command args ...)."
  3396.   (let ((len (length string))
  3397.     (position 0)
  3398.     (arg 0)
  3399.     (args nil))
  3400.     (while (< position len)
  3401.       (if (eq (aref string position) ?\ )
  3402.       (setq args (cons (substring string arg position)  args)
  3403.         arg (1+ position)))
  3404.       (setq position (1+ position)))
  3405.     (setq args (reverse (cons (substring string arg position)  args)))
  3406.     args))
  3407.  
  3408. ;;;
  3409. (defun ilisp (name)
  3410.   "Run an inferior LISP process NAME, input and output via buffer *name*.
  3411. If there is a process already running in *name*, just switch to that buffer.
  3412. Takes the program name from the variable ilisp-program.
  3413. \(Type \\[describe-mode] in the process buffer for a list of commands.)"
  3414.   (set-buffer ilisp-buffer)
  3415.   (if (not (comint-check-proc ilisp-buffer))
  3416.       (let* ((dialect (car ilisp-dialect))
  3417.          (program ilisp-program)
  3418.          (args (lisp-command-args program))
  3419.          ;; Use pipes so that strings can be long
  3420.          (process-connection-type nil)
  3421.          (names (format "%s" name))
  3422.          start)
  3423.     (apply 'make-comint name (car args) nil (cdr args))
  3424.     (comint-setup-ipc)
  3425.     (setq major-mode 'ilisp-mode
  3426.           mode-name "ILISP")
  3427.     (rplaca (car comint-send-queue) (function (lambda ()
  3428.                       (run-hooks 'ilisp-init-hook))))
  3429.     (setq ilisp-initialized (lisp-del ilisp-buffer ilisp-initialized))
  3430.     (if (not (lisp-memk names ilisp-buffers 'car))
  3431.         (setq ilisp-buffers (cons (list names) ilisp-buffers)))
  3432.     (lisp-pop-to-buffer ilisp-buffer)
  3433.     (setq start (window-start (selected-window))
  3434.           ilisp-program program)
  3435.     (goto-char (point-max))
  3436.     (insert (format "Starting %s ...\n" ilisp-program))
  3437.     (set-marker (process-mark (ilisp-process)) (point))
  3438.     (funcall comint-update-status 'start)
  3439.     (if ilisp-motd
  3440.         (progn (lisp-display-output (format ilisp-motd ilisp-version))
  3441.            (set-window-start (selected-window) start)))
  3442.     (if (not ilisp-prefix-match) (require 'completer)))
  3443.       (lisp-pop-to-buffer ilisp-buffer))
  3444.   (use-local-map ilisp-use-map)
  3445.   ;; This is necessary to get mode documentation to come out right
  3446.   (set-default 'ilisp-use-map ilisp-use-map))
  3447.  
  3448. ;;;%Manual
  3449. (autoload 'fi:clman         "fi/clman" 
  3450.       "Look up SYMBOL in the online manual with completion." t)
  3451. (autoload 'fi:clman-apropos "fi/clman" 
  3452.       "Do an apropos search in online manual for STRING." t)
  3453.  
  3454. ;;;%Bridges
  3455. (autoload 'install-bridge "bridge" "Install process bridge." t)
  3456.  
  3457. ;;;%Bugs
  3458. (defun ilisp-bug ()
  3459.   "Generate an ilisp bug report."
  3460.   (interactive)
  3461.   (let ((buffer 
  3462.      (if (y-or-n-p 
  3463.           (format "Is %s the buffer where the error occurred? " 
  3464.               (buffer-name (current-buffer))))
  3465.          (current-buffer))))
  3466.     (if (or (not buffer) (not (mail)))
  3467.     (progn
  3468.       (message 
  3469.        (if buffer 
  3470.            "Can't send bug report until mail buffer is empty."
  3471.            "Switch to the buffer where the error occurred."))
  3472.       (beep))
  3473.       (insert ilisp-bugs-to)
  3474.       (search-forward (concat "\n" mail-header-separator "\n"))
  3475.       (insert "\nYour problem: \n\n")
  3476.       (insert "Type C-c C-c to send\n")
  3477.       (insert "======= Emacs state below: for office use only =======\n")
  3478.       (forward-line 1)
  3479.       (insert (emacs-version))
  3480.       (insert 
  3481.        (format "\nWindow System: %s %s" window-system window-system-version))
  3482.       (let ((mode (save-excursion (set-buffer buffer) major-mode))
  3483.         (match "popper-\\|completer-")
  3484.         (val-buffer buffer)
  3485.         string)
  3486.     (if (or (memq mode lisp-source-modes) (memq mode ilisp-modes))
  3487.         (progn
  3488.           (setq match (concat "ilisp-\\|comint-\\|lisp-" match)
  3489.             val-buffer (save-excursion (set-buffer buffer)
  3490.                            (or (ilisp-buffer) buffer)))
  3491.           (mapcar (function (lambda (dialect)
  3492.                   (setq match (concat (format "%s-\\|" (car dialect))
  3493.                               match))))
  3494.               ilisp-dialects)
  3495.           (save-excursion
  3496.         (set-buffer buffer)
  3497.         (let ((point (point))
  3498.               (start (lisp-defun-begin))
  3499.               (end (lisp-end-defun-text t)))
  3500.           (setq string
  3501.             (format "
  3502. Mode: %s
  3503. Start: %s
  3504. End: %s
  3505. Point: %s
  3506. Point-max: %s
  3507. Code: %s"
  3508.                 major-mode start end point (point-max)
  3509.                 (buffer-substring start end)))))
  3510.           (insert string)))
  3511.     (mapatoms
  3512.      (function (lambda (symbol)
  3513.              (if (and (boundp symbol)
  3514.                   (string-match match (format "%s" symbol))
  3515.                   (not (eq symbol 'ilisp-documentation)))
  3516.              (let ((val (save-excursion
  3517.                       (set-buffer val-buffer) 
  3518.                       (symbol-value symbol))))
  3519.                (if val
  3520.                    (insert (format "\n%s: %s" symbol val))))))))
  3521.     (insert (format "\nLossage: %s" (key-description (recent-keys))))
  3522.     (if (and (or (memq mode lisp-source-modes)
  3523.              (memq mode ilisp-modes))
  3524.          (ilisp-buffer) 
  3525.          (memq 'clisp (ilisp-value 'ilisp-dialect t))
  3526.          (not (cdr (ilisp-value 'comint-send-queue))))
  3527.         (progn
  3528.           (insert (format "\nLISP: %s"
  3529.                   (comint-remove-whitespace
  3530.                    (car (comint-send
  3531.                      (save-excursion
  3532.                        (set-buffer buffer)
  3533.                        (ilisp-process))
  3534.                      "(lisp-implementation-version)"
  3535.                      t t 'version)))))
  3536.           (insert (format "\n*FEATURES*: %s"
  3537.                   (comint-remove-whitespace
  3538.                    (car (comint-send
  3539.                      (save-excursion
  3540.                        (set-buffer buffer)
  3541.                        (ilisp-process))
  3542.                      "(let ((*print-length* nil)
  3543.                        (*print-level* nil))
  3544.                    (print *features*)
  3545.                    nil)"
  3546.                      t t 'version)))))))
  3547.     (insert ?\n)
  3548.     (goto-char (point-min))
  3549.     (re-search-forward "^Subject")
  3550.     (end-of-line)
  3551.     (message "Send with sendmail or your favorite mail program.")))))
  3552.  
  3553. ;;;%Modes
  3554. (set-default 'auto-mode-alist
  3555.          (append '(("\\.cl$" . lisp-mode) ("\\.lisp$" . lisp-mode))
  3556.              auto-mode-alist))
  3557. (setq completion-ignored-extensions 
  3558.       (append '(".68fasl" ".sfasl" ".ifasl" ".pfasl" 
  3559.         ".68fasl4" ".sfasl4" ".ifasl4" ".pfasl4" 
  3560.         ".sbin")
  3561.           completion-ignored-extensions))
  3562.  
  3563. ;;;%Bindings
  3564. (defun ilisp-defkey (keymap key command)
  3565.   "Define KEYMAP ilisp-prefix+KEY as command."
  3566.   (let ((prefix-map (lookup-key keymap ilisp-prefix)))
  3567.     (if (not (keymapp prefix-map))
  3568.     (setq prefix-map
  3569.           (define-key keymap ilisp-prefix (make-sparse-keymap))))
  3570.     (define-key prefix-map key command)))
  3571.  
  3572. ;;;
  3573. (defun lisp-bindings (keymap &optional inferior-p)
  3574.   "Set up the bindings for interacting with an inferior LISP in
  3575. KEYMAP."
  3576.   (if inferior-p
  3577.       (progn (define-key keymap "\C-m" 'return-ilisp)
  3578.          (define-key keymap "\C-a" 'bol-ilisp)
  3579.          (define-key keymap "\C-c\C-c" 'interrupt-subjob-ilisp)
  3580.          (define-key keymap "\C-d" 'delete-char-or-pop-ilisp)
  3581.          (ilisp-defkey keymap "#" 'raw-keys-ilisp))
  3582.       (ilisp-defkey keymap "\C-c" 'compile-defun-and-go-lisp)
  3583.       (define-key keymap "\C-m" 'newline-and-indent-lisp))
  3584.   (define-key   keymap "]"        'close-all-lisp)
  3585.   (define-key   keymap "\M-q"     'reindent-lisp)
  3586.   (define-key   keymap "\C-]"     'close-and-send-lisp)
  3587.   (define-key   keymap "\t"       'indent-line-ilisp)
  3588.   (define-key   keymap "\n"       'newline-and-indent-lisp)
  3589.   (define-key   keymap "\M-\C-q"  'indent-sexp-ilisp)
  3590.   (ilisp-defkey keymap ";"        'comment-region-lisp)
  3591.   (ilisp-defkey keymap ")"        'find-unbalanced-lisp)
  3592.   (define-key   keymap "\M-\C-a"  'beginning-of-defun-lisp)
  3593.   (define-key   keymap "\M-\C-e"  'end-of-defun-lisp)
  3594.   (define-key   keymap "\C-\M-r"  'reposition-window-lisp)
  3595.   (ilisp-defkey keymap "i"        'describe-lisp)
  3596.   (ilisp-defkey keymap "I"        'inspect-lisp)
  3597.   (ilisp-defkey keymap "a"        'arglist-lisp)
  3598.   (ilisp-defkey keymap "d"        'documentation-lisp)
  3599.   (ilisp-defkey keymap "m"        'macroexpand-1-lisp)
  3600.   (ilisp-defkey keymap "M"        'macroexpand-lisp)
  3601.   (define-key   keymap "\M-,"     'next-definition-lisp)
  3602.   (define-key   keymap "\M-."     'edit-definitions-lisp)
  3603.   (define-key   keymap "\M-?"     'search-lisp)
  3604.   (define-key   keymap "\M-\""    'replace-lisp)
  3605.   (ilisp-defkey keymap "^"        'edit-callers-lisp)
  3606.   (define-key   keymap "\M-`"     'next-caller-lisp)
  3607.   (define-key   keymap "\M-\t"    'complete-lisp)
  3608.   (define-key   keymap "\M-\C-m"  'complete)
  3609.   (ilisp-defkey keymap "r"        'eval-region-lisp)
  3610.   (define-key   keymap "\M-\C-x"  'eval-defun-lisp) ; Gnu convention
  3611.   (ilisp-defkey keymap "e"        'eval-defun-lisp)
  3612.   (ilisp-defkey keymap "n"        'eval-next-sexp-lisp)
  3613.   (ilisp-defkey keymap "p"        'package-lisp)
  3614.   (ilisp-defkey keymap "P"        'set-package-lisp)
  3615.   (ilisp-defkey keymap "w"        'compile-region-lisp)
  3616.   (ilisp-defkey keymap "c"        'compile-defun-lisp)
  3617.   (ilisp-defkey keymap "\C-r"     'eval-region-and-go-lisp)
  3618.   (ilisp-defkey keymap "\C-e"     'eval-defun-and-go-lisp)
  3619.   (ilisp-defkey keymap "\C-n"     'eval-next-sexp-and-go-lisp)
  3620.   (ilisp-defkey keymap "\C-w"     'compile-region-and-go-lisp)
  3621.   (ilisp-defkey keymap "t"        'trace-defun-lisp)
  3622.   (ilisp-defkey keymap "!"        'default-directory-lisp)
  3623.   (ilisp-defkey keymap " "        'mark-change-lisp)
  3624.   (let ((ilisp-prefix (concat ilisp-prefix "*")))
  3625.     (ilisp-defkey keymap "l"      'list-changes-lisp)
  3626.     (ilisp-defkey keymap "e"      'eval-changes-lisp)
  3627.     (ilisp-defkey keymap "c"      'compile-changes-lisp)
  3628.     (ilisp-defkey keymap "0"      'clear-changes-lisp))
  3629.   (ilisp-defkey keymap "b"        'switch-to-lisp)
  3630.   (ilisp-defkey keymap "y"        'call-defun-lisp)
  3631.   (ilisp-defkey keymap "z"        'reset-ilisp)
  3632.   (ilisp-defkey keymap "g"        'abort-commands-lisp)
  3633.   (ilisp-defkey keymap "s"        'status-lisp)
  3634.   (ilisp-defkey keymap "S"        'select-ilisp)
  3635.   (define-key   keymap "\C-x\C-f" 'find-file-lisp)
  3636.   (ilisp-defkey keymap "l"        'load-file-lisp)
  3637.   (ilisp-defkey keymap "k"        'compile-file-lisp)
  3638.   (ilisp-defkey keymap "A"        'fi:clman-apropos)
  3639.   (ilisp-defkey keymap "D"        'fi:clman))
  3640.  
  3641. ;;;
  3642. (defun ilisp-bindings ()
  3643.   "Set up the key bindings for LISP and ILISP buffers."
  3644.   (setq ilisp-mode-map (full-copy-sparse-keymap comint-mode-map))
  3645.   ;; Remove stop and quit subjob from comint
  3646.   (define-key ilisp-mode-map "\C-c\C-z" nil)
  3647.   (define-key ilisp-mode-map "\C-c\C-\\" nil)
  3648.   (if (fboundp 'lisp-mode-commands)
  3649.       (lisp-mode-commands ilisp-mode-map)
  3650.     (if (fboundp 'set-keymap-parent)
  3651.     (set-keymap-parent ilisp-mode-map shared-lisp-mode-map)))
  3652.   (lisp-bindings ilisp-mode-map t)
  3653.   (if (boundp 'lisp-mode-map) (lisp-bindings lisp-mode-map))
  3654.   (if (boundp 'scheme-mode-map) (lisp-bindings scheme-mode-map))
  3655.   (ilisp-defkey emacs-lisp-mode-map ";" 'comment-region-lisp)
  3656.   (ilisp-defkey global-map "b" 'switch-to-lisp)
  3657.   (ilisp-defkey global-map "1" 'popper-bury-output)
  3658.   (ilisp-defkey global-map "v" 'popper-scroll-output)
  3659.   (ilisp-defkey global-map "G" 'popper-grow-output)
  3660.   (if (not (boundp 'fi:clman-mode-map))
  3661.       (setq fi:clman-mode-map (make-sparse-keymap)))
  3662.   (ilisp-defkey fi:clman-mode-map "D" 'fi:clman)
  3663.   (ilisp-defkey fi:clman-mode-map "A" 'fi:clman-apropos))
  3664.  
  3665. (defun defkey-ilisp (key command &optional inferior-only)
  3666.   "Define KEY as COMMAND in ilisp-mode-map and lisp-mode-map unless
  3667. optional INFERIOR-ONLY is T.  If the maps do not exist they will be
  3668. created.  This should only be called after ilisp-prefix is set to the
  3669. desired prefix."
  3670.   (if (not ilisp-mode-map) (ilisp-bindings))
  3671.   (define-key ilisp-mode-map key command)
  3672.   (define-key lisp-mode-map key command))
  3673.  
  3674. ;;;
  3675. ;;; All done
  3676. (provide 'ilisp)
  3677. (run-hooks 'ilisp-site-hook)
  3678. (run-hooks 'ilisp-load-hook)
  3679. (if (not lisp-no-popper) 
  3680.     (if (and (boundp 'epoch::version) epoch::version)
  3681.     (require 'epoch-pop)
  3682.     (require 'popper)))
  3683. (if (not ilisp-mode-map) (ilisp-bindings))
  3684.  
  3685.