reslop 0.2.5 → 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 +12 -1
- package/LICENSE +1 -1
- package/README.md +11 -11
- package/bin/reslop.js +3 -8
- package/lib/ansi.js +32 -19
- package/lib/capabilities.js +8 -8
- package/lib/cli.js +40 -74
- package/lib/clipboard.js +39 -47
- 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 +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 +71 -89
- package/lib/git-branches.js +254 -416
- package/lib/git-deps.js +147 -272
- 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 +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 +49 -82
- 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 +220 -333
- package/lib/render/commits.js +160 -361
- 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 -258
- package/lib/render/files.js +40 -85
- package/lib/render/frame.js +78 -117
- package/lib/render/notes.js +139 -210
- package/lib/render/npm.js +213 -177
- package/lib/render/present.js +4 -11
- package/lib/render/primitives.js +72 -174
- 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 -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 +68 -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 +61 -43
- package/lib/session/branches.js +166 -222
- package/lib/session/change-actions.js +49 -119
- package/lib/session/commit.js +274 -355
- package/lib/session/compose.js +556 -714
- package/lib/session/dashboard.js +385 -0
- package/lib/session/dispatch.js +162 -170
- package/lib/session/files-pane.js +76 -44
- package/lib/session/items.js +6 -17
- package/lib/session/lifecycle.js +393 -466
- package/lib/session/load.js +1 -14
- package/lib/session/navigation.js +2 -2
- package/lib/session/npm.js +403 -420
- package/lib/session/ops.js +5 -13
- package/lib/session/pointer.js +16 -14
- package/lib/session/progress.js +39 -30
- package/lib/session/review.js +1 -3
- package/lib/session/tasks.js +276 -235
- package/lib/session/templates.js +51 -59
- package/lib/session/terminal.js +85 -132
- package/lib/session/view.js +47 -81
- package/lib/session/watch.js +196 -212
- package/lib/session.js +81 -161
- package/lib/update.js +44 -111
- package/lib/utilities.js +46 -88
- package/lib/wrap.js +29 -55
- package/package.json +1 -1
package/lib/utilities.js
CHANGED
|
@@ -9,16 +9,12 @@ const IS_WIN = process.platform === 'win32';
|
|
|
9
9
|
const DEFAULT_ENCODING = 'utf8';
|
|
10
10
|
const DEFAULT_MAX_BUFFER = 32 * 1024 * 1024;
|
|
11
11
|
|
|
12
|
-
const UNIX_CLIP = [
|
|
13
|
-
{ cmd: 'wl-copy', args: [] },
|
|
14
|
-
{ cmd: 'xclip', args: ['-selection', 'clipboard'] },
|
|
15
|
-
{ cmd: 'xsel', args: ['--clipboard', '--input'] },
|
|
16
|
-
];
|
|
17
|
-
|
|
18
12
|
const parseVersion = (text) => {
|
|
19
13
|
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(`${text ?? ''}`);
|
|
20
14
|
if (!match) return null;
|
|
21
|
-
const
|
|
15
|
+
const major = Number(match[1]);
|
|
16
|
+
const minor = Number(match[2]);
|
|
17
|
+
const patch = Number(match[3]);
|
|
22
18
|
return { major, minor, patch };
|
|
23
19
|
};
|
|
24
20
|
|
|
@@ -47,20 +43,13 @@ const dateStamp = (date) => {
|
|
|
47
43
|
return `${date.getFullYear()}-${month}-${pad2(date.getDate())}`;
|
|
48
44
|
};
|
|
49
45
|
|
|
50
|
-
const npmBin = (
|
|
51
|
-
platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
46
|
+
const npmBin = () => (IS_WIN ? 'npm.cmd' : 'npm');
|
|
52
47
|
|
|
53
48
|
const spawnBase = (extra = {}) => ({ windowsHide: true, ...extra });
|
|
54
49
|
|
|
55
50
|
const npmOpts = (extra = {}, platform = process.platform) =>
|
|
56
51
|
spawnBase({ shell: platform === 'win32', ...extra });
|
|
57
52
|
|
|
58
|
-
const clipTools = (platform = process.platform) => {
|
|
59
|
-
if (platform === 'win32') return [{ cmd: 'clip', args: [] }];
|
|
60
|
-
if (platform === 'darwin') return [{ cmd: 'pbcopy', args: [] }];
|
|
61
|
-
return UNIX_CLIP;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
53
|
const listen = (emitter, event, handler) => {
|
|
65
54
|
if (!emitter || typeof emitter.on !== 'function') return () => {};
|
|
66
55
|
emitter.on(event, handler);
|
|
@@ -91,69 +80,36 @@ const watchResize = (stdout, proc, onResize, signal) => {
|
|
|
91
80
|
return stop;
|
|
92
81
|
};
|
|
93
82
|
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
error.code = 'ABORT';
|
|
97
|
-
return error;
|
|
98
|
-
};
|
|
83
|
+
const codeError = (message, code) =>
|
|
84
|
+
Object.assign(new Error(message), { code });
|
|
99
85
|
|
|
100
|
-
const
|
|
86
|
+
const abortError = () => codeError('aborted', 'ABORT');
|
|
101
87
|
|
|
102
|
-
const
|
|
103
|
-
if (value === undefined || value === null) return '';
|
|
104
|
-
if (typeof value === 'string') return value;
|
|
105
|
-
return `${value}`;
|
|
106
|
-
};
|
|
88
|
+
const isAbort = (error) => !!(error && error.code === 'ABORT');
|
|
107
89
|
|
|
108
|
-
const procResult = (values = {}) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
};
|
|
90
|
+
const procResult = (values = {}) => ({
|
|
91
|
+
status: values.status ?? null,
|
|
92
|
+
stdout: `${values.stdout ?? ''}`,
|
|
93
|
+
stderr: `${values.stderr ?? ''}`,
|
|
94
|
+
error: values.error ?? null,
|
|
95
|
+
});
|
|
115
96
|
|
|
116
|
-
const
|
|
117
|
-
const encoding = options.encoding ?? DEFAULT_ENCODING;
|
|
118
|
-
const maxBuffer = options.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
97
|
+
const runProcSync = (cmd, args, options = {}) => {
|
|
119
98
|
const opts = spawnBase({
|
|
120
99
|
cwd: options.cwd,
|
|
121
100
|
env: options.env,
|
|
122
|
-
encoding,
|
|
101
|
+
encoding: options.encoding ?? DEFAULT_ENCODING,
|
|
123
102
|
input: options.input,
|
|
124
|
-
maxBuffer,
|
|
103
|
+
maxBuffer: options.maxBuffer ?? DEFAULT_MAX_BUFFER,
|
|
125
104
|
timeout: options.timeout,
|
|
126
105
|
});
|
|
127
106
|
if (options.shell) opts.shell = true;
|
|
128
|
-
return opts;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const runProcSync = (cmd, args, options = {}) => {
|
|
132
|
-
const result = spawnSync(cmd, args, spawnOptions(options));
|
|
133
|
-
return procResult(result);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const attachOutput = (stream, encoding, onChunk) => {
|
|
137
|
-
if (!stream) return;
|
|
138
|
-
stream.setEncoding(encoding);
|
|
139
|
-
stream.on('data', onChunk);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const writeInput = (child, input) => {
|
|
143
|
-
if (!child.stdin) return;
|
|
144
|
-
try {
|
|
145
|
-
if (input) child.stdin.end(input);
|
|
146
|
-
else child.stdin.end();
|
|
147
|
-
} catch {
|
|
148
|
-
// closed
|
|
149
|
-
}
|
|
107
|
+
return procResult(spawnSync(cmd, args, opts));
|
|
150
108
|
};
|
|
151
109
|
|
|
152
110
|
const listenChild = (child, options, resolve) => {
|
|
153
111
|
const encoding = options.encoding ?? DEFAULT_ENCODING;
|
|
154
112
|
const maxBuffer = options.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
155
|
-
const timeout = options.timeout;
|
|
156
|
-
const input = options.input;
|
|
157
113
|
const signal = options.signal;
|
|
158
114
|
let stdout = '';
|
|
159
115
|
let stderr = '';
|
|
@@ -163,46 +119,49 @@ const listenChild = (child, options, resolve) => {
|
|
|
163
119
|
const finish = (result) => {
|
|
164
120
|
if (settled) return;
|
|
165
121
|
settled = true;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (signal && onAbort) {
|
|
169
|
-
signal.removeEventListener('abort', onAbort);
|
|
170
|
-
}
|
|
171
|
-
onAbort = null;
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
if (signal) signal.removeEventListener('abort', onAbort);
|
|
172
124
|
resolve(result);
|
|
173
125
|
};
|
|
174
|
-
|
|
126
|
+
const fail = (error) => {
|
|
175
127
|
child.kill();
|
|
176
|
-
finish(procResult({ stdout, stderr, error
|
|
128
|
+
finish(procResult({ stdout, stderr, error }));
|
|
177
129
|
};
|
|
178
|
-
|
|
179
|
-
|
|
130
|
+
onAbort = () => fail(abortError());
|
|
131
|
+
const append = (chunk, isOut) => {
|
|
132
|
+
if (isOut) stdout += chunk;
|
|
180
133
|
else stderr += chunk;
|
|
181
|
-
if (stdout.length + stderr.length
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
error.code = 'ENOBUFS';
|
|
185
|
-
finish(procResult({ stdout, stderr, error }));
|
|
134
|
+
if (stdout.length + stderr.length > maxBuffer) {
|
|
135
|
+
fail(codeError('maxBuffer exceeded', 'ENOBUFS'));
|
|
136
|
+
}
|
|
186
137
|
};
|
|
187
138
|
if (signal) signal.addEventListener('abort', onAbort);
|
|
188
|
-
if (timeout) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const error = new Error('timed out');
|
|
192
|
-
error.code = 'ETIMEDOUT';
|
|
193
|
-
finish(procResult({ stdout, stderr, error }));
|
|
194
|
-
}, timeout);
|
|
139
|
+
if (options.timeout) {
|
|
140
|
+
const onTimeout = () => fail(codeError('timed out', 'ETIMEDOUT'));
|
|
141
|
+
timer = setTimeout(onTimeout, options.timeout);
|
|
195
142
|
}
|
|
196
143
|
if (signal && signal.aborted) onAbort();
|
|
197
|
-
|
|
198
|
-
|
|
144
|
+
if (child.stdout) {
|
|
145
|
+
child.stdout.setEncoding(encoding);
|
|
146
|
+
child.stdout.on('data', (chunk) => append(chunk, true));
|
|
147
|
+
}
|
|
148
|
+
if (child.stderr) {
|
|
149
|
+
child.stderr.setEncoding(encoding);
|
|
150
|
+
child.stderr.on('data', (chunk) => append(chunk, false));
|
|
151
|
+
}
|
|
199
152
|
child.on('error', (error) => {
|
|
200
153
|
finish(procResult({ stdout, stderr, error }));
|
|
201
154
|
});
|
|
202
155
|
child.on('close', (status) => {
|
|
203
156
|
finish(procResult({ status, stdout, stderr }));
|
|
204
157
|
});
|
|
205
|
-
|
|
158
|
+
if (!child.stdin) return;
|
|
159
|
+
try {
|
|
160
|
+
if (options.input) child.stdin.end(options.input);
|
|
161
|
+
else child.stdin.end();
|
|
162
|
+
} catch {
|
|
163
|
+
// closed
|
|
164
|
+
}
|
|
206
165
|
};
|
|
207
166
|
|
|
208
167
|
const runProc = (cmd, args, options = {}) =>
|
|
@@ -238,7 +197,6 @@ module.exports = {
|
|
|
238
197
|
npmBin,
|
|
239
198
|
spawnBase,
|
|
240
199
|
npmOpts,
|
|
241
|
-
clipTools,
|
|
242
200
|
listen,
|
|
243
201
|
watchResize,
|
|
244
202
|
abortError,
|
package/lib/wrap.js
CHANGED
|
@@ -12,53 +12,37 @@ const wrapPlain = (text, width) => {
|
|
|
12
12
|
let col = 0;
|
|
13
13
|
let lastBreak = -1;
|
|
14
14
|
let i = 0;
|
|
15
|
-
const slice = (from, to) => {
|
|
16
|
-
let out = '';
|
|
17
|
-
for (let k = from; k < to; k++) out += parts[k];
|
|
18
|
-
return out;
|
|
19
|
-
};
|
|
20
|
-
const flush = (end) => {
|
|
21
|
-
rows.push(slice(start, end));
|
|
22
|
-
start = end;
|
|
23
|
-
col = 0;
|
|
24
|
-
lastBreak = -1;
|
|
25
|
-
};
|
|
26
15
|
while (i < parts.length) {
|
|
27
16
|
const ch = parts[i];
|
|
28
17
|
const w = graphemeWidth(ch, col);
|
|
29
18
|
if (col + w > width && col > 0) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
const end = lastBreak >= start ? lastBreak + 1 : i;
|
|
20
|
+
rows.push(parts.slice(start, end).join(''));
|
|
21
|
+
start = end;
|
|
22
|
+
i = end;
|
|
23
|
+
col = 0;
|
|
24
|
+
lastBreak = -1;
|
|
36
25
|
continue;
|
|
37
26
|
}
|
|
38
27
|
col += w;
|
|
39
28
|
if (ch === ' ' || ch === '\t') lastBreak = i;
|
|
40
29
|
i += 1;
|
|
41
30
|
}
|
|
42
|
-
rows.push(slice(start
|
|
31
|
+
rows.push(parts.slice(start).join(''));
|
|
43
32
|
return rows;
|
|
44
33
|
};
|
|
45
34
|
|
|
46
35
|
const wrapDoc = (text, width) => {
|
|
47
36
|
const rows = [];
|
|
48
|
-
const parts = text.split('\n');
|
|
49
37
|
let offset = 0;
|
|
50
|
-
for (
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
rows.push({ start: offset + used, text: row });
|
|
56
|
-
used += row.length;
|
|
38
|
+
for (const part of text.split('\n')) {
|
|
39
|
+
let start = offset;
|
|
40
|
+
for (const row of wrapPlain(part, width)) {
|
|
41
|
+
rows.push({ start, text: row });
|
|
42
|
+
start += row.length;
|
|
57
43
|
}
|
|
58
|
-
offset += part.length;
|
|
59
|
-
if (p < parts.length - 1) offset += 1;
|
|
44
|
+
offset += part.length + 1;
|
|
60
45
|
}
|
|
61
|
-
if (!rows.length) rows.push({ start: 0, text: '' });
|
|
62
46
|
return rows;
|
|
63
47
|
};
|
|
64
48
|
|
|
@@ -69,9 +53,8 @@ const cursorInWrap = (text, cursor, width) => {
|
|
|
69
53
|
const rows = wrapDoc(text, width);
|
|
70
54
|
const clamped = Math.max(0, Math.min(cursor, text.length));
|
|
71
55
|
let row = rows.length - 1;
|
|
72
|
-
for (let i = 0; i < rows.length; i++) {
|
|
73
|
-
|
|
74
|
-
if (clamped < next) {
|
|
56
|
+
for (let i = 0; i < rows.length - 1; i++) {
|
|
57
|
+
if (clamped < rows[i + 1].start) {
|
|
75
58
|
row = i;
|
|
76
59
|
break;
|
|
77
60
|
}
|
|
@@ -81,30 +64,25 @@ const cursorInWrap = (text, cursor, width) => {
|
|
|
81
64
|
return { row, col: visibleWidth(line.text.slice(0, take)) };
|
|
82
65
|
};
|
|
83
66
|
|
|
84
|
-
const
|
|
85
|
-
const raw = `${text ?? ''}`;
|
|
86
|
-
if (col <= 0) return start;
|
|
67
|
+
const colIndex = (text, col) => {
|
|
87
68
|
let used = 0;
|
|
88
|
-
let
|
|
89
|
-
for (const ch of graphemes(
|
|
69
|
+
let index = 0;
|
|
70
|
+
for (const ch of graphemes(text)) {
|
|
90
71
|
const w = graphemeWidth(ch, used);
|
|
91
72
|
if (used + w > col) break;
|
|
92
73
|
used += w;
|
|
93
|
-
|
|
74
|
+
index += ch.length;
|
|
94
75
|
}
|
|
95
|
-
return
|
|
76
|
+
return index;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const indexAtRow = (start, text, col) => {
|
|
80
|
+
if (col <= 0) return start;
|
|
81
|
+
return start + colIndex(`${text ?? ''}`, col);
|
|
96
82
|
};
|
|
97
83
|
|
|
98
84
|
const indexAtWrapCol = (row, col, limit) => {
|
|
99
|
-
|
|
100
|
-
let idx = 0;
|
|
101
|
-
for (const ch of graphemes(row.text)) {
|
|
102
|
-
const w = graphemeWidth(ch, used);
|
|
103
|
-
if (used + w > col) break;
|
|
104
|
-
used += w;
|
|
105
|
-
idx += ch.length;
|
|
106
|
-
}
|
|
107
|
-
const pos = row.start + idx;
|
|
85
|
+
const pos = row.start + colIndex(row.text, col);
|
|
108
86
|
if (pos < limit) return pos;
|
|
109
87
|
if (pos <= row.start) return row.start;
|
|
110
88
|
const parts = graphemes(row.text);
|
|
@@ -114,15 +92,11 @@ const indexAtWrapCol = (row, col, limit) => {
|
|
|
114
92
|
const wrapMove = (text, cursor, width, delta, wantCol) => {
|
|
115
93
|
const rows = wrapDoc(text, width);
|
|
116
94
|
const pos = cursorInWrap(text, cursor, width);
|
|
117
|
-
|
|
118
|
-
if (next < 0) next = 0;
|
|
119
|
-
if (next >= rows.length) next = rows.length - 1;
|
|
95
|
+
const next = Math.min(Math.max(pos.row + delta, 0), rows.length - 1);
|
|
120
96
|
const col = wantCol ?? pos.col;
|
|
121
97
|
if (next === pos.row) return { cursor, col };
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
if (next + 1 < rows.length) limit = rows[next + 1].start;
|
|
125
|
-
return { cursor: indexAtWrapCol(row, col, limit), col };
|
|
98
|
+
const limit = next + 1 < rows.length ? rows[next + 1].start : text.length + 1;
|
|
99
|
+
return { cursor: indexAtWrapCol(rows[next], col, limit), col };
|
|
126
100
|
};
|
|
127
101
|
|
|
128
102
|
module.exports = {
|