unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
@ 2012-03-27 23:57 Drew Adams
  2012-03-28  0:31 ` Drew Adams
  0 siblings, 1 reply; 8+ messages in thread
From: Drew Adams @ 2012-03-27 23:57 UTC (permalink / raw)
  To: 11106

Enhancement request:

Be able to add an autoload cookie before a `defface', and have
the face definition handled appropriately, similarly
to what is done for user options (variables).  And be able to
specify `face' as the TYPE arg for function `autoload'.  IOW,
have faces handled by autoloading in a way similar to user
options (variables).
 
For options, the cookie adds property `custom-autoload' to the symbol,
and that property is handled appropriately in code in custom.el etc.
 
It would be good if "function" `autoload' explicitly handled
both options and faces via its TYPE argument, just as it handles
functions and keymaps.
 
In particular, I would like to be able to do the following:
 
;;;###autoload (autoload 'someface "somelib" "Doc" nil 'face)
 
And then have the file somelib.el[c] be autoloaded whenever the face is
used (at least wrt some set of face-accessing functions).
 
An advantage of this is that a file of generated autoloads would not
contain the actual face definition, with its sexp that evals to the
face's default "value".  Instead, it would just contain that
`(autoload...)' form, which would DTRT.
 
This would obviate dealing with computing the default at the time that
the autoloads file is loaded.  And that would mean that any dependencies
within that default sexp would be handled normally, when the library
itself is loaded (not when the generated autoloads file is loaded).
 
If my use case is not clear, ignore it.  You can perhaps come up
with your own use case.  After all, faces are similar to user options
in other ways.  The purpose of this enhancement request is to extend
that similarity to autoloading.

(Just as for options, no one is required or necessarily encouraged
to autoload any faces.  This would just make it possible to do so,
without putting the entire face definition into the autoloads file.)
 

In GNU Emacs 24.0.94.1 (i386-mingw-nt5.1.2600)
 of 2012-03-19 on MARVIN
Windowing system distributor `Microsoft Corp.', version 5.1.2600
Configured using:
 `configure --with-gcc (4.6) --no-opt --enable-checking --cflags
 -ID:/devel/emacs/libs/libXpm-3.5.8/include
 -ID:/devel/emacs/libs/libXpm-3.5.8/src
 -ID:/devel/emacs/libs/libpng-dev_1.4.3-1/include
 -ID:/devel/emacs/libs/zlib-dev_1.2.5-2/include
 -ID:/devel/emacs/libs/giflib-4.1.4-1/include
 -ID:/devel/emacs/libs/jpeg-6b-4/include
 -ID:/devel/emacs/libs/tiff-3.8.2-1/include
 -ID:/devel/emacs/libs/gnutls-3.0.9/include'
 






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-27 23:57 bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options Drew Adams
@ 2012-03-28  0:31 ` Drew Adams
  2012-03-28 12:41   ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Drew Adams @ 2012-03-28  0:31 UTC (permalink / raw)
  To: 11106

I wasn't as clear as I could have been.  Maybe this will help.

There are I guess two requests here: 

1. Handle faces (deffaces) similarly to how options (defcustoms) are handled.

2. Have function `autoload' handle both faces and options via its TYPE arg.

#2 would mean that the face attributes (hereafter default "value" of the face)
and the option default value would not be computed by function `autoload'.
Instead, that function would just cause the proper Lisp file to be loaded
whenever the face or option was first accessed.  If something tries to use the
face or option, and it is not yet defined, the autoload would kick in and the
file would be loaded to define it.

#2 is helpful (to me) because it means that actually assigning a value would be
done only when the library is loaded, not when the autoload form is created.
For example,

;;;###autoload (autoload 'a-face "a-file" nil 'face)

