VS Code + HyperSnips + $\LaTeX$笔记速记

你是否想要在上课的时候随着老师讲课写出笔记?你是否钦慕电子笔记工整漂亮的公式?或者你只是想快点写 \(\LaTeX\) 公式?本教程将试着教你如何使用 VS Code + HyperSnips + \(\LaTeX\) 记数学笔记。

内容包括:

  • TeX Live 在 Windows 或 Linux 下的安装。
  • VS Code 的配置。
  • HyperSnips 的配置,并详细解释为什么要这样配置。

我们的目标是在 VS Code 中达到与 Gilles Castel 相当的速度(与手写一样快)。

在用本教程方法之前,您应当注意:

  • markdown 与 typst 也可以用来记笔记,并且远没有 \(\LaTeX\) 这样复杂。如果您的笔记没有「高度定制」的内容,请优先考虑它们。
  • 本教程的配置内容相当繁琐,并且您(至少)需要 1-2 周的练习才能达到上课跟记笔记的速度。
  • 本教程的配置相当私人化(部分配置基于我自己认为更舒服的习惯或感受),您可能需要根据自己的需求进行修改。

TeX Live 安装(Linux)

本节内容根据王然老师的教程对 Linux 的安装进行了修改。

若您是 Windows 或 macOS 用户,请参考他的教程。

请不要使用 sudo apt install texlive-full,因为远挰的包并不一定是最新的,因此 tlmgr 会出错,并且它会导致本地环境相当混乱。因此,推荐通过 .iso 安装。

建议在 TUNA 下载镜像,你可以在主页右侧“获取下载链接”——“应用软件”——“TeX 排版系统”找到,或是在这个页面找到最新的镜像。

同时,执行以下命令安装必要的软件:

1
sudo apt install fontconfig gedit vim -y

下载后,进入下载目录(文件管理器找到位置,右键终端打开),挂载 .iso 文件,并执行 install-tl

1
2
3
4
sudo mkdir /mnt/texlive
sudo mount -o loop texlive.iso /mnt/texlive # 请把 texlive.iso 替换为你的镜像文件名
cd /mnt/texlive
sudo ./install-tl

点击 I 进行默认安装,然后等待安装完成。

安装完成后,执行

1
sudo umount /mnt/texlive

即可卸载镜像。

配置环境变量

接下来,我们需要配置环境变量。复制以下代码到终端中并执行(注意,要修改第 19 行的年份):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 检测当前用户的 shell
user_shell=$(basename "$SHELL")

# 根据 shell 类型设置配置文件路径
case "$user_shell" in
bash)
config_file="$HOME/.bashrc"
;;
zsh)
config_file="$HOME/.zshrc"
;;
*)
echo "Unsupported shell: $user_shell"
exit 1
;;
esac

# 设置 TeX Live 的年份
year=2024 # 请替换为你的年份

# 添加环境变量到配置文件
echo "Adding TeX Live environment variables to $config_file"
{
echo ""
echo "# TeX Live $year configuration"
echo "export PATH=/usr/local/texlive/$year/bin/x86_64-linux:\$PATH"
echo "export MANPATH=/usr/local/texlive/$year/texmf-dist/doc/man:\$MANPATH"
echo "export INFOPATH=/usr/local/texlive/$year/texmf-dist/doc/info:\$INFOPATH"
} >> "$config_file"

# 使配置生效
source "$config_file"

此时,在终端中执行 tex --version,若输出类似如下的内容,则说明安装成功:

1
2
3
4
5
6
7
8
9
TeX 3.141592653 (TeX Live 2024)
kpathsea version 6.4.0
Copyright 2024 D.E. Knuth.
There is NO warranty. Redistribution of this software is
covered by the terms of both the TeX copyright and
the Lesser GNU General Public License.
For more information about these matters, see the file
named COPYING and the TeX source.
Primary author of TeX: D.E. Knuth.

配置字体

接下来刷新处理字体缓存:

1
2
3
4
year=2024 # 请替换为你的年份
sudo cp /usr/local/texlive/$year/texmf-var/fonts/conf/texlive-fontconfig.conf /etc/fonts/conf.d/09-
texlive.conf
sudo fc-cache -fsv

tlmgr 配置

建议直接处理好 tlmgr 的设置:

1
sudo visudo

在打开的文件中找到 Defaults secure_path,在引号最后加上 :/usr/local/texlive/2024/bin/x86_64-linux,然后使用 Ctrl + S, Ctrl + X 退出。

对该命令的解释

sudoers 是一个配置文件,它规定了哪些用户可以以怎样的身份运行什么程序。sudoers 文件的位置在 /etc/sudoers,但是不要直接编辑这个文件,因为这个文件的语法很复杂,而且一旦出错,就无法使用 sudo 命令了。visudo 是一个编辑 sudoers 文件的工具,它会检查语法错误,避免出现错误。所以,我们使用 visudo 来编辑 sudoers 文件。

在 PATH 变量环境中不同的路径之间用 : 分隔。

最后执行

1
2
sudo tlmgr option repository ctan
sudo tlmgr update --self --all

即可完成 TeX Live 的安装。

VS Code 配置

首先,安装 VS Code。

然后,安装以下插件(Ctrl + Shift + X 打开插件商店):

  • LaTeX Workshop
  • HyperSnips for Math

接下来,我们需要配置 VS Code 的设置。

Ctrl + Shift + P 打开命令面板,输入 首选项:打开用户设置(JSON),打开 settings.json

复制以下代码到 settings.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"latex-workshop.latex.autoBuild.run": "onSave",
"latex-workshop.showContextMenu": true,
"latex-workshop.intellisense.package.enabled": true,
"latex-workshop.message.error.show": false,
"latex-workshop.message.warning.show": false,
"latex-workshop.latex.tools": [
{
"name": "xelatex",
"command": "xelatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DOCFILE%"
]
},
{
"name": "pdflatex",
"command": "pdflatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DOCFILE%"
]
},
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"%DOCFILE%"
]
},
{
"name": "bibtex",
"command": "bibtex",
"args": ["%DOCFILE%"]
},
{
"name": "xelatex-minted",
"command": "xelatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"--shell-escape",
"-8bit",
"%DOCFILE%"
]
},
{
"name": "pdflatex-minted",
"command": "pdflatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"--shell-escape",
"%DOCFILE%"
]
}
],
"latex-workshop.latex.recipes": [
{
"name": "XeLaTeX",
"tools": ["xelatex"]
},
{
"name": "PDFLaTeX",
"tools": ["pdflatex"]
},
{
"name": "BibTeX",
"tools": ["bibtex"]
},
{
"name": "LaTeXmk",
"tools": ["latexmk"]
},
{
"name": "xelatex-minted",
"tools": ["xelatex-minted"]
},
{
"name": "pdflatex-minted",
"tools": ["pdflatex-minted"]
},
{
"name": "xelatex -> bibtex -> xelatex*2",
"tools": ["xelatex", "bibtex", "xelatex", "xelatex"]
},
{
"name": "xelatex-minted -> bibtex -> xelatex-minted*2",
"tools": ["xelatex-minted", "bibtex", "xelatex-minted", "xelatex-minted"]
},
{
"name": "pdflatex -> bibtex -> pdflatex*2",
"tools": ["pdflatex", "bibtex", "pdflatex", "pdflatex"]
}
],
"latex-workshop.latex.clean.fileTypes": [
"*.aux",
"*.bbl",
"*.blg",
"*.idx",
"*.ind",
"*.lof",
"*.lot",
"*.out",
"*.toc",
"*.acn",
"*.acr",
"*.alg",
"*.glg",
"*.glo",
"*.gls",
"*.ist",
"*.fls",
"*.log",
"*.fdb_latexmk"
],
"latex-workshop.latex.autoClean.run": "onFailed",
"latex-workshop.latex.recipe.default": "lastUsed",
"latex-workshop.view.pdf.internal.synctex.keybinding": "double-click"

对以上部分代码的解释

  • "latex-workshop.latex.autoBuild.run": "onSave",: 当保存时自动编译,替代选项是 onFileChange(在检测到任何依赖文件发生更改时,即使是由其他应用程序修改的,也会构建项目)。在初期不太熟练,需要及时查看效果时,这样可以快速预览,同时又不像 onFileChange 那样频繁编译。
  • "latex-workshop.message.error.show": false,"latex-workshop.message.warning.show": false, 用于关闭错误和警告的显示,因为当你在写笔记时,这些信息会干扰你的注意力,并且错误提示对于排查问题并不是很有用。
  • "latex-workshop.latex.tools" 定义了一些编译工具,这里定义了 xelatex, pdflatex, latexmk, bibtex, xelatex-minted, pdflatex-minted。每条内容分别定义了工具的名称、命令、参数。
  • "latex-workshop.latex.recipes" 定义了一些编译方案,这里定义了 XeLaTeX, PDFLaTeX, BibTeX, LaTeXmk, xelatex-minted, pdflatex-minted, xelatex -> bibtex -> xelatex*2, xelatex-minted -> bibtex -> xelatex-minted*2, pdflatex -> bibtex -> pdflatex*2
  • "latex-workshop.latex.clean.fileTypes" 定义了一些需要清理的文件类型。
  • "latex-workshop.latex.autoClean.run": "onFailed", 定义了在编译失败时自动清理。替代选项是 onBuilt(在构建完成后清理)。使用 onBuilt 可以让你的文件夹更干净;使用 onFailed 可以让你编译快一点(在使用编译链配方并且有 bibtex 无关修改时,可以先编译一次,保留文件,随后只使用基础配方快速得到完整文件)。
  • "latex-workshop.latex.recipe.default": "lastUsed", 定义了默认的编译方案。替代选项是 firstlastUsed 可以让你在不同文件中使用不同的编译方案。
  • "latex-workshop.view.pdf.internal.synctex.keybinding": "double-click" 定义了在 PDF 中双击时进行反向搜索。替代选项是 ctrl/cmd + click(默认)。

此时,你的 .tex 文件应该可以正常编译了。找个文件夹,新建一个 .tex 文件,输入以下内容:

1
2
3
4
\documentclass{article}
\begin{document}
Hello, world!
\end{document}

编译器的选择

当你不知道该用什么时选择 xelatex 配方。

LaTeX 是一个排版系统,而不是一个编程语言。因此,它需要一个编译器来将 .tex 文件编译成 .pdf 文件。常见的编译器有 pdflatex, xelatex, lualatex。我们安装的 TeX Live 包含了这三个编译器,以及一些其他的工具。

  • pdflatex 是旧的 TeX 语言的实现,并不支持 Unicode 字符和 OpenType 字体。但是,它的兼容性很好(可以使用一些老的包),因此在一些老的模板中仍然使用。
  • xelatex 是基于 XeTeX 的实现,支持 Unicode 字符和 OpenType 字体。它是现在最常用的编译器。
  • lualatex 是基于 LuaTeX 的实现,支持 Unicode 字符和 OpenType 字体,同时还支持 Lua 语言。它的速度比 xelatex 快,但是在一些包的兼容性上不如 xelatex

我们的配方还提供了 xelatex-mintedpdflatex-minted,这两个配方支持 minted 包,这是一个用于代码高亮的包。该配方编译时多了 --shell-escape 参数,因为该包通过调用外部 pygments 程序来进行代码高亮。但是,该参数使得编译过程中可以执行外部程序,因此可能会有一些安全问题,因此平常不建议使用这两个配方。

配方中还有一些链配方,如 xelatex -> bibtex -> xelatex*2,这种配方可以在编译时自动编译参考文献。这种配方在第一次编译时会生成 .aux 文件,第二次编译时会生成 .bbl 文件,第三次编译时会将参考文献插入到文档中。在没有参考文献的情况下这个配方会报错,因此在没有参考文献的情况下使用 xelatex 配方即可。

此外,本人没有用过 biblatex,因此没有配置 biber,如果你需要使用 biblatex,请自行配置。

保存后编译,VS Code 下方栏应该出现一个 ,表示编译成功,并生成了一个 .pdf 文件。焦点在 .pdf 文件上,按 Ctrl + Alt + V,应该可以看到预览。

双向检索

双向检索是指在 PDF 中双击可以跳转到源文件,而在源文件中按快捷键可以跳转到 PDF。这个功能需要在编译时生成 .synctex.gz 文件,因此需要在编译时添加 -synctex=1 参数。

