Tab 补全快速插入 LaTeX 代码
大家好, 我是小米. 本期我们将介绍如何在 CDLaTeX 中用 Tab 补全命令快速地输入复杂的宏命令和环境模板.
Tab 补全插入宏命令
补全原理很简单, 用几个字母组合加 Tab 生成一些复杂的命令. 例如, fr + Tab 就会生成 \frac{}{}, 这里光标会停留在第一个括号内; 在第一个括号内完成输入后, 按 Tab 光标就会跳到下一个括号中. 因此, 输入一个常见的分数 \frac{1}{2} 只需要输入 f + r + Tab + 1 + Tab + 2.
内置命令举例
CDLaTeX 内置了一些可补全的命令, 可以在 cdlatex-command-alist-default 变量中查看 (C-h v). 我们举一些例子 (以下 ? 所在位置表示补全后光标停留的位置.)
- 分数
fr+ Tab =\frac{?}{}, 根号sq+ Tab =\sqrt{?} - 空格
qq+ Tab =\quad, 大空格qqq+ Tab =\qquad - 括号
lr(+ Tab =\left(?\right),lr[=\left[?\right] - 章节标题
sn+ Tab =\section{?},ss+ Tab =\subsection{?},sss+ Tab =\subsubsubsection{?}
一些自定义例子
te+ Tab =\text{}se+ Tab =\{ \}(set)st+ Tab =\stackover{}{}hl+ Tab =\hline,hhl+ Tab =\\ \hline(表格中常用)big(+ Tab =\big(?\big),Big(+ Tab =\Big(?\Big),bigg(+ Tab =\bigg(?\bigg)(\big,\Big,\bigg等是amsmath中调整括号大小的命令)lr<+ Tab =\langle?\rangle, 一对尖括号 \(\langle \rangle\).
显然, 这里的关键字选择都是用命令中最开始的两到三个字母, 这样非常好记, 也很容易使用.
Tab 补全环境模板
大家可以看到这里的 Tab 补全其实就是一个替换字符串的过程. 当然字符串中也可以包括换行, 因此同样的机制也可以输入形如 \begin{XXX} ... \end{XXX} 的环境.
内置命令举例
equation 环境
equ + Tab 插入如下模板:
其中, \label{eq:XXX} 是 CDLaTeX 调用 reftex 自动生成的数字标签.
类似的数学公式环境还有如
ali+ Tab 插入align环境 (自动生成标签),ali*+ Tab 插入align*环境 (无标签)gat+ Tab 插入gather环境 (自动生成标签),gat*+ Tab 插入gather*环境 (无标签)
列表环境
enu + Tab 插入
此时, 在 enumerate 环境中:
it+ Tab =\item- C-<enter> 会换行并生成
\item
这里, enu + Tab 等同于用 cdlatex-environment (C-c { ) 插入 enumerate 环境
类似的还有
ite+ Tab 插入itemize环境fg+ Tab 插入figure环境
自定义补全命令
现在我们介绍如何自定义你自己需要的补全命令. 默认的补全命令都在 cdlatex-command-alist-default 中, 而现有的所有命令, 包括内置的和自定义的, 都可以通过 C-c ? 查看.
在用 C-c ? 查看时, 我们会在最右一列看到 TEXT 和 MATH 关键字:
MATH关键字表示补全可以在 数学环境 中触发TEXT关键字表示补全可以在 文本环境 中触发
加入自定义新的补全命令通过修改变量 cdlatex-command-alist. 方法是调用 M-x customize-variable =, 然后输入变量名 =cdlatex-command-alist.
带参数的宏命令
例子: te + Tab 输入 \text{?} (光标停在括号内). 我们需要填入如下参数
- keyword:
te - Docstring: 随便填, 只是用于说明的解释性文字, 例如
insert \text{} - Replacement:
\text{?}(?表示光标停留的位置) - Hook:
cdlatex-position-cursor(如果需要指定光标则必填!) - Argument:
nil(这是上面 hook 的参数) - Text Mode:
nil, Math mode:t
保存设置 (Apply and Save) 之后, 在已经打开的 tex 文件中用 C-c C-n 可以刷新设置, 就可以开始使用了.
插入匹配的括号
例子: big{ + Tab 插入 \big\{? \big\}
- keyword:
big{ - Docstring:
insert \big\{? \big\} - Replacement:
\big\{? \big\ - Hook:
cdlatex-position-cursor - Argument:
nil - Text Mode:
nil, Math mode:t
这里有两个细节. 第一是我们在 ? 后面手动多加了一个空格, 这里因为在 LaTeX 编辑模式下, 按 Tab 会自动跳到一个空格位置, 因此我们尽量用空格把代码分隔开来, 便于以后的修改; 既然如此, 我们干脆在模板中加入这个空格.
第二个细节时我们的替换字符串最后少了一个 }. 这是因为 CDLaTeX 中默认会自动匹配输入一对括号 {}. 因此我们只需要补全除了右花括号 } 以外的部分就可以.
CDLaTeX 中自动匹配的括号可以通过 cdlatex-paired-parens 设置, 只针对 $([{<| 6 个字符. 我一般会自动匹配
$([{ . 这里大家只需要注意你在 cdlatex-command-alist 中的设置与 cdlatex-paired-parens 保持一致就可以了.
插入环境
例子: case + Tab 插入
- keyword:
case - Docstring:
insert \begin{cases} \end{cases} - Replacement: 输入框内用 C-j 换行, 然后正常输入需要替换的文本即可
- Hook:
cdlatex-position-cursor - Argument:
nil - Text Mode:
nil, Math mode:t
插入环境 II
插入环境除了直接在 cdlatex-command-alist 的 Replacement 中写入环境模板以外, 还可以通过调用函数 cdlatex-environment 的方式实现.
在 LaTeX 编辑模式中, 有两种用环境名插入环境的方法
- M-x
LaTeX-environment(C-c C-e) +description: 这会调用AucTeX的环境模板 - M-x
cdlatex-environment(C-c { ) +description: 这会调用CDLaTeX的环境模板.
两种模板略有不同. 这第二种插入环境的方法就是用 Tab 补全触发第二个命令.
例子: des + Tab 插入 description 环境
- keyword:
des - Docstring:
insert \begin{description} \end{description} - Replacement:
nil - Hook:
cdlatex-environment - Argument:
("description") - Text Mode:
t, Math mode:nil
这里需要注意的是我们用了一个不同的 hook! 所插入的模板是由 cdlatex-env-alist, cdlatex-env-alist-default 控制的.
使用这种方式插入环境的好处:
- 支持自动插入标签:
AUTOLABEL关键字 (equ+ Tab 生成带标签的环境的实现方式) - 支持多行环境的
item模板 (C-<enter> 触发)
不过, 在一般情况下, 第一种方法直接把环境模板写进 cdlatex-command-alist 也能实现大部分的功能了.
我的一些设置分享
我的 cdlatex-command-alist 变量, 仅做抛砖引玉之用.
(setq cdlatex-command-alist
'(("eq" "insert pairs of \\[ \\]" "\\[ ? \\]" cdlatex-position-cursor nil t t)
("Big(" "insert Big ()" "\\Big( ? \\Big" cdlatex-position-cursor nil nil t)
("Big[" "insert Big[" "\\Big[ ? \\Big" cdlatex-position-cursor nil nil t)
("Big\\|" "insert Big \\|" "\\Big\\| ? \\Big\\|" cdlatex-position-cursor nil nil t)
("Big{" "insert Big{}" "\\Big\\{ ? \\Big\\" cdlatex-position-cursor nil nil t)
("Big|" "insert Big|" "\\Big| ? \\Big|" cdlatex-position-cursor nil nil t)
("aali" "insert equation" "\\left\\{\\begin{aligned}\n? \n\\end{aligned}\\right." cdlatex-position-cursor nil nil t)
("alb" "Insert beamer alert block with overlay" "\\begin{alertblock}<+->{ ? } \n\n\\end{alertblock}" cdlatex-position-cursor nil t nil)
("alb*" "Insert beamer alert block without overlay" "\\begin{alertblock}{ ? } \n\n\\end{alertblock}" cdlatex-position-cursor nil t nil)
("big(" "insert big ()" "\\big( ? \\big" cdlatex-position-cursor nil nil t)
("big[" "insert big []" "\\big[ ? \\big" cdlatex-position-cursor nil nil t)
("big\\|" "insert big \\|" "\\big\\| ? \\big\\|" cdlatex-position-cursor nil nil t)
("bigg(" "insert bigg()" "\\bigg( ? \\bigg" cdlatex-position-cursor nil nil t)
("bigg[" "insert bigg[" "\\bigg[ ? \\bigg" cdlatex-position-cursor nil nil t)
("bigg\\|" "insert bigg\\|" "\\bigg\\| ? \\bigg\\|" cdlatex-position-cursor nil nil t)
("bigg{" "insert bigg{}" "\\bigg\\{ ? \\bigg\\" cdlatex-position-cursor nil nil t)
("bigg|" "insert bigg|" "\\bigg| ? \\bigg|" cdlatex-position-cursor nil nil t)
("big{" "insert big {}" "\\big\\{ ? \\big\\" cdlatex-position-cursor nil nil t)
("big|" "insert big|" "\\big| ? \\big|" cdlatex-position-cursor nil nil t)
("blo" "Insert beamer block with overlay" "\\begin{block}<+->{ ? } \n\n\\end{block}" cdlatex-position-cursor nil t nil)
("blo*" "Insert beamer block WITHOUT overlay" "\\begin{block}{ ? } \n\n\\end{block}" cdlatex-position-cursor nil t nil)
("bn" "binomial" "\\binom{?}{}" cdlatex-position-cursor nil nil t)
("capl" "insert \\bigcap\\limits_{}^{}" "\\bigcap\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("case" "insert cases" "\\begin{cases}\n? & \\\\\n &\n\\end{cases}" cdlatex-position-cursor nil nil t)
("cd" "insert cdots" "\\cdots" nil nil t t)
("cupl" "insert \\bigcup\\limits_{}^{}" "\\bigcup\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("dd" "insert ddots" "\\ddots" nil nil t t)
("def" "insert definition env" "" cdlatex-environment ("definition") t nil)
("des" "insert description" "" cdlatex-environment ("description") t nil)
("enu*" "insert enu" "\\begin{enumerate}\n\\item ?\n\\end{enumerate}" cdlatex-position-cursor nil t nil)
("equ*" "insert unlabel equation" "" cdlatex-environment ("equation*") t nil)
("exb" "Insert beamer example block with overlay" "\\begin{exampleblock}<+->{ ? } \n\n\\end{exampleblock}" cdlatex-position-cursor nil t nil)
("exb*" "Insert beamer example block without overlay" "\\begin{exampleblock}{ ? } \n\n\\end{exampleblock}" cdlatex-position-cursor nil t nil)
("exe" "Insert exercise" "\\begin{exercise}\n? \n\\end{exercise}" cdlatex-position-cursor nil t nil)
("fra" "insert frame (for beamer)" "" cdlatex-environment ("frame") t nil)
("hhl" "insert \\ \\hline" "\\\\ \\hline" ignore nil t nil)
("hl" "insert \\hline" "\\hline" ignore nil t nil)
("ipenu" "insert in paragraph enumerate" "" cdlatex-environment ("inparaenum") t nil)
("ipite" "insert in paragraph itemize" "" cdlatex-environment ("inparaitem") t nil)
("it" "insert \\item" "\\item?" cdlatex-position-cursor nil t nil)
("ld" "insert ldots" "\\ldots" nil nil t t)
("lem" "insert lemma env" "" cdlatex-environment ("lemma") t nil)
("liml" "insert \\lim\\limits_{}" "\\lim\\limits_{?}" cdlatex-position-cursor nil nil t)
("lr<" "insert bra-ket" "\\langle ? \\rangle" cdlatex-position-cursor nil nil t)
("myenu" "insert in my enumerate for beamer" "" cdlatex-environment ("myenumerate") t nil)
("myite" "insert in my itemize for beamer" "" cdlatex-environment ("myitemize") t nil)
("ons" "" "\\onslide<?>{ }" cdlatex-position-cursor nil t t)
("pa" "insert pause" "\\pause" ignore nil t nil)
("pro" "insert proof env" "" cdlatex-environment ("proof") t nil)
("prodl" "insert \\prod\\limits_{}^{}" " \\prod\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("prop" "insert proposition" "" cdlatex-environment ("proposition") t nil)
("se" "insert \\{\\}" "\\{ ? \\}" cdlatex-position-cursor nil nil t)
("spl" "insert split" "" cdlatex-environment ("split") nil t)
("st" "stackrel" "\\stackrel{?}{}" cdlatex-position-cursor nil nil t)
("te" "insert text" "\\text{?}" cdlatex-position-cursor nil nil t)
("thm" "insert theorem env" "" cdlatex-environment ("theorem") t nil)
("vd" "insert vdots" "\\vdots" nil nil t t)))