-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed.xml
3392 lines (2288 loc) · 356 KB
/
feed.xml
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
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Xheldon Blog</title>
<description>The Answer to Life, the Universe and Everything is...</description>
<link>https://www.xheldon.com/</link>
<atom:link href="https://www.xheldon.com/feed.xml" rel="self" type="application/rss+xml" />
<pubDate>Fri, 28 Jun 2024 19:11:26 +0800</pubDate>
<lastBuildDate>Fri, 28 Jun 2024 19:11:26 +0800</lastBuildDate>
<generator>Jekyll v4.2.1</generator>
<item>
<title>如何使用 Notion Flow 模块转换</title>
<description><p>一周前,我构建了 Notion Flow 浏览器扩展:</p>
<p><a class="link-bookmark" href="https://twitter.com/_Xheldon/status/1770466495560294583" target="_blank"><span data-bookmark-img="" data-bookmark-title="X"><img src="" /></span><span><span>Xheldon on Twitter / X</span><span>
Notion Flow 浏览器插件终于发布了,配置和介绍见视频:https://t.co/pw4yYwnt8h官网见:https://t.co/6326Q4gIWC插件用来将 Notion 内容以 Markdown 或者你自定义的任意格式发送到 Github,我用它来写使用了 Github Pages 的 Jekyll 博客,插件会在配置 OSS 后自动处理图片内容到 CDN,非常好用~。— Xheldon (@_Xheldon) March 20, 2024
</span><span>https://twitter.com/_Xheldon/status/1770466495560294583</span></span></a></p>
<p>而刚刚更新的 0.4.1 版本:</p>
<p><a class="link-bookmark" href="https://notion-flow.xheldon.com/blog/2024/03/31/0.4.1" target="_blank"><span data-bookmark-img="https%3A%2F%2Fnotion-flow.xheldon.com%2Fimg%2Findex.png" data-bookmark-title="0"><img src="https%3A%2F%2Fnotion-flow.xheldon.com%2Fimg%2Findex.png" /></span><span><span>0.4.1 | Notion Flow</span><span>
Feature
</span><span>https://notion-flow.xheldon.com/blog/2024/03/31/0.4.1</span></span></a></p>
<p>支持了兼容 AWS S3 API 的自建 OSS 服务,如 Cloudflare R2:</p>
<p><a class="link-bookmark" href="https://www.cloudflare.com/zh-cn/developer-platform/r2/" target="_blank"><span data-bookmark-img="https%3A%2F%2Fcf-assets.www.cloudflare.com%2Fslt3lc6tev37%2F53qCYhQbir5WtIU0VDWESo%2F954a48bfb17f429acf469e5f14345d83%2Funnamed-3.png" data-bookmark-title="C"><img src="https%3A%2F%2Fcf-assets.www.cloudflare.com%2Fslt3lc6tev37%2F53qCYhQbir5WtIU0VDWESo%2F954a48bfb17f429acf469e5f14345d83%2Funnamed-3.png" /></span><span><span>Cloudflare R2 | 零出口费用分布式对象存储 | Cloudflare | Cloudflare</span><span>
Cloudflare R2 是兼容 S3、零出口费用的全球分布式对象存储。 自由移动数据,构建自己期望的多云架构。
</span><span>https://www.cloudflare.com/zh-cn/developer-platform/r2/</span></span></a></p>
<p>本篇文章简单介绍一下我是如何使用这个浏览器扩展用于我的 Github Jekyll 博客的。</p>
<hr />
<p>Jekyll 静态博客是基于 Ruby 构建的,支持插件。所以我自己写了几个插件(Jekyll 博客的插件位于 <code class="language-plaintext highlighter-rouge">_plugins</code> 目录下,写好 ruby 文件后,丢到该目录下,重启服务即可)来处理 Liquid 模板语言,而内容就是来自 Notion Flow 转换的 Notion 内容。如处理 bookmark 的插件内容如下:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">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
</pre></td><td class="rouge-code"><pre><span class="k">module</span> <span class="nn">Jekyll</span>
<span class="k">class</span> <span class="nc">RenderBookMarkBlock</span> <span class="o">&lt;</span> <span class="no">Liquid</span><span class="o">::</span><span class="no">Block</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">tag_name</span><span class="p">,</span> <span class="kp">attr</span><span class="p">,</span> <span class="n">tokens</span><span class="p">)</span>
<span class="k">super</span>
<span class="c1"># 普通的链接没有 yid 和 bid</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="kp">attr</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/url\=\"(.*)\"\stitle\=\"(.*)\"\simg\=\"(.*)\"\syid\=\"(.*)\"\sbid\=\"(.*)\"/</span><span class="p">)</span>
<span class="k">if</span> <span class="o">!</span><span class="n">attrs</span><span class="p">.</span><span class="nf">empty?</span>
<span class="c1"># 外部的 video 链接,youtube、bilibili(如本文上一篇博客就是)</span>
<span class="vi">@url</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="vi">@title</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
<span class="vi">@img</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<span class="vi">@yid</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">3</span><span class="p">]</span>
<span class="vi">@bid</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">4</span><span class="p">]</span>
<span class="vi">@firstChar</span> <span class="o">=</span> <span class="p">(</span><span class="vi">@title</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nf">upcase</span>
<span class="vi">@error</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">else</span>
<span class="c1"># 正常和 notion 一样的 bookmark(如本文上面三个链接就是)</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="kp">attr</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/url\=\"(.*)\"\stitle\=\"(.*)\"\simg\=\"(.*)\"/</span><span class="p">)</span>
<span class="vi">@url</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="vi">@title</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
<span class="vi">@img</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<span class="vi">@firstChar</span> <span class="o">=</span> <span class="p">(</span><span class="vi">@title</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nf">upcase</span>
<span class="vi">@error</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="vi">@desc</span> <span class="o">=</span> <span class="k">super</span>
<span class="k">if</span> <span class="o">!</span><span class="vi">@yid</span><span class="p">.</span><span class="nf">nil?</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="vi">@yid</span><span class="p">.</span><span class="nf">empty?</span>
<span class="s2">"&lt;p class='embed-responsive embed-responsive-16by9'&gt;&lt;iframe src='https://www.youtube.com/embed/</span><span class="si">#{</span><span class="vi">@yid</span><span class="si">}</span><span class="s2">?rel=0' title='YouTube video player' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;"</span>
<span class="k">elsif</span> <span class="o">!</span><span class="vi">@bid</span><span class="p">.</span><span class="nf">nil?</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="vi">@bid</span><span class="p">.</span><span class="nf">empty?</span>
<span class="s2">"&lt;p class='embed-responsive embed-responsive-16by9' style='border-bottom: 1px solid #ddd;'&gt;&lt;iframe src='//player.bilibili.com/player.html?bvid=</span><span class="si">#{</span><span class="vi">@bid</span><span class="si">}</span><span class="s2">&amp;high_quality=1&amp;as_wide=1' scrolling='no' border='0' frameborder='no' framespacing='0' allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;"</span>
<span class="k">else</span>
<span class="s2">"&lt;p&gt;&lt;a class='link-bookmark' href='</span><span class="si">#{</span><span class="vi">@url</span><span class="si">}</span><span class="s2">' target='_blank'&gt;&lt;span data-bookmark-img='</span><span class="si">#{</span><span class="vi">@img</span><span class="si">}</span><span class="s2">' data-bookmark-title='</span><span class="si">#{</span><span class="vi">@firstChar</span><span class="si">}</span><span class="s2">'&gt;&lt;img src='</span><span class="si">#{</span><span class="vi">@img</span><span class="si">}</span><span class="s2">'/&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;</span><span class="si">#{</span><span class="vi">@title</span><span class="si">}</span><span class="s2">&lt;/span&gt;&lt;span&gt;</span><span class="si">#{</span><span class="vi">@desc</span><span class="si">}</span><span class="s2">&lt;/span&gt;&lt;span&gt;</span><span class="si">#{</span><span class="vi">@url</span><span class="si">}</span><span class="s2">&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># 上传的 video</span>
<span class="k">module</span> <span class="nn">Jekyll</span>
<span class="k">class</span> <span class="nc">RenderVideoBlock</span> <span class="o">&lt;</span> <span class="no">Liquid</span><span class="o">::</span><span class="no">Block</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">tag_name</span><span class="p">,</span> <span class="kp">attr</span><span class="p">,</span> <span class="n">tokens</span><span class="p">)</span>
<span class="k">super</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="kp">attr</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/caption\=\"(.*)\"\simg\=\"(.*)\"\ssuffix\=\"(.*)\"/</span><span class="p">)</span>
<span class="vi">@caption</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="vi">@img</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
<span class="vi">@suffix</span> <span class="o">=</span> <span class="n">attrs</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="n">text</span> <span class="o">=</span> <span class="k">super</span>
<span class="s2">"&lt;p caption='</span><span class="si">#{</span><span class="vi">@caption</span><span class="si">}</span><span class="s2">'&gt;&lt;video controls muted&gt;&lt;source src='</span><span class="si">#{</span><span class="vi">@img</span><span class="si">}</span><span class="s2">' type='video/</span><span class="si">#{</span><span class="vi">@suffix</span><span class="si">}</span><span class="s2">' /&gt;&lt;/video&gt;&lt;/p&gt;"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Liquid</span><span class="o">::</span><span class="no">Template</span><span class="p">.</span><span class="nf">register_tag</span><span class="p">(</span><span class="s1">'render_bookmark'</span><span class="p">,</span> <span class="no">Jekyll</span><span class="o">::</span><span class="no">RenderBookMarkBlock</span><span class="p">)</span>
<span class="no">Liquid</span><span class="o">::</span><span class="no">Template</span><span class="p">.</span><span class="nf">register_tag</span><span class="p">(</span><span class="s1">'render_video'</span><span class="p">,</span> <span class="no">Jekyll</span><span class="o">::</span><span class="no">RenderVideoBlock</span><span class="p">)</span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>这段的逻辑是如果遇到 Notion 的 bookmark 模块链接是 Youtube、Bilibili,则转成嵌入视频的 HTML(iframe),否则转成类似于 Notion bookmark 的 HTML(需要配合 CSS 实现)。</p>
<p>所以我使用 Notion Flow 将 Notion 内容转换成 Markdown 格式的同时,自定义了 bookmark 等模块的转换规则,以让博客能够显示 Youtube、Bilibili 和与 Notion 一样的 bookmark 样式内容,如下:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="rouge-code"><pre><span class="nx">video</span><span class="p">:</span> <span class="kd">function</span> <span class="nx">video</span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">block</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">file</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// 用户自己上传的 video 文件,用默认 video 插件处理</span>
<span class="k">return</span> <span class="s2">`&lt;p caption='</span><span class="p">${</span><span class="nx">block</span><span class="p">.</span><span class="nx">caption</span><span class="p">}</span><span class="s2">'&gt;&lt;video controls muted&gt;&lt;source src='</span><span class="p">${</span><span class="nx">block</span><span class="p">.</span><span class="nx">url</span><span class="p">}</span><span class="s2">' type='video/</span><span class="p">${</span><span class="nx">block</span><span class="p">.</span><span class="nx">suffix</span><span class="p">}</span><span class="s2">' /&gt;&lt;/video&gt;&lt;/p&gt;\n`</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">block</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">external</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// 外部链接、youtube 和 bilibili 视频链接,用 bookmark 处理</span>
<span class="k">return</span> <span class="s2">`\n`</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>这里需要注意(我不太懂 ruby), Liquid 模板的标签之间,必须有文本内容(你可以不用),否则,ruby 插件无法生成 HTML。即:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="p">{</span><span class="o">%</span> <span class="nx">render_video</span> <span class="o">%</span><span class="p">}</span><span class="nx">这里必须有任意内容</span><span class="err">!</span><span class="p">{</span><span class="o">%</span> <span class="nx">endrender_video</span> <span class="o">%</span><span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>这样在 ruby 插件中,<code class="language-plaintext highlighter-rouge">super</code> 变量拿到的就是「这里必须有任意内容!」这句话(你可以不使用该变量)。如果没有这段内容,则插件压根不会返回任何内容。</p>
</description>
<pubDate>Sun, 31 Mar 2024 08:00:00 +0800</pubDate>
<link>https://www.xheldon.com/tech/how-i-use-notion-flow.html</link>
<guid isPermaLink="true">https://www.xheldon.com/tech/how-i-use-notion-flow.html</guid>
<category>技术</category>
<category>技巧</category>
<category>教程</category>
<category>工作流</category>
<category>Notion</category>
<category>Jekyll</category>
<category>tech</category>
</item>
<item>
<title>【视频】使用 Notion Flow 简化你的博客发布流程</title>
<description><p>本文分享使用 Notion Flow 来简化你的博客发布流程的视频,具体官网见:</p>
<p><a class="link-bookmark" href="https://notion-flow.xheldon.com" target="_blank"><span data-bookmark-img="https://www.notion.so/image/https%3A%2F%2Fnotion-flow.xheldon.com%2Fimg%2Findex.png?table=block&amp;id=ce39a8c5-ade9-4a4e-bd58-6433c00fd360&amp;spaceId=1e3e7c05-fc11-4038-9f76-92db32b98824&amp;width=500&amp;userId=0bfcee52-05b1-4d38-bf9a-26223d36426c&amp;cache=v2" data-bookmark-title="N"><img src="https://www.notion.so/image/https%3A%2F%2Fnotion-flow.xheldon.com%2Fimg%2Findex.png?table=block&amp;id=ce39a8c5-ade9-4a4e-bd58-6433c00fd360&amp;spaceId=1e3e7c05-fc11-4038-9f76-92db32b98824&amp;width=500&amp;userId=0bfcee52-05b1-4d38-bf9a-26223d36426c&amp;cache=v2" /></span><span><span>Notion Flow | Notion Flow</span><span>
Send your Notion content to github with Markdown
</span><span>https://notion-flow.xheldon.com</span></span></a></p>
<p>Youtube:</p>
<p class="embed-responsive embed-responsive-16by9"><iframe src="https://www.youtube.com/embed/aPitTcsruhM?rel=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></p>
<p>Bilibili:</p>
<p class="embed-responsive embed-responsive-16by9" style="border-bottom: 1px solid #ddd;"><iframe src="//player.bilibili.com/player.html?bvid=BV1Ar421h7tM&amp;high_quality=1&amp;as_wide=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen=""></iframe></p>
</description>
<pubDate>Thu, 21 Mar 2024 08:00:00 +0800</pubDate>
<link>https://www.xheldon.com/tech/use-notion-flow.html</link>
<guid isPermaLink="true">https://www.xheldon.com/tech/use-notion-flow.html</guid>
<category>技术</category>
<category>插件</category>
<category>教程</category>
<category>折腾</category>
<category>视频</category>
<category>工作流</category>
<category>Notion</category>
<category>tech</category>
</item>
<item>
<title>让 VSCode 更好用的设置——前端开发角度</title>
<description><p class="content-callout" style="background:rgb(241, 241, 239); color:;"><span class="content-callout-icon">☝🏻</span><span>后面计划出一期视频说明,因为有些设置的效果需要演示才能看出差异,而我又懒得制作动图在博客中了。</span></p>
<h2 id="前言">前言</h2>
<p>刚开始学习前端的时候,还没有 VSCode,那时我用的是 WebStorm(当时是学生,所以用的盗版)。开箱即用的体验让人爱不释手。后来由于办公电脑配置的下沉,以及它对 4K 及多显示器卡顿问题的长久不解决,再加上周围同事的影响, 最终一击是「配置同步」让我最终切换到 VSCode 。</p>
<p>在适应了没有单独的悬浮搜索框这一史诗级割裂之后,很快就摸索出了我个人认为好用的配置,下面就详细得说一说。如果有人觉得自己的设置比我的更好的,欢迎在下方留言然后附上原因和效果截图。</p>
<p class="content-callout" style="background:rgb(241, 241, 239); color:;"><span class="content-callout-icon">📖</span><span>默认的设置我基本不说了(除非非常好用),我就说我对于默认配置的修改部分。VSCode 中大部分配置都能修改,比如「是否在右侧小地图位置显示光标行」这种的都能,非常好。</span></p>
<h2 id="样式">样式</h2>
<h3 id="主题字体">主题/字体</h3>
<p>主题是 One Dark Pro:</p>
<p><a class="link-bookmark" href="https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme" target="_blank"><span data-bookmark-img="" data-bookmark-title="M"><img src="" /></span><span><span>marketplace.visualstudio.com</span><span>
https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme
</span><span>https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme</span></span></a></p>
<p>字体是 Fira Code:</p>
<p><a class="link-bookmark" href="https://github.com/tonsky/FiraCode?tab=readme-ov-file#download--install" target="_blank"><span data-bookmark-img="https://repository-images.githubusercontent.com/26500787/bf313080-6b02-11ea-9cd5-c3dca880736d" data-bookmark-title="G"><img src="https://repository-images.githubusercontent.com/26500787/bf313080-6b02-11ea-9cd5-c3dca880736d" /></span><span><span>GitHub - tonsky/FiraCode: Free monospaced font with programming ligatures</span><span>
Free monospaced font with programming ligatures. Contribute to tonsky/FiraCode development by creating an account on GitHub.
</span><span>https://github.com/tonsky/FiraCode?tab=readme-ov-file#download--install</span></span></a></p>
<p>Fira Code 是官方推荐字体,<a href="https://code.visualstudio.com/docs/getstarted/tips-and-tricks#:~:text=zoomLevel%22%3A%205-,Font%20ligatures,-%22editor.fontFamily%22">内部也在使用</a>。</p>
<p>Fira Code 对一些符号的变体支持非常好看,如 <code class="language-plaintext highlighter-rouge">===</code> 和 <code class="language-plaintext highlighter-rouge">&lt;=</code> 等(有些需要手动启用字符集和变体):</p>
<p caption="Fira Code 字体"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3371f847-fdd8-410c-82e1-b1d63cd91035.webp" alt="Fira Code 字体" title="Fira Code 字体" /></p>
<p>很多人不习惯 Fira Code 默认的 <code class="language-plaintext highlighter-rouge">&amp;</code> 符号,这可以通过配置来禁用它的变体,具体可以参看其 Github 的介绍,我的设置是:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="p">{</span><span class="w">
</span><span class="nl">"workbench.colorTheme"</span><span class="p">:</span><span class="w"> </span><span class="s2">"One Dark Pro"</span><span class="p">,</span><span class="w">
</span><span class="nl">"editor.fontFamily"</span><span class="p">:</span><span class="w"> </span><span class="s2">"'Fira Code', Monaco, 'Courier New', monospace"</span><span class="p">,</span><span class="w">
</span><span class="nl">"editor.fontLigatures"</span><span class="p">:</span><span class="w"> </span><span class="s2">"'ss01', 'ss02' off, 'ss03', 'ss04', 'ss05', 'ss07', 'cv29', 'cv28', 'cv13'"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table></code></pre></div></div>
<p>另外,行高是 1.4,字号是 13。</p>
<h2 id="编辑器">编辑器</h2>
<p>最主要的就是编辑器设置了,好的编辑器当然是为了提高编码效率,下面逐个说说。</p>
<h3 id="渲染空白字符">渲染空白字符</h3>
<p caption="Editor: Render Whitespace"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/9175365e-0357-4b2f-abf7-cdf20062b2ca.webp" alt="Editor: Render Whitespace" title="Editor: Render Whitespace" /></p>
<p>这个我是使用默认的 selection,即只在划选的时候,如果内容有空白符(空格)才会显示出来,否则不显示,不然影响美观。 <code class="language-plaintext highlighter-rouge">boundary</code> 的设置是总是显示,不好看:</p>
<p caption="选区渲染空白符号"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/12c4e471-e6fc-4b6d-aed7-61d4db16cd18.webp" alt="选区渲染空白符号" title="选区渲染空白符号" /></p>
<h3 id="自动添加删除配对括号">自动添加/删除配对括号</h3>
<p caption="Auto Closing 设置"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/49d09c46-5456-441a-9f72-fccc3a5d761e.webp" alt="Auto Closing 设置" title="Auto Closing 设置" /></p>
<p>这个几个设置使用场景是,如果你输入一个起始括号,如 <code class="language-plaintext highlighter-rouge">({[</code> 会自动在后面给你生成一个 <code class="language-plaintext highlighter-rouge">)}]</code> ,删除的设置也是同理。默认是插入的时候配对,删除的时候也同步配对删除。</p>
<h3 id="括号着色池">括号着色(池)</h3>
<p caption="Bracket Pair Colorization"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/899eeaba-8737-4f07-8e22-9480f915fcbc.webp" alt="Bracket Pair Colorization" title="Bracket Pair Colorization" /></p>
<p>第一个打开后,你的各个括号就会有颜色(而不是白色)。第二个打开后,每种类型的括号,拥有自己独立的一套颜色配置(其实也会不同的括号颜色重复,但不再是按不同括号的显示顺序,而是同种括号的显示顺序来着色了——我的理解和测试)。</p>
<h3 id="矩形选区">矩形选区</h3>
<p caption="Column Selection"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/c64604e0-b420-4845-86e2-bac8d40aaa3d.webp" alt="Column Selection" title="Column Selection" /></p>
<p>默认情况从上往下选择,如果经过某行的行首和行尾,是选中整行的:</p>
<p caption="默认选中效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/d97e73d0-91ae-4e0a-befb-c708ceae1bc0.webp" alt="默认选中效果" title="默认选中效果" /></p>
<p>如果这个开关打开后,就变成了鼠标划选是一个矩形选区(根据鼠标位置,而不是代码位置进行选择),常用场景是同时编辑多行类似缩进的内容,如 JSON 的键等:</p>
<p caption="列选择"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/99dcc5e1-65bd-4048-bf8a-b06443bc7745.webp" alt="列选择" title="列选择" /></p>
<p caption="列选择的一个应用场景"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/85a0ac88-34a6-4843-adfd-ea95f01c1806.gif" alt="列选择的一个应用场景" title="列选择的一个应用场景" /></p>
<p>多说一句,在终端中选中的时候按下 Opt 键,也是这个效果。</p>
<h3 id="复制内容的时候带语法高亮">复制内容的时候带语法高亮</h3>
<p caption="Copy With Syntax Highlighting"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/2e507e99-524a-41c0-978c-42cb1bcbebca.webp" alt="Copy With Syntax Highlighting" title="Copy With Syntax Highlighting" /></p>
<p>有些富文本编辑器,没有特殊处理,因此在直接复制 VSCode 中的代码到富文本编辑器的时候,会将颜色也带上,这通常不是预期。此设置可以让你复制出来的内容不带颜色。</p>
<h3 id="拖拽">拖拽</h3>
<p caption="Drag And Drop"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/319dae0d-0369-4469-abd9-ed2e0c36649c.webp" alt="Drag And Drop" title="Drag And Drop" /></p>
<p>我写码这么多年,几乎没有使用「拖拽」来实现移动代码块的操作,因此建议取消。第二个按住 shift 后拖拽文件到 VSCode,如果是媒体文件则松手后只会显示文件名,如果不按住 shift 则会打开媒体文件,多一个功能挺好的,以备不时之需(这个默认是打开的)。</p>
<h3 id="空选区复制当前行">空选区复制当前行</h3>
<p caption="Empty Selection Clipboard"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/32f95652-6320-4347-8c9e-b7f03dbecd79.webp" alt="Empty Selection Clipboard" title="Empty Selection Clipboard" /></p>
<p>如果选区只是光标,没有选中任何内容,此时进行复制操作会选中当前行。复制当前行更简单了(默认开启)。</p>
<h3 id="自动折叠">自动折叠</h3>
<p caption="Folding"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/96927f79-74ed-4949-b3e0-7cff488269ed.webp" alt="Folding" title="Folding" /></p>
<p>代码折叠肯定是需要的。突出显示折叠范围也是需要的(会跟鼠标在那一行一行的效果,当前行高亮),不然不知道当前行是否折叠了。最后一个是自动折叠 import 部分,我觉得没必要。</p>
<p>折叠我个人喜欢始终显示,因为这个功能太常用了,我经常需要先 hover 到位置,看哪行是被折叠了,然后再点打开折叠,效率太低。我喜欢一眼看到哪些地方被折叠的,所以需要设置成 always:</p>
<p caption="Show Folding Controls"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/0a382e11-522d-490a-a086-703b291ef90e.webp" alt="Show Folding Controls" title="Show Folding Controls" /></p>
<h3 id="括号缩进参考线">括号/缩进参考线</h3>
<p caption="(缩进/括号)参考线"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b537a5b7-b989-4346-837b-919a4705599c.webp" alt="(缩进/括号)参考线" title="(缩进/括号)参考线" /></p>
<p>如下图,不过我没测试出什么是「缩进参考线」,先打开吧。</p>
<p caption="图中高亮的括号"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/f8b0495e-2bd6-4dd5-9eb1-36a33821f1e8.webp" alt="图中高亮的括号" title="图中高亮的括号" /></p>
<h3 id="hover-时浮窗出现的位置">hover 时浮窗出现的位置</h3>
<p caption="Hover 位置"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/da26e746-9e8b-4a3a-9b24-2a38abae431d.webp" alt="Hover 位置" title="Hover 位置" /></p>
<p>一般情况我们看代码是从上往下看的,这个设置 hover 代码后浮窗出现在上方,挡住了内容,还得移动一下鼠标让浮窗消失再出现,建议取消。</p>
<p caption="始终显示提示在下方更合适"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6df3c907-16b9-4cba-b7f3-daa4a5fd4532.webp" alt="始终显示提示在下方更合适" title="始终显示提示在下方更合适" /></p>
<h3 id="悬浮出提示">悬浮出提示</h3>
<p caption="消失延迟其实不需要"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6b18c5da-1193-4e89-b49f-b7775dcdb192.webp" alt="消失延迟其实不需要" title="消失延迟其实不需要" /></p>
<p>鼠标移出一般就是不想让它显示,直接设置为 0。</p>
<h3 id="鼠标缩放字体">鼠标缩放字体</h3>
<p caption="完全没用的功能…"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/2e05860a-01cb-45ff-9d3b-230d8871ebd6.webp" alt="完全没用的功能…" title="完全没用的功能…" /></p>
<p>经常误触,关了。</p>
<h3 id="编辑器区域顶部-padding">编辑器区域顶部 padding</h3>
<p caption="统一视觉间隔"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/07183c4a-3dcc-412d-a7bb-f5167443874d.webp" alt="统一视觉间隔" title="统一视觉间隔" /></p>
<p>我设置为 2。底部 padding 就没必要了。</p>
<p caption="优雅,永不过时"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/9f1cd71d-f579-44c6-8b23-58f558dfeeaf.webp" alt="优雅,永不过时" title="优雅,永不过时" /></p>
<h3 id="滚动条">滚动条</h3>
<p>水平滚动条为 6 宽度,竖直为 25(默认水平 12,竖直 14):</p>
<p caption="Scrollbar"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/2b7e8382-836f-4fe4-a7b5-c88e24332838.webp" alt="Scrollbar" title="Scrollbar" /></p>
<p>我个人是不喜欢滚动到范围外,会导致明明一屏显示完全的内容,出现滚动条,所以最后一个 Scroll Beyond Last Line 关了。</p>
<p caption="滚动条显示信息"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/361fa784-0d98-4055-a56e-58678f0c3a31.webp" alt="滚动条显示信息" title="滚动条显示信息" /></p>
<p>这里要说下为什么竖直滚动条调大为 20,因为在那个区域其实不只是滚动条,还含有三个信息:</p>
<ol>
<li>
<p>滚动条右侧亮黄色的是编辑器警告信息。</p>
</li>
<li>
<p>滚动条中间暗黄色块是匹配的搜索项(含全局搜索和当前编辑器搜索)。其中,暗黄色块也可能是灰色(表示光标选中的部分和类似内容),也可能是淡粉色,表示光标选中的的内容的声明处。</p>
</li>
<li>
<p>占滚动条整行的蓝色线是光标所在的行。</p>
</li>
<li>
<p>滚动条左侧的绿色部分是代码变动的部分。其中,也可能是淡黄色,表示修改部分(如果启用了 git 的话)。</p>
</li>
</ol>
<p>可以看到这部分的信息显示很丰富,所以调宽一点。</p>
<h3 id="平滑滚动">平滑滚动</h3>
<p caption="动画,优雅"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/190452c5-f985-47b4-b238-000edce28c4b.webp" alt="动画,优雅" title="动画,优雅" /></p>
<p>强烈建议开启,这样在滚动的时候就可以知道你大概滚动了多少行,而不是突然跳过去,「不知道滚动到哪里去了」。</p>
<h3 id="滚动吸顶">滚动吸顶</h3>
<p caption="吸顶,好用"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/37741a88-7ba7-481a-9fe5-06ed276af9d3.webp" alt="吸顶,好用" title="吸顶,好用" /></p>
<p>滚动的时候可能需要查看超出当前屏幕的作用域,打开该选项即可。另外,水平滚动的时候会把该 sticky 的函数滚走,我倾向于不滚动它,所以把最后一个选项取消。</p>
<p caption="左右滚动不跟随"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b7b7e17c-ac89-4d69-b1c2-648f0e582a40.webp" alt="左右滚动不跟随" title="左右滚动不跟随" /></p>
<h3 id="光标">光标</h3>
<p caption="Cursor Blinking"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/5736c4cc-e07c-40f1-ae31-e1c16e458a00.webp" alt="Cursor Blinking" title="Cursor Blinking" /></p>
<p>第一个是光标闪烁的淡入淡出,第二个是你在点击不同位置的时候,光标是从上一个位置动画移动到点击位置的,可以让你知道本次点击光标位置相对上一个编辑位置是哪里,信息更丰富了。</p>
<h3 id="查找">查找</h3>
<p caption="编辑器右上角查找小部件"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/eb174538-47bb-44b8-ba84-54df4a37555e.webp" alt="编辑器右上角查找小部件" title="编辑器右上角查找小部件" /></p>
<p>这个建议关掉,搜索的时候,如果不关,会在文件顶部凭空产生一些距离导关闭搜索框的时候编辑器跳动一下,难受。</p>
<p caption="空白,不优雅"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/83dcf800-6ec9-4a8a-8b49-2e69e419bd72.webp" alt="空白,不优雅" title="空白,不优雅" /></p>
<p>不过该选项打开后可能会遮挡住编辑器内容,自己取舍(一般顶部都是 import 后的换行内容,挡住也无所谓)。</p>
<p caption="没空白,优雅"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6878a013-d547-4ccb-9792-32e03a97e9d4.webp" alt="没空白,优雅" title="没空白,优雅" /></p>
<h3 id="自动带入搜索小组件">自动带入搜索小组件</h3>
<p caption="自动带入,优雅"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/f671a305-d7c8-4ae0-b91c-5aa094bbd3a6.webp" alt="自动带入,优雅" title="自动带入,优雅" /></p>
<p>这个建议关掉。我经常会使用搜索,然后搜索后选中某个内容后再搜索(非选中内容),此时编辑器自作聪明的把我选中的内容给带到搜索框中,导致我之前搜索的内容没了,很烦。</p>
<h3 id="缩略图">缩略图</h3>
<p caption="右侧小地图"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b8986040-1b86-4bbd-a99b-1b7d551c8b28.webp" alt="右侧小地图" title="右侧小地图" /></p>
<p>编辑器右侧的缩略图我始终显示出来,它的作用一般是让我知道我当前处于编辑的哪个位置,以及相对于某个函数、组件,我所处的位置,因此我需要缩略图不滚动,同时仅渲染色块即可,不用将每行都渲染出来。</p>
<h3 id="建议">建议</h3>
<p caption="建议预览"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/1cbc255e-2784-461d-a723-ce5f325130a2.webp" alt="建议预览" title="建议预览" /></p>
<p>这个开关建议关闭(默认),因为可能跟 copilot 建议弄混淆,如图是 copilot 的建议:</p>
<p caption="copilot 建议"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/89587ee7-0329-43e7-9a68-814e55bd8e07.webp" alt="copilot 建议" title="copilot 建议" /></p>
<p>而这个是预览的建议:</p>
<p caption="整个一没必要咱就是说"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/26edace2-f059-4f51-a873-47a743946229.webp" alt="整个一没必要咱就是说" title="整个一没必要咱就是说" /></p>
<p caption="最近建议"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/203628d4-4e0c-4f9a-8289-31ab679750dc.webp" alt="最近建议" title="最近建议" /></p>
<p>这个选项默认是 first,即始终使用默认选择第一个建议,但是我经常遇到的问题是,在 CSS 中,我输入 <code class="language-plaintext highlighter-rouge">wid</code> 当然预期是 <code class="language-plaintext highlighter-rouge">width</code>,但是它会给我建议是 <code class="language-plaintext highlighter-rouge">widow</code> 我当然不用这个属性,但每次都是排在第一个,我就每次需要通过箭头来切换,所以此处建议修改成「最近使用」,类似与输入法的「动态调频」:</p>
<p caption="css 最近建议"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/a1edc147-031b-4347-be78-8c6ec3c71bd7.webp" alt="css 最近建议" title="css 最近建议" /></p>
<h2 id="工作台">工作台</h2>
<h3 id="命令提示框">命令提示框</h3>
<p caption="命令建议"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/a62c1989-314d-4675-abbb-cb9f09534480.webp" alt="命令建议" title="命令建议" /></p>
<p>有时候会经常反复输入一个命令,所以打开这个历史命令列表很有用。除此之外,保留输入内容也很有用,比如以 toggle 开头的命令(如 Toggle Screen Capture Mode)。</p>
<p>注意,如果输入内容后按了 esc 导致输入框消失,下次再次唤起不会保留输入内容,只有选择了一个命令执行后,再次唤起,才会保留上次输入的内容。</p>
<h3 id="目录树">目录树</h3>
<p caption="目录树滚动"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/ff187f9a-5588-40fb-927d-89e701495d94.webp" alt="目录树滚动" title="目录树滚动" /></p>
<p>一般动画我都会打开因为「优雅永不过时」。这个设置也影响「设置」界面的滚动(之前对编辑器设置平滑滚动不会影响「设置」界面和目录树界面的滚动效果 )。</p>
<h3 id="快速打开记录历史">快速打开记录历史</h3>
<p caption="快速打开带入上次记录"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b4633d53-e671-437c-a4e9-241fe722c953.webp" alt="快速打开带入上次记录" title="快速打开带入上次记录" /></p>
<p>按下 cmd + p 会出现 quick open 输入框,记住历史挺好的。另外还有个选项是失焦是否自动消失,大部分场景下需要自动消失,偶尔不需要,先保持默认自动消失了。</p>
<h3 id="工作台减少动画效果">工作台减少动画效果</h3>
<p caption="绝不减少动画"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/24d1bc51-76bf-415b-9c79-561bc6eb7caf.webp" alt="绝不减少动画" title="绝不减少动画" /></p>
<p>我的 64G 内存 M1 Max,不需要减少动画(默认是 auto,根据系统配置自动适应,适用于多台电脑间配置同步的问题)。</p>
<h3 id="字体平滑">字体平滑</h3>
<p caption="字体平滑"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/093ce91b-5349-48a0-b563-2a44726f3bf2.webp" alt="字体平滑" title="字体平滑" /></p>
<p>类似于 css 中的 <code class="language-plaintext highlighter-rouge">-webkit-font-smoothing: antialiased;</code> ,default 用于在大多数非 retina 屏上显示最清晰的字体(次像素级),antialiased 是像素级平滑,可能会导致字体更细,见图:</p>
<p caption="default 设置"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/81378425-4fd6-4954-8d27-5317c822b237.webp" alt="default 设置" title="default 设置" /></p>
<p caption="antialiased 设置"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/e24ea63a-7536-48bd-8dec-302b335224a9.webp" alt="antialiased 设置" title="antialiased 设置" /></p>
<p>这个设置虽然是在「工作台」块,但是也影响编辑器区域。可以看到开启了 antialiased 的时候,无论是编辑器区域还是工作台区域,字体都更暗(对比度更弱)、更细了。我喜欢后者,所以开启了。</p>
<p>注意,这个「次像素级」,并不是说比像素还小的级别,而是指「还没到像素」的级别,意思是更低级,而不是更高级。</p>
<h3 id="目录树-sticky">目录树 sticky</h3>
<p caption="目录树滚动吸顶"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/ed8074f7-0e31-4a1f-80f8-1618d2264e73.webp" alt="目录树滚动吸顶" title="目录树滚动吸顶" /></p>
<p>非常好用,滚动的时候可以知道当前的滚动路径,唯一美中不足的是如果能加个 box-shadow 阴影就好了,不然不太好区分的:</p>
<p caption="目录树吸顶效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/5a7c2102-2730-47a0-b225-738a42d86342.webp" alt="目录树吸顶效果" title="目录树吸顶效果" /></p>
<p>sticky 的最大级数也可以修改,默认是 7,足够了(编辑器 sticky 默认是 5 级)。</p>
<p>注意,此设置也同样适用于「设置」界面(原来设置界面属于工作台,而不是编辑器):</p>
<p caption="设置项界面也归它管"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/031c3170-cd43-4775-8401-a95e6c474a75.webp" alt="设置项界面也归它管" title="设置项界面也归它管" /></p>
<p>目录树的缩进我改成 14 了,参考线我喜欢始终显示,不然同级文件太多,不好找:</p>
<p caption="目录树缩进"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/7a67020e-c5a4-4114-9ac0-ff3afcb5cb61.webp" alt="目录树缩进" title="目录树缩进" /></p>
<h3 id="目录导航">目录导航</h3>
<p caption="目录导航显示 icon"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/eae4d00a-68d6-4c64-bab8-34df8fc7f458.webp" alt="目录导航显示 icon" title="目录导航显示 icon" /></p>
<p>目录导航还是需要的,但是不需要文件/文件夹 icon,这样可以显著的和文件内的数组、类进行区分,非常好用:</p>
<p caption="面包屑显示效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/57e4fefd-4c76-42cd-b79c-d3d49eb2d1df.webp" alt="面包屑显示效果" title="面包屑显示效果" /></p>
<h3 id="修改过的-tab">修改过的 tab</h3>
<p>与此相关的有多个,如在修改后未保存的文件上方显示高亮线:</p>
<p caption="高亮修改的 tab"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/e4a60c98-ec6f-452d-84ea-e0835ed963bf.webp" alt="高亮修改的 tab" title="高亮修改的 tab" /></p>
<p>默认显示的是点,此选项打开后,会点和线同时显示,重启编辑器会只显示上方蓝色线(可能是 bug,其实应该不用重启编辑器也能生效)。</p>
<p>效果:</p>
<p caption="修改过的 tab 效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/aea54cb4-158e-4662-a6b5-285fc56fd836.webp" alt="修改过的 tab 效果" title="修改过的 tab 效果" /></p>
<p>因为「点」也占用一部分的 tab 空间,会导致无法显示更多 tab 内容信息,所以建议打开该选项。</p>
<h3 id="鼠标导航">鼠标导航</h3>
<p caption="鼠标前进后退"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/254a8290-8b0a-4ebc-ac36-d453a855719d.webp" alt="鼠标前进后退" title="鼠标前进后退" /></p>
<p>这是个默认选项,但是我也说一下,对于有左侧按键(右手),也即 4、5按键的鼠标而言,的鼠标直接就可以用来导航,非常好用。</p>
<h3 id="tab-固定">tab 固定</h3>
<p caption="允许 tab 固定,好用"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b8c68b52-f2ec-4fb4-ac39-1fd1af2c9ebd.webp" alt="允许 tab 固定,好用" title="允许 tab 固定,好用" /></p>
<p>固定后的 tab 默认出现在编辑器组的左侧,但是如果将其单独排成一行会更直观,与非固定的 tab 区分开,效果如下:</p>
<p caption="tab 固定效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b6868fe5-65b6-4c6b-bd81-3bd15fada494.webp" alt="tab 固定效果" title="tab 固定效果" /></p>
<p>注意,默认情况下,固定的 tab 是无法通过鼠标中键或者 cmd + w 关闭的(按下会打开非固定 tab 而不是关闭固定 tab),此行为可以修改:</p>
<p caption="cmd + w 效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/0259919c-dd23-44f5-89e6-026c2140a424.webp" alt="cmd + w 效果" title="cmd + w 效果" /></p>
<h3 id="tab-关闭按钮">tab 关闭按钮</h3>
<p caption="隐藏关闭按钮"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/c1e66c49-5cab-4d42-9c04-713a6530bb50.webp" alt="隐藏关闭按钮" title="隐藏关闭按钮" /></p>
<p>一直使用左手 cmd + w 关闭 tab,所以此选项可以取消。另外,我其实更习惯双击 tab 关闭,但是官方回复不会做,见:</p>
<p><a class="link-bookmark" href="https://github.com/Microsoft/vscode/issues/52628#issuecomment-420887497" target="_blank"><span data-bookmark-img="https://opengraph.githubassets.com/6aae01759d8646e94084ae3e75250ed52788ea6312fe232e808e001536ef177c/microsoft/vscode/issues/52628" data-bookmark-title="A"><img src="https://opengraph.githubassets.com/6aae01759d8646e94084ae3e75250ed52788ea6312fe232e808e001536ef177c/microsoft/vscode/issues/52628" /></span><span><span>Allow to double click on a tab to close it · Issue #52628 · microsoft/vscode</span><span>
Some of the editors like notepad++ provide Double Click to close a TAB. It would be a great edition to VS Code.
</span><span>https://github.com/Microsoft/vscode/issues/52628#issuecomment-420887497</span></span></a></p>
<h3 id="tab-wrap">tab wrap</h3>
<p caption="tab wrap"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b72dfdff-c447-457d-89de-8ca3a682281d.webp" alt="tab wrap" title="tab wrap" /></p>
<p>如果打开 tab 较多,滚动 tab 的时候就会比较费劲,无法掌控全局,所以我喜欢 wrap tab,效果如下:</p>
<p caption="wrap 效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3738c007-8e6d-4397-a3fb-0a5210402ed2.webp" alt="wrap 效果" title="wrap 效果" /></p>
<p>比较尴尬的一点是,wrap 效果产生的多行 tab,可能跟上面提到的「修改 tab 上方蓝色高亮」搞的比较混乱(蓝色的线不知道是上面 tab 的还是下面 tab 的,得反应一下不直观)。是在 tab 显示更多内容,还是更直观,自己取舍:</p>
<p caption="高亮修改 + tab 高亮效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/bba12f32-b355-4550-aba5-c59950ed66fc.webp" alt="高亮修改 + tab 高亮效果" title="高亮修改 + tab 高亮效果" /></p>
<h3 id="tab-高度">tab 高度</h3>
<p caption="紧凑 tab 布局"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3224c016-4adb-41d2-82f8-83391960259d.webp" alt="紧凑 tab 布局" title="紧凑 tab 布局" /></p>
<p>紧凑布局有利于掌控全局+不占地方。</p>
<h3 id="双击--tab-关闭"><del>双击 tab 关闭(?)</del></h3>
<p caption="没懂这个设置"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3385a990-b192-4aec-963a-ee5996faf19d.webp" alt="没懂这个设置" title="没懂这个设置" /></p>
<p>看字面意思这个选项是官方号称不会做的「双击 tab 关闭」(如上面所言),但即使我关闭了可能会冲突的「双击 tab 自动扩展编辑器组」,该设置依然不生效,不知是不是我理解有误还是 bug。</p>
<h3 id="原生-tab">原生 tab</h3>
<p>与此相关的有两个:</p>
<p caption="原生 tab"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/09ad718f-b4c3-40a3-8c92-8e399613540a.webp" alt="原生 tab" title="原生 tab" /></p>
<p>第一个设置,启用后,可以将多个项目窗口,合并到一个窗口。「窗口」选项中会出现「合并所有窗口」的选项,这样可以在一个窗口中来回切换多个项目,非常好用:</p>
<p caption="合并所有窗口"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/8d13f532-cc6a-49a6-9d2c-88aabf5904e3.webp" alt="合并所有窗口" title="合并所有窗口" /></p>
<p>但是,这样的话就无法使用自定义的标题(其实我觉得也么啥用),自定义标题是这样的:</p>
<p caption="自定义标题栏效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/1d16fa15-9ee4-4647-8458-1103a659a165.webp" alt="自定义标题栏效果" title="自定义标题栏效果" /></p>
<p>第一个设置如果打开了,那第二个就无效了,无论设置为 native 和 custom。如果第一个设置不打开,第二个设置设置为 native,那就没有「合并所有窗口」,也没有「自定义标题栏」(不知道这个设置意义何在)。</p>
<h3 id="目录树拖放">目录树拖放</h3>
<p caption="最好禁用拖拽文件"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/f4f866b8-c0be-456f-8336-2a229c532f61.webp" alt="最好禁用拖拽文件" title="最好禁用拖拽文件" /></p>
<p>我经常误触,然后导致上百个修改…所以关了。</p>
<h3 id="搜索结果自动折叠">搜索结果自动折叠</h3>
<p caption="少于 10 个的文件夹展开"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/5aab9aef-806d-42a0-ab7c-7d58ae4b4849.webp" alt="少于 10 个的文件夹展开" title="少于 10 个的文件夹展开" /></p>
<p>默认总是展开,但是如果搜索结果过多(通常是因为你还没有输入完成),此时展开是没有必要的,而且会耽误你掌控全局。</p>
<p>另外,如果你没有在搜索栏中加入「排除的文件」,那么也可能出现海量搜索结果,如 NextJS 项目的 .next 目录等,因此此设置也是必要的。</p>
<p>需要注意的是,这个「展开」、「折叠」的 10 个文件限制,指的是搜索结果中,出现在某个文件夹下的文件数量,而不是整个搜索结果的文件夹数量:</p>
<p caption="多余 10 个的文件夹折叠"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/67c50309-319c-474a-addf-bbd33925d827.webp" alt="多余 10 个的文件夹折叠" title="多余 10 个的文件夹折叠" /></p>
<p>因此,如果某个文件夹下,出现符合搜索结果的文件过多(文件夹被折叠),通常你就需要检查是否需要提供更多搜索信息了。</p>
<h3 id="搜索框自动填入选择内容">搜索框自动填入选择内容</h3>
<p caption="全局搜索自动带入选择内容"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/42995472-6453-4e61-881e-d7e0ae5da443.webp" alt="全局搜索自动带入选择内容" title="全局搜索自动带入选择内容" /></p>
<p>通常你选中一个内容后想搜索它,因此「Seed On Focus」此选项让你可以节省一个 cmd + v 的操作。</p>
<p>注意,这有区别于「搜索小组件」中的 选中后聚焦到搜索时自动带入。因为在编辑器中你去选中内容,然后聚焦到搜索小组件,不一定是为了搜索,还可能只是为了简单在当前编辑器高亮选中的相同内容以便于查看,但是此时选中后聚焦到搜索小组件,就自动替换成选中内容了,很多时候不符合预期。</p>
<p>而如果你在选中内容后,聚焦到搜索视图(右侧),那大概率是为了搜索内容。</p>
<p>另外搜索结果我会想知道它所处的行号,以确定它在其文档中的位置,所以显示行号也是很有必要的。</p>
<p>最后的 Smart Case 算是一个小技巧,如果都用小写,就表示自己记不太清搜索名字了,如果很确定搜索内容(如驼峰的函数名)的某个字母是大写,那么就区分大小写进行搜索,非常好用。</p>
<p>除此之外,如果能记住上次输入的内容,其实记住也是选中状态,如果不符合自己的输入预期,直接输入内容即可,对自己即将想要搜索的内容没有影响,而如果之前搜索的内容还有用,那岂不是更好?↓</p>
<p caption="注意与搜索小组件的差别"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b84b5d58-94cb-448f-bd1a-cc129aac13bd.webp" alt="注意与搜索小组件的差别" title="注意与搜索小组件的差别" /></p>
<h3 id="搜索忽略全局的-ignore">搜索忽略全局的 ignore</h3>
<p caption="全局忽略设置"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/21a936ed-29c9-4613-b6d4-5ad910fc04f0.webp" alt="全局忽略设置" title="全局忽略设置" /></p>
<p>git 有个全局默认的 ignore,打开该选项可以在搜索的时候将其中列出的文件、文件夹忽略掉,通常是有必要的。</p>
<p>另外还有个在父级目录中启用 ignore,没明白什么意思,可能是多级 git 管理吧,我也勾选上了,既然都 ignore 了嘛:</p>
<p caption="统统勾上"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/fa5ad841-87ee-460f-ad01-d1c7a34f2553.webp" alt="统统勾上" title="统统勾上" /></p>
<h3 id="调试和测试">调试和测试</h3>
<p>恕本人技术水平有限,VSCode 的调试和测试功能用的较少,只用来调试过诸如 NextJS 这类的 NodeJS 应用,使用起来跟 Chrome 差不多。因为用的少,所以没发现有什么痛点,所以没有什么配置可以优化的,这里就不说了。</p>
<h3 id="文件修改效果">文件修改效果</h3>
<p caption="实线比「装订线」好看"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/ef52ba2e-5ff7-4f8f-963d-32da4f899fe6.webp" alt="实线比「装订线」好看" title="实线比「装订线」好看" /></p>
<p>在显示行号那一列,可以设置是实线还是「装订线」来显示差异,如:</p>
<p caption="实在不知道装订线存在的意义"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/4c009676-4e9a-4c90-8eab-5ceffae9593d.webp" alt="实在不知道装订线存在的意义" title="实在不知道装订线存在的意义" /></p>
<p>我更喜欢实线,所以这两个选项都取消了。</p>
<h3 id="取消-git-提交按钮">取消 git 提交按钮</h3>
<p caption="移除多余的 UI 按钮"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6343ab7e-7fc4-4cdc-8b0d-b65eae20b0b7.webp" alt="移除多余的 UI 按钮" title="移除多余的 UI 按钮" /></p>
<p>说实话,左侧的这个提交按钮我从来没用过,都是使用命令行操作的 git,所以这个选项我取消了。</p>
<p>同理,这个按钮(看起来是 github copilot 的按钮,自动生成提交注释),我也取消了,尤其是对于公司项目,强制要求输入内容带上需求/bug 卡片编号的时候,这个智能写提效信息就更没用了:</p>
<p caption="移除自动写提交信息"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/111f48be-42e0-4f6a-b490-7dc832b15045.webp" alt="移除自动写提交信息" title="移除自动写提交信息" /></p>
<h2 id="扩展">扩展</h2>
<h3 id="取消通知">取消通知</h3>
<p caption="取消全部扩展通知"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/caa23ff0-089b-4035-90e1-c914e44c61ac.webp" alt="取消全部扩展通知" title="取消全部扩展通知" /></p>
<p>我不需要任何扩展告诉我应该怎么做,如果有需要,我会主动找它。</p>
<h2 id="终端">终端</h2>
<h3 id="右键行为">右键行为</h3>
<p caption="终端邮件默认居然是选中+菜单"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/8c75e65f-ae00-49f1-982f-82c682b4a2f9.webp" alt="终端邮件默认居然是选中+菜单" title="终端邮件默认居然是选中+菜单" /></p>
<p>一般是鼠标左键选中后,右键出上下文操作。但 VSCode 默认行为居然是选中内容(单词)后出右键,可以,但没必要。</p>
<h3 id="终端最大行数">终端最大行数</h3>
<p caption="最大记录行"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/67d6cb52-ce20-40d2-ab50-548b7a4aab41.webp" alt="最大记录行" title="最大记录行" /></p>
<p>这个其实改不改都行,我偶然情况下需要看很久之前的 log 信息,加上我的 64G 内存,调大点无所谓。</p>
<h3 id="终端滚动动画">终端滚动动画</h3>
<p caption="奇怪的动画,关了"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/7bd7b784-c3e5-456a-9aea-f0374dfa62b0.webp" alt="奇怪的动画,关了" title="奇怪的动画,关了" /></p>
<p>虽然我喜欢动画(优雅),但是很奇怪,在终端的动画滚动似乎有点惯性,很难掌控滚动量,跟编辑器或者工作台内的滚动效果有很大差异,所以我关了。</p>
<h2 id="csslesssass">CSS/Less/Sass</h2>
<h3 id="lint-重复属性警告">lint 重复属性警告</h3>
<p caption="需要设置三次"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/067e3056-d82f-4910-9e47-519259d54577.webp" alt="需要设置三次" title="需要设置三次" /></p>
<p>这个很有必要,有时候你是从外面复制多个属性值粘贴(常见的是从浏览器检查元素的 style 上复制),然后去除重复的属性。</p>
<h2 id="git">Git</h2>
<h3 id="自动-stash">自动 Stash</h3>
<p caption="少操作一次"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/4fee6e57-9088-4a39-bbfe-c86ea5c9beb2.webp" alt="少操作一次" title="少操作一次" /></p>
<p>如图,描述的很清楚了,建议开启,少一步操作。</p>
<h2 id="第三方扩展">第三方扩展</h2>
<p>其实没什么好说的,毕竟都装扩展了,肯定是有自己的需求才会装的,所以按照自己的需求配置即可。</p>
<h3 id="gitlens">GitLens</h3>
<p>不过有些插件,是可以关闭付费推荐的,对,说的就是 <code class="language-plaintext highlighter-rouge">GitLens</code> ,在我(意外)查看 git 分支合入情况的时候,会触发到付费功能的提示,这个可以关闭(感谢插件开发者的大度):</p>
<p caption="关掉 GitLens 付费功能提醒"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/28974458-b244-4ed9-919e-affe90c409fe.webp" alt="关掉 GitLens 付费功能提醒" title="关掉 GitLens 付费功能提醒" /></p>
<h3 id="one-dark-pro">One Dark Pro</h3>
<p caption="高亮部分代码"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/a1ac82b3-7b1c-4fc4-9327-2cd04796bbee.webp" alt="高亮部分代码" title="高亮部分代码" /></p>
<p>这个我喜欢,更显著的看到方法、函数名:</p>
<p caption="效果"><img src="https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/d6235ab1-a532-4188-be52-2f29908b31e5.webp" alt="效果" title="效果" /></p>
<h2 id="后记">后记</h2>
<p>说了这么多设置,适合自己的才是最重要的,祝大家高效工作,早点下班!</p>
</description>
<pubDate>Thu, 21 Dec 2023 08:00:00 +0800</pubDate>
<link>https://www.xheldon.com/life/make-vscode-great-forever.html</link>
<guid isPermaLink="true">https://www.xheldon.com/life/make-vscode-great-forever.html</guid>
<category>技巧</category>
<category>教程</category>
<category>折腾</category>
<category>JavaScript</category>
<category>工作流</category>
<category>生活</category>
<category>VSCode</category>
<category>设置</category>
<category>life</category>
</item>
<item>
<title>使用 Apple TV 收看北京联通 IPTV</title>
<description><h2 id="前言">前言</h2>
<p>之前在 <a href="/life/the-way-to-watching-tv.html">这篇博客</a> 讲了现在家庭观影的方案,其中提到的一个点是使用网络上别人抓取到的 IPTV 的节目地址(m3u 后缀),放入 iPlayTV 中,可以直接播。但是这个节目地址过一段时间就失效了,这是因为联通 IPTV 服务器会时不时的会更新一下节目的播放地址,而 Apple TV 上填写的地址是固定的,无法及时更新,因此本文就来解决这个问题。</p>
<p class="content-callout" style="background:rgb(253, 235, 236); color:;"><span class="content-callout-icon">🚧</span><span>**使用前必读:**本人为北京联通宽带,**光猫使用桥接方式,路由器拨号,软路由 R4S 以旁路由**的方式进行连接。本教程针对该拓扑方案进行介绍,其他网络拓扑如「光猫桥接 + R4S 当主路由进行拨号,或者光猫拨号 + R4S 旁路由」等,也可以实现,但是其中关键的 R4S 设置也许跟本教程有些许的差异,建议多搜索一下,领会其中的精神,不用完全跟我的一样。</span></p>
<p class="content-callout" style="background:rgb(251, 243, 219); color:;"><span class="content-callout-icon">🚧</span><span>同上,如果你是使用光猫直接拨号,你可以直接从光猫接根线出来到旁/主路由上进行组播变单播;也可以直接在支持的设备上使用组播地址进行播放,就不用像我这么麻烦了。具体还要看你家的网络拓扑结构而定。</span></p>
<p class="content-callout" style="background:rgb(251, 236, 221); color:;"><span class="content-callout-icon">🚧</span><span>本教程仅针对北京联通 IPTV 测试成功,其他地区可能有所差异,如果发现文本中有跟地域强相关的内容,请根据你所在的地区替换对应内容。</span></p>
<p class="content-callout" style="background:rgb(244, 238, 238); color:;"><span class="content-callout-icon">🚧</span><span>在修改设置前,请提前先备份所有路由器、设备的设置,以防万一。</span></p>
<p class="content-callout" style="background:rgb(251, 243, 219); color:;"><span class="content-callout-icon">🚧</span><span>我使用的软路由是 R4S,有两个网口。如果你是跟我一样的网络拓扑,请保证你的软路由至少有两个或以上网口,因为一个需要连主路由,另一个需要连光猫。</span></p>
<p class="content-callout" style="background:rgba(244, 240, 247, 0.8); color:;"><span class="content-callout-icon">🚧</span><span>我家的光猫网段是:192.168.1.x,主路由网段是 192.168.5.x;光猫地址是 192.168.1.1,R4S 的地址是 192.168.5.2,主路由 Lan 口地址是 192.168.5.1,路由器 Wan 口地址是 192.168.1.2。</span></p>
<h2 id="确定是否支持白嫖">确定是否支持白嫖</h2>
<p class="content-callout" style="background:rgb(231, 243, 248); color:;"><span class="content-callout-icon">🚧</span><span>目前北京地区的 IPTV 没有增加鉴权,但是从我看到的信息来看其他地区的一些运营商有对 IPTV 进行加密鉴权,即必须用运营商给的 IPTV 盒子的 Mac 地址连接(盒子起到解密的作用),才能实现脱离盒子使用软路由进行局域网任意设备的播放。具体如何实现比较复杂,本教程不介绍这个场景。</span></p>
<h3 id="提前下载-vlc">提前下载 VLC</h3>
<p>光猫桥接,路由器拨号的方式上网后,连接光猫后是无法上网的,因此请先提前在电脑上下载好 VLC 播放软件,以供一会儿进行测试,VLC 播放器地址在这里下载:</p>
<p><a class="link-bookmark" href="https://www.videolan.org/vlc/" target="_blank"><span data-bookmark-img="" data-bookmark-title="O"><img src="" /></span><span><span>Official download of VLC media player, the best Open Source player - VideoLAN</span><span>
Official download of VLC media player, the best Open Source player
</span><span>https://www.videolan.org/vlc/</span></span></a></p>
<h3 id="连接光猫">连接光猫</h3>
<p>将<strong>电脑使用有线的方式连接光猫</strong>的 IPTV 口(如果光猫上没有发现 IPTV 口,则表示光猫支持混插,即接口不区分宽带和 IPTV 口,插任意一个口都行),然后在 VLC 软件中:</p>
<ul>
<li>
<p>打开 File-Open Network。</p>
</li>
<li>
<p>点击下面的 Open RTP/UDP Stream。</p>
</li>
<li>
<p>Protocol 选 RTP,Mode 选 Multicast,IP Address 填:<code class="language-plaintext highlighter-rouge">239.3.1.241</code> (或者 <code class="language-plaintext highlighter-rouge">rtp://239.3.1.241</code> ,具体哪个忘了)端口填 <code class="language-plaintext highlighter-rouge">8000</code> 。</p>
</li>
</ul>
<p>点 Open 之后,如果可以看到北京卫视,说明你可以免费白嫖。</p>
<p caption="VLC RTP 播放"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/ea9168ee-6086-42df-b6b4-269900eb5592.webp" alt="VLC RTP 播放" title="VLC RTP 播放" /></p>
<p class="content-callout" style="background:rgb(251, 243, 219); color:;"><span class="content-callout-icon">💡</span><span>这里的 `rtp://239.3.1.241:8000` 就是北京卫视的组播地址,将来该地址可能有变化,具体准确的地址,可以到 `https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Unicom.m3u` 这里,找到任意一个 rtp 路径后面的 ip 地址进行测试。</span></p>
<h2 id="基本概念解释">基本概念解释</h2>
<p>不想了解的直接跳到下一节。</p>
<h3 id="iptv">IPTV</h3>
<p>根据维基百科对 IPTV 的解释:</p>
<p class="content-callout" style="background:rgb(241, 241, 239); color:;"><span class="content-callout-icon">📖</span><span>网路协定电视(英语:Internet Protocol Television,缩写:IPTV)是宽频电视的一种。IPTV是用宽频网络作为介质传送电视信息的一种系统,将广播节目透过宽频上的网际协议(Internet Protocol, IP)向订户传递数码电视服务。由于需要使用网路,IPTV服务供应商经常会一并提供连接互联网及IP电话等相关服务,也可称为“三重服务”或“三合一服务”(Triple Play)。IPTV是数位电视的一种,因此普通电视机需要配合相应的机顶盒接收频道,也因此供应商通常会向客户同时提供随选视讯服务。虽透过宽频网路及网际协议,但IPTV不一定透过网际网路,为传输品质会通过局域网传输。</span></p>
<p>有此可知,一般情况下 IPTV 都是宽带提供商提供的服务,通过它可以看电视。</p>
<h3 id="组播">组播</h3>
<p>一种 IPTV 实现播放的技术手段,英文名叫「multicast」,也译为多播。具体概念不用弄太清楚,了解到它相比于单播:</p>
<p><strong>优势在于:</strong></p>
<ul>
<li>
<p>不占用互联网带宽。</p>
</li>
<li>
<p>IPTV 盒子起到认证的作用,IPTV 运营商由于是对一个组进行广播,因此对自己的服务器压力较小。</p>
</li>
</ul>
<p>劣势<strong>在于:</strong></p>
<ul>
<li>必须有线连接光猫 IPTV 口(有些光猫支持混插,即不区分 IPTV 口还是宽带口)才能用,因此只能连接 IPTV 盒子的设备使用,不能使用 WiFi 让家里任意设备观看网络电视。</li>
</ul>
<h3 id="单播">单播</h3>
<p>另一种较老的 IPTV 实现播放的技术手段,早期 IPTV 用户不多的时候使用该方案,相比于组播来说,彼之缺点就是其之优点,反之亦然,即:</p>
<p><strong>优势在于:</strong></p>
<ul>
<li>接入后,局域网支持 WiFi ,以供任意设备播放。</li>
</ul>
<p><strong>劣势在于:</strong></p>
<ul>
<li>
<p>跟服务器 1对1 连接,服务器压力较大,用户多的时候播放会比较卡顿。</p>
</li>
<li>
<p>占用宽带的带宽,直接使用互联网连接进行的播放(就跟现在看直播一样)。</p>
</li>
</ul>
<h3 id="udpxy">udpxy</h3>
<blockquote style="border-color:;color:"><p>udpxy服务器是**一款UDP流转HTTP流的代理服务器**,可以将IP直播流转化为HTTP流,方便在各种终端上播放。</p></blockquote>
<p>当无法直接获取到组播地址的时候,用来将组播地址转为单播地址,如组播地址是:a:b, d:e(a、d 为 ip 地址,b、e 为端口);转换成单播地址后就是统一的地址如 z/a/b,z/d/e。播放器监听这个地址 z 即可。</p>
<h3 id="m3u">m3u</h3>
<blockquote style="border-color:;color:"><p>**M3U**(MP3 URL的缩写)是一种播放多媒体列表的文件格式,它的设计初衷是为了播放音频文件,比如MP3,但是越来越多的软件现在用做播放视频文件列表的格式。</p></blockquote>
<p>m3u 文件就是一个里面含有全部播放组播地址的文本文件,在 Apple TV 或者电脑上读取这个文件地址,就可以播放其中的视频地址。</p>
<h3 id="epg">EPG</h3>
<p>包含节目单信息,上一步知道 m3u 地址后,里面都是一个个的 ip 地址,那如何知道每个 ip 地址是哪个频道呢?这个时候就需要一个 EPG 进行配对了,EPG 含有每个地址的节目信息,甚至是频道的简单介绍,EPG 通常会随着视频信号一起广播。</p>
<h2 id="网络拓扑">网络拓扑</h2>
<p caption="网络拓扑-主路由拨号"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/0349a1d5-caeb-4233-b36b-8bc1c7db7565.webp" alt="网络拓扑-主路由拨号" title="网络拓扑-主路由拨号" /></p>
<h2 id="上手实操">上手实操</h2>
<p class="content-callout" style="background:rgb(251, 243, 219); color:;"><span class="content-callout-icon">🚧</span><span>动手之前先按照开头所述检查是否支持白嫖。</span></p>
<h3 id="设置软路由">设置软路由</h3>
<p><strong>安装 udpxy 和 luci-udpxy</strong></p>
<p>这一步就是常规的操作了,UI 安装最方便,如图(安装完成后先别启用,最后一步再启用):</p>
<p caption="软件安装界面"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/2be1ca35-90a8-4936-89cd-5458557ac064.webp" alt="软件安装界面" title="软件安装界面" /></p>
<p><strong>新建/配置网络接口</strong></p>
<p>这一步为了让软路由识别到来自光猫的数据。</p>
<ul>
<li>在 <code class="language-plaintext highlighter-rouge">网络-接口</code> 中新建一个接口,随便起个名字叫 <code class="language-plaintext highlighter-rouge">IPTV</code> :</li>
</ul>
<p caption="新建 IPTV 接口"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/a938e2a7-9723-40f5-8b86-3ed151ba12c5.webp" alt="新建 IPTV 接口" title="新建 IPTV 接口" /></p>
<p>注意箭头的部分,我已经新建好了所以括号中有 IPTV 字样,刚新建的时候是没有的。其中 eth1 是我的 Lan 口,接的是主路由;eth0 是另一个接口,接的即是光猫(IPTV 口);这里我曾经修改过,默认情况下,eht0 是 Lan 口,eth1 是 Wan 口,不重要,这一步是将 Wan 口用作 IPTV 口。</p>
<ul>
<li>配置「IPTV」接口的网关跃点与防火墙设置:</li>
</ul>
<p caption="配置网关跃点"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/d1df1f84-7240-4eb9-872b-6871f9c895a6.webp" alt="配置网关跃点" title="配置网关跃点" /></p>
<p caption="防火墙配置到 wan 上"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/c0e4032b-f066-4fcf-b906-dae85a37d070.webp" alt="防火墙配置到 wan 上" title="防火墙配置到 wan 上" /></p>
<ul>
<li>配置 Wan 口的网关跃点:</li>
</ul>
<p caption="Wan 口网关跃点"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/21347824-ca57-4715-9fe9-cd7b6be0f282.webp" alt="Wan 口网关跃点" title="Wan 口网关跃点" /></p>
<ul>
<li>配置 Lan 口 IGMP 嗅探:</li>
</ul>
<p caption="IGMP 嗅探"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/b075aaec-042b-4f9d-9437-27ea4d17211e.webp" alt="IGMP 嗅探" title="IGMP 嗅探" /></p>
<ul>
<li>配置网络防火墙</li>
</ul>
<p caption="网络防火墙配置"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/577418eb-c3f6-43be-b73b-b1cf3ab5dcea.webp" alt="网络防火墙配置" title="网络防火墙配置" /></p>
<p caption="防火墙配置2"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/b3ce719b-a05d-41ef-ab4a-12eb866178a8.webp" alt="防火墙配置2" title="防火墙配置2" /></p>
<p><strong>配置 udpxy 服务</strong></p>
<ul>
<li>如图配置即可,注意这里的 eth0 是 Wan 口,别搞错了:</li>
</ul>
<p caption="打开 UDPXY"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/bcd40c05-ed7f-43fd-b833-4cee94948150.webp" alt="打开 UDPXY" title="打开 UDPXY" /></p>
<p>最后尝试打开 <a href="[object Object]">http://192.168.5.2:4022/status</a> 验证 udpxy 服务是否启动成功:</p>
<p caption="看到这个就表示成功了"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/189e9cb4-80c9-4b5d-8f57-722660e66145.webp" alt="看到这个就表示成功了" title="看到这个就表示成功了" /></p>
<p>之后,将之前使用 VLC 打开的地址 <code class="language-plaintext highlighter-rouge">rtp://239.3.1.241:8000</code> 改成 <code class="language-plaintext highlighter-rouge">http://192.168.2.1:4022/rtp/239.3.1.241:8000</code> 再尝试打开(不用点下面的 Open RTP/UDP Stream,直接在 URL 中打开)。</p>
<p caption="尝试将 RTP 变 HTTP 播放"><img src="https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/582e015c-4260-4181-a81c-5eafc97a1132.webp" alt="尝试将 RTP 变 HTTP 播放" title="尝试将 RTP 变 HTTP 播放" /></p>