LaTeX workshop 默认的使用 Ctrl + Alt + J 进行 .tex 文件到 .pdf 文件的跳转,并且我们在上面的配置中将双击 PDF 文件作为 .pdf 文件到 .tex 文件的跳转。

编译纠错

若编译出错,VS Code 底部会出现一个 ×。在 .tex 文件中,错误的行会被标记出来。但是,有时候错误信息并不明确,这时可以使用 Ctrl + Alt + X 打开 LaTeX Workshop 的侧边栏,选择 “查看日志消息” - “查看 LaTeX 编译日志”,可以找出错误的原因。

HyperSnips 配置

Ctrl + Shift + P 打开命令面板,输入 HyperSnips: Open Snippets Directory,打开 snippets 文件夹。在其中新建 latex.hsnips 文件,并输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
global
// JavaScript code
function gen_matrix(nrow, ncol) {
let results = "";
let order = 1;
for (var i=0; i < nrow; i++){
results += ' ';
for(var j = 0; j < ncol - 1; j++){
results += "$" + (order).toString() + " & ";
order ++;
}
results += "$" + (order).toString() + " \\\\" + "\\\n";
order ++;
}
return results;
}

function gen_matrix_transposed(nrow, ncol) {
let results = "";
for (var i = 0; i < nrow; i++){
results += ' ';
var j = 0;
for(; j < ncol - 1;j++){
results += "$" + (i + j * ncol + 1).toString() + " & ";
}
results += "$" + (i + j * ncol + 1).toString() + " \\\\" + "\\";
}
return results;
}

function tes_matrix(nrow, ncol,t) {
let results = "";
let order = 1;
for (var i=0; i<nrow; i++){
results += ' ';
for(var j = 0;j <ncol-1;j++){
if (order > 1 ){
results += "${" +(order ).toString() + ":" + t[order-2] + "}\t & ";
}
else{
results += "$" +(order ).toString() + " & ";
}
order ++;
}
results += "$"+(order).toString() +" \\\\" + "\\ ";
order ++;
}
return results;
}

function gen_tabular(nrow, ncol) {
let results = "";
let order = 3;
results += '\\' + "begin{tabular}{"
for(var j = 0; j < ncol; j++){
if(j==ncol-1){
results += " ${" + (order).toString() + ":c} ";
}
else {results += " ${" + (order).toString() + ":c} ${" + (order+1).toString() + ":|}";}
}
results += '}'
order+=2;
results += '\n \\hline\n '
for(var j = 0; j < ncol - 1; j++){
results += "$" + (order).toString() + " & ";
order ++;
}
results += "$" + (order).toString() + " \\\\" + "\\\n";
order ++;
results += ' \\hline\n '
for (var i=0; i < nrow-1; i++){
results += '';
for(var j = 0; j < ncol - 1; j++){
results += "$" + (order).toString() + " & ";
order ++;
}
results += "$" + (order).toString() + " \\\\" + "\\\n ";
order ++;
}
results += '\\hline'
return results;
}

endglobal

# == Fraction Match ==

snippet // "Fraction" iAm
\\frac{${1:${VISUAL}}}{$2}$0
endsnippet

snippet `((\d+)|(\d*)(\\)?([A-Za-z!]+)((\^|_)(\{\d+\}|\d))*)/` "Fraction no ()" iAm
\frac{``rv = m[1]``}{$1}$0
endsnippet

priority 200
snippet `^.*\)/` "Fraction with ()" A
``
let str = m[0];
str = str.slice(0, -1);
let lastIndex = str.length - 1;

let depth = 0;
let i = str.length - 1;

while (true) {
if (str[i] == ')') depth += 1;
if (str[i] == '(') depth -= 1;
if (depth == 0) break;
i -= 1;
}

let results = str.slice(0, i) + "\\frac{" + str.slice(i+1, -1) + "}";
results += "{$1}$0";
rv = results;
``
endsnippet

# == Hat Operation ==

# ==== Auto Capture Hat Operation ====
snippet `(\\?[a-zA-Z]\w*({?\w*})?)(hbar)` "Bar" iAm
\overline{``rv = m[1]``}
endsnippet

snippet `(\\?[a-zA-Z]\w*({?\w*})?)(htd)` "tilde" iAm
\tilde{``rv = m[1]``}
endsnippet
# 上标 ~

snippet `(\\?[a-zA-Z]\w*({?\w*})?)bar` "bar" iAm
\bar{``rv = m[1]``}
endsnippet

snippet `(\\?[a-zA-Z]\w*({?\w*})?)(hat)` "hat" iAm
\hat{``rv = m[1]``}
endsnippet
# 上标 ^

snippet `(\\?[a-zA-Z]\w*({?\w*})?)(hvec)` "Vector postfix" iAm
\vec{``rv = m[1]``}
endsnippet
# 小上标 ->

snippet `(\\?[a-zA-Z]\w*({?\w*})?)(rta)` "Vector postfix" iAm
\overrightarrow{``rv = m[1]``}
endsnippet
# 上标向量

snippet dot "dot" iAm
\dot{$1}$0
endsnippet

priority 1000
snippet hdd "ddot" iAm
\ddot{$1}$0
endsnippet

snippet hsq "\sqrt{}" iAm
\sqrt[]{${1}}$0
endsnippet
#[]中写左上角标。

snippet dig "digree" iAm
^{\circ}
endsnippet

snippet pow "power" iAm
^{$1}$0
endsnippet

snippet sb "subscript" iAm
_{$1}$0
endsnippet

snippet `(})(\d)\2` "auto subscript" iAm
`` rv = m[1] + "_{" + m[2] + "}$0"``
endsnippet
# }xx, xx为相同数字

snippet `([A-Za-z])(\d)` "auto subscript" iAm
`` rv = m[1] + "_{" + m[2] + "}$0" ``
endsnippet

priority 100
snippet `([A-Za-z])_{(\d)}(\d)` "auto subscript" iAm
`` rv = m[1] + "_{" + m[2] + m[3] + "}$0" ``
endsnippet

snippet `\b(?<!\\)([A-Za-z}])([a-z])\2` "auto subscript 2" iAm
`` rv = m[1] + "_{" + m[2].substring(0, 1) + "}$0"``
endsnippet