would put in place the triggers that would cause file "a-file.el[c]" to be
loaded when face `a-face' is first accessed (is still undefined).  That load
would then cause the face to be defined, by evaluating its default "value" sexp.
Similarly for user options.

What I'm describing is in effect what happens for autoloaded functions (IIUC).
It is the loading of the file that actually defines the functions (not the
creation of the autoloads or the loading of a file of autoloads).

I fear I'm not being clear enough.  Perhaps because it's still fuzzy to me.  But
maybe it will make sense to someone.






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-28  0:31 ` Drew Adams
@ 2012-03-28 12:41   ` Stefan Monnier
  2012-03-28 13:39     ` Drew Adams
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2012-03-28 12:41 UTC (permalink / raw)
  To: Drew Adams; +Cc: 11106

> 1. Handle faces (deffaces) similarly to how options (defcustoms) are handled.

I don't know what that means.

> 2. Have function `autoload' handle both faces and options via its TYPE arg.

Can you provide a sample scenario where that would be useful?


        Stefan





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-28 12:41   ` Stefan Monnier
@ 2012-03-28 13:39     ` Drew Adams
  2012-03-28 15:50       ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Drew Adams @ 2012-03-28 13:39 UTC (permalink / raw)
  To: 'Stefan Monnier'; +Cc: 11106

> > 1. Handle faces (deffaces) similarly to how options 
> > (defcustoms) are handled.
> 
> I don't know what that means.

For #1: Make an autoload cookie before a defface do something analogous to what
it does before a defcustom.  I'm no expert on the latter, so yes, this is vague.
IIUC, an autoload cookie handles an option definition by setting the option
value at autoload time, but it does not simply copy the defcustom to the
autoloads file.

> > 2. Have function `autoload' handle both faces and options 
> >    via its TYPE arg.
> 
> Can you provide a sample scenario where that would be useful?

#2 is more important, to me, and is not directly related to #1.

Maybe this scenario will help, maybe not.  (I'm using default "value" of a face
as shorthand for the value of the second arg, SPEC, to defface.)

In the same file, have two deffaces, f1 and f2, in that order.

Suppose that the sexp defining the default value of f2 depends on the value of
f1 and on the availability of function foo.  If foo is not available then f2's
default value uses constants in the SPEC sexp.  If foo is available, then foo is
invoked with f1 as an arg, to come up with f2's default value.

Assume you want to provide autoloading for the faces, to let users get to their
doc.

For that, you add an autoload cookie before each defface.  But that means that
the SPECs get eval'd at autoloads-file generation time, not when the library is
loaded.

What's more, because you want to make foo available if its defining library is
in the user's load-path, you add a soft require: (require 'foolib nil t).  And
since foo would also need to be available at autoloads-generation time, you add
an autoload cookie for that soft require as well.

But one reason for having f2 use f1's (possibly customized) value in its own
SPEC was to let a user customize f1 and have the default value of f2 be based on
that.  At any time, the user should be able to customize f1, restart Emacs and
have f2's value reflect that customization.

