2

The idea is to redefine set-face-attribute so that it sets face attributes normally except for the :weight attribute, which shall always be set to normal (the default value, I think). With this I hope to disable bold fonts in Emacs once and for all.

I got this:

(fset 'original-set-face-attribute (symbol-function 'set-face-attribute))

(defun set-face-attribute (face frame &rest args)
  (progn
    (original-set-face-attribute face frame args)))

So far, it doesn't work. If I do (make-face-bold 'default) I get Wrong type argument: symbolp, (:weight bold). I think what I have to do is remove elements that contain :weight from the list of arguments args.

Drew
  • 29,895
  • 7
  • 74
  • 104
Ernest A
  • 7,526
  • 8
  • 34
  • 40
  • 1
    (1) You can use `defalias` instead of `fset`. (2) Because `ARGS` is a `&rest` parameter, you need to use`apply`: `(apply #'original-set-face-attributes face frame args)`. – Drew Dec 19 '13 at 16:10
  • Personally, although I too hate the effect of `bold` on faces (on MS Windows, at least), I prefer to simply redefine the individual faces. For one thing, there is usually something else I want to change about them, if they use `bold`. – Drew Dec 19 '13 at 16:11
  • @Drew But there are hundreds of faces... – Ernest A Dec 19 '13 at 17:22
  • You're right. In my setup there are well over 300. And I guess I don't bother to remove `bold` from all of them. But then again, some of them I never see. I guess I fix faces to be what I want on an as-needed (and as-seen) basis. – Drew Dec 19 '13 at 18:47
  • Where a bold font wants trumps another font, I set the other one to nil -- `:bold nil`. I do the same for other attributes also. Here is an example: `(make-face 'linum-active) (set-face-attribute 'linum-active nil :foreground "black" :background "#eab700" :bold nil :italic nil :underline nil :box nil :overline nil :height 180)` – lawlist Dec 23 '13 at 02:17

3 Answers3

3

Here's some code to start you off:

(defadvice set-face-attribute
    (before no-bold (face frame &rest args) activate)
  (setq args
        (mapcar (lambda(x) (if (eq x 'bold) 'normal x))
                args)))

I've seen this work for most of the cases, except for basic-faces that don't call set-face-attribute, for instance the error face.

abo-abo
  • 20,038
  • 3
  • 50
  • 71
  • The attributes of the standard faces can be set via X resources, it's the non-standard ones that trouble me. – Ernest A Dec 19 '13 at 13:31
3

Following Aaron's suggestion, here's another solution using face-remap-add-relative.

(defun remap-faces-default-attributes ()
  (let ((family (face-attribute 'default :family))
        (height (face-attribute 'default :height)))
    (mapcar (lambda (face)
              (face-remap-add-relative
               face :family family :weight 'normal :height height))
          (face-list))))

(when (display-graphic-p)
  (add-hook 'minibuffer-setup-hook 'remap-faces-default-attributes)
  (add-hook 'change-major-mode-after-body-hook 'remap-faces-default-attributes))

This one gets rid of bold fonts everywhere and also of variable-width fonts and sets all faces to the same height. Basically it's like running Emacs in a terminal window except with more colours.

Ernest A
  • 7,526
  • 8
  • 34
  • 40
  • If you catch the return value of FACE-REMAP-ADD-RELATIVE, e.g. in a hashtable keyed by `face`, then you can later pass it to FACE-REMAP-REMOVE-RELATIVE to disable the remapping. – Aaron Miller Dec 20 '13 at 01:35
0

Alright! I improved on abo-abo's solution and this is what I've come up with:

(defadvice set-face-attribute
  (before ignore-attributes (face frame &rest args) activate)
  (setq args
        (apply 'nconc
               (mapcar (lambda (i)
                         (let ((attribute (nth i args))
                               (value (nth (1+ i) args)))
                           (if (not (memq attribute
                                          set-face-ignore-attributes))
                               (list attribute value))))
                       (number-sequence 0 (1- (length args)) 2)))))

(setq set-face-ignore-attributes '(:weight :height :box))

It disables :height, :weight and :box attributes (this is configurable via the set-face-ignore-attributes variable) for most fonts. For this to work, it has to go at the very beginning of init.el before the font attributes are set.

Ernest A
  • 7,526
  • 8
  • 34
  • 40