reslop 0.2.4 → 0.2.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/CHANGELOG.md +25 -1
- package/LICENSE +1 -1
- package/README.md +12 -13
- package/bin/reslop.js +3 -8
- package/lib/ansi.js +32 -19
- package/lib/capabilities.js +8 -12
- package/lib/cli.js +40 -74
- package/lib/clipboard.js +48 -18
- package/lib/dashboard/git.js +128 -0
- package/lib/dashboard/model.js +332 -0
- package/lib/dashboard/npm.js +193 -0
- package/lib/dashboard/tree.js +278 -0
- package/lib/deps-diff.js +196 -404
- package/lib/deps.js +240 -399
- package/lib/detect.js +8 -18
- package/lib/diff/align.js +41 -113
- package/lib/diff/diff.js +12 -43
- package/lib/diff/display.js +25 -36
- package/lib/diff/edit.js +6 -20
- package/lib/diff/inline.js +138 -141
- package/lib/diff/items.js +33 -47
- package/lib/diff/parse.js +28 -56
- package/lib/diff/patch.js +12 -33
- package/lib/diff/unit.js +90 -206
- package/lib/editor.js +98 -55
- package/lib/files.js +86 -103
- package/lib/git-branches.js +254 -416
- package/lib/git-deps.js +182 -344
- package/lib/git-reword-todo.js +5 -13
- package/lib/git-worktree.js +141 -212
- package/lib/git.js +21 -49
- package/lib/github.js +67 -181
- package/lib/gitlab.js +40 -90
- package/lib/highlight/bash.js +55 -177
- package/lib/highlight/core.js +157 -132
- package/lib/highlight/css.js +25 -58
- package/lib/highlight/csv.js +19 -37
- package/lib/highlight/dart.js +72 -213
- package/lib/highlight/dot.js +16 -26
- package/lib/highlight/html.js +42 -63
- package/lib/highlight/js.js +177 -506
- package/lib/highlight/json.js +17 -37
- package/lib/highlight/log.js +22 -35
- package/lib/highlight/txt.js +9 -22
- package/lib/highlight.js +17 -46
- package/lib/keys.js +62 -85
- package/lib/manifest.js +67 -130
- package/lib/npm-commands.js +119 -189
- package/lib/remote.js +141 -197
- package/lib/render/branches.js +66 -73
- package/lib/render/chrome.js +264 -323
- package/lib/render/commits.js +187 -500
- package/lib/render/dash-activity.js +212 -0
- package/lib/render/dash-blocks.js +245 -0
- package/lib/render/dash-table.js +290 -0
- package/lib/render/dashboard.js +62 -0
- package/lib/render/diff.js +123 -228
- package/lib/render/files.js +45 -99
- package/lib/render/frame.js +129 -183
- package/lib/render/notes.js +144 -160
- package/lib/render/npm.js +234 -112
- package/lib/render/present.js +4 -11
- package/lib/render/primitives.js +131 -170
- package/lib/render/render.js +5 -14
- package/lib/render/report.js +43 -0
- package/lib/render/tiles.js +260 -0
- package/lib/render/unit.js +15 -28
- package/lib/report-model.js +110 -33
- package/lib/report-parse.js +56 -38
- package/lib/report-render.js +102 -59
- package/lib/report-run.js +87 -78
- package/lib/report-test.js +256 -141
- package/lib/report-tools.js +96 -161
- package/lib/review-merge.js +114 -152
- package/lib/review.js +115 -189
- package/lib/runs.js +225 -0
- package/lib/select.js +89 -75
- package/lib/session/accessors.js +14 -21
- package/lib/session/actions.js +82 -63
- package/lib/session/branches.js +193 -247
- package/lib/session/change-actions.js +171 -214
- package/lib/session/commit.js +280 -342
- package/lib/session/compose.js +559 -674
- package/lib/session/dashboard.js +385 -0
- package/lib/session/dispatch.js +164 -157
- package/lib/session/edit-click.js +57 -0
- package/lib/session/files-pane.js +85 -53
- package/lib/session/items.js +73 -104
- package/lib/session/lifecycle.js +403 -541
- package/lib/session/load.js +48 -68
- package/lib/session/navigation.js +96 -87
- package/lib/session/npm.js +409 -345
- package/lib/session/ops.js +196 -63
- package/lib/session/pointer.js +23 -15
- package/lib/session/progress.js +33 -21
- package/lib/session/review.js +33 -54
- package/lib/session/tasks.js +333 -0
- package/lib/session/templates.js +51 -59
- package/lib/session/terminal.js +85 -136
- package/lib/session/unit.js +3 -4
- package/lib/session/update.js +76 -97
- package/lib/session/view.js +52 -83
- package/lib/session/watch.js +208 -204
- package/lib/session.js +112 -237
- package/lib/update.js +45 -116
- package/lib/utilities.js +67 -89
- package/lib/wrap.js +33 -44
- package/package.json +1 -1
- package/lib/session/todos.js +0 -293
package/lib/review-merge.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const files = require('./files.js');
|
|
4
|
-
const {
|
|
4
|
+
const { TASKS_FILE, taskKind } = files;
|
|
5
5
|
|
|
6
6
|
const flatText = (text) => `${text ?? ''}`.trim().replace(/\n/g, ' ');
|
|
7
7
|
|
|
@@ -9,28 +9,20 @@ const snapTodo = (todo) => ({
|
|
|
9
9
|
file: todo.file ?? '',
|
|
10
10
|
text: flatText(todo.text),
|
|
11
11
|
done: todo.done === true,
|
|
12
|
+
kind: taskKind(todo),
|
|
12
13
|
});
|
|
13
14
|
|
|
14
|
-
const snapList = (todos) =>
|
|
15
|
-
const list = [];
|
|
16
|
-
for (const todo of todos ?? []) {
|
|
17
|
-
const snap = snapTodo(todo);
|
|
18
|
-
if (!snap.text) continue;
|
|
19
|
-
list.push(snap);
|
|
20
|
-
}
|
|
21
|
-
return list;
|
|
22
|
-
};
|
|
15
|
+
const snapList = (todos) => todos.map(snapTodo).filter((snap) => snap.text);
|
|
23
16
|
|
|
24
17
|
const copyMap = (map) => {
|
|
25
18
|
const next = new Map();
|
|
26
|
-
if (!map) return next;
|
|
27
19
|
for (const [key, note] of map) next.set(key, { ...note });
|
|
28
20
|
return next;
|
|
29
21
|
};
|
|
30
22
|
|
|
31
23
|
const snapshotSide = (store) => ({
|
|
32
24
|
status: store.status,
|
|
33
|
-
|
|
25
|
+
tasks: snapList(store.tasks),
|
|
34
26
|
feedback: copyMap(store.feedback),
|
|
35
27
|
code: copyMap(store.code),
|
|
36
28
|
});
|
|
@@ -58,162 +50,137 @@ const pickDone = (baseDone, ourDone, theirDone) => {
|
|
|
58
50
|
|
|
59
51
|
const withDone = (todo, done) => {
|
|
60
52
|
if (todo.done === done) return todo;
|
|
61
|
-
return {
|
|
53
|
+
return { ...todo, done };
|
|
62
54
|
};
|
|
63
55
|
|
|
64
56
|
const liveText = (todo) => flatText(todo.text);
|
|
65
57
|
|
|
66
58
|
const snapText = (snap) => snap.text;
|
|
67
59
|
|
|
60
|
+
const liveKey = (todo) => `${taskKind(todo)}\0${liveText(todo)}`;
|
|
61
|
+
|
|
62
|
+
const snapKey = (snap) => `${taskKind(snap)}\0${snapText(snap)}`;
|
|
63
|
+
|
|
68
64
|
const flags = (n) => new Array(n).fill(false);
|
|
69
65
|
|
|
70
66
|
const adoptTodo = (store, snap) => {
|
|
71
|
-
const id = store.
|
|
72
|
-
store.
|
|
73
|
-
const file = snap.file ||
|
|
74
|
-
return { id, file, text: snap.text, done: snap.done };
|
|
67
|
+
const id = store.nextTaskId;
|
|
68
|
+
store.nextTaskId += 1;
|
|
69
|
+
const file = snap.file || TASKS_FILE;
|
|
70
|
+
return { id, file, text: snap.text, done: snap.done, kind: taskKind(snap) };
|
|
75
71
|
};
|
|
76
72
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
for (let i = 0; i < merged.length; i++) {
|
|
84
|
-
if (liveText(merged[i]) === text) return i;
|
|
85
|
-
}
|
|
86
|
-
return -1;
|
|
87
|
-
};
|
|
73
|
+
const replaceTodo = (todo, snap) => ({
|
|
74
|
+
...todo,
|
|
75
|
+
text: snap.text,
|
|
76
|
+
done: snap.done,
|
|
77
|
+
kind: taskKind(snap),
|
|
78
|
+
});
|
|
88
79
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
80
|
+
class TodoMerge {
|
|
81
|
+
constructor(store, theirs) {
|
|
82
|
+
this.store = store;
|
|
83
|
+
this.ours = store.tasks.filter((todo) => liveText(todo));
|
|
84
|
+
this.theirs = theirs;
|
|
85
|
+
this.usedOurs = flags(this.ours.length);
|
|
86
|
+
this.usedTheirs = flags(theirs.length);
|
|
87
|
+
this.kept = flags(this.ours.length);
|
|
88
|
+
this.dropped = flags(this.ours.length);
|
|
89
|
+
this.theirKeep = flags(theirs.length);
|
|
90
|
+
this.alias = new Map();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
keepOurs(index) {
|
|
94
|
+
this.kept[index] = true;
|
|
95
|
+
this.alias.set(liveKey(this.ours[index]), this.ours[index]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
mergeBase(base) {
|
|
99
|
+
const { ours, theirs } = this;
|
|
100
|
+
const key = snapKey(base);
|
|
101
|
+
const oi = claim(ours, this.usedOurs, key, liveKey);
|
|
102
|
+
const ti = claim(theirs, this.usedTheirs, key, snapKey);
|
|
103
|
+
if (oi >= 0 && ti >= 0) {
|
|
104
|
+
const done = pickDone(base.done, ours[oi].done === true, theirs[ti].done);
|
|
105
|
+
ours[oi] = withDone(ours[oi], done);
|
|
106
|
+
this.keepOurs(oi);
|
|
107
|
+
} else if (oi >= 0) {
|
|
108
|
+
if (ours[oi].done === base.done) this.dropped[oi] = true;
|
|
109
|
+
else this.keepOurs(oi);
|
|
110
|
+
} else if (ti >= 0 && theirs[ti].done !== base.done) {
|
|
111
|
+
this.theirKeep[ti] = true;
|
|
99
112
|
}
|
|
100
|
-
for (let j = i + 1; j < theirs.length && !placed; j++) {
|
|
101
|
-
const next = findMerged(merged, alias, theirs[j].text);
|
|
102
|
-
if (next < 0) continue;
|
|
103
|
-
at = next;
|
|
104
|
-
placed = true;
|
|
105
|
-
}
|
|
106
|
-
const item = adoptTodo(store, theirs[i]);
|
|
107
|
-
merged.splice(at, 0, item);
|
|
108
|
-
alias.set(theirs[i].text, item);
|
|
109
113
|
}
|
|
110
|
-
return merged;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const keepOurs = (ours, kept, alias, index, text) => {
|
|
114
|
-
kept[index] = true;
|
|
115
|
-
alias.set(text, ours[index]);
|
|
116
|
-
};
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
dropped,
|
|
125
|
-
theirKeep,
|
|
126
|
-
alias,
|
|
127
|
-
) => {
|
|
128
|
-
const text = base.text;
|
|
129
|
-
const oi = claim(ours, used.ours, text, liveText);
|
|
130
|
-
const ti = claim(theirs, used.theirs, text, snapText);
|
|
131
|
-
if (oi >= 0 && ti >= 0) {
|
|
132
|
-
const done = pickDone(base.done, ours[oi].done === true, theirs[ti].done);
|
|
133
|
-
ours[oi] = withDone(ours[oi], done);
|
|
134
|
-
keepOurs(ours, kept, alias, oi, text);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
if (oi >= 0) {
|
|
138
|
-
if (ours[oi].done === base.done) {
|
|
139
|
-
dropped[oi] = true;
|
|
115
|
+
mergeFresh(index) {
|
|
116
|
+
const { ours, theirs } = this;
|
|
117
|
+
const key = liveKey(ours[index]);
|
|
118
|
+
const ti = claim(theirs, this.usedTheirs, key, snapKey);
|
|
119
|
+
if (ti < 0) {
|
|
120
|
+
this.kept[index] = true;
|
|
140
121
|
return;
|
|
141
122
|
}
|
|
142
|
-
|
|
143
|
-
|
|
123
|
+
const done = ours[index].done === true || theirs[ti].done === true;
|
|
124
|
+
ours[index] = withDone(ours[index], done);
|
|
125
|
+
this.keepOurs(index);
|
|
144
126
|
}
|
|
145
|
-
if (ti >= 0 && theirs[ti].done !== base.done) theirKeep[ti] = true;
|
|
146
|
-
};
|
|
147
127
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const fillGaps = (merged, gaps, theirs, theirKeep, alias) => {
|
|
156
|
-
let filled = 0;
|
|
157
|
-
for (let i = 0; i < theirs.length && filled < gaps.length; i++) {
|
|
158
|
-
if (!theirKeep[i]) continue;
|
|
159
|
-
const gap = gaps[filled];
|
|
160
|
-
const item = replaceTodo(gap.todo, theirs[i]);
|
|
161
|
-
merged.splice(gap.at, 0, item);
|
|
162
|
-
alias.set(theirs[i].text, item);
|
|
163
|
-
theirKeep[i] = false;
|
|
164
|
-
filled += 1;
|
|
128
|
+
findMerged(merged, snap) {
|
|
129
|
+
const key = snapKey(snap);
|
|
130
|
+
const linked = this.alias.get(key);
|
|
131
|
+
const at = linked ? merged.indexOf(linked) : -1;
|
|
132
|
+
if (at >= 0) return at;
|
|
133
|
+
return merged.findIndex((todo) => liveKey(todo) === key);
|
|
165
134
|
}
|
|
166
|
-
};
|
|
167
135
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
136
|
+
theirPlace(merged, index) {
|
|
137
|
+
const { theirs } = this;
|
|
138
|
+
for (let j = index - 1; j >= 0; j--) {
|
|
139
|
+
const prev = this.findMerged(merged, theirs[j]);
|
|
140
|
+
if (prev >= 0) return prev + 1;
|
|
141
|
+
}
|
|
142
|
+
for (let j = index + 1; j < theirs.length; j++) {
|
|
143
|
+
const next = this.findMerged(merged, theirs[j]);
|
|
144
|
+
if (next >= 0) return next;
|
|
145
|
+
}
|
|
146
|
+
return merged.length;
|
|
174
147
|
}
|
|
175
|
-
const done = ours[index].done === true || theirs[ti].done === true;
|
|
176
|
-
ours[index] = withDone(ours[index], done);
|
|
177
|
-
keepOurs(ours, kept, alias, index, text);
|
|
178
|
-
};
|
|
179
148
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
ours.push(todo);
|
|
185
|
-
}
|
|
186
|
-
const used = { ours: flags(ours.length), theirs: flags(theirs.length) };
|
|
187
|
-
const kept = flags(ours.length);
|
|
188
|
-
const dropped = flags(ours.length);
|
|
189
|
-
const theirKeep = flags(theirs.length);
|
|
190
|
-
const alias = new Map();
|
|
191
|
-
for (const item of base) {
|
|
192
|
-
mergeBaseTodo(item, ours, theirs, used, kept, dropped, theirKeep, alias);
|
|
193
|
-
}
|
|
194
|
-
for (let i = 0; i < ours.length; i++) {
|
|
195
|
-
if (used.ours[i]) continue;
|
|
196
|
-
mergeFreshTodo(ours, theirs, used, kept, alias, i);
|
|
197
|
-
}
|
|
198
|
-
for (let i = 0; i < theirs.length; i++) {
|
|
199
|
-
if (!used.theirs[i]) theirKeep[i] = true;
|
|
149
|
+
place(merged, at, index, item) {
|
|
150
|
+
merged.splice(at, 0, item);
|
|
151
|
+
this.alias.set(snapKey(this.theirs[index]), item);
|
|
152
|
+
this.theirKeep[index] = false;
|
|
200
153
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
cursor += 1;
|
|
208
|
-
continue;
|
|
154
|
+
|
|
155
|
+
merge(base) {
|
|
156
|
+
const { ours, theirs } = this;
|
|
157
|
+
for (const item of base) this.mergeBase(item);
|
|
158
|
+
for (let i = 0; i < ours.length; i++) {
|
|
159
|
+
if (!this.usedOurs[i]) this.mergeFresh(i);
|
|
209
160
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
161
|
+
for (let i = 0; i < theirs.length; i++) {
|
|
162
|
+
if (!this.usedTheirs[i]) this.theirKeep[i] = true;
|
|
163
|
+
}
|
|
164
|
+
const merged = [];
|
|
165
|
+
const gaps = [];
|
|
166
|
+
for (let i = 0; i < ours.length; i++) {
|
|
167
|
+
const at = merged.length + gaps.length;
|
|
168
|
+
if (this.kept[i]) merged.push(ours[i]);
|
|
169
|
+
else if (this.dropped[i]) gaps.push({ at, task: ours[i] });
|
|
170
|
+
}
|
|
171
|
+
for (let i = 0; i < theirs.length && gaps.length; i++) {
|
|
172
|
+
if (!this.theirKeep[i]) continue;
|
|
173
|
+
const gap = gaps.shift();
|
|
174
|
+
this.place(merged, gap.at, i, replaceTodo(gap.task, theirs[i]));
|
|
175
|
+
}
|
|
176
|
+
for (let i = 0; i < theirs.length; i++) {
|
|
177
|
+
if (!this.theirKeep[i]) continue;
|
|
178
|
+
const at = this.theirPlace(merged, i);
|
|
179
|
+
this.place(merged, at, i, adoptTodo(this.store, theirs[i]));
|
|
180
|
+
}
|
|
181
|
+
return merged;
|
|
213
182
|
}
|
|
214
|
-
|
|
215
|
-
store.todos = insertTheir(store, merged, theirs, theirKeep, alias);
|
|
216
|
-
};
|
|
183
|
+
}
|
|
217
184
|
|
|
218
185
|
const sameNote = (left, right) =>
|
|
219
186
|
left.text === right.text && !!left.done === !!right.done;
|
|
@@ -244,10 +211,7 @@ const pickNote = (ours, base, theirs) => {
|
|
|
244
211
|
};
|
|
245
212
|
|
|
246
213
|
const mergeMap = (ours, base, theirs) => {
|
|
247
|
-
const keys = new Set();
|
|
248
|
-
for (const key of ours.keys()) keys.add(key);
|
|
249
|
-
for (const key of base.keys()) keys.add(key);
|
|
250
|
-
for (const key of theirs.keys()) keys.add(key);
|
|
214
|
+
const keys = new Set([...ours.keys(), ...base.keys(), ...theirs.keys()]);
|
|
251
215
|
for (const key of keys) {
|
|
252
216
|
const next = pickNote(ours.get(key), base.get(key), theirs.get(key));
|
|
253
217
|
if (!next) ours.delete(key);
|
|
@@ -257,13 +221,11 @@ const mergeMap = (ours, base, theirs) => {
|
|
|
257
221
|
|
|
258
222
|
const mergeReview = (store, disk) => {
|
|
259
223
|
const base = store.baseline;
|
|
260
|
-
const baseTodos = base ? base.todos : [];
|
|
261
224
|
const baseStatus = base ? base.status : store.status;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
mergeMap(store.
|
|
266
|
-
mergeMap(store.code, code, disk.code);
|
|
225
|
+
const theirs = snapList(disk.tasks);
|
|
226
|
+
store.tasks = new TodoMerge(store, theirs).merge(base?.tasks ?? []);
|
|
227
|
+
mergeMap(store.feedback, base?.feedback ?? new Map(), disk.feedback);
|
|
228
|
+
mergeMap(store.code, base?.code ?? new Map(), disk.code);
|
|
267
229
|
if (store.status === baseStatus && disk.status) store.status = disk.status;
|
|
268
230
|
store.baseline = snapshotSide(disk);
|
|
269
231
|
};
|