(And no, this is not something that can be done in general using face
inheritance.  Assume that in this case function foo does something interesting,
using f1's value as input.)

But if the autoloads file is generated before the user customizes f1 then the
customized f1 value is not used to compute f2.

The dependencies and openness to customization get defeated by the fact that f1
and f2 become fully defined at autoloads generation time (i.e., when the
autoloads file is created).

In addition, foo's library needs to be loaded both when the autoloads file is
generated and when the file with the deffaces is loaded.

Things are a lot more complicated than they should need to be: the logic of
dependencies is carried over (duplicated) from library load time into autoloads
generation time, and some functionality (e.g. customization relationships) is
lost.

The enhancement request (#2) would let you use an autoload cookie with an
explicit `autoload' call for an option or face, on the same line, just as for a
command:

;;;###autoload (autoload 'f2 "file" nil 'face)

At autoload-file generation time, only the `(autoload...)' sexp would be written
to the autoloads file.  And function `autoload' would DTRT, meaning that it
would cause file `file.el[c]' to be loaded whenever face f2 is needed and not
yet defined.

That way, the face itself would not be defined completely at autoload time, but
only when its defining file is loaded.  The autoloads file would only put in
place the autoloading of f2's file; it would not also predefine the face.

Similarly for user options (defcustoms):

;;;###autoload (autoload 'opt1 "optsfile" nil 'option)

That would not set the option value.  It would only set up autoloading for the
option, so that when it is needed and is not yet defined, its defining file,
optsfile.el[c], would be loaded.

This way, the doc for options and faces could be made available to users, and
customization and loading of their definitions would involve only the logic in
their defining files, not also some things happening at autoloads generation
time and possibly getting in the way.

In sum, the idea would be to have function `autoload' become face-aware and
option-aware.  IOW, be able (using function `autoload' with an autoload cookie)
to separate autoloading _per se_ from predefining.

That is essentially what autoloading of functions does.  It does not predefine a
function completely.  It just "defines" it partially using a placeholder, and it
puts in place a mechanism to automatically load its file, which load actually
defines the function fully.  The aim here would be to provide that same feature
(real autoloading) for options and faces.

Autoloading of functions (e.g. commands) does what autoloading was designed to
do: make sure loading takes place automatically if the function is needed but
not yet defined.

IIUC, autoloading of anything other than a function does not do what autoloading
was designed to do.  An autoload cookie simply copies the defining sexp to the
autoloads file, essentially defining it at the time that file is generated.  And
function `autoload' does nothing for a non-function (a keymap being handled as a
function) - it is not option-aware or face-aware.

Dunno whether I'm clear enough.  And again, some lack of clarity is no doubt due
to my insufficient understanding of the autoload code.  Feel free to point out
stuff that I'm missing.  Thx.






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-28 13:39     ` Drew Adams
@ 2012-03-28 15:50       ` Stefan Monnier
  2012-03-28 17:08         ` Drew Adams
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2012-03-28 15:50 UTC (permalink / raw)
  To: Drew Adams; +Cc: 11106

> For #1: Make an autoload cookie before a defface do something
> analogous to what it does before a defcustom.  I'm no expert on the
> latter, so yes, this is vague.  IIUC, an autoload cookie handles an
> option definition by setting the option value at autoload time, but it
> does not simply copy the defcustom to the autoloads file.

;;;###autoload on a defcustom pretty much copies the defcustom, tho it
addmittedly tries to strip away things that won't be needed until the
file is actually loaded.

But I don't know what that would mean for defface.  IOW what is the
concrete problem you see with ;;;###autoload on a defface that you'd
like to see fixed?

> Assume you want to provide autoloading for the faces,

I can't assume it, since you're trying to explain to me why that would
be useful.

> to let users get to their doc.

That's it?  So you only want it for describe-face's purpose?

Then autoloading is not the right answer.  We're back at the issue of
finding documentation for vars, functions, and now faces in not-yet
loaded code.  We don't need to autoload the whole world for that.

[ Sorry, didn't read the rest, assuming that it is not relevant since
  I rejected the main assumption. ]


        Stefan





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-28 15:50       ` Stefan Monnier
@ 2012-03-28 17:08         ` Drew Adams
  2012-03-28 18:45           ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Drew Adams @ 2012-03-28 17:08 UTC (permalink / raw)
  To: 'Stefan Monnier'; +Cc: 11106

> > For #1: Make an autoload cookie before a defface do something
> > analogous to what it does before a defcustom.  I'm no expert on the
> > latter, so yes, this is vague.  IIUC, an autoload cookie handles an
> > option definition by setting the option value at autoload 
> > time, but it does not simply copy the defcustom to the autoloads file.
> 
> ;;;###autoload on a defcustom pretty much copies the defcustom, tho it
> addmittedly tries to strip away things that won't be needed until the
> file is actually loaded.
> 
> But I don't know what that would mean for defface.  IOW what is the
> concrete problem you see with ;;;###autoload on a defface that you'd
> like to see fixed?

No special problem for #1.  It's not completely clear to me how an option is
handled, but clearly the defcustom is not simply copied to the autoloads file.
I took a look at autoload.el and custom.el, as well as the C code for
`autoload', but the entire purpose behind the treatment of defcustom is not
clear to me.  If you think the cookie-handling code does nothing special for
options then you can ignore request #1.

It is request #2 that I am particularly interested in, as I said.

> > Assume you want to provide autoloading for the faces,
> 
> I can't assume it, since you're trying to explain to me why that would
> be useful.

No, I was not trying to explain why autoloading faces can be useful in general.
Yes, I do assume that it can be.

What I explained was a use case for having function `autoload' handle options
and faces - the scenario you asked for.  If you look at that use case perhaps
you will understand more specifically why (real) autoloading can be helpful, and
how different it would be from simply predefining faces completely at autoload
file generation time.

As to the assumption of usefulness in general, since that is apparently a
stumbling block for you: Why, in your opinion, can (real) autoloading be useful
for a command but not for an option or a face?  The same utility you see for a
command I see also for an option or face.

IOW, why do we have function `autoload' for functions?  Why not just use
autoload cookies and have them simply copy a function's defun to the autoloads
file (i.e., not handle functions specially)?

The same reason applies to options and functions: real autoloading has a use,
independent of the use of predefinition.  Imagine handicapping autoload cookies
by removing their special handling of defuns - have them just copy the defun to
the autoloads file, and you will see how their handling of options and faces is
handicapped.

> > to let users get to their doc.
> 
> That's it?  So you only want it for describe-face's purpose?

No, not only the doc.  I want it for the same reasons that any (real)
autoloading is wanted.  I want function `autoload' to do for options and faces
the same kind of thing it does for functions.

Think in terms of function autoloading as the model.  Why provide autoloading of
functions (e.g. commands, keymaps)?  Those same reasons apply to options and
faces, IMO.  It is about doc, sure, but not only doc.

When you do `M-x foo TAB', you see `foobar' as a candidate, if it is autoloaded.
Similarly, if you do `M-x customize-face RET foo TAB' you would see `fooface' as
a candidate, if it were autoloaded.

And just as in the case of a command, the face would not be predefined, just in
order to be autoloadable.  The point of this request is to provide real
autoloading for options and faces, as opposed to simply
predefinition/pre-evaluation (which is what autoload cookies do for an arbitrary
sexp).

The face would be undefined until you tried to access it, and then its defining
file would be loaded and its defface would kick in (at load time) to provide the
definition and hence the "value": either the default value or an already
customized value.  In this example, that definition would be provided to
`customize-face' as a completion candidate.

There is a big difference between defining a face at autoload file generation
time and defining it when the library containing its defface is loaded.  For one
thing, if the user has customized the face then the library's defface will have
no effect, whereas a defface in an autoloads file might be eval'ed before the
user's `custom-file' is loaded.

I gave a specific example (scenario) for this, as you requested.

Think how users interact with autoloaded commands and keymaps.  I would like the
same possibility for faces and options.  For the same reasons.  And yes, one of
those reasons - for commands too - is access to the doc.

> Then autoloading is not the right answer.  We're back at the issue of
> finding documentation for vars, functions, and now faces in not-yet
> loaded code.  We don't need to autoload the whole world for that.

And you're no doubt thinking of only the current handling of autoload cookies
for faces and options.  That handling is indeed heavy-handed, perhaps even
misguided.  It is a sledgehammer substitute for real, lightweight autoloading
(such as is provided for functions by function `autoload').

Autoload cookies simply predefine/pre-evaluate stuff.  They do not really
provide an autoload feature, as does function `autoload'.  Except that for
functions they DTRT: call `autoload'.

Simply predefining in an autoloads file is not what we do for autoloading
function definitions.  This request (#2) is about extending function `autoload'
to handle user options and faces, just as it handles functions (including
commands and keymaps).

For functions, we essentially preload only the doc, and we put in place a
trigger to load the file that actually defines the function.  That's what my
request #2 is about: have function `autoload' treat options and faces
analogously to its treatment of functions.  And an autoload cookie would then
handle defface and defcustom, like it handles defun, by handing things off to
function `autoload'.

I want to be able to actually autoload an option or face, having it become
defined by loading its defining file, and not just having it be predefined in
some autoloads file.

Just like commands, users interact with things that can be customized: options
and faces.  I want to make it possible to let them interact with options and
faces whose definitions have not yet been loaded.

And I do not want to predefine those customizable things just in order to be
able to autoload them.  Just as for autoloaded commands, I want all of the
defining logic to take effect in the library's load environment, not at some
package-install time when a file of autoloads is generated.

Letting user customizations be taken into account when loading is one example of
that.  Library file dependencies is another example.  I want to separate such
logic from the autoloads file - later, load-time binding, if you will.

> [ Sorry, didn't read the rest, assuming that it is not relevant since
>   I rejected the main assumption. ]

A copout.  Try reading before rejecting out of hand.  Especially since you asked
for a scenario and I provided one - I described a specific use case.  And I can
point you to the code that inspired it if my description of it is not clear.
But at least read the description, please.






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-28 17:08         ` Drew Adams
@ 2012-03-28 18:45           ` Stefan Monnier
  2016-04-28 14:17             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2012-03-28 18:45 UTC (permalink / raw)
  To: Drew Adams; +Cc: 11106

> No special problem for #1.  It's not completely clear to me how an
> option is handled, but clearly the defcustom is not simply copied to
> the autoloads file.

Indeed, but it's supposed to be an internal detail (i.e. an optimization).

>> I can't assume it, since you're trying to explain to me why that would
>> be useful.
> No, I was not trying to explain why autoloading faces can be useful in
> general.

Then you were not trying to answer my question (which was not "in
general" but at least in one scenario, by the way).

> As to the assumption of usefulness in general, since that is
> apparently a stumbling block for you: Why, in your opinion, can (real)
> autoloading be useful for a command but not for an option or a face?

Because the user can invoke commands, but not faces (with very few
exceptions).

> IOW, why do we have function `autoload' for functions?  Why not just
> use autoload cookies and have them simply copy a function's defun to
> the autoloads file (i.e., not handle functions specially)?

Because a function usually depends on its surrounding code, so copying
its body without its surroundings would not result in a usable function.
Because such autoloaded functions are simply entry points to the package
and it's convenient to be able to auto-load the package without having to
`require' it explicitly.

> The same reason applies to options and functions: real autoloading has a use,
> independent of the use of predefinition.

I don't see how faces generally depend on their surrounding code.
I don't see how the use of a face will often lead to the use of the rest
of the package where it's defined.

[ I stopped here, sorry, too long. ]


        Stefan





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options
  2012-03-28 18:45           ` Stefan Monnier
@ 2016-04-28 14:17             ` Lars Ingebrigtsen
  0 siblings, 0 replies; 8+ messages in thread
From: Lars Ingebrigtsen @ 2016-04-28 14:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 11106

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I don't see how faces generally depend on their surrounding code.
> I don't see how the use of a face will often lead to the use of the rest
> of the package where it's defined.

Me neither.  Closing.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-04-28 14:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-27 23:57 bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options Drew Adams
2012-03-28  0:31 ` Drew Adams
2012-03-28 12:41   ` Stefan Monnier
2012-03-28 13:39     ` Drew Adams
2012-03-28 15:50       ` Stefan Monnier
2012-03-28 17:08         ` Drew Adams
2012-03-28 18:45           ` Stefan Monnier
2016-04-28 14:17             ` Lars Ingebrigtsen

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).