# Custom: Add more greek letters
snippet `(\\mu|\\alpha|\\sigma|\\rho|\\beta|\\gamma|\\delta|\\zeta|\\eta|\\varepsilon|\\epsilon|\\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|\\varGamma)([a-z])\2` "auto subscript for greek letter" iAm
`` rv = m[1] + "_{" + m[2].substring(0, 1) + "}" ``
endsnippet

# == Font Operation ==

# ==== Static Operation ====

snippet txt "text" iA
\text{$1}$0
endsnippet

snippet tit "text it" iA
\textit{$1}$0
endsnippet
# 斜体字体

priority 1000
snippet mbb "mathbb" iAm
\mathbb{$1}$0
endsnippet

snippet RR "R" iAm
\mathbb{R}
endsnippet

snippet NN "N" iAm
\mathbb{N}
endsnippet

snippet ZZ "Z" iAm
\mathbb{Z}
endsnippet

snippet QQ "Q" iAm
\mathbb{Q}
endsnippet

snippet CC "C" iAm
\mathbb{C}
endsnippet

# ==== Dynamic Operation ====

priority 100
snippet `(\\?[a-zA-Z]\w*({?\w*})?)(bf|BF)` "mathbf" iAm
\mathbf{``rv = m[1]``$1}$0
endsnippet
# 正体加粗

priority 100
snippet `(\\?[a-zA-Z]\w*({?\w*})?)(bm|BM)` "mathbm" iAm
\bm{``rv = m[1]``$1}$0
endsnippet

priority 100
snippet `(\\?[a-zA-Z]\w*({?\w*})?)(bs)` "boldsymbol" iAm
\boldsymbol{``rv = m[1]``}
endsnippet

priority 100
snippet `(\\?[a-zA-Z]\w*({?\w*})?)(sf)` "mathsf" iAm
\mathsf{``rv = m[1]``}
endsnippet
# 无衬线体

priority 100
snippet `(\\?[a-zA-Z]\w*({?\w*})?)(frak)` "mathfrak" iAm
\mathfrak{``rv = m[1]``}
endsnippet
# 斯拉夫字体

priority 100
snippet `(\\?[a-zA-Z]\w*({?\w*})?)cal` "mathcal" iAm
\mathcal{``rv = m[1].toUpperCase()``}$0
endsnippet

priority 100
snippet `(?<!\\)\b([a-zA-Z]+)rm` "mathrm" iAm
\mathrm{``rv = m[1]``}
endsnippet
# 字母由数学斜体变为正体,即罗马体。

priority 100
snippet `(?<!\\)\b([a-zA-Z]+)opn` "operatorname" iAm
\operatorname{``rv = m[1]``}
endsnippet

# == Auto Symbol ==

snippet oo "\infty" iAmm
\infty
endsnippet

snippet ... "cdots" iAm
\cdots
endsnippet

snippet cdots; "vdots" iAm
vdots
endsnippet

snippet vdots; "ddots" iAm
ddots
endsnippet

snippet `(\d\d+);;` "0, 1, 2, ..., n" iAm
``rv = m[1].split('').map((d) => "${1:a}_" + d + " ${2:b}_" + d + "${3:,} ").join('');``\ldots${3:,} ${1:a}_${4:n} ${2:b}_${5:n}$0
endsnippet
# 多按 tab

snippet `(\d\d+)\.\.` "0, 1, 2, ..., n" iAm
``rv = m[1].split('').map((d) => "${1:a}_" + d + "${2:,} ").join('');``\ldots${2:,} ${1:a}_${3:n}$0
endsnippet
# 输入12..

snippet `(\d\d+),,` "0, 1, 2" iiAm
``rv = m[1].split('').map((d) => "${1:a}_" + d).join("${2:,} ");``
endsnippet
# 输入12,

snippet <> "Diamond" iA
\diamond
endsnippet

# +... -> , \cdots
# - ... -> , \cdots
# add a space if there already is one.
priority 101
snippet `(?<=[-+])\s*\.\.\.` "smart cdots" imA
\cdots
endsnippet

# It seems that \ldots is only used when , ...,
# ,... -> , \ldots
# , ... -> , \ldots
priority 101
snippet `(?<=,)(\s*)\.\.\.` "smart ldots" imA
\ldots
endsnippet

snippet ** "dot multiply" iAm
\cdot
endsnippet

snippet +- "pm" iAm
\pm
endsnippet

snippet -+ "mp" iAm
\mp
endsnippet

priority 101
snippet xx "cross" iAm
\times
endsnippet

snippet eps "epsilon" iAm
\epsilon
endsnippet

priority 100
snippet veps "varepsilon" iAm
\varepsilon
endsnippet

priority 100
snippet ell "ell" iAm
\ell
endsnippet

priority 100
snippet log "log" iAm
\log
endsnippet

snippet bin "binom" iAm
\binom{$1}{$2}
endsnippet

snippet oth "otherwise" iAm
\text{otherwise}
endsnippet

snippet star "star" iAm
^{*}
endsnippet

snippet `(?<!\\)(oint|iiint|iint|int)` "integrate" iAm
\\``rv = m[1]``_{$1}^{$2} $0
endsnippet

snippet `(?<!\\)(min|max|argmin|argmax|sup|inf)` "min|max|argmin|argmax|sup|inf" iAm
\\``rv = m[1]``
endsnippet

snippet `(?<!\\)(sin|cos|tan|arccot|cot|csc|ln|exp|det|perp|arcsin|arccos|arctan|arccot|arccsc|arcsec|ell|nabla|notin|not)` "function" iAm
\\``rv = m[1] + " "``$0
endsnippet

priority 1000
snippet `(?<!\\)(mu|alpha|sigma|rho|beta|Beta|gamma|delta|pi|zeta|eta|varepsilon|theta|iota|kappa|vartheta|lambda|nu|rho|tau|upsilon|varphi|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)` "greek" iAm
\\``rv = m[1]``
endsnippet

snippet U\psilon "tocorret" iAm
\Upsilon
endsnippet

snippet u\psilon "tocorret" iAm
\upsilon
endsnippet

snippet `\\not ?in` "notin" iAm
``rv = "\\notin "``$0
endsnippet

snippet `\\not ?EE` "notexists" iAm
``rv = "\\nexists "``$0
endsnippet

priority 200
snippet inn "in" iAm
\in
endsnippet

priority 200
snippet `\\ln ?ot` "in" iA
\lnot
endsnippet

