配置 LaTeX 公式自动补全
❤
首先安装 HyperSnips - Visual Studio Marketplace 插件。
安装完成后,按下快捷键 Ctrl + Shift + P
,输入命令 Open Snippets Directory
,就可以打开一个文件夹。在该文件夹新建一个文件 markdown.hsnips
。
从下面这些 snips 中选择你需要的复制进去,或者自己写你需要的 snip(拉到文末教你怎么写)。
snips 来源:OrangeX4、自己写的
数学环境支持(必需)
用于检测当前位置是否在数学公式内部。
此代码为全局代码,后面所有数学公式内的替换都依赖于此代码。
global
function math(context) {
return context.scopes.some(s => s.includes("math"));
}
endglobal
分数线
功能是把斜杠 /
替换成分数 \frac{}{}
。分为两类。一类是无括号分数:
1/
-> \frac{1}{}
a_1/
-> \frac{a_1}{}
a+b^2/
-> a+\frac{b^2}{}
context math(context)
snippet `((\d+)|(\d*)(\\)?([A-Za-z!]+)((\^|_)(\{\d+\}|\d))*)/` "Fraction no ()" iA
\frac{``rv = m[1]``}{$1}$0
endsnippet
对于上面的 a+b^2
这个例子,如果我们需要指定把 a+b^2
作为分子,那就需要添加括号。有括号分数:
(a+b^2)/
-> \frac{a+b^2}{}
((a+b^2))/
-> \frac{(a+b^2)}{}
context math(context)
snippet `[^\$]*\)/` "Fraction with ()" iA
``
let str = m[0];
str = str.slice(0, -1);
let lastIndex = str.length - 1;
let depth = 0;
let i = str.length - 1;
while (i > -1) {
if (str[i] == ')') depth += 1;
if (str[i] == '(') depth -= 1;
if (depth == 0) break;
i -= 1;
}
if (i == -1) rv = m[0];
else{
let results = str.slice(0, i) + "\\frac{" + str.slice(i+1, -1) + "}";
results += "{$1}$0";
rv = results;
}
``
endsnippet
函数名和希腊字母自动加 \
在函数名(如 sin,cos,ln 等)和希腊字母(如 alpha 等)前面自动加入 \
eps
-> \varepsilon
(极限的 ε−δ 语言中的 ε)
delta
-> \delta
(极限的 ε−δ 语言中的 δ )
sin
-> \sin
pi
-> \pi
(圆周率 π)
context math(context)
snippet eps "varepsilon" wA
\varepsilon
endsnippet
context math(context)
snippet `(?<=\b|\d+)(?<!\\)(sin|cos|arccot|cot|csc|ln|log|lg|exp|star|perp|arcsin|arccos|arctan|arccot|arccsc|arcsec|pi|zeta|oint|iiint|iint|int|ell|nabla|notin)` "function" wA
\\``rv = m[1]``
endsnippet
context math(context)
snippet `(?<=\b|\d+)(?<!\\)(mu|alpha|sigma|rho|beta|gamma|delta|zeta|eta|epsilon|theta|iota|kappa|vartheta|lambda|nu|pi|rho|tau|upsilon|varphi|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)` "greek" wA
\\``rv = m[1]``
endsnippet
关于极限
\limits
(primitive command) Place limits over and under a large operator. This is the default position in display style.
\nolimits
(primitive command) Place limits of a large operator as subscript and superscript expressions. This is the default position in text style.
\displaylimits
(primitive command) Restore default placement for limits.
简言之在 \lim
、\sum
等巨运算符后面再加个 \limits
会强制把运算范围放到巨运算符的上面和下面(在行内公式中默认是想上下标一样放在右上角和右下角)。例子:
\lim_{n \to \infty} \sqrt{n+1}-\sqrt{n}
\(\lim_{n \to \infty} \sqrt{n+1}-\sqrt{n}\)
\lim\limits_{n \to \infty} \sqrt{n+1}-\sqrt{n}
\(\lim\limits_{n \to \infty} \sqrt{n+1}-\sqrt{n}\)
\sum_{n=1}^{\infty} \frac{1}{n^2}
\(\sum_{n=1}^{\infty} \frac{1}{n^2}\)
\sum\limits_{n \to \infty} \frac{1}{n^2}
\(\sum\limits_{n=1}^{\infty} \frac{1}{n^2}\)
所以 snip 有两个版本
有 \limits
版:
context math(context)
snippet `(?<!\\)lim` "limit" wA
\lim\limits_{${1:n} \to ${2:\infty}}
endsnippet
无 \limits
版:
context math(context)
snippet `(?<!\\)lim` "limit" wA
\lim_{${1:n} \to ${2:\infty}}
endsnippet
注:上面的例子中有两个占位符:${1:n}
、${2:\infty}
。你可以用 Tab 快速跳到下一个占位符,这时你可以编辑该占位符或再次跳到下一个。冒号后面的字符串(如果有的话)是默认文本,例如 ${2:\infty}
这个位置的默认文本是 \infty
。占位符的遍历顺序是按数字升序。
特殊的集合
\RR
-> \mathbb{R}
context math(context)
snippet `\\([RQZNC]){2}` "set" iA
\mathbb{``rv=m[1]``}
endsnippet
自动加 \left
\right
打完括号(...)
或[...]
后再打一个空格,会自动在括号两边加 \left
\right
。例如:
(\frac{1}{x})
Space -> \left(\frac{1}{x}\right)
context math(context)
snippet `^.*(?<!right)(\)) $` A
``
let str = m[0];
str = str.replace(/\$/g, "\\$");
str = str.slice(0, -1);
let lastIndex = str.length - 1;
let depth = 0;
let i = str.length - 1;
while (i > -1) {
if (str[i] == ')') depth += 1;
if (str[i] == '(') depth -= 1;
if (depth == 0) break;
i -= 1;
}
if (i == -1) rv = m[0];
else{
let inside = str.slice(i+1, -1);
if (/^[1-9]$/.test(inside)) rv = m[0];
else {
rv = str.slice(0, i) + "\\left(" + inside + "\\right)";
}
}
``
endsnippet
context math(context)
snippet `^.*(?<!right)(\]) $` A
``
let str = m[0];
str = str.replace(/\$/g, "\\$");
str = str.slice(0, -1);
let lastIndex = str.length - 1;
let depth = 0;
let i = str.length - 1;
while (i > -1) {
if (str[i] == ']') depth += 1;
if (str[i] == '[') depth -= 1;
if (depth == 0) break;
i -= 1;
}
if (i == -1) rv = m[0];
else{
let inside = str.slice(i+1, -1);
if (/^[1-9]$/.test(inside)) rv = m[0];
else {
rv = str.slice(0, i) + "\\left[" + inside + "\\right]";
}
}
``
endsnippet
其他各种各样的替换
以下内容抄自 OrangeX4 的 snips,需要的自取
# ==== Auto Capture Hat Operation ====
context math(context)
snippet `(\(?)(\\?[a-zA-Z]\w*)(\)?)(hbar|BAR)` "Bar" iA
\overline{``rv = m[1] + m[2] + m[3]``}
endsnippet
context math(context)
snippet `(\\?[a-zA-Z]\w*)(htd|TD)` "tilde" iA
\widetilde{``rv = m[1]``}
endsnippet
context math(context)
snippet `(\\?[a-zA-Z]\w*)(hat|HAT)` "hat" iA
\hat{``rv = m[1]``}
endsnippet
context math(context)
snippet `(\\?[a-zA-Z]\w*)(hvec)` "Vector postfix" iA
\vec{``rv = m[1]``}
endsnippet
context math(context)
snippet `(\\?[a-zA-Z]\w*)(rta)` "Vector postfix" iA
\overrightarrow{``rv = m[1]``}
endsnippet
context math(context)
snippet `(\\?[a-zA-Z]\w*)(hdot)` "dot" iA
\dot{``rv = m[1]``}
endsnippet
context math(context)
snippet `(\\?[a-zA-Z]\w*)(hddot)` "ddot" iA
\ddot{``rv = m[1]``}
endsnippet
# ===== Static Hat Operation ====
context math(context)
snippet hbar "bar" iA
\overline{$1}$0
endsnippet
context math(context)
snippet hat "hat" iA
\hat{$1}$0
endsnippet
context math(context)
snippet hsq "\sqrt{}" iA
\sqrt{${1}}$0
endsnippet
# == Superscript Operation ==
context math(context)
snippet invs "inverse" wA
^{-1}
endsnippet
priority 10000
context math(context)
snippet TR "inverse" iA
^{\mathsf{T}}
endsnippet
context math(context)
snippet CL "complement" wA
^{c}
endsnippet
context math(context)
snippet R+ "R0+" iA
R_0^+
endsnippet
context math(context)
snippet pow "power" iA
^{${1:2}}$0
endsnippet
# == Subscript Operation ==
context math(context)
snippet td "subscript" iA
_{${1}}$0
endsnippet
context math(context)
snippet `([A-Za-z])(\d)` "auto subscript" wA
`` rv = m[1] + "_" + m[2]``
endsnippet
priority 100
context math(context)
snippet `([A-Za-z])_(\d{2})` "auto subscript" wA
`` rv = m[1] + "_{" + m[2] + "}$0" ``
endsnippet
priority 100
context math(context)
snippet `([A-Za-z])S(\d)` "auto subscript" wA
`` rv = m[1] + "_{" + m[2] + "$1}$2"``
endsnippet
context math(context)
snippet `\b(?<!\\)([A-Za-z])([a-z])\2` "auto subscript 2" iA
`` rv = m[1] + "_" + m[2].substring(0, 1) ``
endsnippet
context math(context)
snippet `\b(?<!\\)([A-Za-z])S([a-z])\2` "auto subscript 2" iA
`` rv = m[1] + "_{" + m[2].substring(0, 1) + "$1}$2"``
endsnippet
# Custom: Add more greek letters
context math(context)
snippet `(\\mu|\\alpha|\\sigma|\\rho|\\beta|\\gamma|\\delta|\\zeta|\\eta|\\varepsilon|\\theta|\\iota|\\kappa|\\vartheta|\\lambda|\\nu|\\pi|\\rho|\\tau|\\upsilon|\\phi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)([a-z])\2` "auto subscript for greek letter" iA
`` rv = m[1] + "_" + m[2].substring(0, 1) ``
endsnippet
context math(context)
snippet `(\\mu|\\alpha|\\sigma|\\rho|\\beta|\\gamma|\\delta|\\zeta|\\eta|\\varepsilon|\\theta|\\iota|\\kappa|\\vartheta|\\lambda|\\nu|\\pi|\\rho|\\tau|\\upsilon|\\phi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)S([a-z])\2` "auto subscript for greek letter" iA
`` rv = m[1] + "_{${1:" + m[2].substring(0, 1) + "}}$2"``
endsnippet
# == Font Operation ==
# ==== Static Operation ====
context math(context)
snippet txt "text" iA
\text{$1}$0
endsnippet
context math(context)
snippet tit "text it" iA
\textit{$1}$0
endsnippet
snippet mcal "mathcal" im
\mathcal{$1}$0
endsnippet
context math(context)
snippet mbb "mathbb" iA
\mathbb{$1}$0
endsnippet
context math(context)
snippet mbf "mathbb" iA
\mathbf{$1}$0
endsnippet
context math(context)
snippet mbf "mathbm" iA
\mathbf{$1}$0
endsnippet
# ==== Dynamic Operation ====
priority 100
context math(context)
snippet `(\\?[a-zA-Z]\w*)(bf|BF)` "mathbf" iA
\mathbf{``rv = m[1]``}
endsnippet
priority 100
context math(context)
snippet `(\\?[a-zA-Z]\w*)(bm|BM)` "mathbm" iA
\bm{``rv = m[1]``}
endsnippet
priority 100
context math(context)
snippet `(\\?[a-zA-Z]\w*)(bs)` "boldsymbol" iA
\boldsymbol{``rv = m[1]``}
endsnippet
priority 100
context math(context)
snippet `(\\?[a-zA-Z]\w*)mcal` "mathcal" iA
\mathcal{``rv = m[1].toUpperCase() ``} $0
endsnippet
priority 100
context math(context)
snippet `(?<!\\)\b([a-zA-Z]+)rm` "mathrm" iA
\mathrm{``rv = m[1]``}
endsnippet
priority 100
context math(context)
snippet `(\\?[a-zA-Z]\w*)mbb` iA
\mathbb{``rv = m[1]``} $0
endsnippet
# == Auto Symbol ==
snippet oo "\infty" wAmm
\infty
endsnippet
context math(context)
snippet ... "cdots" iA
\cdots
endsnippet
snippet <> "hokje" iA
\diamond
endsnippet
# +... -> , \cdots
# - ... -> , \cdots
# add a space if there already is one.
priority 101
snippet `(?<=[-+])\s*\.\.\.` "smart cdots" irA
\cdots
endsnippet
# It seems that \ldots is only used when , ...,
# ,... -> , \ldots
# , ... -> , \ldots
priority 101
snippet `(?<=,)(\s*)\.\.\.` "smart ldots" irA
\ldots
endsnippet
context math(context)
snippet ** "dot multiply" iA
\cdot
endsnippet
context math(context)
snippet xx "cross" iA
\times
endsnippet
# ==== Space Symbol ====
context math(context)
snippet `(?<=\b|\d+)(?<!\\)(quad)` "ln" wA
\\``rv = m[1]``
endsnippet
# ==== Logic Symbol ====
context math(context)
snippet -> "to" iA
\to
endsnippet
context math(context)
snippet !> "mapsto" iA
\mapsto
endsnippet
context math(context)
snippet vdash "vdash" iA
\\vdash
endsnippet
context math(context)
snippet => "implies" iA
\implies
endsnippet
context math(context)
snippet =< "implied by" iA
\impliedby
endsnippet
context math(context)
snippet iff "if and only if" iA
\iff
endsnippet
context math(context)
snippet EE "exist" iA
\exists
endsnippet
context math(context)
snippet AA "forall" iA
\forall
endsnippet
context math(context)
snippet bec "because" iA
\because
endsnippet
context math(context)
snippet thr "therefore" iA
\therefore
endsnippet
# ==== Compare Symbol ====
context math(context)
snippet -- "setminus" iA
\setminus
endsnippet
context math(context)
snippet >= "greater than" iA
\geqslant $0
endsnippet
context math(context)
snippet dis "displaystyle" iA
\displaystyle
endsnippet
context math(context)
snippet <= "less than" iA
\leqslant $0
endsnippet
context math(context)
snippet != "no equals" iA
\neq
endsnippet
context math(context)
snippet == " constan equals" iA
\equiv
endsnippet
context math(context)
context math(context)
snippet ~~ " Appro equals" iA
\thickapprox
endsnippet
context math(context)
context math(context)
snippet ~= " Appro equals2" iA
\cong
endsnippet
context math(context)
snippet >> ">>" iA
\gg
endsnippet
context math(context)
snippet << "<<" iA
\ll
endsnippet
# == Auto Environment ==
# ==== Auto Math Mode ====
snippet lm "inline Math" wA
$${1}$$0
endsnippet
snippet dm "display Math" wA
$$
${1}
$$$0
endsnippet
# ==== Common Environment ====
context math(context)
snippet case "cases" wA
\begin{cases}
$1 \\\\
\end{cases}
endsnippet
context math(context)
snippet ali "aligned" wA
\begin{aligned}
$1 \\\\
\end{aligned}
endsnippet
# == Auto Adaptive Close ==
context math(context)
snippet ceil "ceil" iA
\left\lceil $1 \right\rceil $0
endsnippet
context math(context)
snippet floor "floor" iA
\left\lfloor $1 \right\rfloor$0
endsnippet
priority 100
snippet @( "left( right)" Aim
\left( ${1} \right) $0
endsnippet
priority 100
snippet @| "left| right|" Aim
\left| ${1} \right| $0
endsnippet
priority 100
snippet @{ "left\{ right\}" Aim
\left\\{ ${1} \right\\} $0
endsnippet
priority 100
snippet @[ "left[ right]" Aim
\left[ ${1} \right] $0
endsnippet
priority 100
context math(context)
snippet @< "leftangle rightangle" iA
\left<${1} \right>$0
endsnippet
snippet ( "auto close ()" iA
(${1})
endsnippet
snippet { "auto close {}" iA
{${1}}
endsnippet
snippet [ "auto close []" iA
[${1}]
endsnippet
priority 200
context math(context)
snippet norm iA
\left\| ${1} \right\|_{$2}$3
endsnippet
# == Snippet ==
# ==== General Snippet ====
# ====== Lite Snippet ======
context math(context)
snippet tag "tag" iA
\tag{$1}
endsnippet
context math(context)
snippet xyb "Auto (x, y)" iA
(x, y)
endsnippet
context math(context)
snippet xyzb "Auto (x, y ,z)" iA
(x, y, z)
endsnippet
priority 100
context math(context)
snippet `\b([a-zA-Z])n(\d)` "x[n+1]" iA
``rv = m[1]``_{${1:n}+``rv = m[2]``}$0
endsnippet
# Unkown
context math(context)
snippet rij "mrij" iA
(${1:x}_${2:n})_{${3:$2} \\in ${4:N}}$0
endsnippet
priority 200
context math(context)
snippet abs "absolute value" iA
\left\vert ${1} \right\vert $0
endsnippet
snippet beg "begin{} / end{}" bA
\\begin{$1}
$0
\\end{$1}
endsnippet
# ======== N Series ========
priority 100
context math(context)
snippet comma "comma" iA
${1:\\alpha}_1,${1:\\alpha}_2,\\cdots,${1:\\alpha}_${2:n}
endsnippet
priority 100
context math(context)
snippet plus "plus" iA
${1:k}_1${2:\\alpha}_1+${1:k}_2${2:\\alpha}_2+\\cdots+${1:k}_${3:n}${2:\\alpha}_${3:n}
endsnippet
context math(context)
snippet `\b([a-z])=n` "i=1,2,\cdots,n" wA
``rv = m[1]``=1,2,\cdots,n
endsnippet
# ======== Common Operator Snippet ========
context math(context)
snippet `(?<!\\)sum` "sum" wA
\sum\limits_{n=${1:1}}^{${2:\infty}} ${3:a_n z^n}
endsnippet
context math(context)
snippet taylor "taylor" wA
\sum\limits_{${1:k}=${2:0}}^{${3:\infty}} ${4:c_$1} (x-a)^$1 $0
endsnippet
context math(context)
snippet `(?<!\\)lim` "limit" wA
\lim\limits_{${1:n} \to ${2:\infty}}
endsnippet
context math(context)
snippet `(?<!\\)prod` "product" wA
\prod_{${1:n=${2:1}}}^{${3:\infty}} ${4:${VISUAL}} $0
endsnippet
context math(context)
snippet `(?<!\\)part` "d/dx" wA
\frac{\partial ${1:V}}{\partial ${2:x}}$0
endsnippet
priority 100
context math(context)
snippet `(?<!\\)diff` "d/dx" wA
\frac{\mathrm{d}${1:y}}{\mathrm{d}${2:x}}$0
endsnippet
context math(context)
snippet buu "bigcup" wA
\bigcup_{${1:i \in ${2: I}}} $0
endsnippet
context math(context)
snippet bnn "bigcap" wA
\bigcap_{${1:i \in ${2: I}}} $0
endsnippet
priority 100
context math(context)
snippet dint "integral" wA
\int_{${1:-\infty}}^{${2:\infty}} ${3} ~\\mathrm{d}${4:x} $0
endsnippet
priority 200
context math(context)
snippet `c(o|n)?(l|n)?(b|c)?int` "s egral" wA
``
let final = "\\"; // init
let isO = m[1] == "o";
(isO) ? final += "o" : "" // o option
let b = 1;
let isL = m[2] == "l";
(m[3] == 'b') ? b = 2 : (m[3] == 'c') ? b = 3 : 1;
for (let i = 0; i < b - 1; i++) {
final += "i";
}
final += "int";
final += ((b >= 2) || (b != 1 && !isO && isL)) ? "\\limits" : "";
let r = (b == 3) ? "E" : (b == 1 && (isL || isO)) ? "C" : "R";
final += ((b >= 2) || isO || (b == 1 && isL)) ? "_{${1:" + r + "}}" : "_{${1:-\\infty}}^{${2:\\infty}}";
let x = (b == 2) ? "A" : (b == 3) ? "V" : (b == 1 && isL) ? "s" : "x";
final += " ${3} ~\\mathrm{d}${4:" + x + "} $0";
rv = final;
``
endsnippet
# Custom: Can add more defined operator
priority 100
context math(context)
snippet `(?<![\a-zA-Z])(rank|lcm|gcd)` "math function" wA
\\operatorname{``rv = m[1]``}
endsnippet
context math(context)
snippet `(?<![\a-zA-Z])arg(max|min)` "argmin/max" wA
\mathop{\arg\\``rv = m[1]``}
endsnippet
# ====== Big Snippet ======
context math(context)
snippet bigdef "Big function" iA
\begin{equation$6}
\begin{aligned}
$1\colon $2 &\longrightarrow $3 \\\\
$4 &\longmapsto $1($4) = $5
\end{aligned}
\end{equation$6}$0
endsnippet
context math(context)
snippet bigmin "Optimization problem" iA
\begin{equation$4}
\begin{aligned}
\min &\quad ${1:f(x)}\\\\
\text{s.t.} &\quad ${2:g(x)} \leq 0\\\\
&\quad ${3:h(x)} = 0\\\\
\end{aligned}
\end{equaiton$4}$0
endsnippet
context math(context)
snippet bigmax "Optimization problem" wA
\begin{equation$4}
\begin{aligned}
\max &\quad ${1:f(x)}\\\\
\text{s.t.} &\quad ${2:g(x)} \leq 0\\\\
&\quad ${3:h(x)} = 0\\\\
\end{aligned}
\end{equation$4}$0
endsnippet
context math(context)
snippet deff "Definition of function" wA
$1\colon ${2:\\mathbb{R\}} \to ${3:\\mathbb{R\}}, ${4:x} \mapsto $0
endsnippet
context math(context)
snippet iid "independent and identical distribution" iA
\overset{\text{i.i.d.}}{\sim}
endsnippet
context math(context)
snippet defe "define equal" wA
\overset{\underset{\mathrm{def}}{}}{=}
endsnippet
# == Matrix ==
# ==== Static Matrix ====
snippet pmat "pmat" wm
\begin{pmatrix}
${1: }
\end{pmatrix} $0
endsnippet
snippet bmat "pmat" wm
\begin{bmatrix}
$1
\end{bmatrix} $0
endsnippet
context math(context)
snippet vecC "column vector" iA
\begin{pmatrix} ${1:x}_1 \\\\ ${1:x}_2 \\\\ \vdots \\\\ ${1:x}_${2:n} \end{pmatrix}
endsnippet
context math(context)
snippet vecR "row vector" iA
\begin{pmatrix} ${1:x}_1, ${1:x}_2, \cdots, ${1:x}_${2:n} \end{pmatrix}$0
endsnippet
priority 300
context math(context)
snippet omis "omission" iA
\\begin{pmatrix}${1:1}&${2:1}&\\cdots&${4:1}\\\\${5:1}&${6:1}&\\cdots&${8:1}\\\\\\vdots&\\vdots&\\ddots&\\vdots\\\\${13:1}&${14:1}&\\cdots&${16:1}\\end{pmatrix}
endsnippet
priority 300
context math(context)
snippet submat "omission" iA
\\begin{pmatrix}
${1:a}_{11} & ${1:a}_{12} & \\cdots & ${1:a}_{1n} \\\\
${1:a}_{21} & ${1:a}_{22} & \\cdots & ${1:a}_{2n} \\\\
\\vdots & \\vdots & \\ddots & \\vdots \\\\
${1:a}_{n1} & ${1:a}_{n2} & \\cdots & ${1:a}_{nn}
\\end{pmatrix}
endsnippet
priority 300
context math(context)
snippet subplusmat "omission" iA
\\begin{pmatrix}
${1:a}_{11}+{2:b}_{11} & ${1:a}_{12}+{2:b}_{12} & \\cdots & ${1:a}_{1n}+{2:b}_{1n} \\\\
${1:a}_{21}+{2:b}_{21} & ${1:a}_{22}+{2:b}_{22} & \\cdots & ${1:a}_{2n}+{2:b}_{2n} \\\\
\\vdots & \\vdots & \\ddots & \\vdots \\\\
${1:a}_{n1}+{2:b}_{n1} & ${1:a}_{n2}+{2:b}_{n2} & \\cdots & ${1:a}_{nn}+{2:b}_{nn}
\\end{pmatrix}
endsnippet
context math(context)
snippet jacobi "jacobi" iA
\\begin{pmatrix}\\frac{\\partial ${1:f}_1}{\\partial ${2:x}_1}&\\frac{\\partial ${1:f}_1}{\\partial ${2:x}_2}&\\cdots&\\frac{\\partial ${1:f}_1}{\\partial ${2:x}_${3:n}}\\\\\\frac{\\partial ${1:f}_2}{\\partial ${2:x}_1}&\\frac{\\partial ${1:f}_2}{\\partial ${2:x}_2}&\\cdots&\\frac{\\partial ${1:f}_2}{\\partial ${2:x}_${3:n}}\\\\\\vdots&\\vdots&\\ddots&\\vdots\\\\\\frac{\\partial ${1:f}_${3:m}}{\\partial ${2:x}_1}&\\frac{\\partial ${1:f}_${3:m}}{\\partial ${2:x}_2}&\\cdots&\\frac{\\partial ${1:f}_${3:m}}{\\partial ${2:x}_${3:n}}\\end{pmatrix}
endsnippet
# ==== Dynamic Matrix ====
priority 300
context math(context)
snippet `(b|p|v)mata([1-9])` "bmatrix" iwA
\\begin{``rv = m[1]``matrix}``
let len = m[2];
let results = "";
for (var i=0; i<len; i++){
results += "$1 &".repeat(len-1) + " $1 \\\\\\\\";
}
rv = results;
``\\end{``rv = m[1]``matrix}$0
endsnippet
priority 300
context math(context)
snippet `(b|p|v)mat([1-9])` "bmatrix" iwA
\\begin{``rv = m[1]``matrix}``
rv = gen_matrix(m[2],m[2]);
``\\end{``rv = m[1]``matrix}$0
endsnippet
priority 300
context math(context)
snippet `vec([1-9])` "col vector" iwA
\\begin{pmatrix}``
rv = gen_matrix(m[1], 1);
``\\end{pmatrix}$0
endsnippet
priority 300
context math(context)
snippet `vecr([1-9])` "row vector" iwA
\\begin{pmatrix}``
rv = gen_matrix(1, m[1]);
``\\end{pmatrix}$0
endsnippet
# == General ==
snippet \box "Box"
``rv = '┌' + '─'.repeat(t[0].length + 2) + '┐'``
│ $1 │
``rv = '└' + '─'.repeat(t[0].length + 2) + '┘'``
endsnippet
priority 300
snippet `table(\d)(\d)` "create table with rows and columns" wA
``
rv = createTable(m[1], m[2]);
``
endsnippet
snip编写帮助
翻译自 HyperSnips 的 readme
Snippet 文件
Snippet 文件扩展名为.hsnips
,该文件由两种块组成:全局块和 snippet 块。
全局块是 JavaScript 代码块,其代码在当前文件中定义的所有 snippet 之间共享。它们是用 global 关键字定义的,如下所示。
global
// JavaScript代码
endglobal
Snippet 块是 snippet 的定义。它们是用 snippet 关键字定义的,如下所示。
context expression
snippet trigger "description" flags
body
endsnippet
其中触发器是必需的,描述和标志字段是可选的。
触发器 trigger
触发器可以是任何不含空格的字符序列,或由反斜线(`)包围的正则表达式。
标志 flags
标志字段是一连串的字符,用于修改 snippet 的行为,可用的标志有以下几种。
A
:自动扩展 snippet - 通常 snippet 在按下 Tab 键时被激活,如果使用A
标志,snippet 将在其触发器匹配时自动激活,这对正则表达式 snippet 特别有用。
i
: 字内扩展* - 默认情况下,一个 snippet 的触发器仅在触发器前面有空白字符时才会匹配。使用该选项后,无论前面的字符是否为空白字符,snippet 都会被触发。例如,一个 snippet 可以在一个单词的中间被触发。
w
: 单词边界* - 使用该选项后,只有当触发器是一个单词边界的字符时,才会触发 snippet。例如,允许在触发器跟随标点符号的情况下进行扩展,而不扩展较大词的后缀。
b
: 行首扩展* - 使用该选项后,只有触发器是该行的第一个单词时才会触发。换句话说,如果这一行直到触发器之前都只有空白,则展开。
M
: 多行模式 - 默认情况下,正则表达式匹配将只匹配当前行的内容,当该选项被启用时,最后的hsnips.multiLineContext
行将可用于匹配。
标 星号 * 的标志只影响非正则表达式触发器的 snippet。
主体部分 body
body 是在 snippet 展开时将替换触发器的文本,与 Visual Studio Code 通常的 snippet 一样,可以使用制表位 $1
、$2
等。
HyperSnips 的全部功能在使用 JavaScript 时发挥作用:您可以在 snippet 中包含由两个反引号(``)分隔的代码块,代码块将在 snippet 展开时或制表位($1
、$2
等)处的文本改变时运行。
JavaScript 代码块
在代码块中,您可以访问一些特殊变量:
rv
:你的代码块的返回值,这个变量的值会在 snippet 展开时替换代码块。
t
:制表位内文本的数组,其顺序与在 snippet body 中定义的制表位顺序相同。您可以使用它来动态更改 snippet 内容。
m
:正则表达式触发器匹配组的数组,如果触发器不是正则表达式,则为空数组。
w
:当前打开的工作区的 URI 字符串,如果没有工作区打开,则为空字符串。
path
:当前文档的 URI 字符串。(无标题文档具有无标题的方案)
此外,在一个代码块中定义的每个变量都将在 snippet 的所有后续代码块中可用。
require
函数还可用于导入 NodeJS 模块。
上下文匹配
您可以在 snippet 块之前加入上下文行,它后跟任何 javascript 表达式,并且该 snippet 仅在上下文表达式的计算结果为 true 时可用。
在上下文表达式中,您可以使用上下文变量,它具有以下类型:
interface Context {
scopes: string[];
}
此处,scopes
代表当前光标位置的 TextMate
范围,可以通过在 VSCode 中运行 Developer: Inspect Editor Tokens and Scopes
命令来查看。
例如,这里是一个自动的 LaTeX 片段,它只在数学块内扩展:
global
function math(context) {
return context.scopes.some(s => s.includes("math"));
}
endglobal
context math(context)
snippet inv "inverse" Ai
^{-1}
endsnippet
例子
- Simple snippet which greets you with the current date and time
snippet dategreeting "Gives you the current date!"
Hello from your hsnip at ``rv = new Date().toDateString()``!
endsnippet
- 能在输入时够动态改变大小的文本框
snippet box "Box" A
``rv = '┌' + '─'.repeat(t[0].length + 2) + '┐'``
│ $1 │
``rv = '└' + '─'.repeat(t[0].length + 2) + '┘'``
endsnippet
- 插入当前文件名
snippet filename "Current Filename"
``rv = require('path').basename(path)``
endsnippet