From: storm@cua.dk (Kim F. Storm)
Cc: rms@gnu.org, schwab@suse.de, michael.cadilhac-@t-lrde.epita.fr,
emacs-devel@gnu.org, eliz@gnu.org, snogglethorpe@gmail.com,
miles@gnu.org
Subject: Re: File modes facilities.
Date: Tue, 25 Oct 2005 10:51:41 +0200 [thread overview]
Message-ID: <m3ll0i568y.fsf@kfs-l.imdomain.dk> (raw)
In-Reply-To: <87oe5e5xll.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Mon, 24 Oct 2005 19:02:41 -0400")
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>>> 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.
>>>
>>> Indeed, this is much better.
>>> The only problem I still see with it is that it interacts poorly
>>> with aliases.
Here is a new patch which fully supports command aliases, optionally
with different interactive specs:
*** data.c 19 Sep 2005 00:24:45 +0200 1.254
--- data.c 25 Oct 2005 00:49:49 +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,801 ----
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))
! {
! fun = indirect_function_overriding_spec (cmd, &specs);
! if (!NILP (specs))
! return list2 (Qinteractive, specs);
! }
! else
! 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;
--- 810,826 ----
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;
***************
*** 1912,1917 ****
--- 1927,1975 ----
return hare;
}
+ /* If OBJECT is a symbol, find the end of its function chain and
+ return the value found there. If OBJECT is not a symbol, just
+ return it. If there is a cycle in the function chain, signal a
+ cyclic-function-indirection error.
+
+ This is like indirect_function, except that it looks for an
+ overriding interactive specification on each symbol alias, and
+ it will return prematurely if found. */
+ Lisp_Object
+ indirect_function_overriding_spec (object, specs)
+ register Lisp_Object object;
+ Lisp_Object *specs;
+ {
+ Lisp_Object tortoise, hare;
+
+ *specs = Qnil;
+ hare = tortoise = object;
+
+ for (;;)
+ {
+ if (!SYMBOLP (hare) || EQ (hare, Qunbound))
+ break;
+ if ((*specs = Fget (hare, Qinteractive), !NILP (*specs)))
+ return hare;
+ hare = XSYMBOL (hare)->function;
+
+ if (!SYMBOLP (hare) || EQ (hare, Qunbound))
+ break;
+ if ((*specs = Fget (hare, Qinteractive), !NILP (*specs)))
+ return hare;
+ hare = XSYMBOL (hare)->function;
+
+ tortoise = XSYMBOL (tortoise)->function;
+
+ if (EQ (hare, tortoise))
+ Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil));
+ }
+
+ return hare;
+ }
+
+
+
DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 1, 0,
doc: /* Return the function at the end of OBJECT's function chain.
If OBJECT is a symbol, follow all function indirections and return the final
*** lisp.h 02 Oct 2005 21:08:17 +0200 1.542
--- lisp.h 25 Oct 2005 00:48:23 +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;
***************
*** 2159,2164 ****
--- 2159,2166 ----
EXFUN (Fsymbol_plist, 1);
EXFUN (Fsymbol_name, 1);
extern Lisp_Object indirect_function P_ ((Lisp_Object));
+ extern Lisp_Object indirect_function_overriding_spec P_ ((Lisp_Object,
+ Lisp_Object *));
EXFUN (Findirect_function, 1);
EXFUN (Ffset, 2);
EXFUN (Fsetplist, 2);
*** callint.c 14 Aug 2005 14:47:25 +0200 1.140
--- callint.c 25 Oct 2005 10:47:36 +0200
***************
*** 321,328 ****
else
enable = Qnil;
- fun = indirect_function (function);
-
specs = Qnil;
string = 0;
/* The idea of FILTER_SPECS is to provide away to
--- 321,326 ----
***************
*** 333,343 ****
/* If k or K discard an up-event, save it here so it can be retrieved with U */
up_event = Qnil;
/* 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. */
! if (SUBRP (fun))
{
string = (unsigned char *) XSUBR (fun)->prompt;
if (!string)
--- 331,347 ----
/* If k or K discard an up-event, save it here so it can be retrieved with U */
up_event = Qnil;
+ fun = indirect_function_overriding_spec (function, &specs);
+
/* 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. */
! if (!NILP (specs))
! {
! filter_specs = specs;
! }
! else if (SUBRP (fun))
{
string = (unsigned char *) XSUBR (fun)->prompt;
if (!string)
***************
*** 357,363 ****
{
Lisp_Object form;
GCPRO2 (function, prefix_arg);
! form = Finteractive_form (function);
UNGCPRO;
if (CONSP (form))
specs = filter_specs = Fcar (XCDR (form));
--- 361,367 ----
{
Lisp_Object form;
GCPRO2 (function, prefix_arg);
! form = Finteractive_form (function, Qt);
UNGCPRO;
if (CONSP (form))
specs = filter_specs = Fcar (XCDR (form));
*** eval.c 14 Aug 2005 14:47:28 +0200 1.256
--- eval.c 25 Oct 2005 00:52:49 +0200
***************
*** 1907,1916 ****
{
register Lisp_Object fun;
register Lisp_Object funcar;
! fun = function;
!
! fun = indirect_function (fun);
if (EQ (fun, Qunbound))
return Qnil;
--- 1907,1917 ----
{
register Lisp_Object fun;
register Lisp_Object funcar;
+ Lisp_Object specs;
! fun = indirect_function_overriding_spec (function, &specs);
! if (!NILP (specs))
! return Qt;
if (EQ (fun, Qunbound))
return Qnil;
--
Kim F. Storm <storm@cua.dk> http://www.cua.dk
next prev parent reply other threads:[~2005-10-25 8:51 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-19 20:09 File modes facilities Michael Cadilhac
2005-10-19 20:35 ` Stefan Monnier
2005-10-19 21:28 ` Michael Cadilhac
2005-10-19 22:19 ` Nick Roberts
2005-10-19 22:44 ` Michael Cadilhac
2005-10-19 22:48 ` Kim F. Storm
2005-10-19 22:57 ` Edward O'Connor
2005-10-19 23:00 ` Michael Cadilhac
2005-10-20 9:04 ` Eli Zaretskii
2005-10-20 10:41 ` Michael Cadilhac
2005-10-20 11:51 ` Romain Francoise
2005-10-20 12:41 ` Eli Zaretskii
2005-10-20 14:18 ` Michael Cadilhac
2005-10-20 16:15 ` Stefan Monnier
2005-10-20 22:16 ` Kim F. Storm
2005-10-21 3:21 ` Stefan Monnier
2005-10-21 8:44 ` Andreas Schwab
2005-10-21 12:59 ` Michael Cadilhac
2005-10-21 14:14 ` Miles Bader
2005-10-21 14:43 ` Kim F. Storm
2005-10-21 16:42 ` Michael Cadilhac
2005-10-21 22:19 ` Richard M. Stallman
2005-10-24 14:02 ` Kim F. Storm
2005-10-24 14:16 ` David Kastrup
2005-10-24 16:02 ` Andreas Schwab
2005-10-24 21:00 ` Kim F. Storm
2005-10-24 14:46 ` Stefan Monnier
2005-10-24 22:14 ` Kim F. Storm
2005-10-24 23:02 ` Stefan Monnier
2005-10-25 8:51 ` Kim F. Storm [this message]
2005-10-25 20:29 ` Richard M. Stallman
2005-10-25 15:58 ` Richard M. Stallman
2005-10-25 21:34 ` Kim F. Storm
2005-10-26 8:52 ` Kim F. Storm
2005-10-27 1:31 ` Richard M. Stallman
2005-10-27 1:29 ` Richard M. Stallman
2005-10-21 10:58 ` Kim F. Storm
2005-10-21 11:05 ` Kim F. Storm
2005-10-21 15:07 ` Stefan Monnier
2005-10-21 17:51 ` Richard M. Stallman
2005-10-21 18:43 ` Stefan Monnier
2005-10-22 4:18 ` Richard M. Stallman
2005-10-22 5:39 ` Drew Adams
2005-10-22 6:17 ` Miles Bader
2005-10-22 6:32 ` Drew Adams
2005-10-22 7:33 ` Miles Bader
2005-10-22 7:45 ` Drew Adams
2005-10-23 18:05 ` Stefan Monnier
2005-10-23 18:27 ` Drew Adams
2005-10-24 13:37 ` Richard M. Stallman
2005-10-24 13:40 ` Stefan Monnier
2005-10-24 16:41 ` Drew Adams
2005-10-24 16:59 ` Stefan Monnier
2005-10-24 17:13 ` Drew Adams
2005-10-20 23:38 ` Richard M. Stallman
2005-10-21 0:58 ` Michael Cadilhac
2005-10-21 1:06 ` Miles Bader
2005-10-21 1:24 ` Michael Cadilhac
2005-10-21 17:51 ` Richard M. Stallman
2005-10-23 23:42 ` Michael Cadilhac
2005-10-24 14:09 ` Kim F. Storm
2005-10-25 15:58 ` Richard M. Stallman
2005-10-20 1:42 ` Kevin Ryde
2005-10-20 2:01 ` Miles Bader
2005-10-20 7:12 ` Michael Cadilhac
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3ll0i568y.fsf@kfs-l.imdomain.dk \
--to=storm@cua.dk \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=michael.cadilhac-@t-lrde.epita.fr \
--cc=miles@gnu.org \
--cc=rms@gnu.org \
--cc=schwab@suse.de \
--cc=snogglethorpe@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).