配置 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.

from Definition of \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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM