emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: File modes facilities.


From: Kim F. Storm
Subject: Re: File modes facilities.
Date: Mon, 24 Oct 2005 16:02:38 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

"Richard M. Stallman" <address@hidden> writes:

>     *** callint.c     14 Aug 2005 14:47:25 +0200      1.140
>     --- callint.c     21 Oct 2005 16:38:22 +0200
>     ***************
>     *** 346,351 ****
>     --- 346,356 ----
>             function = wrong_type_argument (Qcommandp, function);
>             goto retry;
>           }
>     +       else if (*string == '#')
>     +         {
>     +           string = 0;
>     +           goto get_interactive_form;
>     +         }
>
> This would be much cleaner (and easier to use) if it read the Lisp
> expression out of the string itself, after the #.

I did consider that, and we could do that as well, but IMO, the whole
point of this to allow interactive specs for built-in functions to be
written in Lisp, i.e. in a .el file, so people can improve on the code
without modifying the base functionality.

Also, doing it right in the string makes it much harder to edit and
debug, and may cause problems on systems which has an upper limit on
constant string size.

> But as I said, I'd rather not install this now.

Ok, as a strong advocate of focusing on the release, I have to accept
that :-), although this change is really minor compared to some of the
other recent changes to core functionality ...

However, the patch is not the right approach in any case -- as it only
allows creating an interactive spec for DEFUN's which explicitly allow
it with the prompt = "#" marker.

Below is a _much_better_ patch which allows ANY function to have its
interactive specification overridden, and consequently you can make
any function into a command.

Here are some trivial examples:

(put 'set-file-modes 'interactive
     '(list (read-file-name "Set modes on file: ")
            (read-number "New modes (decimal): ")))

(put 'set-file-times 'interactive
     '(list (read-file-name "Set current time on file: ")
            (current-time)))

(defun test (a b)
 (message "%d" (+ a b)))

(put 'test 'interactive
     '(list (read-number "a: ")
            (read-number "b: ")))

(put 'test 'interactive "nx: \nny: ")


*** callint.c   14 Aug 2005 14:47:25 +0200      1.140
--- callint.c   24 Oct 2005 14:40:54 +0200      
***************
*** 333,338 ****
--- 333,348 ----
    /* If k or K discard an up-event, save it here so it can be retrieved with 
U */
    up_event = Qnil;
  
+   /* Allow overriding the interactive spec of any function
+      by placing an interactive property on the function name.  */
+ 
+   if (SYMBOLP (function)
+       && (specs = Fget (function, Qinteractive), !NILP (specs)))
+     {
+       filter_specs = specs;
+       goto override_interactive_form;
+     }
+ 
    /* Decode the kind of function.  Either handle it and return,
       or go to `lose' if not interactive, or go to `retry'
       to specify a different function, or set either STRING or SPECS.  */
***************
*** 357,363 ****
      {
        Lisp_Object form;
        GCPRO2 (function, prefix_arg);
!       form = Finteractive_form (function);
        UNGCPRO;
        if (CONSP (form))
        specs = filter_specs = Fcar (XCDR (form));
--- 367,373 ----
      {
        Lisp_Object form;
        GCPRO2 (function, prefix_arg);
!       form = Finteractive_form (function, Qt);
        UNGCPRO;
        if (CONSP (form))
        specs = filter_specs = Fcar (XCDR (form));
***************
*** 365,370 ****
--- 375,382 ----
        goto lose;
      }
  
+     override_interactive_form:
+ 
    /* If either SPECS or STRING is set to a string, use it.  */
    if (STRINGP (specs))
      {

*** data.c      19 Sep 2005 00:24:45 +0200      1.254
--- data.c      24 Oct 2005 14:40:32 +0200      
***************
*** 775,788 ****
    return make_string (name, strlen (name));
  }
  
! DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 1, 0,
         doc: /* Return the interactive form of CMD or nil if none.
  If CMD is not a command, the return value is nil.
  Value, if non-nil, is a list \(interactive SPEC).  */)
