Doom Emacs设置字体时org bullet显示不对

这段时间在折腾doom emacs的中文字体和英文字体设置。参考了论坛里很多帖子。遇到很奇怪的问题,如下:

论坛上主流的中文字体设置方式

(defun +my/better-font()
(interactive)
;; english font
(if (display-graphic-p)
    (progn
      (set-face-attribute 'default nil :font (font-spec :family "Monaco" :size 13))
      (set-fontset-font t 'unicode (font-spec :family "Monaco Nerd Font Mono") nil 'prepend)
      (dolist (charset '(kana han symbol cjk-misc bopomofo))
        (set-fontset-font (frame-parameter nil 'font)
                          charset
                          (font-spec :family "STHeiti" :size 15)))) ;; 14 16 20 22 28
  ))

(defun +my|init-font(frame)
(with-selected-frame frame
  (if (display-graphic-p)
      (+my/better-font))))

(if (and (fboundp 'daemonp) (daemonp))
  (add-hook 'after-make-frame-functions #'+my|init-font)
 (+my/better-font))
(add-hook 'doom-init-ui-hook #'+my/better-font)

在这种设置下,中文字体和unicode字符正常显示,但是org mode出现了奇怪的现象:

第二层的bullet变得巨大无比。经测试,有些字体会出现这样的情况,比如Monaco, InconsolataGo,有些则不会,比如Fira Code.

有遇到类似问题的么?

试试这个方法,看看管用不?

这个东西应该取决于字体,你可以对单独的字符指定字体,可能你那里不一定是这四个字符

(dolist (character '(?\x25C9 ?\x25CB ?\x2738 ?\x273F))
  (set-fontset-font nil character "DejaVu Sans"))

我用describe-char查一下图里第二层那个巨大的圆圈,得到的结果是这样的:

             position: 43045 of 43768 (98%), column: 1
            character: * (displayed as *) (codepoint 42, #o52, #x2a)
              charset: ascii (ASCII (ISO646 IRV))
code point in charset: 0x2A
               script: latin
               syntax: _ 	which means: symbol
             category: .:Base, a:ASCII, l:Latin, r:Roman
             to input: type "C-x 8 RET 2a" or "C-x 8 RET ASTERISK"
          buffer code: #x2A
            file code: #x2A (encoded by coding system utf-8-unix)
              display: composed to form "*" (see below)

Composed by the rule:
	(?○)
The component character(s) are displayed by these fonts (glyph codes):
 ○: mac-ct:-*-STHeiti-normal-normal-normal-*-15-*-*-*-p-0-iso10646-1 (#x1BF0)
See the variable ‘reference-point-alist’ for the meaning of the rule.

Character code properties: customize what to show
  name: ASTERISK
  general-category: Po (Punctuation, Other)
  decomposition: (42) ('*')

There is an overlay here:
 From 43045 to 43046
  face                 region
  priority             (nil . 100)
  window               #<window 13 on main.org>


There are text properties here:
  composition          [Show]
  face                 (org-superstar-header-bullet org-level-2)
  fontified            t
  line-prefix          [Show]
  org-category         "main"
  wrap-prefix          [Show]

我不清楚这里为什么会是STHeiti。。。 如果按照你建议的策略去尝试的话,我这个字符对应的code应该是这里输出的哪一个?是#x1BF0嘛?

我解决了,谢谢提醒。看了你的回复之后,我想起了用describe-char查查输出(见楼上),然后发现这个字体是STHeiti。这是因为源代码里设置中文字体那块把symbol也加进中文字体的设置里去了。我把那个symbol去掉就好了。

如果你没有自己设置的话,对应字符编码应该就是我那个

Composed by the rule:
	(?◉) 

我试过,你可以在这个位置的字符,再 describe-char 就可以拿到了

有一些字体对应的这几个字符显示效果不好,所以你也可以特殊指定一下这几个字符的字体

很有道理。

我刚才还在想,既然之前论坛流传的那个中文字体设置方式把symbol设置到了中文里面,那一定有道理。与其把symbol从charset list里删掉,不如针对一下你提议的那几个字符。

现在我的代码是这样:

(defun +my/better-font()
  (interactive)
  (if (display-graphic-p)
      (progn
        ;; English font
        (set-face-attribute 'default nil :font (font-spec :family "MonacoB" :size 13))
        ;; Unicode font
        (set-fontset-font t 'unicode (font-spec :family "Monaco Nerd Font Mono") nil 'prepend)
        ;; Chinese font
        (dolist (charset '(kana han symbol cjk-misc bopomofo))
          (set-fontset-font (frame-parameter nil 'font)
                            charset
                            (font-spec :family "STHeiti" :size 15)))
        ;; Solve the org bullet problem
        (dolist (charset '(?\x25cb))
          (set-fontset-font nil charset (font-spec :family "MonacoB" :size 13)))) ;; 14 16 20 22 28
))

(defun +my|init-font(frame)
  (with-selected-frame frame
    (if (display-graphic-p)
        (+my/better-font))))

(if (and (fboundp 'daemonp) (daemonp))
  (add-hook 'after-make-frame-functions #'+my|init-font)
 (+my/better-font))

圆圈正常显示。但奇怪的是,我去圆圈那里重新describe-char,他告诉我字体是DejaVu Sans Mono. 而我明明设置的是Monaco. (Monaco并不是导致圆圈放大的原因。中文字体才是。之前那里显示的是中文字体。)

现在的输出如下:

             position: 11940 of 43768 (27%), column: 1
            character: * (displayed as *) (codepoint 42, #o52, #x2a)
              charset: ascii (ASCII (ISO646 IRV))
code point in charset: 0x2A
               script: latin
               syntax: _ 	which means: symbol
             category: .:Base, a:ASCII, l:Latin, r:Roman
             to input: type "C-x 8 RET 2a" or "C-x 8 RET ASTERISK"
          buffer code: #x2A
            file code: #x2A (encoded by coding system utf-8-unix)
              display: composed to form "*" (see below)

Composed by the rule:
	(?○)
The component character(s) are displayed by these fonts (glyph codes):
 ○: mac-ct:-*-DejaVu Sans Mono-bold-normal-normal-*-13-*-*-*-m-0-iso10646-1 (#xA22)
See the variable ‘reference-point-alist’ for the meaning of the rule.

Character code properties: customize what to show
  name: ASTERISK
  general-category: Po (Punctuation, Other)
  decomposition: (42) ('*')

There is an overlay here:
 From 11940 to 11941
  face                 region
  priority             (nil . 100)
  window               #<window 3 on main.org>


There are text properties here:
  composition          [Show]
  face                 (org-superstar-header-bullet org-level-2)
  fontified            t
  line-prefix          [Show]
  wrap-prefix          [Show]

[back]

不影响最终效果就是了,只不过如果这里describe的结果不对,那对代码的理解还是有问题。还是想理解一下。

你的字符应该是 ?\x25cb,所以没有设置对

展示成 DejaVu Sans Mono 应该是因为你的配置里面没有覆盖到它,然后会默认使用 monospace ,我刚刚再arch下试 monospace 对应的就是 DejaVu Sans Mono

但是我看了你的配置没想明白为啥没覆盖到这个字符

我自己设置的就是?\x25cb啊,不知道为什么没有覆盖。而且既然我把symbol放在了中文字体那里,如果这里没有覆盖,按照之前配置的结果,他应该是显示中文字体才对啊。

看错了,你的设置应该是对的,我也不清楚什么原因