difit 4.0.5 → 4.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +1 -0
- package/README.ko.md +1 -0
- package/README.md +1 -0
- package/README.zh.md +1 -0
- package/dist/cli/comment.d.ts +2 -0
- package/dist/cli/comment.js +91 -0
- package/dist/cli/comment.test.d.ts +1 -0
- package/dist/cli/comment.test.js +164 -0
- package/dist/cli/index.js +103 -12
- package/dist/cli/utils.d.ts +1 -0
- package/dist/cli/utils.js +7 -0
- package/dist/client/assets/{_baseFor-DKyA49xd.js → _baseFor-Dq1lbcoh.js} +1 -1
- package/dist/client/assets/{arc-COOp7iVe.js → arc-1g1LrDb3.js} +1 -1
- package/dist/client/assets/architecture-YZFGNWBL-MZfdAdY6.js +1 -0
- package/dist/client/assets/architectureDiagram-Q4EWVU46-D87-Rmwy.js +36 -0
- package/dist/client/assets/{blockDiagram-DXYQGD6D-CtNJnEWN.js → blockDiagram-DXYQGD6D-Cep-MIFv.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-BqG-1m6C.js → c4Diagram-AHTNJAMY-BQuH9Txx.js} +1 -1
- package/dist/client/assets/channel-CJqLEVLU.js +1 -0
- package/dist/client/assets/{chunk-2KRD3SAO-DqP2NJNd.js → chunk-2KRD3SAO-CpQQpmvx.js} +1 -1
- package/dist/client/assets/chunk-336JU56O-Ddk9EzgO.js +2 -0
- package/dist/client/assets/chunk-426QAEUC-2xhUznDE.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-BT78EnQ6.js → chunk-4BX2VUAB-Ca-N0Wd9.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-C4w_Bwzw.js → chunk-4TB4RGXK-ZTWP_Onw.js} +2 -2
- package/dist/client/assets/{chunk-55IACEB6-z3MQSTaj.js → chunk-55IACEB6-Dub40zHG.js} +1 -1
- package/dist/client/assets/{chunk-5FUZZQ4R-Chei69aj.js → chunk-5FUZZQ4R-Cgda0gtZ.js} +1 -1
- package/dist/client/assets/{chunk-5PVQY5BW-HgRiIs0X.js → chunk-5PVQY5BW-D8JPH_tm.js} +1 -1
- package/dist/client/assets/{chunk-67CJDMHE-B2q10-fp.js → chunk-67CJDMHE-U1KyLHzG.js} +1 -1
- package/dist/client/assets/{chunk-7N4EOEYR-DPgxysWq.js → chunk-7N4EOEYR-WzOy51nD.js} +1 -1
- package/dist/client/assets/{chunk-AA7GKIK3-BqmVmKLq.js → chunk-AA7GKIK3-DlWOj4lr.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-CaIgleFn.js → chunk-BSJP7CBP-CcZ0op08.js} +1 -1
- package/dist/client/assets/{chunk-CIAEETIT-ByD-tlNF.js → chunk-CIAEETIT-qVSphnw5.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-d3RUKKAj.js → chunk-EDXVE4YY-76SPH4sf.js} +1 -1
- package/dist/client/assets/{chunk-ENJZ2VHE-CNq5Qmg9.js → chunk-ENJZ2VHE-CKULNIzL.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DYfHJ6MV.js → chunk-FMBD7UC4-CvDPP3mb.js} +1 -1
- package/dist/client/assets/{chunk-FOC6F5B3-BRpSWlZj.js → chunk-FOC6F5B3-DceW0hWA.js} +1 -1
- package/dist/client/assets/{chunk-ICPOFSXX-B_MThwG6.js → chunk-ICPOFSXX-ChGBNZMk.js} +2 -2
- package/dist/client/assets/{chunk-K5T4RW27-DmamW1Ds.js → chunk-K5T4RW27-DBHdC4ln.js} +10 -10
- package/dist/client/assets/{chunk-KGLVRYIC-CRbg4c4z.js → chunk-KGLVRYIC-DRS7yiGQ.js} +1 -1
- package/dist/client/assets/{chunk-LIHQZDEY-CHQPSdB3.js → chunk-LIHQZDEY-KsE8dyJP.js} +1 -1
- package/dist/client/assets/{chunk-ORNJ4GCN-CIsQ4Zi4.js → chunk-ORNJ4GCN-Dnp4oHRD.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-Cxi0kdGg.js → chunk-OYMX7WX6-CciaotDu.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-BiVE5u_E.js +1 -0
- package/dist/client/assets/{chunk-U2HBQHQK-V_hneCfR.js → chunk-U2HBQHQK-nbp7CjBP.js} +1 -1
- package/dist/client/assets/{chunk-X2U36JSP-De4pvO-I.js → chunk-X2U36JSP-Chs85loT.js} +1 -1
- package/dist/client/assets/{chunk-XPW4576I-B_osXKp6.js → chunk-XPW4576I-VtI9b561.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-C_kqXssD.js → chunk-YZCP3GAM-sBsewSoO.js} +1 -1
- package/dist/client/assets/{chunk-ZZ45TVLE-B_xtlma5.js → chunk-ZZ45TVLE-TMgeW_px.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-CfyHazmg.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-D7Rb-bnu.js +1 -0
- package/dist/client/assets/clone-8xC1huEg.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-5TzM3w9g.js +1 -0
- package/dist/client/assets/{cytoscape.esm-DRReFUEO.js → cytoscape.esm-DdcHPZAZ.js} +2 -2
- package/dist/client/assets/{dagre-KV5264BT-BWYGReXF.js → dagre-KV5264BT-xvyFOxd3.js} +1 -1
- package/dist/client/assets/{dagre-DU-XBdcU.js → dagre-sb6WtN4K.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-DpUUhvWz.js → diagram-5BDNPKRD-ChRpAe5p.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-BJoTrUAx.js → diagram-G4DWMVQ6-C_8BED4A.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-CAk1GW5g.js → diagram-MMDJMWI5-BMwXEou2.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-Cct6g7FA.js → diagram-TYMM5635-CeAkx82D.js} +1 -1
- package/dist/client/assets/{dist-61sCfOmN.js → dist-CwC9dd2Z.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-DHs2bXUj.js → erDiagram-SMLLAGMA-yGCTeXGt.js} +1 -1
- package/dist/client/assets/{flatten-mnWyE-RB.js → flatten-SRIRKgqP.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-DLu-6dfC.js → flowDiagram-DWJPFMVM-CugkvbmM.js} +1 -1
- package/dist/client/assets/ganttDiagram-T4ZO3ILL-BXnlBFgK.js +292 -0
- package/dist/client/assets/gitGraph-7Q5UKJZL-BeTWkPrd.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-Bc_rL3_k.js → gitGraphDiagram-UUTBAWPF-B61aCwwu.js} +1 -1
- package/dist/client/assets/{graphlib-BVMK0xYE.js → graphlib-BMWKz3zT.js} +1 -1
- package/dist/client/assets/index-D2Y8-unG.css +2 -0
- package/dist/client/assets/index-D9v_eYzS.js +79 -0
- package/dist/client/assets/info-OMHHGYJF-MUNR2tTt.js +1 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-Cf8u4jgP.js → infoDiagram-42DDH7IO-Bkh6nTL2.js} +1 -1
- package/dist/client/assets/{isEmpty-CiiIHfXR.js → isEmpty-CStpjy4G.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-7n7DvfEb.js → ishikawaDiagram-UXIWVN3A-D_fdVT6_.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-BMkeQqJb.js → journeyDiagram-VCZTEJTY-DkXVokNF.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-B8KkeZLS.js → kanban-definition-6JOO6SKY-y8qq7qvL.js} +1 -1
- package/dist/client/assets/{line-CVpcI6kj.js → line-B0LcTqNY.js} +1 -1
- package/dist/client/assets/{linear-DmhiOOKU.js → linear-CqIjr2qp.js} +1 -1
- package/dist/client/assets/mermaid-parser.core-Du6QzpZO.js +4 -0
- package/dist/client/assets/{mermaid.core-R7nXpPx-.js → mermaid.core-CZBu-oKJ.js} +3 -3
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-CwcHocMZ.js → mindmap-definition-QFDTVHPH-BJrRxSkM.js} +1 -1
- package/dist/client/assets/{ordinal-k--hYEme.js → ordinal-DIg8h6NI.js} +1 -1
- package/dist/client/assets/packet-4T2RLAQJ-Ci-Uu57s.js +1 -0
- package/dist/client/assets/pie-ZZUOXDRM-pm57XGIg.js +1 -0
- package/dist/client/assets/{pieDiagram-DEJITSTG-BVAn8Lmr.js → pieDiagram-DEJITSTG-Debmhc0u.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-C2XZ_zxa.js → quadrantDiagram-34T5L4WZ-SE3g2BC9.js} +1 -1
- package/dist/client/assets/radar-PYXPWWZC-CH-AuSDw.js +1 -0
- package/dist/client/assets/{reduce-BTlHjXna.js → reduce-CG4cgj93.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-CfO16pkI.js → requirementDiagram-MS252O5E-1mv41puC.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-D_4_234M.js → sankeyDiagram-XADWPNL6-CLjPRtOP.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-B-yHKMuK.js → sequenceDiagram-FGHM5R23-Cs-P3AtR.js} +1 -1
- package/dist/client/assets/src-5XpQHeIJ.js +1 -0
- package/dist/client/assets/{stateDiagram-FHFEXIEX-BeG2di4I.js → stateDiagram-FHFEXIEX-CmB1fohY.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-D6jsrR-f.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-DhtnMGcE.js → timeline-definition-GMOUNBTQ-BMUafJOI.js} +1 -1
- package/dist/client/assets/treeView-SZITEDCU-BGsVMAdJ.js +1 -0
- package/dist/client/assets/treemap-W4RFUUIX-DXnhegXy.js +1 -0
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CBn69TcQ.js → vennDiagram-DHZGUBPP-CpZ1Qhjz.js} +1 -1
- package/dist/client/assets/wardley-RL74JXVD-COd5nWj-.js +1 -0
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CEoSJmN1.js → wardleyDiagram-NUSXRM2D-C-zH0lsd.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-BZ_X9tkn.js → xychartDiagram-5P7HB3ND-SkLFuEHZ.js} +1 -1
- package/dist/client/index.html +2 -4
- package/dist/client/site-data/blobs/080c0e6/cHVibGljL3NpdGUtZGF0YS9vZy1pbWFnZS5wbmc.png +0 -0
- package/dist/client/site-data/blobs/55f23a1/bGFuZGluZy9wdWJsaWMvZGlmaXQvbG9nby5wbmc.png +0 -0
- package/dist/client/site-data/blobs/66ff7c6/cHVibGljL2xvZ28ucG5n.png +0 -0
- package/dist/client/site-data/blobs/e6977fe/cHVibGljL2xvZ28ucG5n.png +0 -0
- package/dist/client/site-data/og-image.png +0 -0
- package/dist/server/file-watcher.d.ts +2 -1
- package/dist/server/file-watcher.js +9 -3
- package/dist/server/git-diff.d.ts +5 -0
- package/dist/server/git-diff.js +65 -1
- package/dist/server/git-diff.test.js +50 -0
- package/dist/server/server.js +265 -68
- package/dist/server/server.test.js +228 -0
- package/dist/tui/App.js +0 -1
- package/dist/types/diff.d.ts +4 -4
- package/dist/types/watch.d.ts +30 -1
- package/dist/utils/commentImports.d.ts +2 -0
- package/dist/utils/commentImports.js +119 -1
- package/dist/utils/editorOptions.d.ts +58 -35
- package/dist/utils/editorOptions.js +150 -24
- package/dist/utils/editorOptions.test.js +201 -9
- package/package.json +7 -4
- package/dist/client/assets/architecture-YZFGNWBL-Cs2Q6RQP.js +0 -1
- package/dist/client/assets/architectureDiagram-Q4EWVU46-BO4dVPUA.js +0 -36
- package/dist/client/assets/channel-_xDT1u3-.js +0 -1
- package/dist/client/assets/chunk-336JU56O-D1qa7Qzb.js +0 -2
- package/dist/client/assets/chunk-426QAEUC-6J_A_wvD.js +0 -1
- package/dist/client/assets/chunk-CFjPhJqf.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-C0QzfgZ8.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-5XrS-DAQ.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-Covl2vKy.js +0 -1
- package/dist/client/assets/clone-rhRH8pyW.js +0 -1
- package/dist/client/assets/cose-bilkent-S5V4N54A-BvXFc7Rr.js +0 -1
- package/dist/client/assets/ganttDiagram-T4ZO3ILL-CMIzlKAR.js +0 -292
- package/dist/client/assets/gitGraph-7Q5UKJZL-A_wWsXju.js +0 -1
- package/dist/client/assets/index-BPoqJmrs.js +0 -79
- package/dist/client/assets/index-Cq_APK7Y.css +0 -2
- package/dist/client/assets/info-OMHHGYJF-Bv3kK2Bb.js +0 -1
- package/dist/client/assets/mermaid-parser.core-CnJ9Tv8l.js +0 -4
- package/dist/client/assets/packet-4T2RLAQJ-D2q3-9ae.js +0 -1
- package/dist/client/assets/pie-ZZUOXDRM-GivlQcUF.js +0 -1
- package/dist/client/assets/preload-helper-DSXbuxSR.js +0 -1
- package/dist/client/assets/radar-PYXPWWZC-C9pD6VNR.js +0 -1
- package/dist/client/assets/src-CjDs0_Ij.js +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DvcSq7KE.js +0 -1
- package/dist/client/assets/treeView-SZITEDCU-BSNk8_yV.js +0 -1
- package/dist/client/assets/treemap-W4RFUUIX-ym4zQztE.js +0 -1
- package/dist/client/assets/wardley-RL74JXVD-B02H6ReJ.js +0 -1
- /package/dist/client/assets/{array-BNor45A1.js → array-DOVTz2Mq.js} +0 -0
- /package/dist/client/assets/{defaultLocale-DPzUsThw.js → defaultLocale-Ck2Xxk-C.js} +0 -0
- /package/dist/client/assets/{init-C0L3woqb.js → init-Bft5Ffpj.js} +0 -0
- /package/dist/client/assets/{katex-FOM3xZj7.js → katex-CeIlAR55.js} +0 -0
- /package/dist/client/assets/{path-sMK4d_s9.js → path-DfRbCp9y.js} +0 -0
- /package/dist/client/assets/{prism-bash-iQBez6et.js → prism-bash-CPkZUJMA.js} +0 -0
- /package/dist/client/assets/{prism-clojure-CTkJ-FW_.js → prism-clojure-BpoF2XhX.js} +0 -0
- /package/dist/client/assets/{prism-csharp-DAAROvjt.js → prism-csharp-BEk8D1-3.js} +0 -0
- /package/dist/client/assets/{prism-dart-CMjMHaBW.js → prism-dart-ByLYrdQB.js} +0 -0
- /package/dist/client/assets/{prism-elixir-B9cwzXs0.js → prism-elixir-BZtyIEab.js} +0 -0
- /package/dist/client/assets/{prism-haskell-Vgx7BCAm.js → prism-haskell-NAsbeo3V.js} +0 -0
- /package/dist/client/assets/{prism-hcl-Du4YC80h.js → prism-hcl-crnGqmVp.js} +0 -0
- /package/dist/client/assets/{prism-java-CWuFbfVD.js → prism-java-BovStacA.js} +0 -0
- /package/dist/client/assets/{prism-markup-templating-h9TC-ifW.js → prism-markup-templating-Cl8NiLjy.js} +0 -0
- /package/dist/client/assets/{prism-nix-CqauNIYa.js → prism-nix-BS_cm_1n.js} +0 -0
- /package/dist/client/assets/{prism-perl-DhcRwJzx.js → prism-perl-DGLVMq5H.js} +0 -0
- /package/dist/client/assets/{prism-php-DcBIrISj.js → prism-php-BskSwJN8.js} +0 -0
- /package/dist/client/assets/{prism-protobuf-DuPg7Jbg.js → prism-protobuf-DfbIYpO7.js} +0 -0
- /package/dist/client/assets/{prism-ruby-lhDmuasn.js → prism-ruby-FBVh1PRE.js} +0 -0
- /package/dist/client/assets/{prism-scala-YlPat9I4.js → prism-scala--9AfMHPY.js} +0 -0
- /package/dist/client/assets/{prism-solidity-C3nR0EVH.js → prism-solidity-BgJNkj1z.js} +0 -0
- /package/dist/client/assets/{prism-sql-Cz-8DmQS.js → prism-sql-C9Czmpov.js} +0 -0
- /package/dist/client/assets/{prism-vim-C3oukvmk.js → prism-vim-CzUNf0WQ.js} +0 -0
- /package/dist/client/assets/{rough.esm-DeLgKbOI.js → rough.esm-Bbn_-PMU.js} +0 -0
|
@@ -1,24 +1,216 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { DEFAULT_EDITOR_ID, EDITOR_OPTIONS, resolveEditorOption } from './editorOptions';
|
|
2
|
+
import { buildEditorSpawnSpec, CUSTOM_EDITOR_ID, DEFAULT_EDITOR_ID, EDITOR_OPTIONS, NONE_EDITOR_ID, parseEditorArgsTemplate, resolveEditorOption, } from './editorOptions';
|
|
3
3
|
describe('editorOptions', () => {
|
|
4
|
-
it('includes Zed in editor options', () => {
|
|
4
|
+
it('includes Zed in editor options with the unified command+args shape', () => {
|
|
5
5
|
const zed = EDITOR_OPTIONS.find((option) => option.id === 'zed');
|
|
6
6
|
expect(zed).toBeDefined();
|
|
7
7
|
expect(zed).toMatchObject({
|
|
8
8
|
id: 'zed',
|
|
9
9
|
label: 'Zed',
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
lineFormat: 'path-suffix',
|
|
10
|
+
command: 'zed',
|
|
11
|
+
argsTemplate: '%file:%line',
|
|
13
12
|
});
|
|
14
13
|
});
|
|
15
|
-
it('resolves zed editor from id', () => {
|
|
14
|
+
it('resolves zed editor from id and case-insensitively', () => {
|
|
16
15
|
expect(resolveEditorOption('zed').id).toBe('zed');
|
|
17
|
-
});
|
|
18
|
-
it('resolves zed editor case-insensitively', () => {
|
|
19
16
|
expect(resolveEditorOption('ZED').id).toBe('zed');
|
|
20
17
|
});
|
|
21
|
-
it('falls back to default editor when unknown value is passed', () => {
|
|
18
|
+
it('falls back to the default editor when an unknown value is passed', () => {
|
|
22
19
|
expect(resolveEditorOption('unknown-editor').id).toBe(DEFAULT_EDITOR_ID);
|
|
23
20
|
});
|
|
21
|
+
it('keeps the "none" option with empty command/args so the UI can hide inputs', () => {
|
|
22
|
+
const none = EDITOR_OPTIONS.find((option) => option.id === NONE_EDITOR_ID);
|
|
23
|
+
expect(none).toBeDefined();
|
|
24
|
+
expect(none?.command).toBe('');
|
|
25
|
+
expect(none?.argsTemplate).toBe('');
|
|
26
|
+
});
|
|
27
|
+
it('exposes a "custom" placeholder entry with empty command/args', () => {
|
|
28
|
+
const custom = EDITOR_OPTIONS.find((option) => option.id === CUSTOM_EDITOR_ID);
|
|
29
|
+
expect(custom).toBeDefined();
|
|
30
|
+
expect(custom?.label).toBe('Custom…');
|
|
31
|
+
expect(custom?.command).toBe('');
|
|
32
|
+
expect(custom?.argsTemplate).toBe('');
|
|
33
|
+
});
|
|
34
|
+
it('excludes editors that are no longer widely used for code review', () => {
|
|
35
|
+
const ids = EDITOR_OPTIONS.map((option) => option.id);
|
|
36
|
+
for (const deprecated of ['textwrangler', 'lyx', 'texmaker', 'alpha', 'atom', 'textadept']) {
|
|
37
|
+
expect(ids, `${deprecated} should not be registered`).not.toContain(deprecated);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
describe('preset editor templates', () => {
|
|
41
|
+
const cases = [
|
|
42
|
+
{
|
|
43
|
+
id: 'vscode',
|
|
44
|
+
command: 'code',
|
|
45
|
+
argsTemplate: '-g %file:%line',
|
|
46
|
+
expectedArgs: ['-g', '/tmp/file.ts:42'],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'cursor',
|
|
50
|
+
command: 'cursor',
|
|
51
|
+
argsTemplate: '-g %file:%line',
|
|
52
|
+
expectedArgs: ['-g', '/tmp/file.ts:42'],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'zed',
|
|
56
|
+
command: 'zed',
|
|
57
|
+
argsTemplate: '%file:%line',
|
|
58
|
+
expectedArgs: ['/tmp/file.ts:42'],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'textmate',
|
|
62
|
+
command: 'mate',
|
|
63
|
+
argsTemplate: '-l %line %file',
|
|
64
|
+
expectedArgs: ['-l', '42', '/tmp/file.ts'],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'bbedit',
|
|
68
|
+
command: 'bbedit',
|
|
69
|
+
argsTemplate: '+%line %file',
|
|
70
|
+
expectedArgs: ['+42', '/tmp/file.ts'],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'emacs',
|
|
74
|
+
command: 'emacsclient',
|
|
75
|
+
argsTemplate: '--no-wait +%line %file',
|
|
76
|
+
expectedArgs: ['--no-wait', '+42', '/tmp/file.ts'],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'macvim',
|
|
80
|
+
command: 'mvim',
|
|
81
|
+
argsTemplate: '--remote-silent +%line %file',
|
|
82
|
+
expectedArgs: ['--remote-silent', '+42', '/tmp/file.ts'],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'sublime',
|
|
86
|
+
command: 'subl',
|
|
87
|
+
argsTemplate: '%file:%line',
|
|
88
|
+
expectedArgs: ['/tmp/file.ts:42'],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: 'nova',
|
|
92
|
+
command: 'nova',
|
|
93
|
+
argsTemplate: 'open %file -l %line',
|
|
94
|
+
expectedArgs: ['open', '/tmp/file.ts', '-l', '42'],
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
for (const testCase of cases) {
|
|
98
|
+
it(`registers ${testCase.id} with the expected command and template`, () => {
|
|
99
|
+
const option = EDITOR_OPTIONS.find((entry) => entry.id === testCase.id);
|
|
100
|
+
expect(option, `${testCase.id} should be registered`).toBeDefined();
|
|
101
|
+
expect(option?.command).toBe(testCase.command);
|
|
102
|
+
expect(option?.argsTemplate).toBe(testCase.argsTemplate);
|
|
103
|
+
});
|
|
104
|
+
it(`builds a spawn spec for ${testCase.id} with %file/%line substituted`, () => {
|
|
105
|
+
const option = resolveEditorOption(testCase.id);
|
|
106
|
+
const spec = buildEditorSpawnSpec({
|
|
107
|
+
command: option.command,
|
|
108
|
+
argsTemplate: option.argsTemplate,
|
|
109
|
+
filePath: '/tmp/file.ts',
|
|
110
|
+
lineNumber: 42,
|
|
111
|
+
});
|
|
112
|
+
expect(spec).not.toBeNull();
|
|
113
|
+
expect(spec?.command).toBe(testCase.command);
|
|
114
|
+
expect(spec?.args).toEqual(testCase.expectedArgs);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
describe('parseEditorArgsTemplate', () => {
|
|
119
|
+
it('splits whitespace-separated tokens', () => {
|
|
120
|
+
expect(parseEditorArgsTemplate('-l %line %file')).toEqual(['-l', '%line', '%file']);
|
|
121
|
+
});
|
|
122
|
+
it('collapses runs of whitespace', () => {
|
|
123
|
+
expect(parseEditorArgsTemplate(' -l %line\t%file ')).toEqual(['-l', '%line', '%file']);
|
|
124
|
+
});
|
|
125
|
+
it('preserves double-quoted segments', () => {
|
|
126
|
+
expect(parseEditorArgsTemplate('+%line "%file"')).toEqual(['+%line', '%file']);
|
|
127
|
+
});
|
|
128
|
+
it('preserves single-quoted segments', () => {
|
|
129
|
+
expect(parseEditorArgsTemplate("'%file' -line %line")).toEqual(['%file', '-line', '%line']);
|
|
130
|
+
});
|
|
131
|
+
it('keeps adjacent quoted and unquoted fragments in a single token', () => {
|
|
132
|
+
expect(parseEditorArgsTemplate('"%file":%line')).toEqual(['%file:%line']);
|
|
133
|
+
});
|
|
134
|
+
it('returns an empty array for empty or whitespace-only input', () => {
|
|
135
|
+
expect(parseEditorArgsTemplate('')).toEqual([]);
|
|
136
|
+
expect(parseEditorArgsTemplate(' \t ')).toEqual([]);
|
|
137
|
+
expect(parseEditorArgsTemplate(undefined)).toEqual([]);
|
|
138
|
+
expect(parseEditorArgsTemplate(null)).toEqual([]);
|
|
139
|
+
});
|
|
140
|
+
it('decodes \\" and \\\\ inside double-quoted segments', () => {
|
|
141
|
+
expect(parseEditorArgsTemplate('--msg "say \\"hi\\""')).toEqual(['--msg', 'say "hi"']);
|
|
142
|
+
expect(parseEditorArgsTemplate('"a\\\\b"')).toEqual(['a\\b']);
|
|
143
|
+
});
|
|
144
|
+
it('leaves other backslash sequences inside double quotes untouched', () => {
|
|
145
|
+
expect(parseEditorArgsTemplate('"\\s+ \\$PATH"')).toEqual(['\\s+ \\$PATH']);
|
|
146
|
+
});
|
|
147
|
+
it('treats single-quoted segments as fully literal', () => {
|
|
148
|
+
expect(parseEditorArgsTemplate('\'say \\"hi\\"\'')).toEqual(['say \\"hi\\"']);
|
|
149
|
+
});
|
|
150
|
+
it('supports an emacsclient --eval template with escaped double quotes', () => {
|
|
151
|
+
const template = '--eval "(tctony/persp-view-file-line-external \\"%file\\" %line)"';
|
|
152
|
+
expect(parseEditorArgsTemplate(template)).toEqual([
|
|
153
|
+
'--eval',
|
|
154
|
+
'(tctony/persp-view-file-line-external "%file" %line)',
|
|
155
|
+
]);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
describe('buildEditorSpawnSpec', () => {
|
|
159
|
+
it('returns null when the command is blank', () => {
|
|
160
|
+
expect(buildEditorSpawnSpec({
|
|
161
|
+
command: '',
|
|
162
|
+
argsTemplate: '-l %line %file',
|
|
163
|
+
filePath: '/tmp/file.ts',
|
|
164
|
+
lineNumber: 1,
|
|
165
|
+
})).toBeNull();
|
|
166
|
+
expect(buildEditorSpawnSpec({
|
|
167
|
+
command: ' ',
|
|
168
|
+
argsTemplate: '%file',
|
|
169
|
+
filePath: '/tmp/file.ts',
|
|
170
|
+
lineNumber: 1,
|
|
171
|
+
})).toBeNull();
|
|
172
|
+
});
|
|
173
|
+
it('trims the command and substitutes %file and %line', () => {
|
|
174
|
+
const spec = buildEditorSpawnSpec({
|
|
175
|
+
command: ' mate ',
|
|
176
|
+
argsTemplate: '-l %line "%file"',
|
|
177
|
+
filePath: '/tmp/file.ts',
|
|
178
|
+
lineNumber: 12,
|
|
179
|
+
});
|
|
180
|
+
expect(spec).toEqual({
|
|
181
|
+
command: 'mate',
|
|
182
|
+
args: ['-l', '12', '/tmp/file.ts'],
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
it('substitutes line 1 when no line number is provided', () => {
|
|
186
|
+
const spec = buildEditorSpawnSpec({
|
|
187
|
+
command: 'mate',
|
|
188
|
+
argsTemplate: '-l %line %file',
|
|
189
|
+
filePath: '/tmp/file.ts',
|
|
190
|
+
lineNumber: null,
|
|
191
|
+
});
|
|
192
|
+
expect(spec?.args).toEqual(['-l', '1', '/tmp/file.ts']);
|
|
193
|
+
});
|
|
194
|
+
it('returns an empty args array when the template is empty', () => {
|
|
195
|
+
const spec = buildEditorSpawnSpec({
|
|
196
|
+
command: 'my-editor',
|
|
197
|
+
argsTemplate: '',
|
|
198
|
+
filePath: '/tmp/file.ts',
|
|
199
|
+
lineNumber: 3,
|
|
200
|
+
});
|
|
201
|
+
expect(spec).toEqual({ command: 'my-editor', args: [] });
|
|
202
|
+
});
|
|
203
|
+
it('builds a spawn spec for an emacsclient --eval elisp invocation', () => {
|
|
204
|
+
const spec = buildEditorSpawnSpec({
|
|
205
|
+
command: 'emacsclient',
|
|
206
|
+
argsTemplate: '--eval "(tctony/persp-view-file-line-external \\"%file\\" %line)"',
|
|
207
|
+
filePath: '/tmp/foo.ts',
|
|
208
|
+
lineNumber: 42,
|
|
209
|
+
});
|
|
210
|
+
expect(spec).toEqual({
|
|
211
|
+
command: 'emacsclient',
|
|
212
|
+
args: ['--eval', '(tctony/persp-view-file-line-external "/tmp/foo.ts" 42)'],
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
24
216
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "difit",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.6",
|
|
4
4
|
"description": "A lightweight command-line tool that spins up a local web server to display Git commit diffs in a GitHub-like Files changed view",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -37,9 +37,12 @@
|
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"dev": "node scripts/dev.js",
|
|
40
|
+
"dev:site": "pnpm run build:cli && node scripts/export-site-data.js && vite --config vite.config.site.ts --open /",
|
|
40
41
|
"dev:cli": "tsc --project tsconfig.cli.json && NODE_ENV=development node dist/cli/index.js",
|
|
41
|
-
"build": "
|
|
42
|
+
"build": "pnpm run build:cli && vite build",
|
|
43
|
+
"build:site": "pnpm run build:cli && node scripts/export-site-data.js && GITHUB_PAGES=true vite build --config vite.config.site.ts",
|
|
42
44
|
"build:cli": "tsc --project tsconfig.cli.json",
|
|
45
|
+
"export:site-data": "node scripts/export-site-data.js",
|
|
43
46
|
"package:vscode": "pnpm -C packages/vscode run package",
|
|
44
47
|
"start": "pnpm run build && node dist/cli/index.js",
|
|
45
48
|
"check": "oxlint . --type-aware --type-check --deny-warnings --report-unused-disable-directives",
|
|
@@ -93,7 +96,7 @@
|
|
|
93
96
|
"happy-dom": "^20.0.0",
|
|
94
97
|
"knip": "^6.0.0",
|
|
95
98
|
"lefthook": "^2.0.0",
|
|
96
|
-
"oxfmt": "^0.
|
|
99
|
+
"oxfmt": "^0.46.0",
|
|
97
100
|
"oxlint": "^1.49.0",
|
|
98
101
|
"oxlint-tsgolint": "^0.21.0",
|
|
99
102
|
"playwright": "^1.54.1",
|
|
@@ -107,5 +110,5 @@
|
|
|
107
110
|
"engines": {
|
|
108
111
|
"node": ">=21.0.0"
|
|
109
112
|
},
|
|
110
|
-
"packageManager": "pnpm@10.33.
|
|
113
|
+
"packageManager": "pnpm@10.33.2"
|
|
111
114
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./chunk-K5T4RW27-DmamW1Ds.js";import{n as e}from"./chunk-7N4EOEYR-DPgxysWq.js";export{e as createArchitectureServices};
|