!      (cmd)
!      Lisp_Object cmd;
  {
!   Lisp_Object fun = indirect_function (cmd);
  
    if (SUBRP (fun))
      {
--- 775,799 ----
    return make_string (name, strlen (name));
  }
  
! DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 2, 0,
         doc: /* Return the interactive form of CMD or nil if none.
  If CMD is not a command, the return value is nil.
+ If optional second arg NO-OVERRIDE is non-nil, do not look for an
+ overriding `interactive' specification property on CMD.
  Value, if non-nil, is a list \(interactive SPEC).  */)
!   (cmd, no_override)
!      Lisp_Object cmd, no_override;
  {
!   Lisp_Object fun;
!   Lisp_Object specs;
! 
!  retry:
!   if (NILP (no_override)
!       && SYMBOLP (cmd)
!       && (specs = Fget (cmd, Qinteractive), !NILP (specs)))
!     return list2 (Qinteractive, specs);
! 
!   fun = indirect_function (cmd);
  
    if (SUBRP (fun))
      {
***************
*** 797,811 ****
    else if (CONSP (fun))
      {
        Lisp_Object funcar = XCAR (fun);
        if (EQ (funcar, Qlambda))
        return Fassq (Qinteractive, Fcdr (XCDR (fun)));
!       else if (EQ (funcar, Qautoload))
        {
          struct gcpro gcpro1;
          GCPRO1 (cmd);
          do_autoload (fun, cmd);
          UNGCPRO;
!         return Finteractive_form (cmd);
        }
      }
    return Qnil;
--- 808,824 ----
    else if (CONSP (fun))
      {
        Lisp_Object funcar = XCAR (fun);
+ 
        if (EQ (funcar, Qlambda))
        return Fassq (Qinteractive, Fcdr (XCDR (fun)));
! 
!       if (EQ (funcar, Qautoload))
        {
          struct gcpro gcpro1;
          GCPRO1 (cmd);
          do_autoload (fun, cmd);
          UNGCPRO;
!         goto retry;
        }
      }
    return Qnil;

*** eval.c      14 Aug 2005 14:47:28 +0200      1.256
--- eval.c      24 Oct 2005 14:48:31 +0200      
***************
*** 1908,1913 ****
--- 1908,1917 ----
    register Lisp_Object fun;
    register Lisp_Object funcar;
  
+   if (SYMBOLP (function)
+       && !NILP (Fget (function, Qinteractive)))
+     return Qt;
+ 
    fun = function;
  
    fun = indirect_function (fun);

*** fileio.c    20 Oct 2005 16:48:05 +0200      1.557
--- fileio.c    21 Oct 2005 16:21:25 +0200      
***************
*** 3462,3468 ****
    return make_number (st.st_mode & 07777);
  }
  
! DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
         doc: /* Set mode bits of file named FILENAME to MODE (an integer).
  Only the 12 low bits of MODE are used.  */)
    (filename, mode)
--- 3462,3468 ----
    return make_number (st.st_mode & 07777);
  }
  
! DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, "#",
         doc: /* Set mode bits of file named FILENAME to MODE (an integer).
  Only the 12 low bits of MODE are used.  */)
    (filename, mode)

*** lisp.h      02 Oct 2005 21:08:17 +0200      1.542
--- lisp.h      24 Oct 2005 14:41:07 +0200      
***************
*** 2117,2123 ****
  extern Lisp_Object Qinteger;
  
  extern void circular_list_error P_ ((Lisp_Object));
! EXFUN (Finteractive_form, 1);
  
  /* Defined in frame.c */
  extern Lisp_Object Qframep;
--- 2117,2123 ----
  extern Lisp_Object Qinteger;
  
  extern void circular_list_error P_ ((Lisp_Object));
! EXFUN (Finteractive_form, 2);
  
  /* Defined in frame.c */
  extern Lisp_Object Qframep;


--
Kim F. Storm <address@hidden> http://www.cua.dk





reply via email to

[Prev in Thread] Current Thread [Next in Thread]