38

如何更改 Emacs 用于基于每个模式设置文本样式的默认面?

例如,假设我已经对我拥有的面部自定义感到满意,其中包括默认的固定宽度字体。但是,在一种特定模式下(markdown-mode.el例如),我希望默认字体为可变宽度。

为 markdown 模式设置独特的标题、链接等样式很容易:只需将光标放在样式化的文本和M-x describe-face上,然后单击链接即可对其进行自定义。

但是,如果没有指定其他面,则默认面是使用的面,因此它不是特定于 markdown-mode,如果修改将影响所有其他模式。

markdown-mode-hook使用此模式设置缓冲区的默认面时,我可以使用什么魔法?

4

5 回答 5

34

像这样的东西怎么样:

(add-hook 'markdown-mode-hook (lambda () (variable-pitch-mode t))

然后您可以自定义variable-pitch人脸,缓冲区中的其他人脸将继承此人脸,而不是默认人脸。

阅读文档了解buffer-face-mode更多自定义细节。(BufFace 也用于text-scale-increasetext-scale-decrease...非常有用。)

于 2009-02-11T00:37:47.650 回答
6

我必须给出部分答案,因为这太复杂而无法当场弄清楚,而且我已经超出了我的时间预算。

面是框架属性。一帧可以同时显示多个缓冲区。模式是一个缓冲区属性。您询问如何在每种模式的基础上改变面部。结合所有这些,似乎这个问题不可能没有一个完全正确的答案。

如果您假设给定的帧永远不会显示多个缓冲区,则可以近似得到所需的答案。您实际上可以使用类似这样的方法来完成此操作,但修改为使用特殊显示正则表达式和一组与您的降价模式缓冲区名称匹配的正则表达式。

(append special-display-buffer-names
        '("*VC-log*"
          "*Help*"
          ("*Completions*" 
           (height . 25)
           (font . "8x13"))))

但是,这可能不是您想要的。您的问题似乎暗示改变单个框架的面部属性。

再次假设一帧一次不会显示多个缓冲区,您可以尝试建议切换到缓冲区。但这可能还不够低,而且可能太慢了。(未经测试)

(defadvice switch-to-buffer (after switch-to-buffer activate compile)
  "change the frame's default face after switch-to-buffer"
  (doSomethingToChangePropertiesOfDefaultFace))

现在对于我的实际(不完整)答案......

一种更好但更复杂的方法将指示 markdown-mode 为尚未分配内置面之一的所有区域使用新面。您可以使用 copy-face 创建一个新面孔,并使用 set-face-* 为其赋予有趣的属性。

修改 markdown-mode 的 font-lock-defaults 以覆盖默认的 font-lock-fontify-region-function,如 font-lock.el 的第 946 行附近的注释块中所述,开头为“Fontification functions”。您可能可以使用一个非常轻微修改的 font-lock-default-fontify-region ,它在它之后立即执行一个额外的步骤:

  (unless font-lock-keywords-only
    (font-lock-fontify-syntactically-region beg end loudly))

额外的步骤解析区域类似于 font-lock-fontify-syntactically-region 所做的,将区域分解为“有趣的”子区域。但是这一次您会找到具有默认面的子区域,然后将这些子区域设置为您之前创建的新面。

总而言之,你的 .emacs 文件中应该只有几行 elisp,再加上与原始文件只有微小差异的 font-lock-default-fontify-region 的副本(调用一个新函数),加上复制 font-lock-fontify-syntactically-region 并修改它以进行您的竞标(最困难的部分)。

实际上,如果您“之后”建议 font-lock-fontify-syntactically-region 那么您可能甚至不需要修改 font-lock-defaults 或 font-lock-default-fontify-region。

于 2009-02-11T09:39:42.420 回答
5

variable-pitch-mode 很棒。我通过这个线程发现了它。但它可以变得更棒:

(dolist (hook '(erc-mode-hook
        LaTeX-mode-hook
        org-mode-hook
        edit-server-start-hook
        markdown-mode-hook))
  (add-hook hook (lambda () (variable-pitch-mode t))))

只需将您想要无衬线字体的任何模式添加到列表中即可。

于 2010-09-20T22:34:23.293 回答
4

有一段代码我觉得非常方便,来自 EmacsWiki。这样做的好处是不仅可以设置字体,还可以方便地进行配置:height:width

;; Use variable width font faces in current buffer
(defun my-buffer-face-mode-variable ()
  "Set font to a variable width (proportional) fonts in current buffer"
  (interactive)
  (setq buffer-face-mode-face '(:family "DejaVu Sans" :height 100 :width semi-condensed))
  (buffer-face-mode))
;; Use monospaced font faces in current buffer
(defun my-buffer-face-mode-fixed ()
  "Sets a fixed width (monospace) font in current buffer"
  (interactive)
  (setq buffer-face-mode-face '(:family "Consolas" :height 100))
  (buffer-face-mode))
;; Set default font faces for Info and ERC modes
(add-hook 'erc-mode-hook 'my-buffer-face-mode-variable)
(add-hook 'Info-mode-hook 'my-buffer-face-mode-variable)

结合load-theme-buffer-local包,您甚至可以轻松地为缓冲区指定颜色主题:

(defun my-buffer-face-mode-variable ()
  "Set font to a variable width (proportional) fonts in current buffer"
  (interactive)
  (setq buffer-face-mode-face '(:family "DejaVu Sans" :height 100 :width semi-condensed))
  (buffer-face-mode)
  (load-theme-buffer-local 'leuven (current-buffer)))
于 2015-05-24T06:02:26.297 回答
2

即使对于 emacs 版本 22.3.1,它实际上也很简单......

只需尝试以下操作:

(progn 
  (set-buffer "your buffer name here")
  (overlay-put (make-overlay 0 (buffer-size)) 'face 'your-face))
于 2010-01-13T22:21:51.337 回答