;;;; -*- Mode:Common-Lisp; Package:COMMON-LISP-USER; Syntax:common-lisp -*- ;;;; *-* File: /usr/local/gbbopen/extended-repl.lisp *-* ;;;; *-* Edited-By: cork *-* ;;;; *-* Last-Edit: Fri Sep 19 09:44:24 2008 *-* ;;;; *-* Machine: cyclone.cs.umass.edu *-* ;;;; ************************************************************************** ;;;; ************************************************************************** ;;;; * ;;;; * Extended REPL Command Processing ;;;; * for CLISP, CMUCL, SCL, ECL, and SBCL REPL and for SLIME (Emacs->Swank) ;;;; * ;;;; ************************************************************************** ;;;; ************************************************************************** ;;; ;;; Written by: Dan Corkill ;;; ;;; Copyright (C) 2005-2008, Dan Corkill ;;; Part of the GBBopen Project (see LICENSE for license information). ;;; ;;; Porting Notice: ;;; ;;; These extensions add: ;;; - keyword-command capabilities to the REPL in CLISP, CMUCL, SCL, ;;; and SBCL ;;; - interface into CLISP's *user-commands* facility ;;; - extend ECL's command repertoire ;;; - add keyword-command support to SLIME's Emacs->Swank interface ;;; ;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ;;; ;;; 06-04-05 File created. (Corkill) ;;; 02-02-06 Added ECL support. (Corkill) ;;; 02-04-06 Added SLIME (Emacs->Swank) support. (Corkill) ;;; 04-17-08 Reworked SLIME mechanism. (Corkill) ;;; ;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * (in-package :common-lisp-user) ;;; --------------------------------------------------------------------------- ;;; In ECL, setup an Extended REPL command topic (must be done destructively, ;;; as si::*tpl-commands* is already lexically bound in the default TLP) #+ecl (setf (rest si::*tpl-commands*) (adjoin (list "Extended REPL Commands") (cdr si::*tpl-commands*) :key #'car :test #'equal)) ;;; --------------------------------------------------------------------------- ;;; In Allegro, we hide non-native help commands by saving the command-name ;;; strings in *non-native-help-commandss* and fwrapping ;;; tpl::get-commands-list to remove the commands from its returned value. #+allegro (defvar *non-native-help-commands* nil) #+allegro (def-fwrapper filtered-get-commands-list-wrap () ;; Remove non-native extended-REPL commands: (remove-if #'(lambda (command) (member (first command) *non-native-help-commands* :test #'equal)) (call-next-fwrapper))) #+allegro (fwrap 'top-level::get-commands-list 'extended-repl 'filtered-get-commands-list-wrap) ;;; --------------------------------------------------------------------------- ;;; With-system-name (copied in module-manager/module-manager.lisp for ;;; startup.lisp only invocation) (defvar *current-system-name* nil) (defmacro with-system-name ((&optional system-name) &body body) (unless (keywordp system-name) (error "System name, ~s, must be a keyword." system-name)) `(let ((*current-system-name* ',system-name)) ,@body)) ;;; --------------------------------------------------------------------------- (defvar *extended-repl-commands* nil) (defun get-extended-repl-command (command) (assoc command *extended-repl-commands* :test #'eq)) (compile-if-advantageous 'get-extended-repl-command) ;;; =========================================================================== ;;; Define-repl-command (defun redefining-cl-user-repl-command-warning (command fn) ;; avoid SBCL optimization warning: (declare (optimize (speed 1))) (let ((*package* (find-package ':common-lisp))) (format t "~&;; Redefining ~s function for REPL-command ~s~%" fn command))) (compile-if-advantageous 'redefining-cl-user-repl-command-warning) ;;; --------------------------------------------------------------------------- (defun add-repl-command-spec (command-spec) (setf *extended-repl-commands* (cons command-spec (delete (first command-spec) (the list *extended-repl-commands*) :test #'eq :key #'car)))) (compile-if-advantageous 'add-repl-command-spec) ;;; --------------------------------------------------------------------------- (defmacro define-repl-command (command-name lambda-list &rest body) (let ((.options. nil)) ;; Handle (