@mak-98/dirvi-cli 0.2.1 → 0.3.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/dist/application/action.d.ts +19 -0
- package/dist/application/action.d.ts.map +1 -0
- package/dist/application/action.js +1 -0
- package/dist/application/display-rows.d.ts +3 -3
- package/dist/application/display-rows.d.ts.map +1 -1
- package/dist/application/display-rows.js +7 -7
- package/dist/application/effect-to-action.d.ts +5 -0
- package/dist/application/effect-to-action.d.ts.map +1 -0
- package/dist/application/effect-to-action.js +79 -0
- package/dist/application/fold-helpers.d.ts +2 -2
- package/dist/application/fold-helpers.d.ts.map +1 -1
- package/dist/application/fold-helpers.js +0 -17
- package/dist/application/intent-to-effect.d.ts +39 -0
- package/dist/application/intent-to-effect.d.ts.map +1 -0
- package/dist/application/intent-to-effect.js +118 -0
- package/dist/application/reducer-action.d.ts +19 -0
- package/dist/application/reducer-action.d.ts.map +1 -0
- package/dist/application/reducer-action.js +1 -0
- package/dist/application/reducer.d.ts +3 -28
- package/dist/application/reducer.d.ts.map +1 -1
- package/dist/application/reducer.js +16 -172
- package/dist/application/user-input-to-intent.d.ts +15 -0
- package/dist/application/user-input-to-intent.d.ts.map +1 -0
- package/dist/application/user-input-to-intent.js +56 -0
- package/dist/domain/event-message.d.ts +3 -3
- package/dist/domain/event-message.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/infrastructure/input.d.ts +3 -3
- package/dist/infrastructure/input.d.ts.map +1 -1
- package/dist/infrastructure/input.js +16 -7
- package/dist/infrastructure/load-initial-props.d.ts.map +1 -1
- package/dist/infrastructure/load-initial-props.js +6 -8
- package/dist/infrastructure/user-input.d.ts +17 -0
- package/dist/infrastructure/user-input.d.ts.map +1 -0
- package/dist/infrastructure/user-input.js +35 -0
- package/dist/ui/App.d.ts +4 -5
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +54 -58
- package/dist/ui/App2.d.ts +11 -0
- package/dist/ui/App2.d.ts.map +1 -0
- package/dist/ui/App2.js +96 -0
- package/dist/ui/AppShell.d.ts +3 -3
- package/dist/ui/AppShell.d.ts.map +1 -1
- package/dist/ui/AppShell.js +3 -3
- package/dist/ui/components/DirEntries.d.ts +2 -1
- package/dist/ui/components/DirEntries.d.ts.map +1 -1
- package/dist/ui/components/DirEntries.js +6 -7
- package/dist/ui/components/UnixEntryComponent.d.ts +6 -0
- package/dist/ui/components/UnixEntryComponent.d.ts.map +1 -0
- package/dist/ui/components/UnixEntryComponent.js +12 -0
- package/dist/ui/components/ViewRowComponent.d.ts +5 -0
- package/dist/ui/components/ViewRowComponent.d.ts.map +1 -0
- package/dist/ui/components/ViewRowComponent.js +13 -0
- package/dist/ui/hooks/useView.d.ts +4 -0
- package/dist/ui/hooks/useView.d.ts.map +1 -0
- package/dist/ui/hooks/useView.js +30 -0
- package/dist/ui/view.d.ts +18 -0
- package/dist/ui/view.d.ts.map +1 -0
- package/dist/ui/view.js +74 -0
- package/package.json +2 -2
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { UnixEntry, UnixEntryPath } from 'dirvi-lib';
|
|
2
|
+
export type Action = {
|
|
3
|
+
kind: 'nextEntry';
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'prevEntry';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'updateDir';
|
|
8
|
+
path: UnixEntryPath;
|
|
9
|
+
entries: UnixEntry[] | undefined;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'outDir';
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'toggleFold';
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'fold';
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'unfold';
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/application/action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,MAAM,MAAM,GACd;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;CAClC,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;CAChB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;CACpB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function createDisplayRows(buffer:
|
|
3
|
-
export declare function displayRowAtPath(buffer:
|
|
1
|
+
import { DisplayRow, UnixEntryPath, FoldNode, UnixEntry } from 'dirvi-lib';
|
|
2
|
+
export declare function createDisplayRows(buffer: UnixEntry[], folds: FoldNode): DisplayRow[];
|
|
3
|
+
export declare function displayRowAtPath(buffer: UnixEntry[], folds: FoldNode, path: UnixEntryPath): DisplayRow | undefined;
|
|
4
4
|
//# sourceMappingURL=display-rows.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-rows.d.ts","sourceRoot":"","sources":["../../src/application/display-rows.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"display-rows.d.ts","sourceRoot":"","sources":["../../src/application/display-rows.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EAAE,QAAQ,EACvB,SAAS,EAEV,MAAM,WAAW,CAAC;AAuDnB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EAAE,EACnB,KAAK,EAAE,QAAQ,GACd,UAAU,EAAE,CAEd;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EAAE,EACnB,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,aAAa,GAClB,UAAU,GAAG,SAAS,CAqBxB"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { hasFold } from './fold-helpers.js';
|
|
1
|
+
import { UnixEntryPath, FoldNode, } from 'dirvi-lib';
|
|
3
2
|
function displayRowsAtPath(entries, path, foldNode) {
|
|
4
3
|
const rows = [];
|
|
5
4
|
let index = 0;
|
|
6
5
|
while (index < entries.length) {
|
|
7
6
|
const entry = entries[index];
|
|
8
|
-
if (foldNode !== undefined &&
|
|
7
|
+
if (foldNode !== undefined && FoldNode.getIfEntryFolded(foldNode, entry)) {
|
|
9
8
|
const entryNames = [];
|
|
10
|
-
while (index < entries.length &&
|
|
9
|
+
while (index < entries.length &&
|
|
10
|
+
FoldNode.getIfEntryFolded(foldNode, entries[index])) {
|
|
11
11
|
entryNames.push(entries[index].name);
|
|
12
12
|
index += 1;
|
|
13
13
|
}
|
|
@@ -31,7 +31,7 @@ function displayRowsAtPath(entries, path, foldNode) {
|
|
|
31
31
|
return rows;
|
|
32
32
|
}
|
|
33
33
|
export function createDisplayRows(buffer, folds) {
|
|
34
|
-
return displayRowsAtPath(buffer
|
|
34
|
+
return displayRowsAtPath(buffer, [], folds);
|
|
35
35
|
}
|
|
36
36
|
export function displayRowAtPath(buffer, folds, path) {
|
|
37
37
|
if (path.length === 0) {
|
|
@@ -42,9 +42,9 @@ export function displayRowAtPath(buffer, folds, path) {
|
|
|
42
42
|
const entryName = path[path.length - 1];
|
|
43
43
|
return rows.find((row) => {
|
|
44
44
|
if (row.kind === 'entry') {
|
|
45
|
-
return (row.entry.name === entryName &&
|
|
45
|
+
return (row.entry.name === entryName && UnixEntryPath.equal(row.parentPath, parentPath));
|
|
46
46
|
}
|
|
47
|
-
return (
|
|
47
|
+
return (UnixEntryPath.equal(row.parentPath, parentPath) &&
|
|
48
48
|
row.entryNames.includes(entryName));
|
|
49
49
|
});
|
|
50
50
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { NavigationNode, State } from 'dirvi-lib';
|
|
2
|
+
import type { ReducerAction } from './reducer-action.js';
|
|
3
|
+
import { EffectAction } from './intent-to-effect.js';
|
|
4
|
+
export declare function effectToAction(effectAction: EffectAction, navigation: NavigationNode, state: State): ReducerAction | undefined;
|
|
5
|
+
//# sourceMappingURL=effect-to-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-to-action.d.ts","sourceRoot":"","sources":["../../src/application/effect-to-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,cAAc,EAC1B,KAAK,EAAE,KAAK,GACX,aAAa,GAAG,SAAS,CAsG3B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { NavigationNode } from 'dirvi-lib';
|
|
2
|
+
export function effectToAction(effectAction, navigation, state) {
|
|
3
|
+
switch (effectAction.kind) {
|
|
4
|
+
case 'nextEntry': {
|
|
5
|
+
const cursor = NavigationNode.nextCursor(navigation, state.cursor);
|
|
6
|
+
return cursor === undefined
|
|
7
|
+
? undefined
|
|
8
|
+
: {
|
|
9
|
+
kind: 'changeCursor',
|
|
10
|
+
cursor,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
case 'prevEntry': {
|
|
14
|
+
const cursor = NavigationNode.previousCursor(navigation, state.cursor);
|
|
15
|
+
return cursor === undefined
|
|
16
|
+
? undefined
|
|
17
|
+
: {
|
|
18
|
+
kind: 'changeCursor',
|
|
19
|
+
cursor,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
case 'updateDir':
|
|
23
|
+
return {
|
|
24
|
+
kind: 'updateDir',
|
|
25
|
+
path: effectAction.path,
|
|
26
|
+
entries: effectAction.entries,
|
|
27
|
+
};
|
|
28
|
+
case 'outDir': {
|
|
29
|
+
const cursor = NavigationNode.parentCursor(navigation, state.cursor);
|
|
30
|
+
return cursor === undefined
|
|
31
|
+
? undefined
|
|
32
|
+
: {
|
|
33
|
+
kind: 'changeCursor',
|
|
34
|
+
cursor,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
case 'fold': {
|
|
38
|
+
if (state.cursor.kind === 'fold') {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const path = [...state.cursor.parentPath, state.cursor.entryName];
|
|
42
|
+
const entry = NavigationNode.getEntryAtPath(navigation, path);
|
|
43
|
+
if (entry === undefined) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const cursor = NavigationNode.cursorAfterFold(navigation, state.cursor);
|
|
47
|
+
if (cursor === undefined) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
kind: 'fold',
|
|
52
|
+
parentPath: state.cursor.parentPath,
|
|
53
|
+
entry,
|
|
54
|
+
cursor,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
case 'unfold': {
|
|
58
|
+
if (state.cursor.kind !== 'fold') {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
const node = NavigationNode.getNodeAtPath(navigation, state.cursor.parentPath);
|
|
62
|
+
if (node === undefined || node.foldedEntries.length === 0) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const firstFoldedEntry = node.foldedEntries[0];
|
|
66
|
+
return {
|
|
67
|
+
kind: 'unfold',
|
|
68
|
+
parentPath: state.cursor.parentPath,
|
|
69
|
+
cursor: {
|
|
70
|
+
kind: 'entry',
|
|
71
|
+
parentPath: state.cursor.parentPath,
|
|
72
|
+
entryName: firstFoldedEntry.name,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
case 'toggleFold':
|
|
77
|
+
return effectToAction(state.cursor.kind === 'fold' ? { kind: 'unfold' } : { kind: 'fold' }, navigation, state);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { UnixEntry, UnixEntryName
|
|
1
|
+
import type { UnixEntry, UnixEntryName } from 'dirvi-lib';
|
|
2
|
+
import { FoldNode } from 'dirvi-lib';
|
|
2
3
|
export declare function hasFold(node: FoldNode, entryName: UnixEntryName): boolean;
|
|
3
4
|
export declare function entryIsFolded(node: FoldNode | undefined, entry: UnixEntry): boolean;
|
|
4
|
-
export declare function updateFoldNodeAtPath(node: FoldNode, path: UnixEntryName[], update: (node: FoldNode) => FoldNode): FoldNode;
|
|
5
5
|
export declare function setFolds(node: FoldNode, entries: UnixEntry[]): FoldNode;
|
|
6
6
|
export declare function addFold(node: FoldNode, entryName: UnixEntryName): FoldNode;
|
|
7
7
|
export declare function unfoldFoldSequence(node: FoldNode, entries: UnixEntry[], entryName: UnixEntryName): FoldNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fold-helpers.d.ts","sourceRoot":"","sources":["../../src/application/fold-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"fold-helpers.d.ts","sourceRoot":"","sources":["../../src/application/fold-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAEzE;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,GAAG,SAAS,EAC1B,KAAK,EAAE,SAAS,GACf,OAAO,CAET;AAGD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,CAOvE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,GAAG,QAAQ,CAS1E;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,SAAS,EAAE,EACpB,SAAS,EAAE,aAAa,GACvB,QAAQ,CA8BV"}
|
|
@@ -1,26 +1,9 @@
|
|
|
1
|
-
import { createEmptyFoldNode } from 'dirvi-lib';
|
|
2
1
|
export function hasFold(node, entryName) {
|
|
3
2
|
return node.folds.includes(entryName);
|
|
4
3
|
}
|
|
5
4
|
export function entryIsFolded(node, entry) {
|
|
6
5
|
return node !== undefined && hasFold(node, entry.name);
|
|
7
6
|
}
|
|
8
|
-
export function updateFoldNodeAtPath(node, path, update) {
|
|
9
|
-
const [currentName, ...remainingPath] = path;
|
|
10
|
-
// Base case
|
|
11
|
-
if (currentName === undefined) {
|
|
12
|
-
return update(node);
|
|
13
|
-
}
|
|
14
|
-
// Create childNode to create path in tree to the needed node
|
|
15
|
-
const childNode = node.children[currentName] ?? createEmptyFoldNode();
|
|
16
|
-
return {
|
|
17
|
-
...node,
|
|
18
|
-
children: {
|
|
19
|
-
...node.children,
|
|
20
|
-
[currentName]: updateFoldNodeAtPath(childNode, remainingPath, update),
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
7
|
// Replaces all folds at a node
|
|
25
8
|
export function setFolds(node, entries) {
|
|
26
9
|
const entryNames = entries.map((entry) => entry.name);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { State } from 'dirvi-lib';
|
|
2
|
+
import { Intent } from './user-input-to-intent.js';
|
|
3
|
+
import { UnixEntry, UnixEntryPath } from 'dirvi-lib';
|
|
4
|
+
export type EffectAction = {
|
|
5
|
+
kind: 'nextEntry';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'prevEntry';
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'updateDir';
|
|
10
|
+
path: UnixEntryPath;
|
|
11
|
+
entries: UnixEntry[] | undefined;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'outDir';
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'fold';
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'unfold';
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'toggleFold';
|
|
20
|
+
};
|
|
21
|
+
export type Effect = {
|
|
22
|
+
effectType: 'dispatchEffectAsAction';
|
|
23
|
+
action: EffectAction;
|
|
24
|
+
} | {
|
|
25
|
+
effectType: 'loadDir';
|
|
26
|
+
path: UnixEntryPath;
|
|
27
|
+
} | {
|
|
28
|
+
effectType: 'printFile';
|
|
29
|
+
path: UnixEntryPath;
|
|
30
|
+
} | {
|
|
31
|
+
effectType: 'exit';
|
|
32
|
+
exitMessage: string;
|
|
33
|
+
};
|
|
34
|
+
export type EffectResult = {
|
|
35
|
+
commandBuffer: string;
|
|
36
|
+
effect?: Effect;
|
|
37
|
+
};
|
|
38
|
+
export declare function intentToEffect(intent: Intent, state: State): EffectResult | undefined;
|
|
39
|
+
//# sourceMappingURL=intent-to-effect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-to-effect.d.ts","sourceRoot":"","sources":["../../src/application/intent-to-effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAQ,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAGrD,MAAM,MAAM,YAAY,GACpB;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;CAClC,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;CAChB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,MAAM,GACd;IACE,UAAU,EAAE,wBAAwB,CAAC;IACrC,MAAM,EAAE,YAAY,CAAC;CACtB,GACD;IACE,UAAU,EAAE,SAAS,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC;CACrB,GACD;IACE,UAAU,EAAE,WAAW,CAAC;IACxB,IAAI,EAAE,aAAa,CAAC;CACrB,GACD;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEN,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AA0GF,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,SAAS,CAiC1B"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Cursor, View } from 'dirvi-lib';
|
|
2
|
+
function dispatchAction(action) {
|
|
3
|
+
return {
|
|
4
|
+
effectType: 'dispatchEffectAsAction',
|
|
5
|
+
action,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function interactRightToEffect(state) {
|
|
9
|
+
const currentEntry = View.getEntryAtCursor(state);
|
|
10
|
+
if (currentEntry === undefined) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const path = Cursor.getPath(state.cursor);
|
|
14
|
+
if (path === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (currentEntry.kind === 'directory') {
|
|
18
|
+
if (currentEntry.entries === undefined) {
|
|
19
|
+
return {
|
|
20
|
+
effectType: 'loadDir',
|
|
21
|
+
path,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return dispatchAction({
|
|
26
|
+
kind: 'updateDir',
|
|
27
|
+
path,
|
|
28
|
+
entries: undefined,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (currentEntry.kind === 'file') {
|
|
33
|
+
return {
|
|
34
|
+
effectType: 'printFile',
|
|
35
|
+
path,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// TODO Later: Peeking on folds
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
function interactLeftToEffect(state) {
|
|
42
|
+
if (state.cursor.parentPath.length === 0) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return dispatchAction({
|
|
46
|
+
kind: 'outDir',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// Here if the updated command buffer reaches a recognized motion,
|
|
50
|
+
// sends the effect.
|
|
51
|
+
function commandBufferToEffectResult(updatedCommandBuffer) {
|
|
52
|
+
switch (updatedCommandBuffer) {
|
|
53
|
+
case 'q':
|
|
54
|
+
return {
|
|
55
|
+
commandBuffer: '',
|
|
56
|
+
effect: {
|
|
57
|
+
effectType: 'exit',
|
|
58
|
+
exitMessage: '',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
case 'za':
|
|
62
|
+
return {
|
|
63
|
+
commandBuffer: '',
|
|
64
|
+
effect: dispatchAction({
|
|
65
|
+
kind: 'toggleFold',
|
|
66
|
+
}),
|
|
67
|
+
};
|
|
68
|
+
case 'zc':
|
|
69
|
+
return {
|
|
70
|
+
commandBuffer: '',
|
|
71
|
+
effect: dispatchAction({
|
|
72
|
+
kind: 'fold',
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
case 'zo':
|
|
76
|
+
return {
|
|
77
|
+
commandBuffer: '',
|
|
78
|
+
effect: dispatchAction({
|
|
79
|
+
kind: 'unfold',
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
default:
|
|
83
|
+
return {
|
|
84
|
+
commandBuffer: updatedCommandBuffer,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Effect derived from Intent and the state.
|
|
89
|
+
export function intentToEffect(intent, state) {
|
|
90
|
+
switch (intent.intentType) {
|
|
91
|
+
case 'updateCommandBuffer':
|
|
92
|
+
return commandBufferToEffectResult(intent.updatedCommandBuffer);
|
|
93
|
+
case 'interactRight':
|
|
94
|
+
return {
|
|
95
|
+
commandBuffer: '',
|
|
96
|
+
effect: interactRightToEffect(state),
|
|
97
|
+
};
|
|
98
|
+
case 'interactLeft':
|
|
99
|
+
return {
|
|
100
|
+
commandBuffer: '',
|
|
101
|
+
effect: interactLeftToEffect(state),
|
|
102
|
+
};
|
|
103
|
+
case 'interactDown':
|
|
104
|
+
return {
|
|
105
|
+
commandBuffer: '',
|
|
106
|
+
effect: dispatchAction({
|
|
107
|
+
kind: 'nextEntry',
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
case 'interactUp':
|
|
111
|
+
return {
|
|
112
|
+
commandBuffer: '',
|
|
113
|
+
effect: dispatchAction({
|
|
114
|
+
kind: 'prevEntry',
|
|
115
|
+
}),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Cursor, UnixEntry, UnixEntryPath } from 'dirvi-lib';
|
|
2
|
+
export type ReducerAction = {
|
|
3
|
+
kind: 'changeCursor';
|
|
4
|
+
cursor: Cursor;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'updateDir';
|
|
7
|
+
path: UnixEntryPath;
|
|
8
|
+
entries: UnixEntry[] | undefined;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'fold';
|
|
11
|
+
parentPath: UnixEntryPath;
|
|
12
|
+
entry: UnixEntry;
|
|
13
|
+
cursor: Cursor;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'unfold';
|
|
16
|
+
parentPath: UnixEntryPath;
|
|
17
|
+
cursor: Cursor;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=reducer-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reducer-action.d.ts","sourceRoot":"","sources":["../../src/application/reducer-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;CAClC,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,aAAa,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,29 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} | {
|
|
5
|
-
kind: 'prevEntry';
|
|
6
|
-
} | {
|
|
7
|
-
kind: 'toggleDir';
|
|
8
|
-
path: EntryPath;
|
|
9
|
-
} | {
|
|
10
|
-
kind: 'printFile';
|
|
11
|
-
path: EntryPath;
|
|
12
|
-
} | {
|
|
13
|
-
kind: 'outDir';
|
|
14
|
-
} | {
|
|
15
|
-
kind: 'toggleFold';
|
|
16
|
-
} | {
|
|
17
|
-
kind: 'fold';
|
|
18
|
-
} | {
|
|
19
|
-
kind: 'unfold';
|
|
20
|
-
} | {
|
|
21
|
-
kind: 'directoryLoaded';
|
|
22
|
-
path: UnixEntryName[];
|
|
23
|
-
entries: UnixEntry[];
|
|
24
|
-
} | {
|
|
25
|
-
kind: 'exit';
|
|
26
|
-
exitMessage: string;
|
|
27
|
-
};
|
|
28
|
-
export declare function reducer(view: View, action: Action): View;
|
|
1
|
+
import { State } from 'dirvi-lib';
|
|
2
|
+
import { ReducerAction } from './reducer-action.js';
|
|
3
|
+
export declare function reducer(state: State, action: ReducerAction): State;
|
|
29
4
|
//# sourceMappingURL=reducer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/application/reducer.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/application/reducer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACN,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,GAAG,KAAK,CA8ClE"}
|
|
@@ -1,187 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { createDisplayRows, displayRowAtPath } from './display-rows.js';
|
|
4
|
-
import { entryAtPath } from './dir-buffer-helpers.js';
|
|
5
|
-
function updateEntries(entries, currentPath, newEntries) {
|
|
6
|
-
const [currentName, ...remainingPath] = currentPath;
|
|
7
|
-
if (currentName === undefined) {
|
|
8
|
-
throw new Error('Cannot update directory entries with an empty path');
|
|
9
|
-
}
|
|
10
|
-
let found = false;
|
|
11
|
-
const updatedEntries = entries.map((entry) => {
|
|
12
|
-
if (entry.name !== currentName) {
|
|
13
|
-
return entry;
|
|
14
|
-
}
|
|
15
|
-
found = true;
|
|
16
|
-
if (remainingPath.length === 0) {
|
|
17
|
-
if (entry.kind !== 'directory') {
|
|
18
|
-
throw new Error(`Cannot load entries for non-directory entry "${entry.name}" of kind "${entry.kind}"`);
|
|
19
|
-
}
|
|
20
|
-
if (newEntries === undefined) {
|
|
21
|
-
return {
|
|
22
|
-
kind: 'directory',
|
|
23
|
-
name: entry.name,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
...entry,
|
|
28
|
-
entries: newEntries,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
if (entry.kind !== 'directory') {
|
|
32
|
-
throw new Error(`Cannot descend through non-directory entry "${entry.name}"`);
|
|
33
|
-
}
|
|
34
|
-
if (entry.entries === undefined) {
|
|
35
|
-
throw new Error(`Cannot descend into unexpanded directory "${entry.name}"`);
|
|
36
|
-
}
|
|
37
|
-
return {
|
|
38
|
-
...entry,
|
|
39
|
-
entries: updateEntries(entry.entries, remainingPath, newEntries),
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
if (!found) {
|
|
43
|
-
throw new Error(`Directory path does not contain entry "${currentName}"`);
|
|
44
|
-
}
|
|
45
|
-
return updatedEntries;
|
|
46
|
-
}
|
|
47
|
-
function updateEntriesAtPath(buffer, path, newEntries) {
|
|
48
|
-
return {
|
|
49
|
-
...buffer,
|
|
50
|
-
entries: updateEntries(buffer.entries, path, newEntries),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
export function reducer(view, action) {
|
|
1
|
+
import { UnixEntry, FoldNode, } from 'dirvi-lib';
|
|
2
|
+
export function reducer(state, action) {
|
|
54
3
|
switch (action.kind) {
|
|
55
|
-
case '
|
|
56
|
-
case 'prevEntry': {
|
|
57
|
-
const displayRows = createDisplayRows(view.buffer, view.folds);
|
|
58
|
-
const currentIndex = displayRows.findIndex((row) => rowsEqual(view.cursor, row));
|
|
59
|
-
if (currentIndex === -1) {
|
|
60
|
-
return view;
|
|
61
|
-
}
|
|
62
|
-
const direction = action.kind === 'nextEntry' ? 1 : -1;
|
|
63
|
-
const targetIndex = currentIndex + direction;
|
|
64
|
-
if (targetIndex < 0 || targetIndex >= displayRows.length) {
|
|
65
|
-
return view;
|
|
66
|
-
}
|
|
67
|
-
const newCursor = displayRows[targetIndex];
|
|
4
|
+
case 'changeCursor':
|
|
68
5
|
return {
|
|
69
|
-
...
|
|
70
|
-
cursor:
|
|
6
|
+
...state,
|
|
7
|
+
cursor: action.cursor,
|
|
71
8
|
};
|
|
72
|
-
|
|
73
|
-
case 'toggleDir': {
|
|
74
|
-
const buffer = updateEntriesAtPath(view.buffer, action.path, undefined);
|
|
9
|
+
case 'updateDir':
|
|
75
10
|
return {
|
|
76
|
-
...
|
|
77
|
-
buffer,
|
|
11
|
+
...state,
|
|
12
|
+
buffer: UnixEntry.setEntriesAtPath(state.buffer, action.path, action.entries),
|
|
78
13
|
};
|
|
79
|
-
}
|
|
80
|
-
case 'printFile':
|
|
81
|
-
// Handled by App
|
|
82
|
-
return view;
|
|
83
|
-
case 'directoryLoaded': {
|
|
84
|
-
// Add new entries to path
|
|
85
|
-
const buffer = updateEntriesAtPath(view.buffer, action.path, action.entries);
|
|
86
|
-
return {
|
|
87
|
-
...view,
|
|
88
|
-
buffer,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
// 1. Identify the directory represented by parentPath
|
|
92
|
-
// 2. Check whether the cursor fold contains all its entries
|
|
93
|
-
// 3. Unload the directory entries
|
|
94
|
-
// 4. Recalculate the parent display row
|
|
95
|
-
// 5. Move the cursor to that parent row
|
|
96
|
-
case 'outDir': {
|
|
97
|
-
const cursor = view.cursor;
|
|
98
|
-
const parentPath = cursor.parentPath;
|
|
99
|
-
if (parentPath.length === 0) {
|
|
100
|
-
return view;
|
|
101
|
-
}
|
|
102
|
-
const parentEntry = entryAtPath(view.buffer, parentPath);
|
|
103
|
-
const shouldUnloadDirectory = cursor.kind === 'fold' &&
|
|
104
|
-
parentEntry?.kind === 'directory' &&
|
|
105
|
-
parentEntry.entries !== undefined &&
|
|
106
|
-
entryNamesEqual(cursor.entryNames, parentEntry.entries.map((entry) => entry.name));
|
|
107
|
-
const buffer = shouldUnloadDirectory
|
|
108
|
-
? updateEntriesAtPath(view.buffer, parentPath, undefined)
|
|
109
|
-
: view.buffer;
|
|
110
|
-
const updatedView = {
|
|
111
|
-
...view,
|
|
112
|
-
buffer,
|
|
113
|
-
};
|
|
114
|
-
const parentDisplayRow = displayRowAtPath(updatedView.buffer, updatedView.folds, parentPath);
|
|
115
|
-
if (parentDisplayRow === undefined || parentDisplayRow.kind !== 'entry') {
|
|
116
|
-
return view;
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
...updatedView,
|
|
120
|
-
cursor: parentDisplayRow,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
case 'toggleFold':
|
|
124
|
-
return reducer(view, view.cursor.kind === 'fold' ? { kind: 'unfold' } : { kind: 'fold' });
|
|
125
14
|
case 'fold': {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
const currentName = cursor.entry.name;
|
|
131
|
-
const parentPath = cursor.parentPath;
|
|
132
|
-
const entry = entryAtPath(view.buffer, [...parentPath, currentName]);
|
|
133
|
-
if (entry === undefined) {
|
|
134
|
-
return view;
|
|
135
|
-
}
|
|
136
|
-
const folds = updateFoldNodeAtPath(view.folds, parentPath, (node) => addFold(node, currentName));
|
|
137
|
-
const updatedView = {
|
|
138
|
-
...view,
|
|
15
|
+
const folds = FoldNode.addFoldedEntryAtPath(state.folds, action.parentPath, action.entry);
|
|
16
|
+
return {
|
|
17
|
+
...state,
|
|
139
18
|
folds,
|
|
19
|
+
cursor: action.cursor,
|
|
140
20
|
};
|
|
141
|
-
const foldedRow = displayRowAtPath(updatedView.buffer, updatedView.folds, [...parentPath, currentName]);
|
|
142
|
-
return foldedRow === undefined
|
|
143
|
-
? updatedView
|
|
144
|
-
: {
|
|
145
|
-
...updatedView,
|
|
146
|
-
cursor: foldedRow,
|
|
147
|
-
};
|
|
148
21
|
}
|
|
149
22
|
case 'unfold': {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
const firstEntryName = cursor.entryNames[0];
|
|
155
|
-
if (firstEntryName === undefined) {
|
|
156
|
-
return view;
|
|
157
|
-
}
|
|
158
|
-
const { parentPath } = cursor;
|
|
159
|
-
const parentEntry = parentPath.length === 0
|
|
160
|
-
? undefined
|
|
161
|
-
: entryAtPath(view.buffer, parentPath);
|
|
162
|
-
const entries = parentPath.length === 0
|
|
163
|
-
? view.buffer.entries
|
|
164
|
-
: parentEntry?.kind === 'directory'
|
|
165
|
-
? parentEntry.entries
|
|
166
|
-
: undefined;
|
|
167
|
-
if (entries === undefined) {
|
|
168
|
-
return view;
|
|
169
|
-
}
|
|
170
|
-
const folds = updateFoldNodeAtPath(view.folds, parentPath, (node) => unfoldFoldSequence(node, entries, firstEntryName));
|
|
171
|
-
const updatedView = {
|
|
172
|
-
...view,
|
|
23
|
+
const folds = FoldNode.modifyAtPath(state.folds, action.parentPath, (node) => FoldNode.clearFoldedEntries(node));
|
|
24
|
+
return {
|
|
25
|
+
...state,
|
|
173
26
|
folds,
|
|
27
|
+
cursor: action.cursor,
|
|
174
28
|
};
|
|
175
|
-
const unfoldedRow = displayRowAtPath(updatedView.buffer, updatedView.folds, [...parentPath, firstEntryName]);
|
|
176
|
-
return unfoldedRow === undefined
|
|
177
|
-
? updatedView
|
|
178
|
-
: {
|
|
179
|
-
...updatedView,
|
|
180
|
-
cursor: unfoldedRow,
|
|
181
|
-
};
|
|
182
29
|
}
|
|
183
|
-
case 'exit':
|
|
184
|
-
// Exit is handled by App.
|
|
185
|
-
return view;
|
|
186
30
|
}
|
|
187
31
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { UserInput } from '../infrastructure/user-input.js';
|
|
2
|
+
export type Intent = {
|
|
3
|
+
intentType: 'interactRight';
|
|
4
|
+
} | {
|
|
5
|
+
intentType: 'interactLeft';
|
|
6
|
+
} | {
|
|
7
|
+
intentType: 'interactDown';
|
|
8
|
+
} | {
|
|
9
|
+
intentType: 'interactUp';
|
|
10
|
+
} | {
|
|
11
|
+
intentType: 'updateCommandBuffer';
|
|
12
|
+
updatedCommandBuffer: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function userInputToIntent(userInput: UserInput, commandBuffer: string): Intent | undefined;
|
|
15
|
+
//# sourceMappingURL=user-input-to-intent.d.ts.map
|