我做什么

我做什么

\newcommand我的编辑器(Aquamacs/AucTeX)中的语法高亮如下所示:

在此处输入图片描述

我不喜欢它,因为定义中的所有内容都具有相同的浅蓝色。相比之下,如果我改用\def,我会得到以下突出显示,我更喜欢这样。

在此处输入图片描述

根据AucTeX 手册,§3.1.1,AucTeX在变量中保存了一个“功能”关键字列表。font-latex-match-function-keywords它目前包含:begin,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,end。​​​​​​​​​​​​​​​​pagenumberingthispagestylepagestylenofilesincludeonlybibliographystyledocumentstyledocumentclassnewcommandnewenvironmentnewlengthnewtheoremnewcounterrenewenvironmentrenewcommandrenewtheoremusepackagefboxmboxsboxvspacehspacethinspacenegthinspaceenspaceenskipquadqquadnonumbercenteringTeXLaTeX

我想从该列表中删除所有那些倾向于使用长参数的命令,即:newenvironmentrenewenvironmentnewcommandrenewcommandfbox和。我可以在我的文件中mbox放入sbox哪些 LISP 指令.emacs来执行此操作?

答案1

解决方案是使用您想要的内容覆盖内置的字体。您可以使用该font-latex-add-keywords函数来实现。有关参数规范的更多信息,请参阅宏的字体化在里面AUCTeX 手册

要更改您提到的宏的字体,您可以将其添加到.emacs

