9

Suppose I want the face helm-match to have an unset foreground. Unfortunately, helm-match inherits from match so, if I try to unset the foreground normally:

(set-face-foreground 'helm-match nil)

The inherited foreground becomes active. I'd rather not mess with the match face itself (because I can't tell what ramifications that would have), and I would like to avoid hard coding the other values in helm-match because I use multiple themes.

How can I achieve this sanely?

3
  • Just customize the face (helm-match). That's what face customization is for. Show all the attributes in Customize, and uncheck the inheritance.
    – Drew
    Commented Jan 30, 2016 at 2:04
  • 1
    @Drew I would like to preserve the inheritance of other attributes.
    – PythonNut
    Commented Jan 30, 2016 at 2:18
  • 1
    So leave Inherit checked and check whatever other attributes you want to override any from the inherited face. The point is to use Customize (customize-face).
    – Drew
    Commented Jan 30, 2016 at 2:35

3 Answers 3

0

Use unspecified as value instead.

See also face attributes.

4
  • Nope. unspecified causes the face to inherit the property from the parent.
    – PythonNut
    Commented Jan 30, 2016 at 2:18
  • @PythonNut: yes, from linked page: "An unspecified attribute tells Emacs to refer instead to a parent face", what would you want instead?
    – npostavs
    Commented Jan 30, 2016 at 8:34
  • What about unspecified for the inherit attribute?
    – wasamasa
    Commented Jan 30, 2016 at 13:08
  • 5
    @npostavs I would like the face attribute to be truly unspecified. That is, left to lower priority faces on the same character, for example.
    – PythonNut
    Commented Feb 2, 2016 at 6:22
0

The easiest way is to see how your own Emacs version handles the situation. let's for instance consider changing the Info-quoted face:

  1. Do M-x customize-face press enter, and then type Info-quoted and press enter (note that the I should be capital) to see the attributes.
  2. Do the changes you want. In this case, let the checkmark for "Inherit" be there but delete the value (e.g use the "Del" button)
  3. Press "Apply" button. At this stage you can see the face change applied to all buffers.
  4. Press the "state" button to open the menu
  5. From the menu, click on "Show lisp expression"
  6. Copy the lisp expression and use it in your Emacs config

screenshot of first three steps

screenshot of steps 4 and 5

screenshot of step 6

0

I was trying to achieve the same effect, and based on this email thread, this isn't generally achievable, unfortunately.

I believe the closest we can get to this behavior is manually copying the attributes of the face we want to inherit from instead of actually using :inherit. This allows the face to merge with other faces properly, but doesn't hold up if you change themes.

If you want to change themes, you'd probably have to keep track of which faces you "disinherited," reset them before loading a new theme, and re-disinherit them after loading the theme.

I haven't implemented that last part, but here's a function that copies over the attributes from the parent face before removing the parent:

(defun disinherit-face (face &optional frame)
  "Make FACE non-inherited on FRAME without changing its appearance.

Sets each of the face's unspecified attributes to the the
corresponding value from the face specified in its `:inherit'
attribute, and sets its `:inherit' attribute to nil.

If FRAME is provided, read and set FACE's attributes for that frame.
If FRAME is t, read and set the defaults for face FACE for new frames.
If FRAME is nil, read attributes from the selected frame
and set them for all frames (including the defaults for new frames)."
  (let ((face-attrs (delq :inherit
                          (mapcar 'car face-attribute-name-alist)))
        (args '(:inherit nil)))
    (dolist (attr face-attrs args)
      (push (face-attribute face attr frame t) args)
      (push attr args))
    (apply 'set-face-attribute face frame args)))
;; This code may be used under the GNU General Public License version 3
;; or later, or CC-BY-SA 4.0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.