priority 2000
snippet varGamma "\varGamma" iAm
\varGamma
endsnippet

priority 200
snippet \pii "p_i" iAm
p_i
endsnippet

snippet sse "subseteq" iAm
\subseteq
endsnippet

snippet sqs "sqsubset" iAm
\sqsubseteq
endsnippet

snippet tto "to" iAm
\to
endsnippet

snippet -< "leftrightarrow(le-ri-ar)" iAm
\leftrightarrow
endsnippet

snippet <- "leftarrow" iAm
\leftarrow
endsnippet

priority 200
snippet `(?<!\\)(cap|cup|land|lor|lnot|oplus|ominus|otimes|sqcap|sqcup|vdash|models|uparrow|downarrow|vDash|nvDash)` "logic operator" iAm
\\``rv = m[1]``
endsnippet

priority 200
snippet `(?<=\b|\d+)(?<!\\)(bot|top|dagger)` "logic symbols" iAm
\\``rv = m[1]``
endsnippet

snippet li "limits" im
\limits_{$1}^{$2} $0
endsnippet

snippet -> "to" iAm
\to
endsnippet

snippet !> "mapsto" iAm
\mapsto
endsnippet

snippet => "implies" iAm
\implies
endsnippet

snippet =< "implied by" iAm
\impliedby
endsnippet

priority 200
snippet iff "if and only if" iAm
\iff
endsnippet

snippet EE "exist" iAm
\exists
endsnippet

snippet AA "forall" iAm
\forall
endsnippet

snippet bec "because" iAm
\because
endsnippet

snippet thr "therefore" iAm
\therefore
endsnippet

snippet >= "greater than" iAm
\geqslant $0
endsnippet

snippet dis "displaystyle" iAm
\displaystyle
endsnippet

snippet <= "less than" iAm
\leqslant $0
endsnippet

snippet != "no equals" iAm
\neq
endsnippet

snippet == " constan equals" iAm
\equiv
endsnippet

snippet sim "sim" iAm
\sim
endsnippet

snippet `\\sim eq` "simeq" iAm
\simeq
endsnippet

snippet ~~ " Amppro equals" iAm
\approx
endsnippet

snippet ~= " Amppro equals2" iAm
\cong
endsnippet

snippet >> ">>" iAm
\gg
endsnippet

snippet << "<<" iAm
\ll
endsnippet

# == Auto Environment ==

# ==== Auto Math Mode ====

snippet lm "inline Math" iA
$${1}$$0
endsnippet

snippet and "&" iiwAm
&
endsnippet

snippet eqt "equation" wA
\begin{equation}
${1}
\end{equation}$0
endsnippet

snippet eqs "equation*" wA
\begin{equation*}
${1}
\end{equation*}
endsnippet

# ==== Common Environment ====

snippet case "cases" iAm
\begin{cases}
$1, & $2 \\\\
$3, & $4 \\\\
\end{cases}
endsnippet

snippet ali "aligned" iAm
\begin{aligned}
$1 \\\\
\end{aligned}
endsnippet

# == Auto Adaptive Close ==

snippet ceil "ceil" iAm
\left\lceil $1 \right\rceil $0
endsnippet

snippet floor "floor" iAm
\left\lfloor $1 \right\rfloor$0
endsnippet

priority 100
snippet set "\{ \}" Aim
\\{ ${1} \mid ${2} \\}$0
endsnippet

priority 200
snippet norm "Norm" iAm
\left\| ${1} \right\|$2
endsnippet

priority 200
snippet abs "absolute value" iAm
\left\lvert ${1} \right\rvert $0
endsnippet

snippet Vert "Verts" iAm
\left\Vert $1 \right\Vert $0
endsnippet

