Subject: 23.1; In Emacs 23, face-spec-set amends instead of setting

From: [email-masked]
Date: Fri, 20 Nov 2009 06:28:16 -0800 (PST)

In Emacs 22,

    (face-spec-set 'ido-subdir '((t :inherit dired-directory)))

sets the ido-subdir face.  In Emacs 23, the same form merely amends
the defface spec -- the defface's :foreground "red" property isn't
unset.  This problem has existed for a long time; until recently I was
working around it with filthy kludges of the form

    (put 'ido-subdir 'face-alias 'dired-directory)

Today, I wanted to make w3m-anchor inherit from the 'link face, but to
override :underline.  So I tried this, and rediscovered the problem.

    (face-spec-set 'w3m-anchor '((t :inherit link :underline nil)))

The elisp code below, when loaded by emacs -Q, demonstrates the
problem (by taking snapshots of customize-face's rendering of the face
after each attempt).

I apologize for the ranting below.  By this point, I am sick of trying
to wade through all this new 'theme-foo crap that manages to make the
face subsystem even more obtuse and confusing than it already was.

    ;; Goal: to completely destory upstream's ido-subdir's spec and
    ;; replace it with a simple (t :inherit 'dired-directory).
    ;;
    ;; Load this with emacs -Q -l example.el

    (require 'dired)
    (require 'ido)

    (defun snapshot (description)
      (customize-face 'ido-subdir)
      (search-forward "Attributes: ")
      (kill-ring-save (point-at-bol)
                      (point-max))
      (switch-to-buffer "*scratch*")
      (insert description)
      (insert "\n")
      (yank)
      (insert "\n"))

    (snapshot "Before doing anything")

    (face-spec-set 'ido-subdir '((t :inherit dired-directory)) t)
    (snapshot "face-spec-set with FOR-DEFFACE does nothing.  Just checking...")

    (face-spec-set 'ido-subdir '((t :inherit dired-directory)))
    (snapshot "face-spec-set without FOR-DEFFACE *amends* in Emacs 23,
    whereas in Emacs 22 it used to work as advertised -- it *set* the face!")

    (face-spec-reset-face 'ido-subdir)
    (face-spec-set 'ido-subdir '((t :inherit dired-directory)))
    (snapshot "Does a face-spec-RESET-face work?  No!")

    (custom-set-faces '(ido-subdir ((t :inherit dired-directory))))
    (snapshot "CUSTOM-SET-FACES works (if you comment out the previous
    attempts above), but it's aesthetically ugly to have multiple C-S-F
    calls in my .emacs.  Nor do I want to sort my .emacs configuration by
    the kind of variables I set -- foo face configuration belongs with foo
    variable configuration and foo helper functions.")

    (face-spec-set 'ido-subdir '((t :foreground nil :inherit dired-directory)))
    (snapshot "Yes, I can use :foreground nil, but to do so, I need to
    know that upstream is using :foreground and not something else.  Am I
    expected to use :foo nil for *ALL* properties, in case upstream
    decides to set another property in the next release?!")

In GNU Emacs 23.1.1 (i486-pc-linux-gnu)
 of 2009-09-14 on raven, modified by Debian
configured using `configure  '--build=i486-linux-gnu' '--host=i486-linux-gnu' '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' '--localstatedir=/var/lib' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--with-pop=yes' '--enable-locallisppath=/etc/emacs23:/etc/emacs:/usr/local/share/emacs/23.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/23.1/site-lisp:/usr/share/emacs/site-lisp:/usr/share/emacs/23.1/leim' '--with-x=no' 'build_alias=i486-linux-gnu' 'host_alias=i486-linux-gnu' 'CFLAGS=-DDEBIAN -g -O2' 'LDFLAGS=-g' 'CPPFLAGS=''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: C
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_AU.utf8
  value of $XMODIFIERS: nil
  locale-coding-system: utf-8-unix
  default-enable-multibyte-characters: t

Major mode: rcirc

Minor modes in effect:
  shell-dirtrack-mode: t
  rcirc-low-priority-flag: t
  rcirc-omit-mode: t
  diff-auto-refine-mode: t
  rcirc-track-minor-mode: t
  xterm-mouse-mode: t
  savehist-mode: t
  icomplete-mode: t
  partial-completion-mode: t
  show-paren-mode: t
  delete-selection-mode: t
  use-hard-newlines: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  global-auto-composition-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
t , SPC DEL DEL SPC E V E R SPC g o o DEL DEL DEL b 
e c o m e SPC e DEL t e l e v i s i o n SPC r p DEL 
DEL p r e s e n t e r s RET E v e n SPC o n e s SPC 
w i t h SPC n o SPC f a c i a l SPC ESC b ESC [ 1 ~ 
C-k E v e n SPC t h e SPC w u s s y SPC o n e s SPC 
w i t h SPC n o SPC m o u s t a c h e , SPC l i k e 
SPC M a c C DEL G u y v e r ESC [ 1 ~ C-k C-x ESC O 
D ESC O B ESC O A ESC O A ESC [ 4 ~ ESC O C C-x ESC 
O C ESC x r e p o r t SPC e m a c s SPC b u g RET f 
a c e - s p e c - s e t SPC n o w SPC a m e n d s ESC 
[ 1 ~ C-k TAB C-g C-x ESC O B TAB I SPC n e v e r SPC 
c l a i m e d SPC h e SPC w a s SPC c o o l SPC - - 
SPC j u s t SPC h i s SPC n a m e SPC i s SPC c o o 
l RET C-r j e w i s h RET RET RET C-x ESC O D C-x ESC 
O C ESC x ESC O A RET

Recent messages:
Mark saved where search started [6 times]
Mark set
Mark activated
Quit
Mark set
Mark saved where search started
Mark set [2 times]
Quit [2 times]
windmove-do-window-select: Minibuffer is inactive
Mark saved where search started