Hello,
I am a relative lisp novice, but in the course of doing a few things with
XEmacs, I've encountered a lisp hitch I want to understand better (I've
asked on an xemacs group to no avail).
Specifically, consider the following function:
(custom-set-faces &rest ARGS)
This function apparently takes discrete arguments, rather than a list of
arguments (if anyone wants to explain the rationale, that would be fine
also as each parameter is the same thing, a spec entry).
I have a case where I have multiple lists of spec entries defined like
this:
(defconst dark-bg-faces
'( '(font-lock-comment-face ((t (:foreground "pink"))) t)
'(font-lock-constant-face ((t (:foreground "cyan"))) t)))
(defconst light-bg-faces
'( '(font-lock-comment-face ((t (:foreground "firebrick"))) t)
'(font-lock-constant-face ((t (:foreground "ForestGreen"))) t)))
And I would like to do something like this
(custom-set-faces 'light-bg-faces)
Which obviously doesn't work, as custom set faces is supposed to take spec
entries, rather than a list of spec entries. I have several ways to work
around this problem, but it seems to me that there may be a really neat way
of binding each element in the list to unnamed variables using a let
expression, and that may be a very elegant solution to some of the ways I
sometimes change the font entries interactively (rather than having to use
a iterative expression). Is this possible and simple, or impossible/messy?
Thanks for any help,
--
Brad Settlemyer
http://deepcopy.org/
Progamming in the trenches
Brad Settlemyer wrote:
> Specifically, consider the following function:
>
> (custom-set-faces &rest ARGS)
>
> This function apparently takes discrete arguments, rather than a list of
> arguments (if anyone wants to explain the rationale, that would be fine
> also as each parameter is the same thing, a spec entry).
>
> I have a case where I have multiple lists of spec entries defined like
> this:
>
> (defconst dark-bg-faces
> '( '(font-lock-comment-face ((t (:foreground "pink"))) t)
> '(font-lock-constant-face ((t (:foreground "cyan"))) t)))
>
> (defconst light-bg-faces
> '( '(font-lock-comment-face ((t (:foreground "firebrick"))) t)
> '(font-lock-constant-face ((t (:foreground "ForestGreen"))) t)))
>
> And I would like to do something like this
>
> (custom-set-faces 'light-bg-faces)
>
Hmm, I was just catching up on the traffic on the newsgroup, and it appears
that values-list may be the answer, but thus far I haven't been able to get
it to work. Hopefully this question isn't overly redundant, I know that
there are several groups I don't read because of the incessant newby
repetitiveness. Again, thanks for any help.
--
Brad Settlemyer
http://deepcopy.org/
Progamming in the trenches
Brad Settlemyer wrote:
> Hello,
>
> I am a relative lisp novice, but in the course of doing a few things
> with
> XEmacs, I've encountered a lisp hitch I want to understand better (I've
> asked on an xemacs group to no avail).
>
> Specifically, consider the following function:
>
> (custom-set-faces &rest ARGS)
>
I've gotten the answer. ELisp doesn't support the common lisp impl of
values-list (grrr), I had to emulate the functionality using
multiple-value-bind, which isn't quite as neat, but does work. Sorry to
interupt your regularly scheduled entertainment, I had a misplaced quote in
my defined lists that was screwing me up.
--
Brad Settlemyer
http://deepcopy.org/
Progamming in the trenches
Brad Settlemyer <···········@deepcopy.org> writes:
> Brad Settlemyer wrote:
>
> > Hello,
> >
> > I am a relative lisp novice, but in the course of doing a few things
> > with
> > XEmacs, I've encountered a lisp hitch I want to understand better (I've
> > asked on an xemacs group to no avail).
> >
> > Specifically, consider the following function:
> >
> > (custom-set-faces &rest ARGS)
> >
>
> I've gotten the answer. ELisp doesn't support the common lisp impl of
> values-list (grrr), I had to emulate the functionality using
> multiple-value-bind, which isn't quite as neat, but does work. Sorry to
> interupt your regularly scheduled entertainment, I had a misplaced quote in
> my defined lists that was screwing me up.
Hmm, I guess using apply would be even prettier.
(let ((faces-list (list ...)))
(apply #'custom-set-faces faces-list))
Utterly untried and so forth, but...
//Ingvar
--
When in doubt, debug-on-entry the function you least suspect have
anything to do with something.
Brad Settlemyer <···········@deepcopy.org> writes:
> (defconst dark-bg-faces
> '( '(font-lock-comment-face ((t (:foreground "pink"))) t)
> '(font-lock-constant-face ((t (:foreground "cyan"))) t)))
>
> (defconst light-bg-faces
> '( '(font-lock-comment-face ((t (:foreground "firebrick"))) t)
> '(font-lock-constant-face ((t (:foreground "ForestGreen"))) t)))
>
> And I would like to do something like this
>
> (custom-set-faces 'light-bg-faces)
I'll give you a few solutions.
1. You could do it like this:
(eval (cons 'custom-set-faces light-bg-faces))
or
(eval `(custom-set-faces ,@light-bg-faces))
These first compute the list
(custom-set-faces
'(font-lock-comment-face ((t (:foreground "firebrick"))) t)
'(font-lock-constant-face ((t (:foreground "ForestGreen"))) t))
and then evaluate it with the eval function.
2. If you remove the inner quotes, like this:
(defconst light-bg-faces
'((font-lock-comment-face ((t (:foreground "firebrick"))) t)
(font-lock-constant-face ((t (:foreground "ForestGreen"))) t)))
then you can apply the custom-set-faces function to this list of
arguments.
(apply 'custom-set-faces light-bg-faces)
or
(apply #'custom-set-faces light-bg-faces)
In Emacs Lisp, there is no difference between these; but in
Common Lisp, only #' can refer to local functions defined with
FLET or LABELS.
3. You seem to be defining separate sets of face specifications
for dark and light backgrounds, then presumably choosing one set
at runtime. You could instead handle both dark and light
backgrounds in the same specifications:
(custom-set-faces
'(font-lock-comment-face ((((background dark))
(:foreground "pink"))
(((background light))
(:foreground "firebrick"))) t)
'(font-lock-constant-face ((((background dark))
(:foreground "cyan"))
(((background light))
(:foreground "ForestGreen"))) t))
This has the advantage that you can keep editing the faces with
customize-face.
4.
> there may be a really neat way of binding each element in the
> list to unnamed variables using a let expression
You can't have unnamed variables. Gensyms are the closest you
can get. You would have to construct the let expression at
runtime and then evaluate it with eval.
(eval
(let* ((bindings (mapcar #'(lambda (spec)
(list (gensym) spec))
light-bg-faces))
(gensyms (mapcar #'car bindings)))
`(let ,bindings
(custom-set-faces ,@gensyms))))
See my solution 1 for a simpler way of using eval.