The following message is a courtesy copy of an article
that has been posted to comp.emacs.xemacs as well.
For reasons given below, I am copying this message to xemacs-beta in the
hopes of attracting the attention of someone who actually knows how to
use specifiers.
On 16 Jan 2004 at 11:31:39 +0100, Klaus Berndl <klaus.berndl(a)sdm.de>
wrote:
Thanks for the hint - in the meanwhile i have tried to understand
specifiers
from the XEmacs lisp-manual - especially for my needs (s.b.). But i have to
admit, that i went lost in all these locales, domains, inst-pairs etc... and
thousands of different functions related to specifiers...Unfortunatelly the
provided example in the manual drives me not in the right direction. Maybe I'm
too dump but I'm missing some more examples in the manual - there is a lot of
theory but only one short example for only one special situation.
This is, unfortunately, a common complaint among those who have tried to
understand specifiers. Let's try to use this as an opportunity to come
up with an example or two for the manual. I haven't ever done much of
anything with specifiers myself, so I won't be much help, I'm afraid.
here are my needs:
I have a normal variable, lets say foo:
(defvar foo nil)
What i want is giving `foo' a separate value in whenever used in a new frame.
All i have to do with GNU Emacs is:
1. (make-variable-frame-local 'foo)
2. Adding a hook to `after-make-frame-functions' which does:
(modify-frame-parameters frame (list (cons 'foo nil)))
Thats all; now GNU Emacs uses in the every new frame an own value of 'foo.
Setting 'foo with setq in a frame autom. modifies the frame-local value and
getting the value of 'foo autom. uses the frame-local value if there is any.
How can i achieve that with the specifier-mechanism of XEmacs?
Thanks a lot for any hints (a very short example for 'foo would be the best)!
I'm think that frame-local variables are evil for the same reason that I
think buffer-local variables are evil: the declaration is both global
and invisible. By that, I mean that you cannot tell whether a variable
is "normal", buffer-local, or frame-local just by looking at it. So if
I have namespace management problems, and some other Lisp package
happens to use a variable name that I already declared frame- or
buffer-local, weird stuff is going to happen, and it will be extremely
hard to track down.
Here's my attempt at deciphering specifiers for your particular
application. It did not work the way I thought it would from reading
the documentation and browsing through specifier.el and specifier.c. I
also looked at the way specifiers are used in gutter-items.el, which I
thought was quite helpful until it failed to work the way I expected.
Perhaps some xemacs-beta denizen can whack me with a Clue Stick <tm>.
(defconst my-frame-local-var (make-generic-specifier nil))
That is supposed to bind my-frame-local-var to a generic specifier with
a default value of nil. A "generic" specifier is one whose instances
are Lisp objects. If you happen to know that you will always be setting
the variable to integer, natural number, or boolean (nil and t) values,
then you can declare the specifier to have a more restrictive type.
my-frame-local-var => #<generic-specifier global=(nil) 0x19df>
Here is the current (and so far only) frame:
(selected-frame) => #<x-frame "emacs" 0xf21>
Now I add an instantiator for that frame:
(set-specifier my-frame-local-var t (selected-frame))
my-frame-local-var =>
#<generic-specifier global=(#<x-frame "emacs" 0xf21> . t) 0x19df>
What's going on here? The default of nil has disappeared! Well, that
must mean that I did something wrong, but darned if I know what. I'll
spawn a second frame now and see what happens. On this frame, I get:
(selected-frame) => #<x-frame "emacs" 0x1a2b>
Let's look up the value of my-frame-local-var in this new frame:
(specifier-instance my-frame-local-var (selected-frame)) =>
(#<x-frame "emacs" 0xf21> . t)
Now I'm lost. I have NO idea why I got a dotted pair when I was
expecting nil. Clearly I've done something wrong, but what? This looks
like what gutter-items.el is doing to me. Furthermore, if I use
set-specifier again to add a value for this new frame, it replaces,
rather than adds to, the setting for the first frame.
I know David Kastrup complained about the opaque specifier
documentation, and I have to agree. I don't think that David, Klaus, or
I are stupid, and we certainly all have a fair to middling amount of
experience with (X)Emacs. Yet we've all had trouble figuring out how to
do something simple and fundamental with specifiers. That says
something very unflattering about the specifier documentation.
--
Jerry James
http://www.ittc.ku.edu/~james/