(defun my-font-latex-add-custom-keywords ()
  (eval-after-load "font-latex"
    '(font-latex-add-keywords '(("newenvironment" "*{[[")
                                ("renewenvironment" "*{[[")
                                ("newcommand" "*|{\\[[")
                                ("renewcommand" "*|{\\[[")
                                ("providecommand" "*|{\\[[")
                                ("fbox" "")
                                ("mbox" "")
                                ("sbox" ""))
                              'function)))

(add-hook 'LaTeX-mode-hook 'my-font-latex-add-custom-keywords)

答案2

您可以自定义字体锁定功能名称界面(font-lock-function-name-face):

  • M-x customize-face
  • 选择font-lock-function-name-face
  • 取消选中Foreground
  • 按下Save for future sessions按钮

答案3

为了摆脱这种字体烦恼,我的设置始于giordano 的回答但随着我发现问题,它已经发生了一些变化。

我做什么

(require 'tex-site)   ; Load AUCTeX

(defun my-font-latex-remove-unwanted-fontification-keywords ()
  (dolist (command '("newenvironment"
                     "renewenvironment"
                     "newcommand"
                     "renewcommand"
                     "providecommand"
                     "fbox"
                     "mbox"
                     "sbox"))
    (setq-default font-latex-match-function-keywords-local
                  (remove (assoc-string
                           command font-latex-match-function-keywords-local)
                          font-latex-match-function-keywords-local))))

(eval-after-load "font-latex"
  '(my-font-latex-remove-unwanted-fontification-keywords))

(defun my-font-latex-add-custom-keywords ()
  ;; Add our fontification specs for these keywords
  (font-latex-add-keywords '(("newenvironment" "*{[[")
                             ("renewenvironment" "*{[[")
                             ("newcommand" "*|{\\[[")
                             ("renewcommand" "*|{\\[[")
                             ("providecommand" "*|{\\[[")
                             ("fbox" "")
                             ("mbox" "")
                             ("sbox" ""))
                           'function))

(defun my-LaTeX-mode-hook ()
  (message "Loading <insert your name here>'s LaTeX mode hook")
  ;; Use font-latex.el for fontification
  (require 'font-latex)
  (my-font-latex-add-custom-keywords))

(add-hook 'LaTeX-mode-hook #'my-LaTeX-mode-hook)
  • ~/.emacs.d/auctex/style/xparse.el
;; File created by <your name here>. Loaded after, and overrides part of the
;; settings done by xparse.el from the AUCTeX installation.

(TeX-add-style-hook
 "xparse"
 (lambda ()
   (when (and (featurep 'font-latex)
          (eq TeX-install-font-lock 'font-latex-setup))
     (message "Adding <your name here>'s own keywords for `font-latex' (%s)"
              "xparse style file")
     (font-latex-add-keywords
              '(("DeclareDocumentCommand" "|{\\")
                ("NewDocumentCommand" "|{\\")
                ("RenewDocumentCommand" "|{\\")
                ("ProvideDocumentCommand" "|{\\")
                ("DeclareExpandableDocumentCommand" "|{\\")
                ("NewExpandableDocumentCommand" "|{\\")
                ("RenewExpandableDocumentCommand" "|{\\")
                ("ProvideExpandableDocumentCommand" "|{\\")
                ("DeclareDocumentEnvironment" "{")
                ("NewDocumentEnvironment" "{")
                ("RenewDocumentEnvironment" "{")
                ("ProvideDocumentEnvironment" "{"))
                  'function)))
 LaTeX-dialect)

解释

删除我们想要重新定义的内置关键字

让我们从第一步开始:

(defun my-font-latex-remove-unwanted-fontification-keywords ()
  (dolist (command '("newenvironment"
                     "renewenvironment"
                     "newcommand"
                     "renewcommand"
                     "providecommand"
                     "fbox"
                     "mbox"
                     "sbox"))
    (setq-default font-latex-match-function-keywords-local
                  (remove (assoc-string
                           command font-latex-match-function-keywords-local)
                          font-latex-match-function-keywords-local))))

(eval-after-load "font-latex"
  '(my-font-latex-remove-unwanted-fontification-keywords))

改编自AUCTeX 手册中的建议严格来说,除非我遗漏了什么,否则这部分只是在某些AUCTeX 样式文件会产生重新声明相关关键字( 、 等)的奇怪想法\newcommand\renewcommand事实上,这样的样式文件运行 LaTeX-mode-hook,因此可以覆盖我们通过font-latex-add-keywords此钩子执行的任何操作。除了这个原因之外,这样做会从 的默认值中清除 (关键字,语法) 对font-latex-match-function-keywords-local,这样当我稍后使用我喜欢的语法规范重新添加相同的关键字时(见下文),它们只会发生一次在 的结果值中font-latex-match-function-keywords-local。请注意:

  • 因为最终,此代码仅执行setq-default调用,所以不需要从运行LaTeX-mode-hook;因此,我们通过这种方式节省了一些时间。

  • 我使用assoc-string而不是TeX-assoc-string(在线 AUCTeX 手册中仍然提到,但已在 AUCTeX 存储库中修复),因为后者已于 2017 年从 AUCTeX 中删除(提交 d3d321a8d2)。

  • 正如 AUCTeX 手册中提到的,由于它以某种方式摆弄了font-latex内部结构,因此这段代码不能保证继续工作照原样在 的未来版本中font-latex

  • 我对\fbox\mbox\sbox等应用了相同的字体化更改,因为在我看来,这些框命令的参数字体化并不比和朋友更可取。\newcommand\renewcommand\newcommand

重新定义已删除的内置关键字的字体规范

第二位与giordano 的回答

(defun my-font-latex-add-custom-keywords ()
  ;; Add our fontification specs for these keywords
  (font-latex-add-keywords '(("newenvironment" "*{[[")
                             ("renewenvironment" "*{[[")
                             ("newcommand" "*|{\\[[")
                             ("renewcommand" "*|{\\[[")
                             ("providecommand" "*|{\\[[")
                             ("fbox" "")
                             ("mbox" "")
                             ("sbox" ""))
                           'function))

(defun my-LaTeX-mode-hook ()
  (message "Loading <insert your name here>'s LaTeX mode hook")
  ;; Use font-latex.el for fontification
  (require 'font-latex)
  (my-font-latex-add-custom-keywords))

(add-hook 'LaTeX-mode-hook #'my-LaTeX-mode-hook)

这会重新添加我们刚刚删除的关键字,但使用我喜欢的语法:不要对宏和环境的替换文本使用特殊颜色(有关语法的解释见下文"*|{\\[[")。

注意:由于my-font-latex-add-custom-keywords调用font-latex-add-keywords,在此特定情况下,会自动修改缓冲区局部变量font-latex-match-function-keywords-local,因此my-font-latex-add-custom-keywords必须从font-latex处于活动状态的缓冲区(LaTeX 模式下的缓冲区)运行。这就是为什么我从LaTeX-mode-hook而不是使用 来调用此函数的原因(eval-after-load "font-latex" ...)。事实上,后者可以...(load "font-latex")执行的任何缓冲区重新运行,甚至在同一个 Emacs 会话中多次运行——这会在错误的缓冲区中设置缓冲区局部变量。

覆盖来自 AUCTeX 样式文件的不良字体规范

这是最后一步,我们创建文件~/.emacs.d/auctex/style/xparse.el(其内容见上文)。此文件负责处理由解析例如\NewDocumentCommand\NewDocumentEnvironment等等。对于这些,上面描述的技术不起作用,因为相应的font-latex关键字不是的一部分font-latex-built-in-keyword-classes;而是由AUCTeX 样式文件,即xparse.el当前 AUCTeX 安装的一部分文件。仅当您的文档使用该包时,才会激活此特定样式文件,并且运行xparse它定义的钩子(添加为)TeX-add-style-hook LaTeX-mode-hook。因此,调用font-latex-add-keywordsLaTeX-mode-hook覆盖 AUCTeXxparse.el文件中声明的 LaTeX 命令的语法规范不起作用,因为 AUCTeX 样式文件中定义的钩子会运行 LaTeX-mode-hook

幸运的是,有一个简单的解决办法:如上所示,我们所要做的就是创建我们自己的样式文件(如上所示)并将其放入~/.emacs.d/auctex/style/,因为它是一个手写的 AUCTeX 样式文件(与用于~/.emacs.d/auctex/auto/自动生成的样式文件1的相反)。

注意:我的样式文件xparse包含如下行:

("NewDocumentEnvironment" "{")

第二个字符串的语法解释在 AUCTeX 手册中。在本例中,它告诉 AUCTeX 只给 的第一个括号分隔参数赋予特殊颜色\NewDocumentEnvironment。这样,视觉注意力就只集中在\NewDocumentEnvironment和环境名称上,这样我就得到了这样的结果:

字体效果良好的屏幕截图

如果我改用这个规范:

("NewDocumentEnvironment" "{{")

第二个参数将被着色,如下所示:

字体效果不佳(过多)的屏幕截图

没什么大不了的,但我相信这更令人分心而不是有帮助(当我浏览 LaTeX 代码时,我想快速查看哪个命令或环境从哪里开始;它的参数的数量和类型不需要突出)。

最后,让我们解释一下字体化规范\newcommand。如果你这样做,C-h v font-latex-built-in-keyword-classes你应该会看到这样的一行:

("newcommand" "*|{\\[[{")

这意味着,在此处使用的 AUCTeX 版本中,默认\newcommand声明具有以下属性:

  • 它的特点是星号形式(*);
  • 第一个参数是 ( |) 括号分隔的 ( {) 或控制序列标记 ( \,必须\\按照 Emacs Lisp 字符串的形式书写,读取字符串的语法定义在GNU Emacs Lisp 参考手册(英文):
  • 以下两个参数用括号 ( ) 分隔[,与 LaTeX 中的可选参数一样;
  • 最后一个参数由括号 ( ) 分隔{:这是宏替换文本,如果全部显示为同一种颜色,尤其是那种让人难以集中注意力的颜色,那就太讨厌了。因此,通过将其替换为:
("newcommand" "*|{\\[[")

我们抑制宏替换文本的特殊字体化,并通过使用

("newcommand" "*|{\\")

我们甚至会抑制两个可选参数的特殊字体(但是,它们不会以分散注意力的颜色显示"*|{\\[[",所以它们并没有真正打扰我)。

未加载样式文件时

在某些情况下,您可能拥有一些文档,这些文档应该从样式文件中受益,但事实并非如此。这当然可能会导致字体问题。为了诊断此问题,我会*Messages*在打开或恢复相关文件后检查缓冲区。例如,如果文件已按我指定的方式进行字体处理\usepackage{xparse}但未\NewDocumentCommand进行,则可能怀疑我的 xparse.el 在 ~/.emacs.d/auctex/style/ 中未加载。由于我在此 xparse.el 中进行了调用,因此这很容易发现(message ...)。当我的添加项运行时,我收到相同类型的消息LaTeX-mode-hook,因此在这种情况下,诊断是通过查看我的添加项打印的消息LaTeX-mode-hook而不是我自己的 xparse.el 中打印的消息来获得的。

那么,为什么会发生这种情况呢?好吧,AUCTeX 中的样式系统并不是很简单,但我认为,当我正在处理的 .tex(或 .sty、.cls……)文件的名称与已加载的非空 AUCTeX 样式具有相同的主干时,就会发生我在这里谈论的情况。例如,当我将文档命名为 doc.tex 时,即使我(setq TeX-parse-self t)的文档中有 xparse fontification,我也看不到 xparse fontificationEmacs 初始化文件(总是)并且文档有\usepackage{xparse}。这是因为 AUCTeX 样式机制已经加载了一个名为的样式,显然对应于 tex/latex/base/doc.sty,因此 AUCTeX 错误地认为解析我的 doc.tex 没有用(它只在已加载样式的列表中doc记录了名称,因此无法区分我的 doc.tex 和官方的 tex/latex/base/doc.sty)。docTeX-style-hook-list

可以通过首先打开包含以下内容的 /path/to/unique-filename.tex 来重现同一问题的另一个化身:

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn

\NewDocumentCommand \somecommand { m }
  { }

\ExplSyntaxOff

\begin{document}
\end{document}

\usepackage{xcolor}是否确保记录的 AUCTeX 样式信息不会为空——当 AUCTeX 决定“我们是否应该运行这个文件?”unique-filename时,会检查样式信息是否为空。)TeX-auto-apply

然后打开 /path/to/other/unique-filename.tex 包含:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand \somecommand { m }
  { }

\ExplSyntaxOff

\begin{document}
\end{document}

第一个文档没有\NewDocumentCommand字体;这是意料之中的,因为它(从 LaTeX 的角度来看是错误的)没有加载xparse。然而,第二个文件没有\NewDocumentCommand字体化,而我的 xparse.el 样式文件说应该有。原因是,当加载或恢复第二个文件时,AUCTeX 发现它已经有非空的样式信息unique-filename(已为第一个 unique-filename.tex 加载),因此它认为解析第二个 unique-filename.tex 没有用,尽管我已将其设置TeX-parse-selft

为了解决这个问题,你可以设置一个键绑定来运行一个命令(TeX-run-style-hooks "xparse")。实际上,因为我的 Emacs 范围设置中已经有了类似以下内容:

(defun my-unconditionally-revert-buffer ()
  "Revert buffer from file on disk without asking any question."
  (interactive)
  (revert-buffer t t))

(put #'my-unconditionally-revert-buffer 'disabled t)

(global-set-key [f5] #'my-unconditionally-revert-buffer)

我已经对其进行了扩展,以便密钥也可以在 LaTeX 缓冲区中f5运行:(TeX-run-style-hooks "xparse")

(defun my-unconditionally-revert-buffer-and-rerun-style-hooks ()
  (interactive)
  (my-unconditionally-revert-buffer)
  (dolist (style '("xparse"))
    (TeX-run-style-hooks style)))

(put #'my-unconditionally-revert-buffer-and-rerun-style-hooks 'disabled t)

(define-key LaTeX-mode-map [f5]
  #'my-unconditionally-revert-buffer-and-rerun-style-hooks)

因此,当出现问题时,我首先保存缓冲区,然后按f5重新加载文件(保存后不是特别有用)解析它以收集相关的 AUCTeX 样式信息(它被解析是因为我(setq TeX-parse-self t)在我的Emacs 初始化文件)。


脚注

  1. AUCTeX 可以检测何时使用诸如\newcommand和之类的命令,并自动根据或文件\newenvironment中对这些命令的调用生成样式信息(还有、和其他;请参阅.tex.sty.cls.ltx.dtx自动定制在 AUCTeX 手册中,TeX-file-extensions变量和TeX-auto-generateAUCTeX 命令)。

相关内容