求助:set-face-attribute和custom-set-faces有何区别?(已解决)

作为颜值党,折腾各种face必可不少。平时都是用set-face-attribute,也没出什么问题,所以没怎么在意set-face-attribute和custom-set-faces的区别。

直到今日折腾(global-hl-line-mode +1)时发现两者有一些区别的。起因为:我使用的bespoke-themes主题定义的region的背景色和global-hl-line-mode的背景色都是一样的,导致make set后的region显示不出来。

下图是主题给region的背景色定义:

于是我就(require 'bespoke-theme)把主题里面的自定义的颜色拿出来用。并且在(use-package bespoke-themes ...)的代码块最后加入set-face-attribute,如图:

写完直接C-x C-e是可以顺利覆盖掉主题定义的region background的,但是也出现了一个问题(问题一):emacs重启后并不能使得set-face-attribute生效,不管是把set-face-attribute放在early-init还是init的开头,都不行,而直接C-x C-e是可以生效的。

我就再尝试用custom-set-faces来配置,发现是可以成功随emacs启动而生效的。问题二:为何custom-set-faces就可以生效呢?因为它的优先级更高,可以覆盖掉主题对region的定义吗?代码如下:

认真对比上面两张截图后发现set-face-attribute的颜色比custom-set-faces的浅一些,这是为何呢?(问题三)明明都是引用了同一个颜色"bespoke-foreground"。

我还是比较喜欢用set-face-attribute,一来没有过多的扩号,二来这样配置后的region颜色没那么深,region后的文字看得清晰一些。希望有大佬解答一下,谢谢! :pray:

发现问题三中颜色不同的原因是custom-set-faces不能load到主题自定义的颜色"bespoke-foreground"(刚开始没留意到error信息),而默认用了比"bespoke-foreground"深色一些的黑色代替。相比之下, set-face-attribute 是可以load到的。这样看来set-face-attribute 更好用一些。

附上主题定义的所有颜色:

执着于引用主题自定义的颜色来覆盖region background的原因是:一、默认下region的颜色与hl-line的相同导致region无法显示是因为主题引起的,想配置region的颜色的时候能够跟主题的配置结合在一起,放 在 (use-package bespoke-themes ...) 代码块里。以后换主题了也不会引起region background颜色error。 二、主题自定义的颜色可以随着系统亮/暗变化而变化,引用了"bespoke-foreground"颜色后也可以让region颜色有动态变化。

现在最重要的是解决 “ set-face-attribute 不能随emacs启动而生效” 这一问题。

随便po上主题的完整配置:第一个when是在macos上主题随系统亮暗变化,第二个when是在windows或linux上主题随日出日落变化,经纬度定位于广州塔,bespoke-theme没有独立的light-theme.el和dark-theme.el,配置不了circadian,暂时用emacs自带的theme代替一下。

这些放在init.el开头都不能随emacs启动而生效,真是奇怪了。

(set-face-background 'region "red")

(set-face-attribute 'region nil :background "red")

(with-eval-after-load 'bespoke-themes
  (set-face-background 'region "red"))

(with-eval-after-load 'bespoke-themes
  (set-face-attribute 'region nil :background "red"))

最后还是用macos系统亮暗的函数来解决……

  (defun autoload-region (appearance)
    (pcase ns-system-appearance
      ('light (set-face-background 'region bespoke-blue))
      ('dark  (set-face-background 'region bespoke-blue))))
  (add-hook 'ns-system-appearance-change-functions 'autoload-region)

但是仍然想不明白set-face-attribute在emacs启动时没生效,而之前给hl-line设置(set-face-attribute hl-line-face nil :inherit 'unspecified :background "gray85")是可以生效的。

也许原因与use-package + theme + macos系统亮暗函数三者之间的内在逻辑有关系吧?