@gjermundgaraba-designs/pixel-paper 0.20.1 → 0.22.0
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/DESIGN.md +21 -15
- package/dist/src/bench/bench.d.ts +14 -0
- package/dist/src/bench/bench.d.ts.map +1 -0
- package/dist/src/bench/bench.js +9 -0
- package/dist/src/bench/index.d.ts +3 -0
- package/dist/src/bench/index.d.ts.map +1 -0
- package/dist/src/bench/index.js +1 -0
- package/dist/src/chip/chip.d.ts +10 -0
- package/dist/src/chip/chip.d.ts.map +1 -1
- package/dist/src/chip/chip.js +19 -0
- package/dist/src/chip/index.d.ts +2 -2
- package/dist/src/chip/index.d.ts.map +1 -1
- package/dist/src/chip/index.js +1 -1
- package/dist/src/drag/drag.d.ts +18 -0
- package/dist/src/drag/drag.d.ts.map +1 -1
- package/dist/src/drag/drag.js +35 -7
- package/dist/src/field/field.d.ts +3 -0
- package/dist/src/field/field.d.ts.map +1 -1
- package/dist/src/field/field.js +2 -2
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/lineDiff/index.d.ts +2 -0
- package/dist/src/lineDiff/index.d.ts.map +1 -1
- package/dist/src/lineDiff/index.js +1 -0
- package/dist/src/lineDiff/lineDiff.d.ts +8 -4
- package/dist/src/lineDiff/lineDiff.d.ts.map +1 -1
- package/dist/src/lineDiff/lineDiff.js +19 -15
- package/dist/src/lineDiff/patch.d.ts +35 -0
- package/dist/src/lineDiff/patch.d.ts.map +1 -0
- package/dist/src/lineDiff/patch.js +146 -0
- package/dist/src/menu/menu.d.ts +6 -6
- package/dist/src/rail/index.d.ts +1 -1
- package/dist/src/rail/index.d.ts.map +1 -1
- package/dist/src/rail/index.js +1 -1
- package/dist/src/rail/rail.d.ts +217 -17
- package/dist/src/rail/rail.d.ts.map +1 -1
- package/dist/src/rail/rail.js +133 -15
- package/dist/src/reel/index.d.ts +1 -1
- package/dist/src/reel/index.d.ts.map +1 -1
- package/dist/src/reel/index.js +1 -1
- package/dist/src/reel/layout.d.ts +21 -26
- package/dist/src/reel/layout.d.ts.map +1 -1
- package/dist/src/reel/layout.js +84 -106
- package/dist/src/reel/reel.d.ts +30 -172
- package/dist/src/reel/reel.d.ts.map +1 -1
- package/dist/src/reel/reel.js +144 -195
- package/dist/src/rows/rows.d.ts +9 -1
- package/dist/src/rows/rows.d.ts.map +1 -1
- package/dist/src/rows/rows.js +1 -1
- package/dist/src/sortable/sortable.d.ts +30 -30
- package/dist/src/toast/toast.d.ts +12 -12
- package/dist/src/window/window.d.ts +3 -1
- package/dist/src/window/window.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bench/bench.ts +24 -0
- package/src/bench/index.ts +2 -0
- package/src/chip/chip.ts +31 -0
- package/src/chip/index.ts +2 -2
- package/src/drag/drag.ts +60 -1
- package/src/field/field.ts +5 -1
- package/src/index.ts +1 -0
- package/src/lineDiff/index.ts +2 -0
- package/src/lineDiff/lineDiff.ts +29 -24
- package/src/lineDiff/patch.ts +218 -0
- package/src/pixel-paper.css +202 -32
- package/src/rail/index.ts +2 -0
- package/src/rail/rail.ts +181 -16
- package/src/reel/index.ts +0 -1
- package/src/reel/layout.ts +78 -118
- package/src/reel/reel.ts +108 -216
- package/src/rows/rows.ts +14 -2
- package/src/tokens.css +2 -1
- package/src/window/window.ts +3 -1
|
@@ -11,7 +11,8 @@ export type ViewConfig = Readonly<{
|
|
|
11
11
|
}>;
|
|
12
12
|
/** Configuration for rendering a unified diff with `patchView`. */
|
|
13
13
|
export type PatchViewConfig = Readonly<{
|
|
14
|
-
/** One file's unified diff, as `diff -u` or `git diff -- <path>` writes it
|
|
14
|
+
/** One file's unified diff, as `diff -u` or `git diff -- <path>` writes it, its git header
|
|
15
|
+
* included. */
|
|
15
16
|
patch: string;
|
|
16
17
|
/** Names the two sides for screen readers: `"Version 3 against version 4"`. */
|
|
17
18
|
label: string;
|
|
@@ -23,8 +24,11 @@ export declare const view: <Message>(config: ViewConfig, h: HtmlBuilder<Message>
|
|
|
23
24
|
/** A unified diff the caller already has (from a server, or `git diff -- <path>`) as `view`'s
|
|
24
25
|
* table: its hunks' lines, numbered from their headers, and the unchanged lines between hunks
|
|
25
26
|
* folded into a counted row. Lines past the last hunk are not in the patch, so nothing counts
|
|
26
|
-
* them.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* them. What git's header says beyond the lines prints as a note line above the table, or in
|
|
28
|
+
* its place: a rename, a mode change, an empty or binary file (`describePatch` has the
|
|
29
|
+
* sentences). A file whose type changed (a file that became a symlink) is two sections, each
|
|
30
|
+
* its own table under one note, named for its side (`"<label>, as it was"`). An empty patch
|
|
31
|
+
* says there is no difference, as `view` does; text that is not a diff, or holds several
|
|
32
|
+
* files, says it cannot be shown as lines. */
|
|
29
33
|
export declare const patchView: <Message>(config: PatchViewConfig, h: HtmlBuilder<Message>) => Html;
|
|
30
34
|
//# sourceMappingURL=lineDiff.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lineDiff.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/lineDiff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"lineDiff.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/lineDiff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAWtD,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd;mBACe;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC;oBACgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAyEH;;kFAEkF;AAClF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAO3E,CAAC;AAEF;;;;;;;;+CAQ+C;AAC/C,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,eAAe,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAoBrF,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
-
import { Array, Option
|
|
2
|
+
import { Array, Option } from "effect";
|
|
3
3
|
import { LOCALE } from "../locale/locale.js";
|
|
4
|
-
import { DiffRow, diffRowsOf,
|
|
4
|
+
import { DiffRow, diffRowsOf, foldUnchanged, hasChanges } from "./diff.js";
|
|
5
|
+
import { SAME_NOTE, readPatch } from "./patch.js";
|
|
5
6
|
// VIEW
|
|
6
7
|
const DEFAULT_CONTEXT = 2;
|
|
7
8
|
const COLUMN_COUNT = 4;
|
|
@@ -29,7 +30,6 @@ const rowView = (row, h) => __foldkitBrandViewResult((DiffRow.match(row, {
|
|
|
29
30
|
Fold: ({ count, firstOldNumber }) => __foldkitBrandViewResult((foldView(count, firstOldNumber, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#Fold"),
|
|
30
31
|
})), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#rowView");
|
|
31
32
|
const noteView = (note, h) => __foldkitBrandViewResult((h.p([h.Class("note-line")], [note])), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#noteView");
|
|
32
|
-
const SAME_NOTE = "No difference: both sides hold the same text.";
|
|
33
33
|
const tableView = (rows, label, h) => __foldkitBrandViewResult((h.div([h.Class("diff-wrap")], [
|
|
34
34
|
h.table([h.AriaLabel(label), h.Class("diff")], [
|
|
35
35
|
h.tbody([], Array.map(rows, (row) => __foldkitBrandViewResult((rowView(row, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#anonymous"))),
|
|
@@ -48,18 +48,22 @@ export const view = (config, h) => {
|
|
|
48
48
|
/** A unified diff the caller already has (from a server, or `git diff -- <path>`) as `view`'s
|
|
49
49
|
* table: its hunks' lines, numbered from their headers, and the unchanged lines between hunks
|
|
50
50
|
* folded into a counted row. Lines past the last hunk are not in the patch, so nothing counts
|
|
51
|
-
* them.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
51
|
+
* them. What git's header says beyond the lines prints as a note line above the table, or in
|
|
52
|
+
* its place: a rename, a mode change, an empty or binary file (`describePatch` has the
|
|
53
|
+
* sentences). A file whose type changed (a file that became a symlink) is two sections, each
|
|
54
|
+
* its own table under one note, named for its side (`"<label>, as it was"`). An empty patch
|
|
55
|
+
* says there is no difference, as `view` does; text that is not a diff, or holds several
|
|
56
|
+
* files, says it cannot be shown as lines. */
|
|
54
57
|
export const patchView = (config, h) => {
|
|
55
58
|
const { patch, label } = config;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
const { notes, tables } = readPatch(patch);
|
|
60
|
+
const parts = [
|
|
61
|
+
...(Array.isReadonlyArrayNonEmpty(notes) ? [noteView(Array.join(notes, " "), h)] : []),
|
|
62
|
+
...Array.map(tables, ({ rows, maybeSide }) => __foldkitBrandViewResult((tableView(rows, Option.match(maybeSide, { onNone: () => __foldkitBrandViewResult((label), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onNone"), onSome: (side) => __foldkitBrandViewResult((`${label}, ${side}`), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onSome") }), h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#anonymous~2")),
|
|
63
|
+
];
|
|
64
|
+
// a lone table or note is drawn bare, so a flush window's body still meets its table
|
|
65
|
+
return __foldkitBrandViewResult((Array.match(parts, {
|
|
66
|
+
onEmpty: () => __foldkitBrandViewResult((noteView(SAME_NOTE, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onEmpty"),
|
|
67
|
+
onNonEmpty: ([part, ...others]) => __foldkitBrandViewResult((Array.isArrayEmpty(others) ? part : h.div([h.Class("stack gap-s")], parts)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onNonEmpty"),
|
|
68
|
+
})), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#patchView");
|
|
65
69
|
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Option } from "effect";
|
|
2
|
+
import { type DiffRow } from "./diff.ts";
|
|
3
|
+
/** The name a path in git's header stands for: git C-quotes a name with unusual bytes
|
|
4
|
+
* (`"caf\303\251.txt"`), and leaves any other as it is. */
|
|
5
|
+
export declare const unquoted: (path: string) => string;
|
|
6
|
+
/** What a diff of two same texts says. */
|
|
7
|
+
export declare const SAME_NOTE = "No difference: both sides hold the same text.";
|
|
8
|
+
/** A table of the patch's lines; `maybeSide` says which side of a type change it is. */
|
|
9
|
+
type Table = Readonly<{
|
|
10
|
+
rows: ReadonlyArray<DiffRow>;
|
|
11
|
+
maybeSide: Option.Option<string>;
|
|
12
|
+
}>;
|
|
13
|
+
/** What `patchView` draws: its notes as a line, then its tables. */
|
|
14
|
+
export type PatchReading = Readonly<{
|
|
15
|
+
maybeRenamedFrom: Option.Option<string>;
|
|
16
|
+
notes: ReadonlyArray<string>;
|
|
17
|
+
tables: ReadonlyArray<Table>;
|
|
18
|
+
}>;
|
|
19
|
+
/** What `patchView` makes of a patch: the notes it prints and the tables it draws. */
|
|
20
|
+
export declare const readPatch: (patch: string) => PatchReading;
|
|
21
|
+
/** What a patch says beyond its lines, as `patchView` prints it. */
|
|
22
|
+
export type PatchDescription = Readonly<{
|
|
23
|
+
/** The path a rename left, unquoted: for a heading such as `old.txt → new.txt`. */
|
|
24
|
+
maybeRenamedFrom: Option.Option<string>;
|
|
25
|
+
/** The sentences `patchView` prints above the patch's lines, or in their place: a rename,
|
|
26
|
+
* a mode change, a type change, an empty or binary file, no difference, or a patch it
|
|
27
|
+
* cannot show as lines. */
|
|
28
|
+
notes: ReadonlyArray<string>;
|
|
29
|
+
}>;
|
|
30
|
+
/** What `patchView` says about a patch from `git diff`, read from its header: the notes it
|
|
31
|
+
* prints (`["Renamed from old.txt."]`), for a caller that prints them itself, and the path a
|
|
32
|
+
* rename left. */
|
|
33
|
+
export declare const describePatch: (patch: string) => PatchDescription;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=patch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/patch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAErD,OAAO,EAAE,KAAK,OAAO,EAAmB,MAAM,WAAW,CAAC;AAgC1D;4DAC4D;AAC5D,eAAO,MAAM,QAAQ,SAAU,MAAM,KAAG,MAO9B,CAAC;AAsCX,0CAA0C;AAC1C,eAAO,MAAM,SAAS,kDAAkD,CAAC;AAIzE,wFAAwF;AACxF,KAAK,KAAK,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAE1F,oEAAoE;AACpE,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CAC9B,CAAC,CAAC;AAoFH,sFAAsF;AACtF,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,YAiBzC,CAAC;AAIF,oEAAoE;AACpE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,mFAAmF;IACnF,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC;;gCAE4B;IAC5B,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B,CAAC,CAAC;AAEH;;mBAEmB;AACnB,eAAO,MAAM,aAAa,UAAW,MAAM,KAAG,gBAI7C,CAAC"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { Array, Option, String, pipe } from "effect";
|
|
3
|
+
import { diffRowsOfPatch } from "./diff.js";
|
|
4
|
+
// QUOTED PATHS
|
|
5
|
+
const ESCAPED_BYTES = {
|
|
6
|
+
a: 7,
|
|
7
|
+
b: 8,
|
|
8
|
+
t: 9,
|
|
9
|
+
n: 10,
|
|
10
|
+
v: 11,
|
|
11
|
+
f: 12,
|
|
12
|
+
r: 13,
|
|
13
|
+
};
|
|
14
|
+
// an octal escape is one byte of the name's UTF-8, so the bytes are gathered before decoding
|
|
15
|
+
const QUOTED_PART = /\\([0-7]{3})|\\(.)|[^\\]+/gu;
|
|
16
|
+
const bytesOf = (text) => __foldkitBrandViewResult(([...new TextEncoder().encode(text)]), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#bytesOf");
|
|
17
|
+
const bytesOfPart = ([part, octal, escaped]) => {
|
|
18
|
+
if (octal !== undefined) {
|
|
19
|
+
return __foldkitBrandViewResult(([Number.parseInt(octal, 8)]), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#bytesOfPart");
|
|
20
|
+
}
|
|
21
|
+
else if (escaped !== undefined) {
|
|
22
|
+
return __foldkitBrandViewResult((Option.match(Option.fromUndefinedOr(ESCAPED_BYTES[escaped]), {
|
|
23
|
+
onNone: () => __foldkitBrandViewResult((bytesOf(escaped)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#onNone"),
|
|
24
|
+
onSome: (byte) => __foldkitBrandViewResult(([byte]), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#onSome"),
|
|
25
|
+
})), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#bytesOfPart");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return __foldkitBrandViewResult((bytesOf(part)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#bytesOfPart");
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
/** The name a path in git's header stands for: git C-quotes a name with unusual bytes
|
|
32
|
+
* (`"caf\303\251.txt"`), and leaves any other as it is. */
|
|
33
|
+
export const unquoted = (path) => __foldkitBrandViewResult((path.length >= 2 && path.startsWith('"') && path.endsWith('"')
|
|
34
|
+
? new TextDecoder().decode(Uint8Array.from(Array.flatMap(Array.fromIterable(path.slice(1, -1).matchAll(QUOTED_PART)), bytesOfPart)))
|
|
35
|
+
: path), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#unquoted");
|
|
36
|
+
// HEADER
|
|
37
|
+
const GIT_SECTION = "diff --git ";
|
|
38
|
+
// the header is what comes before the first hunk, so a changed line that reads like a header
|
|
39
|
+
// line ("+rename from x") is never taken for one
|
|
40
|
+
const headOf = (section) => __foldkitBrandViewResult((Array.takeWhile(section.split("\n"), (line) => __foldkitBrandViewResult((!line.startsWith("@@") && !line.startsWith("--- ")), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous"))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#headOf");
|
|
41
|
+
const valueAfter = (head, prefix) => __foldkitBrandViewResult((pipe(Array.findFirst(head, String.startsWith(prefix)), Option.map((line) => __foldkitBrandViewResult((line.slice(prefix.length)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~2")))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#valueAfter");
|
|
42
|
+
const hasLine = (head, prefix) => __foldkitBrandViewResult((Option.isSome(valueAfter(head, prefix))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#hasLine");
|
|
43
|
+
const hasHunk = (section) => __foldkitBrandViewResult((Array.some(section.split("\n"), String.startsWith("@@ "))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#hasHunk");
|
|
44
|
+
// git writes one section per file, after whatever precedes the first (a commit's message, a
|
|
45
|
+
// mail's head); a patch without a git header is one section
|
|
46
|
+
const sectionsOf = (patch) => {
|
|
47
|
+
const [first = "", ...others] = patch.split(/(?=^diff --git )/mu);
|
|
48
|
+
return __foldkitBrandViewResult((Array.isArrayNonEmpty(others) && !first.startsWith(GIT_SECTION)
|
|
49
|
+
? others
|
|
50
|
+
: [first, ...others]), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#sectionsOf");
|
|
51
|
+
};
|
|
52
|
+
// READING
|
|
53
|
+
/** What a diff of two same texts says. */
|
|
54
|
+
export const SAME_NOTE = "No difference: both sides hold the same text.";
|
|
55
|
+
const UNREADABLE_NOTE = "This diff cannot be shown as lines.";
|
|
56
|
+
const BINARY_NOTE = "A binary file: its change has no lines.";
|
|
57
|
+
const unreadable = {
|
|
58
|
+
maybeRenamedFrom: Option.none(),
|
|
59
|
+
notes: [UNREADABLE_NOTE],
|
|
60
|
+
tables: [],
|
|
61
|
+
};
|
|
62
|
+
const lineNote = (head, hasRows) => {
|
|
63
|
+
if (hasLine(head, "Binary files ") || hasLine(head, "GIT binary patch")) {
|
|
64
|
+
return __foldkitBrandViewResult((Option.some(BINARY_NOTE)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#lineNote");
|
|
65
|
+
}
|
|
66
|
+
else if (hasRows) {
|
|
67
|
+
return __foldkitBrandViewResult((Option.none()), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#lineNote");
|
|
68
|
+
}
|
|
69
|
+
else if (hasLine(head, "new file mode ")) {
|
|
70
|
+
return __foldkitBrandViewResult((Option.some("New empty file.")), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#lineNote");
|
|
71
|
+
}
|
|
72
|
+
else if (hasLine(head, "deleted file mode ")) {
|
|
73
|
+
return __foldkitBrandViewResult((Option.some("Deleted empty file.")), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#lineNote");
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return __foldkitBrandViewResult((Option.none()), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#lineNote");
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const readSection = (section) => {
|
|
80
|
+
const head = headOf(section);
|
|
81
|
+
const maybeRows = diffRowsOfPatch(section);
|
|
82
|
+
const maybeRenamedFrom = Option.map(valueAfter(head, "rename from "), unquoted);
|
|
83
|
+
const notes = [
|
|
84
|
+
...Option.toArray(Option.map(maybeRenamedFrom, (from) => __foldkitBrandViewResult((`Renamed from ${from}.`), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~3"))),
|
|
85
|
+
...Option.toArray(Option.map(Option.all({ before: valueAfter(head, "old mode "), after: valueAfter(head, "new mode ") }), ({ before, after }) => __foldkitBrandViewResult((`Mode ${before} → ${after}.`), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~4"))),
|
|
86
|
+
...Option.toArray(lineNote(head, Option.isSome(maybeRows))),
|
|
87
|
+
];
|
|
88
|
+
const isUnread = Option.isNone(maybeRows) && (hasHunk(section) || Array.isArrayEmpty(notes));
|
|
89
|
+
return __foldkitBrandViewResult((isUnread
|
|
90
|
+
? unreadable
|
|
91
|
+
: {
|
|
92
|
+
maybeRenamedFrom,
|
|
93
|
+
notes,
|
|
94
|
+
tables: Option.toArray(Option.map(maybeRows, (rows) => (__foldkitBrandViewResult(({ rows, maybeSide: Option.none() }), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~5")))),
|
|
95
|
+
}), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#readSection");
|
|
96
|
+
};
|
|
97
|
+
const KINDS = {
|
|
98
|
+
"100644": "a file",
|
|
99
|
+
"100755": "an executable file",
|
|
100
|
+
"120000": "a symlink",
|
|
101
|
+
"160000": "a submodule",
|
|
102
|
+
};
|
|
103
|
+
const kindOf = (mode) => __foldkitBrandViewResult((KINDS[mode] ?? `mode ${mode}`), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#kindOf");
|
|
104
|
+
const sideTable = (section, side) => __foldkitBrandViewResult((Option.toArray(Option.map(diffRowsOfPatch(section), (rows) => (__foldkitBrandViewResult(({ rows, maybeSide: Option.some(side) }), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~6"))))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#sideTable");
|
|
105
|
+
// a file that became a symlink (or any other kind) is two sections for one path: the old
|
|
106
|
+
// kind deleted, then the new one added
|
|
107
|
+
const readTypeChange = (gone, added) => {
|
|
108
|
+
const [goneHead, addedHead] = [headOf(gone), headOf(added)];
|
|
109
|
+
return __foldkitBrandViewResult((Option.flatMap(Option.all({
|
|
110
|
+
before: valueAfter(goneHead, "deleted file mode "),
|
|
111
|
+
after: valueAfter(addedHead, "new file mode "),
|
|
112
|
+
}), ({ before, after }) => __foldkitBrandViewResult((goneHead[0] === addedHead[0]
|
|
113
|
+
? Option.some({
|
|
114
|
+
maybeRenamedFrom: Option.none(),
|
|
115
|
+
notes: [`It was ${kindOf(before)} and is now ${kindOf(after)}.`],
|
|
116
|
+
tables: [...sideTable(gone, "as it was"), ...sideTable(added, "as it is")],
|
|
117
|
+
})
|
|
118
|
+
: Option.none()), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~7"))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#readTypeChange");
|
|
119
|
+
};
|
|
120
|
+
/** What `patchView` makes of a patch: the notes it prints and the tables it draws. */
|
|
121
|
+
export const readPatch = (patch) => {
|
|
122
|
+
const text = patch.replaceAll("\r\n", "\n");
|
|
123
|
+
if (String.isEmpty(String.trim(text))) {
|
|
124
|
+
return __foldkitBrandViewResult(({ maybeRenamedFrom: Option.none(), notes: [SAME_NOTE], tables: [] }), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#readPatch");
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const sections = sectionsOf(text);
|
|
128
|
+
const [first, second, ...rest] = sections;
|
|
129
|
+
if (first !== undefined && second === undefined) {
|
|
130
|
+
return __foldkitBrandViewResult((readSection(first)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#readPatch");
|
|
131
|
+
}
|
|
132
|
+
else if (first !== undefined && second !== undefined && Array.isArrayEmpty(rest)) {
|
|
133
|
+
return __foldkitBrandViewResult((Option.getOrElse(readTypeChange(first, second), () => __foldkitBrandViewResult((unreadable), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#anonymous~8"))), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#readPatch");
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
return __foldkitBrandViewResult((unreadable), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#readPatch");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/** What `patchView` says about a patch from `git diff`, read from its header: the notes it
|
|
141
|
+
* prints (`["Renamed from old.txt."]`), for a caller that prints them itself, and the path a
|
|
142
|
+
* rename left. */
|
|
143
|
+
export const describePatch = (patch) => {
|
|
144
|
+
const { maybeRenamedFrom, notes } = readPatch(patch);
|
|
145
|
+
return __foldkitBrandViewResult(({ maybeRenamedFrom, notes }), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/patch.js#describePatch");
|
|
146
|
+
};
|
package/dist/src/menu/menu.d.ts
CHANGED
|
@@ -76,6 +76,8 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
76
76
|
};
|
|
77
77
|
commands?: Update.Commands<{
|
|
78
78
|
readonly _tag: "CompletedFocus";
|
|
79
|
+
} | {
|
|
80
|
+
readonly _tag: "PressedEscape";
|
|
79
81
|
} | {
|
|
80
82
|
readonly _tag: "ClickedToggle";
|
|
81
83
|
} | {
|
|
@@ -84,8 +86,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
84
86
|
readonly _tag: "CompletedPlaceSlip";
|
|
85
87
|
} | {
|
|
86
88
|
readonly _tag: "LeftSlip";
|
|
87
|
-
} | {
|
|
88
|
-
readonly _tag: "PressedEscape";
|
|
89
89
|
} | {
|
|
90
90
|
readonly _tag: "PressedTab";
|
|
91
91
|
} | {
|
|
@@ -125,11 +125,11 @@ export declare const BindSlip: Mount.MountDefinitionWithArgs<"BindSlip", {
|
|
|
125
125
|
isEnd: Schema.Boolean;
|
|
126
126
|
edge: Schema.Literals<readonly ["First", "Last"]>;
|
|
127
127
|
}, {
|
|
128
|
+
readonly _tag: "PressedEscape";
|
|
129
|
+
} | {
|
|
128
130
|
readonly _tag: "CompletedPlaceSlip";
|
|
129
131
|
} | {
|
|
130
132
|
readonly _tag: "LeftSlip";
|
|
131
|
-
} | {
|
|
132
|
-
readonly _tag: "PressedEscape";
|
|
133
133
|
} | {
|
|
134
134
|
readonly _tag: "PressedTab";
|
|
135
135
|
}>;
|
|
@@ -175,6 +175,8 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
175
175
|
readonly edge: "First" | "Last";
|
|
176
176
|
}, {
|
|
177
177
|
readonly _tag: "CompletedFocus";
|
|
178
|
+
} | {
|
|
179
|
+
readonly _tag: "PressedEscape";
|
|
178
180
|
} | {
|
|
179
181
|
readonly _tag: "ClickedToggle";
|
|
180
182
|
} | {
|
|
@@ -183,8 +185,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
183
185
|
readonly _tag: "CompletedPlaceSlip";
|
|
184
186
|
} | {
|
|
185
187
|
readonly _tag: "LeftSlip";
|
|
186
|
-
} | {
|
|
187
|
-
readonly _tag: "PressedEscape";
|
|
188
188
|
} | {
|
|
189
189
|
readonly _tag: "PressedTab";
|
|
190
190
|
} | {
|
package/dist/src/rail/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { FollowRailDrawer, HideRailDrawer, Message, Model, ShowRailDrawer, close, id, init, isOpen, update, view, } from "./rail.ts";
|
|
1
|
+
export { FollowRailDrawer, HideRailDrawer, Message, Model, OutMessage, ShowRailDrawer, close, id, init, isOpen, subscriptions, update, view, } from "./rail.ts";
|
|
2
2
|
export type { InitConfig, ViewInputs } from "./rail.ts";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,KAAK,EACL,cAAc,EACd,KAAK,EACL,EAAE,EACF,IAAI,EACJ,MAAM,EACN,MAAM,EACN,IAAI,GACL,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,KAAK,EACL,UAAU,EACV,cAAc,EACd,KAAK,EACL,EAAE,EACF,IAAI,EACJ,MAAM,EACN,aAAa,EACb,MAAM,EACN,IAAI,GACL,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/src/rail/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { FollowRailDrawer, HideRailDrawer, Message, Model, ShowRailDrawer, close, id, init, isOpen, update, view, } from "./rail.js";
|
|
1
|
+
export { FollowRailDrawer, HideRailDrawer, Message, Model, OutMessage, ShowRailDrawer, close, id, init, isOpen, subscriptions, update, view, } from "./rail.js";
|