经验分享:emacs单独设置中文与英语的字体

emacsclient 使用的是你的终端的字体,而不是你在emacs里面设置的字体,比如我终端使用的就是Sarasa Mono Slab SC所以显示的是正常的。如图

image

注意下面的display一栏写的是terminal code,意思是使用的是终端的字体来显示,所以说你改一下终端的字体就好了。。。

呃,这个我还真的不知道是什么原因。两种设置方法对显示效果不同的字使用describe-char有什么信息区别吗?

看了下doom的源码,好像可以通过设置doom-unicode-font来实现中文的显示,效果看起来也还好,直接用这个是不是更方便一些?

另外,emacsclient下,我describe-char查看到的信息是

display: by this font (glyph code)
ftcrhb:-unknown-file-icons-normal-normal-normal-*-16-*-*-*-*-0-iso10646-1 (#x68)

似乎不是由终端定义的?

对,你提醒了我。

我一开始的需求是设置emoji的字体,而当时我使用的中文字体sarasa-gothic是没有emoji的,并且当时不知道怎么单独为emoji设置字体,就用doom-unicode-font来设置emoji的字体了。

现在知道怎么单独设置emoji的字体了,根据我的观察,emoji一般都在symbol这个script里面。因此这样就好了:

(set-fontset-font "fontset-default" 'symbol (font-spec :family "Apple Color Emoji" :size 14)nil 'prepend)

这样就是先将所有unicode字符没有设置过字体的的设置成Sarasa Mono Slab SC,而不用苦苦去找CJK的字集范围来设置,再将其中的emoji字符的字体设置成Apple Color Emoji

但是这样仍然有问题,就是缩放的时候,emoji的字体大小仍然保持在14,这个问题之前我已经提及过:

对于这个问题,我发现只要在设置字体的时候不设置:size属性,就可以解决这个问题,反之,如果加上,就会出现调节不了中文字体大小的问题,比如下面这个设置:

(setq doom-font (font-spec :family "Iosevka Nerd Font Mono" :size 18)
      ;; 下面三行去掉了 :size 18 
      doom-serif-font (font-spec :family "Sarasa Mono Slab SC")
      doom-variable-pitch-font (font-spec :family "Iosevka Nerd Font Mono")
      doom-unicode-font (font-spec :family "Sarasa Mono Slab SC")
      doom-big-font (font-spec :family "Sarasa Mono Slab SC" :size 24))

所以前面的设置得改成下面这样

(set-fontset-font "fontset-default" 'symbol (font-spec :family "Apple Color Emoji") nil 'prepend)

这样的问题是没有办法对齐了,之前的中文字体是18,而emoji字体14是刚好对齐的,刚好一个中文字符的宽度和一个emoji符号的宽度相等,而现在emoji也是18了,必然导致对不齐了。这个问题我也没有办法解决,毕竟鱼与熊掌不可兼得。。。

总结

现在我的字体设置如下:

(setq doom-font (font-spec :family "Iosevka Nerd Font Mono" :size 18)
      doom-serif-font (font-spec :family "Sarasa Mono Slab SC")
      doom-variable-pitch-font (font-spec :family "Iosevka Nerd Font Mono")
      doom-unicode-font (font-spec :family "Sarasa Mono Slab SC")
      doom-big-font (font-spec :family "Sarasa Mono Slab SC" :size 24))
(defun colawithsauce/set-fonts ()
  (interactive)
  (set-fontset-font "fontset-default" 'symbol (font-spec :family "Apple Color Emoji" :size 14)nil 'prepend)
(add-hook! 'window-setup-hook :append 'colawithsauce/set-fonts) ;;言
3 个赞

今天更新了一下doom,发现言字的字体又出现了问题,看起来是doom的更新导致的。

目前暂时的解决方法还是只能借鉴Centaur的方法,手动设置一下中文unicode段的字体了。

应该是这个commit的问题

本来的函数的执行结果如下

更改后的执行结果如下

可以发现我们设置的 doom-unicode-font 被排到了 doom-unicode-extra-fonts 的前面了,这样就导致下面那句语句执行的时候我们设置的这个unicode字体反而在'unicode 这个script里面的顺序被排到了后面。

image

这样应该是为了修复all-the-icons图标被用户设置的 unicode 字体覆盖的问题。但是all-the-icons里面的“file”这个图标字体又有“言”这个字的残体,查找顺序又在这次commit之后变成了先查找all-the-icons里面的字体。。。所以就会导致言这个字被覆盖。

但是既然之前没有出过因为我们的sarasa字体覆盖了all-the-icons的字体的内容导致一些all-the-icons的图标显示不了的问题,那么可能以后都不会出这样的问题吧。所以我的解决方法如下:

(setq doom-font (font-spec :family "Iosevka" :size 20)
      doom-serif-font (font-spec :family "Noto Serif CJK SC")
      doom-variable-pitch-font (font-spec :family "Comic Neue":weight 'extra-bold)
      ;; doom-unicode-font (font-spec :family "Sarasa Fixed Slab SC")
      doom-big-font (font-spec :family "Sarasa Mono Slab SC" :size 23))
(defun colawithsauce/set-fonts ()
  (set-fontset-font "fontset-default" 'unicode (font-spec :family "Sarasa Fixed Slab SC") nil 'prepend)
  (set-fontset-font "fontset-default" 'symbol (font-spec :family "Apple Color Emoji") nil 'prepend))
(add-hook! 'after-setting-font-hook :append 'colawithsauce/set-fonts) ;;言

解决之后的fontset-default字体长这样

image

happy emacsing! :smiley:

5 个赞

有什么修改意见可以去 Discord 上面跟作者提。我前几天也发现这个问题了,当时更新之后我设置的 doom-unicode-font 都不起作用了。我建议了这个 commit 之后中文字体才恢复。不过我的“言”字显示也不对。后来干脆把 file-icon 这个字体删了。

我又来更新了,昨天晚上发现如果用daemon启动的话,字体设置会不生效,当打开一个frame的时候字体会变成1px那么小,我一开始只能出下策:用display-graphic-p检测是否是用gui启动的emacs,如是则启用字体设置,否则就不启用。

但是昨天晚上觉得这样不爽,就折腾了下,发现这个问题是fontset在gui与daemon的启动情况下不同导致的,在gui下面使用的是fontset-default,而daemon启动下,M-x describe-fontset C-M-j得到的fontsetfontset-auto2,折腾了几个小时(真的浪费生命)无果,然后用了一个笨方法:每次打开frame的时候都重新设置字体。

恰好,最近我也更改了我的默认字体的设置方法:通过设置default这个face的字体,也一并分享了

综上,我的配置如下:

;; all the icons.
(defun colawithsauce/all-the-icons-enable ()
  (interactive)
  (all-the-icons-ibuffer-mode +1)
  (all-the-icons-dired-mode +1)
  (all-the-icons-ivy-rich-mode +1)
  )
(defun colawithsauce/all-the-icons-disable ()
  (interactive)
  (all-the-icons-ibuffer-mode -1)
  (all-the-icons-dired-mode -1)
  (all-the-icons-ivy-rich-mode -1)
  )
(if (display-graphic-p)
    (colawithsauce/all-the-icons-enable)
  (colawithsauce/all-the-icons-disable))

(doom-modeline-mode)

;; setting fonts
(use-package faces
  :custom-face
  (variable-pitch
   ((t (:font ,(font-xlfd-name (font-spec :family "WenQuanYi Micro Hei"
                                          :foundry "Outline"
                                          ;; If we do not specify this, Emacs
                                          ;; selects ascii and we miss accents
                                          :registry "iso10646-1"))
              :slant normal :weight normal
              :height 138 :width normal))))
  (default
    ((t (:font ,(font-xlfd-name (font-spec :family "Comic Mono"
                                           :foundry "Outline"
                                           ;; If we do not specify this, Emacs
                                           ;; selects ascii and we miss accents
                                           :registry "iso10646-1"))
               :slant normal :weight normal
               :height 138 :width normal))))
  (fixed-pitch
   ((t (:inherit default))))

  :config
  (defun colawithsauce/set-unicode-fonts (frame)
    "Setting unicode-char fonts for emacs."
    ;; Use Noto for everything to get consistent view
    ;; Chinese, simplified
    (set-fontset-font t 'unicode "Sarasa Mono Slab SC" frame)
    ;; Symbols, including b/w emoji
    (set-fontset-font t 'symbol "Apple Color Emoji" frame 'prepend))
  (add-hook 'after-make-frame-functions #'colawithsauce/set-unicode-fonts))

1 个赞

我又更新了,因为看到rescale这个方法

;; setting fonts
(use-package faces
  :custom-face
  (variable-pitch
   ((t (:font ,(font-xlfd-name (font-spec :family "Iosevka"
                                          :foundry "Outline"
                                          ;; If we do not specify this, Emacs
                                          ;; selects ascii and we miss accents
                                          :registry "iso10646-1"))
              :slant normal :weight normal
              :height 138 :width normal))))
  (default
    ((t (:font ,(font-xlfd-name (font-spec :family "Comic Mono"
                                           :foundry "Outline"
                                           ;; If we do not specify this, Emacs
                                           ;; selects ascii and we miss accents
                                           :registry "iso10646-1"))
               :slant normal :weight normal
               :height 138 :width normal))))
  (fixed-pitch
   ((t (:inherit default))))

  :config
  (defun colawithsauce/set-unicode-fonts (frame)
    "Setting unicode-char fonts for emacs."
    ;; Use Noto for everything to get consistent view
    ;; Chinese, simplified
    (set-fontset-font t 'unicode (font-spec :family "Sarasa Mono Slab SC" :weight 'semi-bold) frame)
    ;; Symbols, including b/w emoji
    (set-fontset-font t 'symbol "Apple Color Emoji" frame 'prepend))
  (add-hook 'after-make-frame-functions #'colawithsauce/set-unicode-fonts)

  ;; Rescale to restrict font into same height.
  (add-to-list 'face-font-rescale-alist '("Apple Color Emoji" . 0.9))
  (add-to-list 'face-font-rescale-alist '("Sarasa Mono Slab SC" . 0.88))

  ;; Disable font rescale in variable-pitch mode
  (defun colawithsauce/disable-rescale-maybe ()
    "remove stuffs in `face-font-scale-alist' when in buffer-face-mode."
    (if buffer-face-mode
        (setq-local face-font-rescale-alist nil)
      (setq-local face-font-rescale-alist '(("Sarasa Mono Slab SC" . 0.88) ("Apple Color Emoji" . 0.9) ("-cdac$" . 1.3)))))
  (add-hook
   'buffer-face-mode-hook #'colawithsauce/disable-rescale-maybe))

然后打开了 variable-pitch 之后,关掉 rescale 的效果,可以见到 rescale 消失了,字体变大了

(P.S. 日语是因为我这段是抄了别人的配置)

1 个赞

可以设置成在org-mode与不在org-mode里的中文使用不同的字体吗?不在org-mode里设了set-fontset-font以后,org-mode里也会生效。

我现在已经放弃配置不同的字体了,转而只使用更纱黑体,因为感觉无论怎么设置总是能够发现有不完美的地方,但是使用更纱黑体却能够处处都很合理。。。

1 个赞

这是正常。。。。 折腾字体说实话挺没劲的。

1 个赞

时间宝贵,不要浪费时间在折腾字体上面

3 个赞

可惜的是除了更纱,没别个能选的。。

你的更纱黑体,看网页正常吗?我用更纱黑体看elfeed,正文好多乱码,但是其他地方都正常,十分奇怪;

正常的啊?你在论坛开一个新的帖子把截图什么的发出来看看?

Emacs 里面乱码和字体一般没有关系,只有显示不出来/显示的是方块才可能是字体的问题

忘了在哪儿抄的作业了,可能是centaur,然后自己改了一下:

(defun font-installed-p (font-name)
  "Check if font with FONT-NAME is available."
  (find-font (font-spec :name font-name)))
(when (display-graphic-p)
  (cl-loop for font in '("Cascadia Code" "SF Mono" "Source Code Pro"
                         "Fira Code" "Menlo" "Monaco" "Dejavu Sans Mono"
                         "Lucida Console" "Consolas" "SAS Monospace")
           when (font-installed-p font)
           return (set-face-attribute
                   'default nil
                   :font (font-spec :family font
                                    :weight 'normal
                                    :slant 'normal
                                    :size (cond ((eq system-type 'gnu/linux) 14.0)
                                                ((eq system-type 'windows-nt) 12.5)))))
  (cl-loop for font in '("OpenSansEmoji" "Noto Color Emoji" "Segoe UI Emoji"
                         "EmojiOne Color" "Apple Color Emoji" "Symbola" "Symbol")
           when (font-installed-p font)
           return (set-fontset-font t 'unicode
                                    (font-spec :family font
                                               :size (cond ((eq system-type 'gnu/linux) 16.5)
                                                           ((eq system-type 'windows-nt) 15.0)))
                                    nil 'prepend))
  (cl-loop for font in '("思源黑体 CN" "思源宋体 CN" "微软雅黑 CN"
                         "Source Han Sans CN" "Source Han Serif CN"
                         "WenQuanYi Micro Hei" "文泉驿等宽微米黑"
                         "Microsoft Yahei UI" "Microsoft Yahei")
           when (font-installed-p font)
           return (set-fontset-font t '(#x4e00 . #x9fff)
                                    (font-spec :name font
                                               :weight 'normal
                                               :slant 'normal
                                               :size (cond ((eq system-type 'gnu/linux) 16.5)
                                                           ((eq system-type 'windows-nt) 15.0)))))
  (cl-loop for font in '("HanaMinB" "SimSun-ExtB")
           when (font-installed-p font)
           return (set-fontset-font t '(#x20000 . #x2A6DF)
                                    (font-spec :name font
                                               :weight 'normal
                                               :slant 'normal
                                               :size (cond ((eq system-type 'gnu/linux) 16.5)
                                                           ((eq system-type 'windows-nt) 15.0))))))
1 个赞

和我的好像啊

https://emacs.nasy.moe/#Font

10 个赞

这是我见过的最叼的 emacs 配置了,真的。

1 个赞