reslop 0.1.8 → 0.1.9
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 +14 -1
- package/README.md +26 -38
- package/lib/ansi.js +2 -0
- package/lib/capabilities.js +3 -0
- package/lib/deps/changes.js +92 -1
- package/lib/deps/items.js +5 -2
- package/lib/deps/manifest.js +7 -0
- package/lib/deps/rows.js +0 -1
- package/lib/deps.js +65 -10
- package/lib/files.js +30 -1
- package/lib/git/branches.js +97 -5
- package/lib/git.js +6 -0
- package/lib/keys.js +9 -2
- package/lib/render/branches.js +39 -17
- package/lib/render/chrome.js +35 -15
- package/lib/render/commits.js +138 -0
- package/lib/render/files.js +30 -10
- package/lib/render/frame.js +6 -1
- package/lib/render/primitives.js +1 -1
- package/lib/render.js +1 -2
- package/lib/session/actions.js +65 -24
- package/lib/session/branches.js +16 -18
- package/lib/session/change-actions.js +8 -5
- package/lib/session/commit.js +191 -29
- package/lib/session/dispatch.js +12 -2
- package/lib/session/files-pane.js +10 -1
- package/lib/session/items.js +112 -7
- package/lib/session/lifecycle.js +44 -4
- package/lib/session/navigation.js +3 -2
- package/lib/session/pointer.js +7 -0
- package/lib/session/view.js +4 -2
- package/lib/session.js +37 -9
- package/package.json +2 -2
package/lib/session/items.js
CHANGED
|
@@ -21,25 +21,127 @@ const npmBusyKind = (item) => {
|
|
|
21
21
|
return 'npm i';
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const blockKey = (item) => {
|
|
25
25
|
if (!item || !item.file) return '';
|
|
26
26
|
const rel = itemPath(item);
|
|
27
27
|
if (isTodoItem(item)) return `todo:${TODO_FILE}`;
|
|
28
|
-
const origin = item.origin ?? '';
|
|
29
28
|
const depId = depChangeKey(item);
|
|
30
|
-
if (depId) return `${
|
|
29
|
+
if (depId) return `${rel}:dep:${depId}`;
|
|
31
30
|
if (!item.hunk) {
|
|
32
31
|
const block = item.blockId ?? '-';
|
|
33
|
-
return `${
|
|
32
|
+
return `${rel}:file:${block}`;
|
|
34
33
|
}
|
|
35
34
|
const oldStart = item.hunk.oldStart;
|
|
36
35
|
const newStart = item.hunk.newStart;
|
|
37
36
|
const block = item.blockId ?? '-';
|
|
38
|
-
return `${
|
|
37
|
+
return `${rel}:${oldStart}:${newStart}:${block}`;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const itemKey = (item) => {
|
|
41
|
+
const key = blockKey(item);
|
|
42
|
+
if (!key || isTodoItem(item)) return key;
|
|
43
|
+
const origin = item.origin ?? '';
|
|
44
|
+
return `${origin}:${key}`;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const blockLinesKey = (item) => {
|
|
48
|
+
if (!item || !item.file || isTodoItem(item)) return '';
|
|
49
|
+
if (!item.hunk) return '';
|
|
50
|
+
const parts = [itemPath(item)];
|
|
51
|
+
for (const line of item.hunk.lines) {
|
|
52
|
+
if (line.blockId !== item.blockId) continue;
|
|
53
|
+
if (line.type === 'ctx') continue;
|
|
54
|
+
parts.push(`${line.type}:${line.text}`);
|
|
55
|
+
}
|
|
56
|
+
return parts.join('\0');
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const pushBucket = (map, key, item) => {
|
|
60
|
+
if (!key) return;
|
|
61
|
+
const list = map.get(key) ?? [];
|
|
62
|
+
list.push(item);
|
|
63
|
+
map.set(key, list);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const takeBucket = (map, key, used) => {
|
|
67
|
+
if (!key) return null;
|
|
68
|
+
const list = map.get(key);
|
|
69
|
+
if (!list || !list.length) return null;
|
|
70
|
+
while (list.length) {
|
|
71
|
+
const item = list.shift();
|
|
72
|
+
if (!used.has(item)) return item;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const pathOf = (item) => itemPath(item) || '';
|
|
78
|
+
|
|
79
|
+
const groupByPath = (items) => {
|
|
80
|
+
const groups = new Map();
|
|
81
|
+
for (const item of items) {
|
|
82
|
+
const rel = pathOf(item);
|
|
83
|
+
const list = groups.get(rel) ?? [];
|
|
84
|
+
list.push(item);
|
|
85
|
+
groups.set(rel, list);
|
|
86
|
+
}
|
|
87
|
+
return groups;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const alignGroup = (prev, next) => {
|
|
91
|
+
if (!prev.length) return next;
|
|
92
|
+
if (!next.length) return [];
|
|
93
|
+
const byBlock = new Map();
|
|
94
|
+
const byLines = new Map();
|
|
95
|
+
for (const item of next) {
|
|
96
|
+
pushBucket(byBlock, blockKey(item), item);
|
|
97
|
+
pushBucket(byLines, blockLinesKey(item), item);
|
|
98
|
+
}
|
|
99
|
+
const used = new Set();
|
|
100
|
+
const ordered = [];
|
|
101
|
+
for (const item of prev) {
|
|
102
|
+
const byText = takeBucket(byLines, blockLinesKey(item), used);
|
|
103
|
+
const taken = byText ?? takeBucket(byBlock, blockKey(item), used);
|
|
104
|
+
if (!taken) continue;
|
|
105
|
+
used.add(taken);
|
|
106
|
+
ordered.push(taken);
|
|
107
|
+
}
|
|
108
|
+
for (const item of next) {
|
|
109
|
+
if (used.has(item)) continue;
|
|
110
|
+
ordered.push(item);
|
|
111
|
+
}
|
|
112
|
+
return ordered;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const alignLoadedItems = (prev, next) => {
|
|
116
|
+
if (!prev.length || !next.length) return next;
|
|
117
|
+
const nextGroups = groupByPath(next);
|
|
118
|
+
const seen = new Set();
|
|
119
|
+
const ordered = [];
|
|
120
|
+
for (const [rel, list] of groupByPath(prev)) {
|
|
121
|
+
seen.add(rel);
|
|
122
|
+
const aligned = alignGroup(list, nextGroups.get(rel) ?? []);
|
|
123
|
+
for (const item of aligned) ordered.push(item);
|
|
124
|
+
}
|
|
125
|
+
for (const [rel, list] of nextGroups) {
|
|
126
|
+
if (seen.has(rel)) continue;
|
|
127
|
+
for (const item of list) ordered.push(item);
|
|
128
|
+
}
|
|
129
|
+
return ordered;
|
|
39
130
|
};
|
|
40
131
|
|
|
41
132
|
const restoredIndex = (items, item) => {
|
|
42
133
|
if (!item || !item.file) return -1;
|
|
134
|
+
const origin = item.origin ?? '';
|
|
135
|
+
const lines = blockLinesKey(item);
|
|
136
|
+
if (lines) {
|
|
137
|
+
let any = -1;
|
|
138
|
+
for (let i = 0; i < items.length; i++) {
|
|
139
|
+
if (blockLinesKey(items[i]) !== lines) continue;
|
|
140
|
+
if (any < 0) any = i;
|
|
141
|
+
if ((items[i].origin ?? '') === origin) return i;
|
|
142
|
+
}
|
|
143
|
+
if (any >= 0) return any;
|
|
144
|
+
}
|
|
43
145
|
const key = itemKey(item);
|
|
44
146
|
if (key) {
|
|
45
147
|
const exact = items.findIndex((entry) => itemKey(entry) === key);
|
|
@@ -47,7 +149,6 @@ const restoredIndex = (items, item) => {
|
|
|
47
149
|
}
|
|
48
150
|
const rel = itemPath(item);
|
|
49
151
|
if (!rel) return -1;
|
|
50
|
-
const origin = item.origin ?? '';
|
|
51
152
|
const start = item.hunk ? item.hunk.newStart : 0;
|
|
52
153
|
let fileMatch = -1;
|
|
53
154
|
let best = -1;
|
|
@@ -106,8 +207,9 @@ const createItemCollection = () => {
|
|
|
106
207
|
const isDismissed = (item) => state.dismissed.has(itemKey(item));
|
|
107
208
|
|
|
108
209
|
const replace = (items) => {
|
|
210
|
+
const aligned = alignLoadedItems(state.items, items);
|
|
109
211
|
const next = [];
|
|
110
|
-
for (const item of
|
|
212
|
+
for (const item of aligned) {
|
|
111
213
|
if (isDismissed(item)) continue;
|
|
112
214
|
next.push(item);
|
|
113
215
|
}
|
|
@@ -168,8 +270,11 @@ module.exports = {
|
|
|
168
270
|
depChangeKey,
|
|
169
271
|
needsReload,
|
|
170
272
|
npmBusyKind,
|
|
273
|
+
blockKey,
|
|
171
274
|
itemKey,
|
|
172
275
|
itemFeedKey,
|
|
276
|
+
blockLinesKey,
|
|
277
|
+
alignLoadedItems,
|
|
173
278
|
restoredIndex,
|
|
174
279
|
sameBlock,
|
|
175
280
|
canEditCode,
|
package/lib/session/lifecycle.js
CHANGED
|
@@ -6,7 +6,7 @@ const path = require('node:path');
|
|
|
6
6
|
const { isAbortError } = require('./load.js');
|
|
7
7
|
const { createDiskWatcher, POLL_MS } = require('./watch.js');
|
|
8
8
|
const files = require('../files.js');
|
|
9
|
-
const { itemPath } = files;
|
|
9
|
+
const { itemPath, relativeAge } = files;
|
|
10
10
|
const { MANIFEST, LOCKFILE } = require('../deps/manifest.js');
|
|
11
11
|
const review = require('../review.js');
|
|
12
12
|
const { hasNotes } = review;
|
|
@@ -103,6 +103,28 @@ const itemRels = (collection) => {
|
|
|
103
103
|
return rels;
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
+
const fileDatesFromDisk = (top, rels) => {
|
|
107
|
+
const dates = new Map();
|
|
108
|
+
if (!top) return dates;
|
|
109
|
+
const now = Date.now();
|
|
110
|
+
for (const rel of rels) {
|
|
111
|
+
try {
|
|
112
|
+
const st = fs.statSync(path.join(top, rel));
|
|
113
|
+
dates.set(rel, relativeAge(st.mtimeMs, now));
|
|
114
|
+
} catch {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return dates;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const stampItemDates = (items, dates) => {
|
|
122
|
+
for (const item of items) {
|
|
123
|
+
const date = dates.get(itemPath(item));
|
|
124
|
+
if (date) item.date = date;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
106
128
|
const syncItemWatches = (api) => {
|
|
107
129
|
if (!api.diskWatcher) return;
|
|
108
130
|
api.diskWatcher.watchFiles(itemRels(api.collection));
|
|
@@ -117,6 +139,10 @@ const applyLoaded = (api, loaded) => {
|
|
|
117
139
|
const here = ui.current();
|
|
118
140
|
ui.top = loaded.top ?? api.loadConfig.cwd;
|
|
119
141
|
collection.replace(loaded.items);
|
|
142
|
+
stampItemDates(
|
|
143
|
+
collection.items,
|
|
144
|
+
fileDatesFromDisk(ui.top, itemRels(collection)),
|
|
145
|
+
);
|
|
120
146
|
if (loaded.rev) ui.rev = loaded.rev;
|
|
121
147
|
if (loaded.revShort) {
|
|
122
148
|
ui.revShort = loaded.revShort;
|
|
@@ -340,9 +366,11 @@ const refreshFromRepo = (api, extra = {}) => {
|
|
|
340
366
|
};
|
|
341
367
|
|
|
342
368
|
const reloadAfterChange = (api, afterLoad) => {
|
|
343
|
-
const
|
|
369
|
+
const hereItem = api.ui.current();
|
|
370
|
+
const hereIndex = api.nav.index;
|
|
344
371
|
const restore = () => {
|
|
345
|
-
api.
|
|
372
|
+
const idx = api.collection.findRestoredIndex(hereItem);
|
|
373
|
+
api.nav.index = idx >= 0 ? idx : hereIndex;
|
|
346
374
|
api.ui.clampIndex();
|
|
347
375
|
api.ui.syncReviewPath();
|
|
348
376
|
api.ui.syncFileCursor();
|
|
@@ -380,10 +408,20 @@ const shouldDeferWatch = (api) => {
|
|
|
380
408
|
return false;
|
|
381
409
|
};
|
|
382
410
|
|
|
411
|
+
const WATCH_IGNORE_MS = 500;
|
|
412
|
+
|
|
413
|
+
const ignoreWatch = (api, ms = WATCH_IGNORE_MS) => {
|
|
414
|
+
const extra = watchOpts(api);
|
|
415
|
+
const now = extra.now ?? Date.now;
|
|
416
|
+
api.ignoreWatchUntil = now() + ms;
|
|
417
|
+
};
|
|
418
|
+
|
|
383
419
|
const onDiskChange = (api) => {
|
|
420
|
+
const extra = watchOpts(api);
|
|
421
|
+
const now = extra.now ?? Date.now;
|
|
422
|
+
if (now() < (api.ignoreWatchUntil ?? 0)) return;
|
|
384
423
|
if (shouldDeferWatch(api)) {
|
|
385
424
|
if (api.watchRetry !== null) return;
|
|
386
|
-
const extra = watchOpts(api);
|
|
387
425
|
const setTimeoutFn = extra.setTimeout ?? setTimeout;
|
|
388
426
|
const delay = extra.debounceMs ?? 200;
|
|
389
427
|
api.watchRetry = setTimeoutFn(() => {
|
|
@@ -456,6 +494,7 @@ const createLifecycle = (api) => {
|
|
|
456
494
|
api.diskWatcher = null;
|
|
457
495
|
api.watchRetry = null;
|
|
458
496
|
api.watchStamp = '';
|
|
497
|
+
api.ignoreWatchUntil = 0;
|
|
459
498
|
api.npmExtras = null;
|
|
460
499
|
return {
|
|
461
500
|
applyLoaded: (loaded) => applyLoaded(api, loaded),
|
|
@@ -469,6 +508,7 @@ const createLifecycle = (api) => {
|
|
|
469
508
|
pollCurrentFile: () => pollCurrentFile(api),
|
|
470
509
|
startWatch: () => startWatch(api),
|
|
471
510
|
stopWatch: () => stopWatch(api),
|
|
511
|
+
ignoreWatch: (ms) => ignoreWatch(api, ms),
|
|
472
512
|
clearNpmExtras: () => clearNpmExtras(api),
|
|
473
513
|
};
|
|
474
514
|
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const files = require('../files.js');
|
|
4
|
-
const {
|
|
4
|
+
const { listPath, isTodoItem, isTodosEntry, TODO_FILE } = files;
|
|
5
5
|
|
|
6
6
|
const initialState = (options = {}) => ({
|
|
7
7
|
pane: options.startPane ?? 'files',
|
|
8
8
|
index: 0,
|
|
9
9
|
fileCursor: 0,
|
|
10
10
|
branchCursor: 0,
|
|
11
|
+
commitCursor: 0,
|
|
11
12
|
scroll: 0,
|
|
12
13
|
listScroll: 0,
|
|
13
14
|
reviewPath: null,
|
|
@@ -34,7 +35,7 @@ const current = (nav, items, todoItem) => {
|
|
|
34
35
|
|
|
35
36
|
const syncReviewPath = (nav, item) => {
|
|
36
37
|
if (nav.pane !== 'diff') return;
|
|
37
|
-
nav.reviewPath = item ?
|
|
38
|
+
nav.reviewPath = item ? listPath(item) : null;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
const clampFileCursor = (nav, length) => {
|
package/lib/session/pointer.js
CHANGED
|
@@ -97,6 +97,13 @@ const RELEASE_TARGETS = [
|
|
|
97
97
|
options.onCheckoutBranch();
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
|
+
{
|
|
101
|
+
match: (options) => options.getPane() === 'commits',
|
|
102
|
+
hits: 'fileHits',
|
|
103
|
+
onHit: (options, hit) => {
|
|
104
|
+
options.nav.commitCursor = hit.cursor;
|
|
105
|
+
},
|
|
106
|
+
},
|
|
100
107
|
{
|
|
101
108
|
match: (options) => options.getPane() === 'diff',
|
|
102
109
|
hits: 'todoHits',
|
package/lib/session/view.js
CHANGED
|
@@ -77,7 +77,7 @@ const counts = (api, notes = noteCounts(api.review.store)) => {
|
|
|
77
77
|
const viewStatus = (api) => api.ui.status || api.ui.busy;
|
|
78
78
|
|
|
79
79
|
const view = (api) => {
|
|
80
|
-
const { composer, nav, ui, gitBranches, updater } = api;
|
|
80
|
+
const { composer, nav, ui, gitBranches, commits, updater } = api;
|
|
81
81
|
const templates = composer.shownTemplates();
|
|
82
82
|
const change = ui.change;
|
|
83
83
|
const sourceKind = (change && SOURCE_KIND[change.source]) || '';
|
|
@@ -100,6 +100,8 @@ const view = (api) => {
|
|
|
100
100
|
branch: ui.branch,
|
|
101
101
|
branches: gitBranches.branches,
|
|
102
102
|
branchCursor: nav.branchCursor,
|
|
103
|
+
commits: commits.commits,
|
|
104
|
+
commitCursor: nav.commitCursor,
|
|
103
105
|
repoName: repoNameOf(api),
|
|
104
106
|
revShort: ui.revShort || '',
|
|
105
107
|
sourceLabel: ui.sourceLabel || '',
|
|
@@ -115,7 +117,7 @@ const view = (api) => {
|
|
|
115
117
|
templateIndex: composer.clampedTemplateIndex(templates),
|
|
116
118
|
updateFrom: updater.from,
|
|
117
119
|
updateTo: updater.to,
|
|
118
|
-
dropName: gitBranches.dropName,
|
|
120
|
+
dropName: gitBranches.dropName || commits.dropName,
|
|
119
121
|
};
|
|
120
122
|
};
|
|
121
123
|
|
package/lib/session.js
CHANGED
|
@@ -37,11 +37,17 @@ const PROGRESS_MS = 80;
|
|
|
37
37
|
|
|
38
38
|
const systemNow = () => new Date();
|
|
39
39
|
|
|
40
|
+
const targetHasStaged = (session) => {
|
|
41
|
+
if (session.repo.hasStaged) return session.repo.hasStaged(session.top);
|
|
42
|
+
return session.items.some((item) => item.origin === 'staged');
|
|
43
|
+
};
|
|
44
|
+
|
|
40
45
|
const NAV_FIELDS = [
|
|
41
46
|
'pane',
|
|
42
47
|
'index',
|
|
43
48
|
'fileCursor',
|
|
44
49
|
'branchCursor',
|
|
50
|
+
'commitCursor',
|
|
45
51
|
'scroll',
|
|
46
52
|
'listScroll',
|
|
47
53
|
'reviewPath',
|
|
@@ -197,6 +203,7 @@ const assignControllers = (session) => {
|
|
|
197
203
|
setStatus,
|
|
198
204
|
syncReviewPath: () => session.syncReviewPath(),
|
|
199
205
|
syncFileCursor: () => session.syncFileCursor(),
|
|
206
|
+
ignoreWatch: () => session.lifecycle.ignoreWatch(),
|
|
200
207
|
});
|
|
201
208
|
session.commits = createCommitController({
|
|
202
209
|
repo: () => session.repo,
|
|
@@ -212,6 +219,9 @@ const assignControllers = (session) => {
|
|
|
212
219
|
setStatus,
|
|
213
220
|
isDone: () => session.done,
|
|
214
221
|
pendingExtras: () => session.pendingExtras,
|
|
222
|
+
getMode: () => session.mode,
|
|
223
|
+
getStatus: () => session.status,
|
|
224
|
+
nav: session.nav,
|
|
215
225
|
});
|
|
216
226
|
session.gitBranches = createBranchController({
|
|
217
227
|
repo: () => session.repo,
|
|
@@ -286,6 +296,7 @@ const bindViewer = (session) => {
|
|
|
286
296
|
collection: session.collection,
|
|
287
297
|
review: session.review,
|
|
288
298
|
gitBranches: session.gitBranches,
|
|
299
|
+
commits: session.commits,
|
|
289
300
|
updater: session.updater,
|
|
290
301
|
ui: session,
|
|
291
302
|
});
|
|
@@ -304,6 +315,7 @@ const bindFilesPane = (session) => {
|
|
|
304
315
|
onQuit: () => session.onQuit(),
|
|
305
316
|
onCheckoutBranch: session.gitBranches.onCheckoutBranch,
|
|
306
317
|
onBranchMove: session.gitBranches.onBranchMove,
|
|
318
|
+
onCommitMove: session.commits.onCommitMove,
|
|
307
319
|
layout: () => session.layout,
|
|
308
320
|
setLayout: (value) => {
|
|
309
321
|
session.layout = value;
|
|
@@ -344,6 +356,12 @@ const bindDispatch = (session) => {
|
|
|
344
356
|
if (session.pane === 'branches') {
|
|
345
357
|
return session.branches[session.branchCursor];
|
|
346
358
|
}
|
|
359
|
+
if (session.pane === 'commits') {
|
|
360
|
+
const entry = session.commits.commits[session.commitCursor];
|
|
361
|
+
const staged = targetHasStaged(session);
|
|
362
|
+
if (!entry) return { canCommit: staged };
|
|
363
|
+
return { ...entry, canCommit: staged };
|
|
364
|
+
}
|
|
347
365
|
return session.current();
|
|
348
366
|
},
|
|
349
367
|
composer: session.composer,
|
|
@@ -352,6 +370,7 @@ const bindDispatch = (session) => {
|
|
|
352
370
|
gitBranches: session.gitBranches,
|
|
353
371
|
onFileMove: filesPane.onFileMove,
|
|
354
372
|
onBranchMove: session.gitBranches.onBranchMove,
|
|
373
|
+
onCommitMove: session.commits.onCommitMove,
|
|
355
374
|
onNext: filesPane.onNext,
|
|
356
375
|
onPrev: filesPane.onPrev,
|
|
357
376
|
onOpenFile: filesPane.onOpenFile,
|
|
@@ -398,19 +417,23 @@ const bindDispatch = (session) => {
|
|
|
398
417
|
editing: () => session.finishQuit('editing'),
|
|
399
418
|
cancel: () => session.cancelQuit(),
|
|
400
419
|
},
|
|
401
|
-
commit: {
|
|
402
|
-
commit: () => session.commits.startGitCommit('commit'),
|
|
403
|
-
amend: () => session.commits.startGitCommit('amend'),
|
|
404
|
-
fixup: () => session.commits.startGitCommit('fixup'),
|
|
405
|
-
cancel: session.commits.cancelCommit,
|
|
406
|
-
},
|
|
407
420
|
update: {
|
|
408
421
|
accept: session.updater.accept,
|
|
409
422
|
decline: session.updater.decline,
|
|
410
423
|
},
|
|
411
424
|
drop: {
|
|
412
|
-
confirm:
|
|
413
|
-
|
|
425
|
+
confirm: () => {
|
|
426
|
+
if (session.commits.dropName) {
|
|
427
|
+
return void session.commits.confirmDropCommit();
|
|
428
|
+
}
|
|
429
|
+
session.gitBranches.confirmDropBranch();
|
|
430
|
+
},
|
|
431
|
+
cancel: () => {
|
|
432
|
+
if (session.commits.dropName) {
|
|
433
|
+
return void session.commits.cancelDropCommit();
|
|
434
|
+
}
|
|
435
|
+
session.gitBranches.cancelDropBranch();
|
|
436
|
+
},
|
|
414
437
|
},
|
|
415
438
|
push: {
|
|
416
439
|
force: session.gitBranches.onForcePush,
|
|
@@ -444,6 +467,7 @@ class Session {
|
|
|
444
467
|
if (this.composer) this.composer.reset();
|
|
445
468
|
if (this.ops) this.ops.reset();
|
|
446
469
|
if (this.gitBranches) this.gitBranches.reset();
|
|
470
|
+
if (this.commits) this.commits.reset();
|
|
447
471
|
this.top = this.cwd;
|
|
448
472
|
this.branch = '';
|
|
449
473
|
this.status = '';
|
|
@@ -507,7 +531,11 @@ class Session {
|
|
|
507
531
|
height: size.height,
|
|
508
532
|
color: this.color,
|
|
509
533
|
});
|
|
510
|
-
if (
|
|
534
|
+
if (
|
|
535
|
+
this.pane === 'files' ||
|
|
536
|
+
this.pane === 'branches' ||
|
|
537
|
+
this.pane === 'commits'
|
|
538
|
+
) {
|
|
511
539
|
this.nav.listScroll = frame.listScroll;
|
|
512
540
|
}
|
|
513
541
|
const composing = this.mode === 'compose';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reslop",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Interactive code review and repair planning for AI-assisted changes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"code-review",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"eslint": "^9.39.4",
|
|
60
60
|
"eslint-config-metarhia": "^9.1.9",
|
|
61
61
|
"metaskills": "^1.0.5",
|
|
62
|
-
"prettier": "^3.9.
|
|
62
|
+
"prettier": "^3.9.8"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"metautil": "^5.5.2"
|