Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Message from discussion Colon commands
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Pascal Bourguignon  
View profile  
 More options Jan 13 2008, 2:31 pm
Newsgroups: comp.lang.lisp
From: Pascal Bourguignon <p...@informatimago.com>
Date: Sun, 13 Jan 2008 20:31:18 +0100
Local: Sun, Jan 13 2008 2:31 pm
Subject: Re: Colon commands

Evans Winner <tho...@timbral.net> writes:
> Some research seems to indicate that at least OpenMCL, ACL and LispWorks
> maybe have some kind of facility that allows the definition of commands
> that can be used at the repl that look like--

> :command

> --or maybe--

> :command arg1 [arg2 ... argn]

> I know at least clisp has something like this at least in the debugger.
> Is this is standard Common Lisp facility?  (There is also a comma command
> syntax in scsh, i know, as well.)

It is not standard.  The role of comma is defined only in the context
of backquote.

> Sorry if the question is vague; i don't know if there is an established
> term for this.  I can't find a reference in the Hyperspec.  In any case,
> it might be nice to be able to define commands like that for convenience
> at the repl.  Can it be done?--or is there a reason it's a bad idea?

Note that at least in Allegro Common Lisp, the character prefixing
these commands (both user defined and system provided) is
configurable.

In the case of clisp, there's no prefix character for user commands.
They can be any symbol, not just keywords:

C/USER[23]> (com.informatimago.pjb::define-user-commands (:fecha date user1::dote)
                "Interactive commands"
              "Prints the date."
              (com.informatimago.common-lisp.interactive:date))
:FECHA
C/USER[24]> :fecha
2008-01-13 20:24:57
C/USER[25]> date
2008-01-13 20:25:00
C/USER[26]> user1::dote
2008-01-13 20:25:04

For clisp users:

To define more easily user commands in clisp, I use these macros:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter *user-command-groups* (make-hash-table :test (function equal)))
  (defun ensure-list (item) (if (listp item) item (list item))))

;;(setf custom:*user-commands* nil)

(defun generate-user-commands ()
  (setf custom:*user-commands*
        (let ((commands '()))
          (maphash
           (lambda (category command-list)
             (dolist (command  command-list)
               (destructuring-bind (names docstring body) command
                 (push (coerce
                        (let ((vfun (gensym)))
                          `(lambda ()
                             (flet ((,vfun () ,@body))
                               (list
                                ,(format nil "~%~:@(~{~S ~}~) ~A" names docstring)
                                ,@(mapcar (lambda (name)
                                            `(cons ,(format nil "~(~S~)" name)
                                                   (function ,vfun)))
                                          names)))))
                        'function) commands)))
             (push (coerce
                    `(lambda () (list ,(format nil "~2%~A:" category)))
                    'function) commands))
           *user-command-groups*)
          commands))
  (values))

(defmacro define-user-commands (names category docstring &body body)
  (let ((names (ensure-list names)))
    `(let ((entry (find ',names  (gethash ',category *user-command-groups* '())
                        :test (function equal)
                        :key (function first))))
       (if entry
           (setf (second entry) ',docstring
                 (third  entry) ',body)
           (push (list ',names ',docstring ',body)
                 (gethash ',category *user-command-groups* '())))
       (generate-user-commands)
       ',(first names))))

(defun delete-user-command (name)
  (maphash (lambda (category commands)
             (setf commands (delete name commands
                                    :test (function member)
                                    :key (function first)))
             (if commands
                 (setf (gethash category *user-command-groups*) commands)
                 (remhash category *user-command-groups*)))
            *user-command-groups*)
  (generate-user-commands))

Refer to the Implementation Notes for teh description of custom:*user-commands*.

--
__Pascal Bourguignon__                     http://www.informatimago.com/

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google