reslop 0.2.5 → 0.2.7
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 +22 -1
- package/LICENSE +1 -1
- package/README.md +11 -11
- package/bin/reslop.js +3 -8
- package/lib/ansi.js +72 -19
- package/lib/api.js +1 -1
- package/lib/capabilities.js +8 -8
- package/lib/cli.js +61 -75
- package/lib/clipboard.js +39 -47
- package/lib/dashboard/git.js +128 -0
- package/lib/dashboard/model.js +357 -0
- package/lib/dashboard/npm.js +290 -0
- package/lib/dashboard/tree.js +278 -0
- package/lib/deps-diff.js +197 -402
- package/lib/deps.js +113 -240
- 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 +76 -144
- 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 +79 -178
- package/lib/editor.js +52 -69
- package/lib/files.js +79 -91
- package/lib/find.js +61 -0
- package/lib/git-branches.js +254 -416
- package/lib/git-deps.js +148 -272
- package/lib/git-reword-todo.js +5 -13
- package/lib/git-worktree.js +161 -214
- 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 +155 -141
- 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 +14 -14
- 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 +19 -25
- package/lib/highlight/txt.js +7 -10
- package/lib/highlight.js +17 -46
- package/lib/keys.js +75 -83
- package/lib/manifest.js +67 -126
- package/lib/npm-commands.js +120 -169
- package/lib/remote.js +140 -190
- package/lib/render/branches.js +63 -61
- package/lib/render/chrome.js +412 -347
- package/lib/render/commits.js +160 -361
- package/lib/render/dash-activity.js +212 -0
- package/lib/render/dash-blocks.js +496 -0
- package/lib/render/dash-table.js +295 -0
- package/lib/render/dashboard.js +62 -0
- package/lib/render/diff.js +123 -258
- package/lib/render/files.js +60 -86
- package/lib/render/frame.js +82 -117
- package/lib/render/notes.js +150 -210
- package/lib/render/npm.js +213 -177
- package/lib/render/packages.js +93 -0
- package/lib/render/present.js +4 -11
- package/lib/render/primitives.js +77 -172
- package/lib/render/render.js +5 -14
- package/lib/render/report.js +43 -0
- package/lib/render/repos.js +226 -0
- package/lib/render/search.js +25 -0
- package/lib/render/tiles.js +355 -0
- package/lib/render/unit.js +15 -31
- package/lib/report-model.js +110 -33
- package/lib/report-parse.js +56 -37
- package/lib/report-render.js +102 -59
- package/lib/report-run.js +87 -77
- package/lib/report-test.js +221 -99
- package/lib/report-tools.js +96 -154
- package/lib/review-merge.js +33 -41
- package/lib/review.js +69 -129
- package/lib/runs.js +225 -0
- package/lib/select.js +53 -91
- package/lib/session/accessors.js +14 -21
- package/lib/session/actions.js +189 -65
- package/lib/session/branches.js +164 -222
- package/lib/session/change-actions.js +49 -119
- package/lib/session/commit.js +298 -352
- package/lib/session/compose.js +572 -715
- package/lib/session/dashboard.js +530 -0
- package/lib/session/dispatch.js +197 -171
- package/lib/session/files-pane.js +92 -45
- package/lib/session/find.js +94 -0
- package/lib/session/items.js +6 -17
- package/lib/session/lifecycle.js +420 -466
- package/lib/session/load.js +1 -14
- package/lib/session/navigation.js +4 -2
- package/lib/session/npm.js +403 -420
- package/lib/session/ops.js +5 -13
- package/lib/session/packages.js +143 -0
- package/lib/session/pointer.js +30 -14
- package/lib/session/progress.js +39 -30
- package/lib/session/review.js +1 -3
- package/lib/session/tasks.js +277 -236
- package/lib/session/templates.js +51 -59
- package/lib/session/terminal.js +85 -132
- package/lib/session/view.js +59 -80
- package/lib/session/watch.js +201 -212
- package/lib/session/workspace.js +455 -0
- package/lib/session.js +95 -161
- package/lib/update.js +44 -111
- package/lib/utilities.js +46 -88
- package/lib/workspace.js +166 -0
- package/lib/wrap.js +29 -55
- package/package.json +1 -1
package/lib/session/ops.js
CHANGED
|
@@ -6,17 +6,8 @@ const QUIET_KIND = new Set(['staged', 'unstaged']);
|
|
|
6
6
|
const pickRepoWrite = (repo, name, uiOpen) => {
|
|
7
7
|
const asyncFn = repo[`${name}Async`];
|
|
8
8
|
const allowAsync = uiOpen === true || ASYNC_WITHOUT_UI.includes(name);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
async: true,
|
|
12
|
-
write: (top, ...args) => asyncFn(top, ...args),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
const syncFn = repo[name];
|
|
16
|
-
return {
|
|
17
|
-
async: false,
|
|
18
|
-
write: (top, ...args) => syncFn(top, ...args),
|
|
19
|
-
};
|
|
9
|
+
const isAsync = allowAsync && typeof asyncFn === 'function';
|
|
10
|
+
return { async: isAsync, write: isAsync ? asyncFn : repo[name] };
|
|
20
11
|
};
|
|
21
12
|
|
|
22
13
|
const showsBusy = (kind) => Boolean(kind) && !QUIET_KIND.has(kind);
|
|
@@ -86,7 +77,6 @@ class ChangeQueue {
|
|
|
86
77
|
|
|
87
78
|
startReload() {
|
|
88
79
|
const { ui } = this;
|
|
89
|
-
if (typeof ui.reloadAfterChange !== 'function') return void ui.paint();
|
|
90
80
|
this.reloading = true;
|
|
91
81
|
ui.reloadAfterChange(() => {
|
|
92
82
|
this.reloading = false;
|
|
@@ -231,15 +221,17 @@ class OpsRunner {
|
|
|
231
221
|
this.finishBusy(done, after);
|
|
232
222
|
}
|
|
233
223
|
|
|
234
|
-
runWrite(name, args, kind, done, after) {
|
|
224
|
+
runWrite(name, args, kind, done, after, leave = null) {
|
|
235
225
|
const { ui } = this;
|
|
236
226
|
const picked = pickRepoWrite(ui.repo, name, ui.uiOpen);
|
|
237
227
|
const write = (top) => picked.write(top, ...args);
|
|
238
228
|
if (picked.async) {
|
|
229
|
+
if (leave) leave();
|
|
239
230
|
const refresh = () => after({ doneStatus: done });
|
|
240
231
|
return void this.runBusy(kind, done, write, refresh);
|
|
241
232
|
}
|
|
242
233
|
if (!this.runRepo(done, write)) return;
|
|
234
|
+
if (leave) leave();
|
|
243
235
|
after({});
|
|
244
236
|
if (!ui.status) ui.status = done;
|
|
245
237
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utilities = require('../utilities.js');
|
|
4
|
+
const { IS_WIN, npmBin, oneLine, runProc } = utilities;
|
|
5
|
+
|
|
6
|
+
const INSTALL_MS = 120000;
|
|
7
|
+
|
|
8
|
+
class PackageController {
|
|
9
|
+
constructor(ui) {
|
|
10
|
+
this.ui = ui;
|
|
11
|
+
this.dropName = '';
|
|
12
|
+
this.addDev = false;
|
|
13
|
+
this.running = false;
|
|
14
|
+
this.job = null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
rows() {
|
|
18
|
+
const data = this.ui.dashboard.packagesView();
|
|
19
|
+
const modules = data.modules;
|
|
20
|
+
return modules && modules.packages ? modules.packages : [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
selected() {
|
|
24
|
+
return this.rows()[this.ui.nav.packagesCursor] ?? null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
canWrite() {
|
|
28
|
+
if (this.running) return false;
|
|
29
|
+
const ui = this.ui;
|
|
30
|
+
const caps = ui.capabilities;
|
|
31
|
+
if (!ui.readOnly && (!caps || caps.changes !== false)) return true;
|
|
32
|
+
ui.status = 'read only';
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
need() {
|
|
37
|
+
if (!this.canWrite()) return null;
|
|
38
|
+
const pkg = this.selected();
|
|
39
|
+
if (pkg) return pkg;
|
|
40
|
+
this.ui.status = 'not a package';
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
create() {
|
|
45
|
+
if (!this.canWrite()) return;
|
|
46
|
+
const pkg = this.selected();
|
|
47
|
+
if (pkg && pkg.transitive) {
|
|
48
|
+
this.ui.status = 'transitive';
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.addDev = Boolean(pkg && pkg.dev);
|
|
52
|
+
this.ui.composer.openCompose('package', '');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
finishAdd() {
|
|
56
|
+
const editor = this.ui.composer.editor;
|
|
57
|
+
if (!editor) return;
|
|
58
|
+
const name = editor.text.trim();
|
|
59
|
+
if (!name || /\s/.test(name) || name.startsWith('-')) {
|
|
60
|
+
this.ui.status = 'name';
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const args = ['install', name];
|
|
64
|
+
if (this.addDev) args.push('--save-dev');
|
|
65
|
+
this.ui.composer.closeCompose();
|
|
66
|
+
this.job = this.exec(args, 'npm i', `installed ${name}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
askDrop() {
|
|
70
|
+
const pkg = this.need();
|
|
71
|
+
if (!pkg) return;
|
|
72
|
+
if (pkg.transitive) {
|
|
73
|
+
this.ui.status = 'transitive';
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.dropName = pkg.name;
|
|
77
|
+
this.ui.mode = 'confirmDrop';
|
|
78
|
+
this.ui.status = '';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
cancelDrop() {
|
|
82
|
+
this.dropName = '';
|
|
83
|
+
this.ui.mode = 'review';
|
|
84
|
+
this.ui.status = '';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
confirmDrop() {
|
|
88
|
+
const name = this.dropName;
|
|
89
|
+
this.dropName = '';
|
|
90
|
+
this.ui.mode = 'review';
|
|
91
|
+
if (!name) return;
|
|
92
|
+
const done = `dropped ${name}`;
|
|
93
|
+
this.job = this.exec(['uninstall', name], 'npm uninstall', done);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
updateWanted() {
|
|
97
|
+
const pkg = this.need();
|
|
98
|
+
if (!pkg) return;
|
|
99
|
+
const done = `updated ${pkg.name}`;
|
|
100
|
+
this.job = this.exec(['update', pkg.name], 'npm i', done);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
updateLatest() {
|
|
104
|
+
const pkg = this.need();
|
|
105
|
+
if (!pkg) return;
|
|
106
|
+
const args = ['install', `${pkg.name}@latest`];
|
|
107
|
+
if (pkg.dev) args.push('--save-dev');
|
|
108
|
+
this.job = this.exec(args, 'npm i', `updated ${pkg.name}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async exec(args, busy, done) {
|
|
112
|
+
const ui = this.ui;
|
|
113
|
+
this.running = true;
|
|
114
|
+
ui.status = '';
|
|
115
|
+
ui.ops.setBusy(busy);
|
|
116
|
+
ui.ignoreWatch(INSTALL_MS);
|
|
117
|
+
ui.paint();
|
|
118
|
+
let result;
|
|
119
|
+
try {
|
|
120
|
+
const hook = ui.repo && ui.repo.runPackage;
|
|
121
|
+
const options = { cwd: ui.top, shell: IS_WIN };
|
|
122
|
+
result = hook
|
|
123
|
+
? await hook(ui.top, args)
|
|
124
|
+
: await runProc(npmBin(), args, options);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
result = { error, status: 1, stderr: '' };
|
|
127
|
+
}
|
|
128
|
+
this.running = false;
|
|
129
|
+
ui.ops.clearBusy();
|
|
130
|
+
const failed = !result || result.error || result.status;
|
|
131
|
+
if (failed) {
|
|
132
|
+
const message = result && result.error ? result.error.message : '';
|
|
133
|
+
const stderr = result ? result.stderr : '';
|
|
134
|
+
ui.status = oneLine(stderr, message || 'npm failed');
|
|
135
|
+
} else {
|
|
136
|
+
ui.status = done;
|
|
137
|
+
ui.dashboard.tasks.npm.request();
|
|
138
|
+
}
|
|
139
|
+
ui.paint();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = { PackageController };
|
package/lib/session/pointer.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const select = require('../select.js');
|
|
4
4
|
const editClick = require('./edit-click.js');
|
|
5
|
+
const filesPane = require('./files-pane.js');
|
|
5
6
|
const { extractText, isRange } = select;
|
|
6
7
|
const keys = require('../keys.js');
|
|
7
8
|
const { hitAction } = keys;
|
|
@@ -94,7 +95,19 @@ const RELEASE_TARGETS = [
|
|
|
94
95
|
hits: 'statusHits',
|
|
95
96
|
onHit: (ui, hit) => {
|
|
96
97
|
if (hit.id === 'branch') return void ui.gitBranches.onBranch();
|
|
97
|
-
ui.
|
|
98
|
+
ui.confirmChoice(hit.id);
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
match: (ui) => ui.pane === 'dashboard',
|
|
103
|
+
hits: 'fileHits',
|
|
104
|
+
onHit: (ui, hit) => ui.dashboard.open(hit.cursor),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
match: (ui) => ui.pane === 'repos',
|
|
108
|
+
hits: 'fileHits',
|
|
109
|
+
onHit: (ui, hit) => {
|
|
110
|
+
void ui.workspace.openAt(hit.cursor);
|
|
98
111
|
},
|
|
99
112
|
},
|
|
100
113
|
{
|
|
@@ -103,7 +116,7 @@ const RELEASE_TARGETS = [
|
|
|
103
116
|
onHit: (ui, hit) => {
|
|
104
117
|
const again = armDoubleClick(ui.nav, 'files', hit.cursor);
|
|
105
118
|
ui.nav.fileCursor = hit.cursor;
|
|
106
|
-
if (again)
|
|
119
|
+
if (again) filesPane.onOpenFile(ui);
|
|
107
120
|
},
|
|
108
121
|
},
|
|
109
122
|
{
|
|
@@ -122,7 +135,14 @@ const RELEASE_TARGETS = [
|
|
|
122
135
|
if (ui.mode === 'compose') return;
|
|
123
136
|
const again = armDoubleClick(ui.nav, 'commits', hit.cursor);
|
|
124
137
|
ui.nav.commitCursor = hit.cursor;
|
|
125
|
-
if (again)
|
|
138
|
+
if (again) filesPane.onOpenFile(ui);
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
match: (ui) => ui.pane === 'packages',
|
|
143
|
+
hits: 'fileHits',
|
|
144
|
+
onHit: (ui, hit) => {
|
|
145
|
+
ui.nav.packagesCursor = hit.cursor;
|
|
126
146
|
},
|
|
127
147
|
},
|
|
128
148
|
{
|
|
@@ -135,11 +155,11 @@ const RELEASE_TARGETS = [
|
|
|
135
155
|
},
|
|
136
156
|
},
|
|
137
157
|
{
|
|
138
|
-
match: (ui) => ui.pane === '
|
|
158
|
+
match: (ui) => ui.pane === 'tasks',
|
|
139
159
|
hits: 'taskHits',
|
|
140
160
|
onHit: (ui, hit) => {
|
|
141
|
-
if (hit.check) return void ui.composer.onTaskCheck(hit.cursor);
|
|
142
|
-
ui.composer.onTaskHit(hit.cursor);
|
|
161
|
+
if (hit.check) return void ui.composer.tasks.onTaskCheck(hit.cursor);
|
|
162
|
+
ui.composer.tasks.onTaskHit(hit.cursor);
|
|
143
163
|
},
|
|
144
164
|
},
|
|
145
165
|
{
|
|
@@ -171,14 +191,14 @@ const onRelease = (ui, event) => {
|
|
|
171
191
|
};
|
|
172
192
|
|
|
173
193
|
const POINTER_HANDLERS = {
|
|
174
|
-
wheelUp: (ui) =>
|
|
175
|
-
wheelDown: (ui) =>
|
|
194
|
+
wheelUp: (ui) => filesPane.onScroll(ui, -1),
|
|
195
|
+
wheelDown: (ui) => filesPane.onScroll(ui, 1),
|
|
176
196
|
press: onPress,
|
|
177
197
|
drag: onDrag,
|
|
178
198
|
release: onRelease,
|
|
179
199
|
};
|
|
180
200
|
|
|
181
|
-
const
|
|
201
|
+
const handlePointer = (ui, event) => {
|
|
182
202
|
const kind = event.kind;
|
|
183
203
|
const handler = POINTER_HANDLERS[kind];
|
|
184
204
|
if (!handler) return;
|
|
@@ -187,8 +207,4 @@ const handle = (ui, event) => {
|
|
|
187
207
|
handler(ui, event);
|
|
188
208
|
};
|
|
189
209
|
|
|
190
|
-
|
|
191
|
-
handle: (event) => handle(ui, event),
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
module.exports = { createPointer };
|
|
210
|
+
module.exports = { handlePointer };
|
package/lib/session/progress.js
CHANGED
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
3
|
+
class Progress {
|
|
4
|
+
constructor(term, onTick, intervalMs) {
|
|
5
|
+
this.term = term;
|
|
6
|
+
this.onTick = onTick;
|
|
7
|
+
this.intervalMs = intervalMs;
|
|
8
|
+
this.active = new Set();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
tick() {
|
|
12
|
+
if (!this.active.size) return;
|
|
13
|
+
this.onTick();
|
|
14
|
+
this.schedule();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
schedule() {
|
|
18
|
+
this.term.later('progress', () => this.tick(), this.intervalMs);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
start(id) {
|
|
22
|
+
this.active.add(id);
|
|
23
|
+
this.schedule();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
stop(id) {
|
|
27
|
+
this.active.delete(id);
|
|
28
|
+
if (!this.active.size) this.term.cancel('progress');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
clear() {
|
|
32
|
+
this.active.clear();
|
|
33
|
+
this.term.cancel('progress');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
size() {
|
|
37
|
+
return this.active.size;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = { Progress };
|