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

刚刚发帖之后发现好像并不能很好设置,请忽略我刚刚的发帖,现在试了一下是可以的了

设置默认的字体

(set-face-attribute 'default nil :font (font-spec :family "Source Code Pro" :size 14))

单独设置某个字集的字体

(set-fontset-font t 'unicode (font-spec :family "Noto Color Emoji" :size 14))
(set-fontset-font t '(#x2ff0 . #x9ffc) (font-spec :family "Sarasa Mono Slab SC" :size 18 :weight 'bold))

因为unicode包括了emoji和CJK字集的文字还有其它语言的文字,但是emoji比较分散所以只好先将所有的unicode字符都设置成 emoji 字体,然后再针对 cjk 字集 (#x2ff0 . #x9ffc) 设置字体。

8 个赞

效果如下

我是抄的centaur的。各个平台都能兼容

2 个赞

尴尬,刚刚去看了下,好像我的这个设置方法就是 centaur 的设置方法,他的还全平台可用。我还折腾了这么久。。。

请问下,知道Windows 10 上面怎么实现Emacs 显示彩色的Emoji符号,Noto color emoji 没法装在Windows 上。我尝试了一下下面这个字体,但还是黑白效果。

image

Emacs 显示效果:
image

多谢提醒,参考Centaur的字体设置后,emacs-rime的输入流畅了,再也不会卡顿。Windows 用Segoe UI Emoji 这个字体就可以,不需要安装Sybola了 :smile:

doom-emacs 上面设置字体时,“言” 这个字经常没有显示好

Screenshot from 2020-12-27 13-06-31

用describe-char发现它没有使用我们规定它使用的字体。

我找了一下doom-emacs的源代码,发现可能是它的字体设置覆盖了我的字体设置。

但是我又不太想改动doom-emacs的源代码,只好用下策了,再用我的设置覆盖它的设置:

(defun colawithsauce/set-fonts ()
  (interactive)
  (set-face-attribute 'default nil :font (font-spec :family "Iosevka Nerd Font Mono" :size 18))
  (set-fontset-font t 'unicode (font-spec :family "Apple Color Emoji" :size 14) nil 'prepend)
  (set-fontset-font t '(#x2ff0 . #x9ffc) (font-spec :family "Sarasa Mono Slab SC" :size 18) nil 'prepend)
  )
(add-hook! 'window-setup-hook :append 'colawithsauce/set-fonts) ;;言

image

大功告成!

3 个赞

有个问题,请教下各位大佬。

(set-fontset-font t '(#x2ff0 . #x9ffc) (font-spec :family "Sarasa Mono Slab SC" :size 18) nil 'prepend)

上面这条语句中的(#x2ff0 . #x9ffc) 和 Centur 配置中的 (#x4e00 . #x9fff) 有什么区别? 后者在Archlinux 下打中文句号会强制显示为全角,前者工作正常。

ps:参考了 Fontspec for Unicode coverage in Emacs

 (set-fontset-font t '(#x4E00 . #x9FFF) spec) ;; CJK Unified Ideographs

使用下面的这个范围也不正常,看来是因为安装的CJK字体问题:

  (set-fontset-font t '(#x3400 . #x4DBF) spec) ;; CJK Unified Ideographs Extension A

是这样的,我查看 script-representative-chars 这个变量,可以看到下面这一段:

image

我用有道翻译得到最前面这个变量的意思是: image

然后谷歌搜索 ideographic-description characters unicode range 就得到了这 characters 在 unicode 里面的开始编号,就是 #x2ff0,再搜索CJK的结束字符是 #x9ffc,因此得到了这个范围。

多谢。不过通过这种方法设置字体,在Linux下总是没法成功,用你的这个范围,句号是没问题了,但是字体会有变形,逗号也会变成全角。现在还是使用我原来的方法分别设置中英文字体。然后通过你的方法设置emoji,三大平台都好使了。再次表示感谢😄

我目前的字体配置:

(when (eq system-type 'darwin)
  (setq fonts '("SF Mono" "冬青黑体简体中文"))
  (set-fontset-font t 'unicode "Apple Color Emoji" nil 'prepend)
  (set-face-attribute 'default nil :font
                      (format "%s:pixelsize=%d" (car fonts) 16)))

(when (eq system-type 'windows-nt)
  (setq fonts '("Consolas" "微软雅黑"))
  (set-fontset-font t 'unicode "Segoe UI Emoji" nil 'prepend)
  (set-face-attribute 'default nil :font
                      (format "%s:pixelsize=%d" (car fonts) 24)))

(when (eq system-type 'gnu/linux)
  (setq fonts '("SF Mono" "Noto Sans Mono CJK SC"))
  (set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)
  (set-face-attribute 'default nil :font
                      (format "%s:pixelsize=%d" (car fonts) 24)))

(if (display-graphic-p)
    (dolist (charset '(kana han symbol cjk-misc bopomofo))
      (set-fontset-font (frame-parameter nil 'font) charset
                        (font-spec :family (car (cdr fonts))))))
4 个赞

如果是逗号显示有问题可以试试下面这句

(set-fontset-font t 'cjk-misc (font-spec :family "Sarasa Mono Slab SC" :size 18) nil 'prepend)

刚刚又故计重施了一下,发现逗号的编号原来不在(#x2ff0 . #x9ffc)里面,而是在非常后面的地方:

但是注意到它还是包含在了cjk-misc这个script里面(原来这些script都是分散的嘛?),所以直接设定cjk-misc的字体就可以设置好逗号的字体了。

总之,我感觉我分享的不仅仅是几段配置代码,而是一种在字体显示有问题的时候单独针对显示有问题的字符进行设置的方法,即:“哪里不会点哪里”的方法。

1 个赞

刚刚在使用doom-emacs的时候突然发现doom-big-font-mode对中文无效了,试了试手动调字体,也只有英文的字体受到了调控,中文字体的高度不受调节。

看了下doom-emacs的源代码,发现它的字体大小的调节都是依靠它自己的 doom-font 那一套的,只能调doom-font的大小,残念。。。

但是好像有一个hook ,这提醒了我,要是写一个函数根据 doom-font 的大小参数更改其它的字符的大小参数,然后将其加入到这个hook里面去,应该就可以解决这个问题了。

但是现在忙着考试,等我考完再说。

1 个赞

doom这个好像是一个frame一起变?内置的text-scale-increase说是“Adjust the height of the default face”,你试试。另外还有只改一个buffer的buffer-face-set

我用这个方法,设置:family "思源黑体"一部分字不能正常显示,改成:name "-outline-思源黑体 CN-normal-normal-normal-sans-*-*-*-*-p-*-iso10646-1"就可以 :upside_down_face:

发现一个奇怪的现象,我在doom emacs中进行了类似的设置,emacs可以正常显示,但emacsclient就不行,很费解

我使用的代码,英文字体Cascadia Code PL,中文字体Sarasa Gothic SC,是archwsl+X410的组合

;; fix fonts
(defun fix-fonts()
  (interactive)
  ;; Set default font
  (set-face-attribute 'default nil :font (font-spec :family "Cascadia Code PL" :size 16))
  ;; Specify font for Chinese characters
  (set-fontset-font t '(#x4e00 . #x9fff) (font-spec :family "Sarasa Gothic SC" :size 16) nil 'prepend))
(add-hook! 'window-setup-hook :append 'fix-fonts) ;; 言

左侧是emacs,右侧是emacsclient

也许是因为emacsclient只是新建了一个frame,所以没有触发window-setup-hooo

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) ;;言
4 个赞