snippet beg "begin{" b
\\begin{
endsnippet

snippet taylor "taylor" iAm
\sum_{${1:k}=${2:0}}^{${3:\infty}} ${4:c_$1} (x-a)^$1 $0
endsnippet

snippet `(?<!\\)lim` "limit" iAm
\lim_{${1:n} \to ${2:\infty}}
endsnippet

snippet `(?<!\\)sum` "sum_{min}^{max}" iAm
\sum_{${1:min}}^{${2:max}}
endsnippet

snippet `(?<!\\)SUM` "Common sum" iAm
\sum
endsnippet

snippet `(?<!\\)prod` "product" iAm
\prod_{${1:n=${2:1}}}^{${3:\infty}} ${4:${VISUAL}} $0
endsnippet

snippet `(?<!\\)part` "d/dx" iAm
\frac{\partial ${1:V}}{\partial ${2:x}} $0
endsnippet

priority 300
snippet `(?<!\\)diff` "d/dx" iAm
\frac{\mathop{}\!\mathrm{d}${1:y}}{\mathop{}\!\mathrm{d}${2:x}} $0
endsnippet

priority 400
snippet `(?<!\\)2diff` "d/dx" iAm
\frac{\mathrm{d}^2${1:y}}{\mathrm{d}${2:x}^2} $0
endsnippet

priority 400
snippet `(?<!\\)3diff` "d/dx" iAm
\frac{\mathrm{d}^3${1:y}}{\mathrm{d}${2:x}^3} $0
endsnippet

priority 300
snippet `dd` "dd" iAm
\mathop{}\!\mathrm{d}
endsnippet

priority 300
snippet buu "bigcup" im
\bigcup_{${1:i \in ${2: I}}} $0
endsnippet

snippet bnn "bigcap" im
\bigcap_{${1:i \in ${2: I}}} $0
endsnippet

priority 100
snippet dint "integral" iAm
\int_{${1:-\infty}}^{${2:\infty}} ${3} \\,\\mathrm{d}${4:x}$0
endsnippet

priority 200
snippet `c(o|n)?(l|n)?(b|c)?int` "s egral" iAm
``
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
snippet `(?<![\a-zA-Z])(rank|trace|svd|eye|ones|orth|rows|cols|zeros|diag|rref|hstack|vstack|nullspace|eigen|dim|lcm|gcd|atan2|softmax|eig|sign|const)` "math function" iAm
\\operatorname{``rv = m[1]``}
endsnippet

# ====== Big Snippet ======

snippet over "overset" im
\overset{$1}{$2}$0
endsnippet

snippet done "done" iAm
\hfill\Box
endsnippet

snippet iid "independent and identical distribution" iAm
\overset{\text{i.i.d.}}{\sim}
endsnippet

snippet defe "define equal" iAm
\overset{\mathrm{def}}{=}
endsnippet

snippet deft "define triangleq" iAm
\triangleq
endsnippet

# == Matrix ==

# ==== Dynamic Matrix ====

priority 300
snippet `(b|p|v)mata([1-9])` "bmatrix" iiAm
\\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
snippet `(b|p|v)mat-([1-9])([1-9])` "bmatrix" iiAm
\\begin{``rv = m[1]``matrix}``
rv = "\n" + gen_matrix(m[2],m[3]); + "\n"
``\\end{``rv = m[1]``matrix}$0
endsnippet

priority 2000
snippet `(b|p|v)matr([1-9]{1})` "bmatrix" iiAm
\\begin{``rv = m[1]``matrix}``
rv = gen_matrix_transposed(m[2],m[2]);
``\\end{``rv = m[1]``matrix}$0
endsnippet

# == General ==

snippet label "label" i
\label{${1:randlabel:}``rv = Math.random().toString(36).slice(-10)``}$0
endsnippet

priority 300
snippet figure "figure" i
\begin{figure}[h!]
\centering
\includegraphics[width=1.77in,height=1.75in]{$1}
\caption{$2}
\label{fig:``rv = Math.random().toString(36).slice(-10)``}
\end{figure}
$0
endsnippet

priority 300
snippet tabular "tabular"
\begin{table}[h!]
\caption{$1}
\label{tabular:``rv = Math.random().toString(36).slice(-10)``}
\begin{center}
\begin{tabular}{$3}
\hline
$4\\\\
\hline
$5\\\\
\hline
\end{tabular}
\end{center}
\end{table}
endsnippet

priority 300
snippet `tabular-([1-9])([1-9])` "tabularxx" ibA
\begin{table}[h!]
\caption{$1}
\label{tabular:``rv = Math.random().toString(36).slice(-10)``}
\begin{center}
``rv = gen_tabular(m[1], m[2])``
\end{tabular}
\end{center}
\end{table}
endsnippet

priority 100
snippet `(?<![\a-zA-Z])(span|id)` "math function" iAm
\\operatorname{``rv = m[1]``}_{$1}$0
endsnippet

priority 100
snippet `(?<![\a-zA-Z])(Im|ker)` "math function" iAm
\\operatorname{``rv = m[1]``}$0
endsnippet

snippet circ "circ" iAm
\\circ
endsnippet

snippet `(\}|\]|\)|\|)(b|bb)ig` iAm
``
rv="\\big";
let b=m[2].length;
(b==1)?(rv+="l"):(rv+="gl");
(m[1]=="}")?(rv+="\\{"):(m[1]=="]")?(rv+="["):(m[1]==")")?(rv+="("):(rv+="|");
rv+="$1 \\big";
(b==1)?(rv+="r"):(rv+="gr");
(m[1]=="}")?(rv+="\\\\}"):(rv+=m[1]);
rv+="$0"
``
endsnippet

snippet `(\}|\]|\)|\|)(B|BB|Bb)ig` iAm
``
rv="\\Big";
let b=m[2].length;
(b==1)?(rv+="l"):(rv+="gl");
(m[1]=="}")?(rv+="\\{"):(m[1]=="]")?(rv+="["):(m[1]==")")?(rv+="("):(rv+="|");
rv+="$1 \\Big";
(b==1)?(rv+="r"):(rv+="gr");
(m[1]=="}")?(rv+="\\\\}"):(rv+=m[1]);
rv+="$0"
``
endsnippet

snippet \< "< >" iAm
\langle $1 \rangle $0
endsnippet

snippet vecC "column vector" iAm
\begin{bmatrix} ${1:x}_1 \\\\ ${1:x}_2 \\\\ \vdots \\\\ ${1:x}_${2:n} \end{bmatrix}
endsnippet

snippet vecR "row vector" iAm
\begin{bmatrix} ${1:x}_1, ${1:x}_2, \cdots, ${1:x}_${2:n} \end{bmatrix}$0
endsnippet

priority 300
snippet omis "omission" im
\\begin{bmatrix}
${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{bmatrix}
endsnippet

priority 300
snippet submat "omission" im
\\begin{bmatrix}
${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{bmatrix}
endsnippet

priority 300
snippet subplusmat "omission" im
\\begin{bmatrix}
${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{bmatrix}
endsnippet

snippet jacobi "jacobi" im
\\begin{bmatrix}
\\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{bmatrix}
endsnippet

使用说明

代码片段的核心思想就是通过能够较快输入的字符(触发字符,最好短、并且不容易与其他字符冲突)来触发代码片段的生成,从而减少输入时间。

HyperSnips 的代码片段是通过正则表达式来匹配触发字符的,并且由 Orange X4 大佬开发的版本支持代码片段只在数学环境下触发。

每个代码片段的格式如下:

1
2
3
snippet 触发字符 "代码片段描述" 触发条件
代码片段内容
endsnippet

其中:

  • 触发字符:触发代码片段的字符,可以是一个字符串,也可以是一个正则表达式。
  • 代码片段描述:代码片段的描述,用于在代码片段提示框中显示。
  • 触发条件:触发代码片段的条件,可以是 i(在词语内部也会触发)、A(自动展开)、m(数学模式)。
  • 代码片段内容:代码片段的具体内容,支持使用光标位置、传入参数、使用函数等。

光标位置是由 vscode-snippet 的语法来实现的,可以通过 ${1}${2} 等来表示光标位置,${0} 表示最终的光标位置。

传入的参数是片段中类似 ``rv = m[1]`` 这样的代码,其中 m[1] 表示第一个传入的参数,rv 表示返回的结果。

这里提供了一些常用的代码片段的速查表,可以根据自己的需求进行修改。代码现已经过编辑尽可能不冲突,并符合 LaTeX 的语法习惯。

代码片段速查表

触发方式 代码片段描述 说明
lm Inline Math 生成行内数学公式,即 $...$
eqt Equation 生成 equation 环境,即 \begin{equation} ... \end{equation}
eqs Equation* 生成 equation* 环境,即 \begin{equation*} ... \end{equation*}。其为不编号的行间公式。
选中文本后按 // Fraction 将选择的文本放在分子上,\frac{分子}{分母} 在数学环境中生成分式
输入一个变量名后按 / Fraction no () 变量符合“数字 字母 (下滑线)数字”的格式,如 11x_{31}
(内容)/ Fraction with () 将括号内的文本放在分子上,分母为括号,即生成 \frac{括号内的内容}{}
文字+hbar Bar 效果如 \(\overline{a}\)(Overline 的 上划线更长,适合长文本)
文字+htd Tilde 效果如 \(\tilde{a}\)
文字+bar Bar 效果如 \(\bar{a}\) (Bar 的 上划线更短,适合单字母)
文字+hat Hat 效果如 \(\hat{a}\)
文字+hvec Vector postfix 效果如 \(\vec{a}\) (Vector 的箭头更短)
文字+rta Vector postfix 效果如 \(\overrightarrow{a}\)
dot Dot 效果如 \(\dot{a}\)
hdd Ddot 效果如 \(\ddot{a}\)
hsq Sqrt 效果如 \(\sqrt{a}\) (其中,\sqrt[n]{a} 为 n 次根号)
dig Degree 效果如 \(a^{\circ}\)
pow Power 效果如 \(a^{b}\)
sb Subscript 效果如 \(a_{b}\)
}xx(xx 为相同数字) Auto subscript 将相同数字的内容自动转换为下标,如 }11 变为 _{1}
a2 Auto subscript 将字母后跟的数字自动转换为下标,如 a1 变为 a_{1}
a_{2}3 Auto subscript 将字母后跟的两个数字自动转换为下标,如 a_{1}2 变为 a_{12}
taa Auto subscript 2 将字母后跟的相同小写字母自动转换为下标,如 aaa 变为 a_a
希腊字母+aa(两个相同字母) Auto subscript for greek letter 将希腊字母后跟的小写字母自动转换为下标,如 \alphaaa 变为 \alpha_{a}
txt Text 效果如 \(\text{a}\),用于普通文本
tit Text it 效果如 \(\textit{a}\),用于斜体文本
mbb Mathbb 效果如 \(\mathbb{A}\),用于黑板粗体字母
RR、NN、ZZ、QQ、CC R、N、Z、Q、C 数集符号 \(\mathbb{R N Z Q C}\),即黑板粗体字母的快速写法
文字 + bf 或 BF Mathbf 效果如 \(\mathbf{a}\),用于正体加粗
文字 + bm 或 BM Mathbm 形成 \bm{a} ( markdown 不含此效果)
文字 + bs Boldsymbol 效果如 \(\boldsymbol{a}\),用于粗体符号
文字 + sf Mathsf 效果如 \(\mathsf{a}\),用于无衬线体
文字 + frak Mathfrak 效果如 \(\mathfrak{a}\),用于斯拉夫字体
文字 + cal Mathcal 效果如 \(\mathcal{A}\),用于花体字母。由于花体只支持大写字母,因而自动转大写
文字 + rm Mathrm 效果如 \(\mathrm{a}\),用于正体字母
文字 + opn Operatorname 效果如 \(\operatorname{a}\),用于定义算子(例,如默认无 \(\operatorname{rank}\) 算子,可使其以算子字体渲染)
oo infinity 生成 \(\infty\)
... cdots 生成 \(\cdots\),对应代码为 \codts
cdots; vdots 生成 \(\vdots\),对应代码为 \vdots。即,先按 ...,再按 ; 就等效输入 vdots
vdots; ddots 生成 \(\ddots\),对应代码为 \ddots。同上理。
12;; 0, 1, 2, ..., n 按n和n+1连续增加数字,生成 a_1 b_1, a_2 b_2, \ldots, a_n b_n,其中 a b n 可以分别修改。
12.. 0, 1, 2, ..., n 同上理,生成 a_1, a_2, \ldots, a_n
12,, 0, 1, 2 类似地,生成 a_1, a_2
<> Diamond 生成 \(\diamond\)
+...-... Smart cdots 生成 \cdots,用于表示省略号。若前面有空格,则保留空格。
,... Smart ldots 生成 \ldots,用于表示省略号。若前面有空格,则保留空格。
** Dot multiply 生成 \(\cdot\),用于表示点乘。
+- pm 生成 \(\pm\),用于表示正负号。
-+ mp 生成 \(\mp\),用于表示负正号。
xx Cross 生成 \(\times\),用于表示乘号。
eps Epsilon 生成 \(\epsilon\),用于表示希腊字母 epsilon。
veps Varepsilon 生成 \(\varepsilon\),用于表示希腊字母 varepsilon。
ell Ell 生成 \(\ell\),用于表示希腊字母 ell。
log Log 生成 \(\log\),用于表示对数函数。
bin Binom 生成 \(\binom{a}{b}\),用于表示二项式系数。
oth Otherwise 生成 \(\text{otherwise}\),用于表示其他情况。
star Star 生成 \(^{*}\),用于表示上标星号。
U tocorret 生成 \(\Upsilon\),用于表示希腊字母 Upsilon。此条是为了纠正由于打一半 psi 展开为 \psi 导致的错误。
u tocorret 生成 \(\upsilon\),用于表示希腊字母 upsilon。同上。
(空格)in notin 生成 \(\notin\),用于表示不属于。由上片段输入 not 会自动变为 \not带空格的版本,因而加此条。
(空格)EE notexists 生成 \(\nexists\),用于表示不存在。由上片段输入 not 会自动变为 \not带空格的版本,因而加此条。
inn in 生成 \(\in\),用于表示属于。
(空格)ot lnot 生成 \(\lnot\),用于表示逻辑非。
varGamma varGamma 生成 \(\varGamma\),用于表示希腊字母 varGamma。
\pii p_i 生成 \(p_i\),用于表示下标 i 的 p。为 \pi 的纠正。
sse Subseteq 生成 \(\subseteq\),用于表示子集等于。
sqs Sqs 生成 \(\sqsubseteq\),用于表示平方子集等于。
tto To 生成 \(\to\),用于表示箭头符号。
-< Leftrightarrow 生成 \(\leftrightarrow\),用于表示双向箭头符号。
<- Leftarrow 生成 \(\leftarrow\),用于表示左箭头符号。
li Limits \sin\limits_{a}^{b} 生成如 \(\sin\limits_{a}^{b}\),用于表示上下限。
-> To 生成 \(\to\),用于表示箭头符号。
!> Mapsto 生成 \(\mapsto\),用于表示映射到符号。
=> Implies 生成 \(\implies\),用于表示蕴含符号。
=< Implied by 生成 \(\impliedby\),用于表示被蕴含符号。
iff If and only if 生成 \(\iff\),用于表示当且仅当符号。
EE Exist 生成 \(\exists\),用于表示存在符号。
AA Forall 生成 \(\forall\),用于表示全称量词符号。
bec Because 生成 \(\because\),用于表示因为符号。
thr Therefore 生成 \(\therefore\),用于表示所以符号。
>= Greater than 生成 \(\geqslant\),用于表示大于等于符号。
dis Displaystyle 生成 \displaystyle,此命令加在行内的数学公式前,可以使其显示为行间公式(更高的版本)。
<= Less than 生成 \(\leqslant\),用于表示小于等于符号。
!= No equals 生成 \(\neq\),用于表示不等于符号。
== Constant equals 生成 \(\equiv\),用于表示恒等符号。
sim Sim 生成 \(\sim\),用于表示相似符号。
eq Simeq 生成 \(\simeq\),用于表示约等于符号。
~~ Approx equals 生成 \(\approx\),用于表示近似等于符号。
~= Congruent equals 生成 \(\cong\),用于表示全等符号。
>> Much greater than 生成 \(\gg\),用于表示远大于符号。
<< Much less than 生成 \(\ll\),用于表示远小于符号。
and & 生成 &,用于表示对齐符号。
case Cases 生成 cases 环境,即 \begin{cases} ... \end{cases}
ali Aligned 生成 aligned 环境,即 \begin{aligned} ... \end{aligned}
ceil Ceil 生成 \left\lceil ... \right\rceil,用于表示向上取整。
floor Floor 生成 \left\lfloor ... \right\rfloor,用于表示向下取整。
set Set 生成 \{ ... \mid ... \},用于表示集合。
norm Norm 生成 \left\| ... \right\|,用于表示范数。
abs Absolute value 生成 \left\lvert ... \right\rvert,用于表示绝对值。
Vert Verts 生成 \left\Vert ... \right\Vert,用于表示双竖线符号。
beg Begin 生成 \begin{,搭配 VS code 的自动补全功能,可以快速生成环境。
taylor Taylor 生成 \(\sum_{k=0}^{\infty} c_k (x-a)^k\),用于表示泰勒级数。
lim Limit 生成 \(\lim_{n \to \infty}\),用于表示极限。
sum Sum 生成 \(\sum_{min}^{max}\),用于表示求和。
SUM Common sum 生成 \(\sum\),用于表示求和符号。
prod Product 生成 \(\prod_{n=1}^{\infty}\),用于表示连乘。
part Partial derivative 生成 \(\frac{\partial V}{\partial x}\),用于表示偏导数。
ndiff d/dx 根据 n 生成 \(\frac{\mathrm{d}y}{\mathrm{d}x}\),用于表示导数。n 表示 n 次导。
dd dd 生成 \(\mathop{}\!\mathrm{d}\),用于表示微分符号。使用 \mathop{}\!\mathrm{d} 代替 \mathrm{d} 的好处是可以正确的显示微分号前的空格。
buu Bigcup 生成 \(\bigcup_{i \in I}\),用于表示大并集符号。
bnn Bigcap 生成 \(\bigcap_{i \in I}\),用于表示大交集符号。
dint Integral 生成 \(\int_{-\infty}^{\infty} \, \mathrm{d}x\),用于表示积分符号。
label label 生成形如 \label{randlabel:kgy0ntirtd} 的标签,用于交叉引用。标签中有 10 位随机字符。

代码片段补充说明

  • 可以搜索中间的名称直接找到对应的代码片段,例如搜索 Fraction 就可以找到分式的代码片段。除了 lmeqteqs 三个片段,其余片段都按照在原文件中的顺序排列。

  • 自 710 行后部分不常用的片段,没有在表格中列出,可以自行查看。

  • 支持自动为算符和希腊字母等添加反斜杠,由 integratemin|max|argmin|argmax|sup|inffunctiongreeklogic operatorlogic symbolsmath function 片段定义。

  • 其中,min|max|argmin|argmax|sup|inf 一条片段在符号后自动上空格,这是考虑到这些符号通常后面会有空格,并且如果不加空格易触发其他片段。

  • 部分片段是为了纠正错误出现的,例如 U\psilonu\psilon 是由于打一半 psi 展开为 \psi 导致的错误。

  • \(\LaTeX\) 的数学符号和环境非常多,这里只列出了一部分常用的片段,如果有其他需要,可以自行添加。

  • \(\LaTeX\) 中,\left\right 用于生成自适应大小的括号,可以用于生成各种括号,如圆括号、方括号、大括号等。不过,其大小大于公式高度(括号稍低于公式符号会美观些),并且不能换行,因此提供了 big、Big、bigg、Bigg 四种大小的括号(大小依次增大,固定高度),其用法为:

    • )big,生成 \bigl( \bigr)。其余 }]| 同理。如 \(\displaystyle\bigl( \frac{a}{b}\bigr)\)
    • )Big,生成 \Bigl( \Bigr)。如 \(\displaystyle\Bigl( \sum_{min}^{max}\Bigr)\)
    • )bbig,生成 \biggl( \biggr)
    • )BBig,生成 \Biggl( \Biggr)

问题

  • VS code 默认的补全提示是允许使用 Tab 或者 Enter 键进行选择的,但是在打大量公式时,Enter 键有时会导致换行,有时导致补全(取决于补全提示框是否加载出来),因此建议使用 Tab 键进行选择。关闭 Enter 键的选择功能可以在设置中搜索 editor.acceptSuggestionOnEnter,将其设置为 off。但是 Tab 键本身也和代码片段的光标位置有冲突,还没有解决方案。

  • 由于不少片段需要在数学环境外触发,同时又出现在英文单词内(如 lmeqteqs 等),因此在输入这些单词时可能会触发代码片段。这里没有解决方案,只能尽量不在 .tex 文件中输入英文。

  • 输入法切换还有点麻烦的。有插件vscode-smart-ime可以解决这个问题,但由于 ibus 无法改切换输入法键,只能在 fcitx 下使用。