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/select.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const ansi = require('./ansi.js');
|
|
4
|
-
|
|
5
|
-
const {
|
|
4
|
+
const { ESC, RESET, THEME, seq, fg, bg, stripAnsi, visibleWidth } = ansi;
|
|
5
|
+
const { graphemes, graphemeWidth, firstGrapheme } = ansi;
|
|
6
6
|
|
|
7
7
|
const CSI_FINAL = /[@-~]/;
|
|
8
|
+
const TRUECOLOR = 2;
|
|
8
9
|
|
|
9
10
|
const isRange = (sel) => {
|
|
10
11
|
if (!sel || !sel.start || !sel.end) return false;
|
|
@@ -12,21 +13,16 @@ const isRange = (sel) => {
|
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
const ordered = (sel) => {
|
|
15
|
-
const start = sel
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
if (start.y > end.y) return { first: end, last: start };
|
|
19
|
-
if (start.x <= end.x) return { first: start, last: end };
|
|
20
|
-
return { first: end, last: start };
|
|
16
|
+
const { start, end } = sel;
|
|
17
|
+
const forward = start.y < end.y || (start.y === end.y && start.x <= end.x);
|
|
18
|
+
return forward ? { first: start, last: end } : { first: end, last: start };
|
|
21
19
|
};
|
|
22
20
|
|
|
23
21
|
const slicePlain = (plain, fromCol, toCol) => {
|
|
24
|
-
const parts = graphemes(plain);
|
|
25
22
|
let col = 0;
|
|
26
23
|
let out = '';
|
|
27
|
-
for (const ch of
|
|
28
|
-
const
|
|
29
|
-
const next = col + w;
|
|
24
|
+
for (const ch of graphemes(plain)) {
|
|
25
|
+
const next = col + graphemeWidth(ch, col);
|
|
30
26
|
if (next > fromCol && col < toCol) out += ch;
|
|
31
27
|
col = next;
|
|
32
28
|
if (col >= toCol) break;
|
|
@@ -38,10 +34,8 @@ const lineRange = (rowIndex, sel) => {
|
|
|
38
34
|
const { first, last } = ordered(sel);
|
|
39
35
|
const y = rowIndex + 1;
|
|
40
36
|
if (y < first.y || y > last.y) return null;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (y === first.y) from = first.x - 1;
|
|
44
|
-
if (y === last.y) to = last.x;
|
|
37
|
+
const from = y === first.y ? first.x - 1 : 0;
|
|
38
|
+
const to = y === last.y ? last.x : Infinity;
|
|
45
39
|
if (to <= from) return null;
|
|
46
40
|
return { from, to };
|
|
47
41
|
};
|
|
@@ -60,11 +54,10 @@ const extractText = (rows, sel) => {
|
|
|
60
54
|
return lines.join('\n');
|
|
61
55
|
};
|
|
62
56
|
|
|
63
|
-
const
|
|
57
|
+
const csiEnd = (line, i) => {
|
|
64
58
|
let j = i + 2;
|
|
65
59
|
while (j < line.length && !CSI_FINAL.test(line[j])) j += 1;
|
|
66
|
-
|
|
67
|
-
return j;
|
|
60
|
+
return j < line.length ? j + 1 : j;
|
|
68
61
|
};
|
|
69
62
|
|
|
70
63
|
const parseParams = (body) => {
|
|
@@ -73,45 +66,30 @@ const parseParams = (body) => {
|
|
|
73
66
|
};
|
|
74
67
|
|
|
75
68
|
const applyRgb = (state, field, params, i) => {
|
|
76
|
-
const TRUECOLOR = 2;
|
|
77
69
|
const isTruecolor = params[i + 1] === TRUECOLOR;
|
|
78
|
-
|
|
79
|
-
if (!hasRgb) return 1;
|
|
70
|
+
if (!isTruecolor || i + 4 >= params.length) return 1;
|
|
80
71
|
state[field] = [params[i + 2], params[i + 3], params[i + 4]];
|
|
81
72
|
return 5;
|
|
82
73
|
};
|
|
83
74
|
|
|
84
|
-
const SGR = {
|
|
85
|
-
0: (state) => {
|
|
86
|
-
state.fg = null;
|
|
87
|
-
state.bg = null;
|
|
88
|
-
return 1;
|
|
89
|
-
},
|
|
90
|
-
38: (state, params, i) => applyRgb(state, 'fg', params, i),
|
|
91
|
-
48: (state, params, i) => applyRgb(state, 'bg', params, i),
|
|
92
|
-
39: (state) => {
|
|
93
|
-
state.fg = null;
|
|
94
|
-
return 1;
|
|
95
|
-
},
|
|
96
|
-
49: (state) => {
|
|
97
|
-
state.bg = null;
|
|
98
|
-
return 1;
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
|
|
102
75
|
const applySgr = (params, state) => {
|
|
103
76
|
let i = 0;
|
|
104
77
|
while (i < params.length) {
|
|
105
|
-
const
|
|
106
|
-
|
|
78
|
+
const code = params[i];
|
|
79
|
+
if (code === 38) {
|
|
80
|
+
i += applyRgb(state, 'fg', params, i);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (code === 48) {
|
|
84
|
+
i += applyRgb(state, 'bg', params, i);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (code === 0 || code === 39) state.fg = null;
|
|
88
|
+
if (code === 0 || code === 49) state.bg = null;
|
|
89
|
+
i += 1;
|
|
107
90
|
}
|
|
108
91
|
};
|
|
109
92
|
|
|
110
|
-
const nextGrapheme = (line, index) => {
|
|
111
|
-
const parts = graphemes(line.slice(index));
|
|
112
|
-
return parts[0] ?? '';
|
|
113
|
-
};
|
|
114
|
-
|
|
115
93
|
const parseCells = (line) => {
|
|
116
94
|
const cells = [];
|
|
117
95
|
const state = { fg: null, bg: null };
|
|
@@ -119,24 +97,21 @@ const parseCells = (line) => {
|
|
|
119
97
|
let i = 0;
|
|
120
98
|
while (i < line.length) {
|
|
121
99
|
if (line[i] === ESC && line[i + 1] === '[') {
|
|
122
|
-
const
|
|
123
|
-
if (line[
|
|
124
|
-
|
|
125
|
-
applySgr(parseParams(body), state);
|
|
100
|
+
const end = csiEnd(line, i);
|
|
101
|
+
if (line[end - 1] === 'm') {
|
|
102
|
+
applySgr(parseParams(line.slice(i + 2, end - 1)), state);
|
|
126
103
|
}
|
|
127
|
-
i =
|
|
104
|
+
i = end;
|
|
128
105
|
continue;
|
|
129
106
|
}
|
|
130
107
|
if (line[i] === ESC) {
|
|
131
108
|
i += 1;
|
|
132
109
|
continue;
|
|
133
110
|
}
|
|
134
|
-
const ch =
|
|
111
|
+
const ch = firstGrapheme(line.slice(i));
|
|
135
112
|
if (!ch) break;
|
|
136
113
|
const width = graphemeWidth(ch, col);
|
|
137
|
-
|
|
138
|
-
const bg = state.bg;
|
|
139
|
-
cells.push({ ch, fg, bg, col, width });
|
|
114
|
+
cells.push({ ch, fg: state.fg, bg: state.bg, col, width });
|
|
140
115
|
col += width;
|
|
141
116
|
i += ch.length;
|
|
142
117
|
}
|
|
@@ -145,10 +120,10 @@ const parseCells = (line) => {
|
|
|
145
120
|
|
|
146
121
|
const rgbKey = (rgb) => (rgb ? `${rgb[0]},${rgb[1]},${rgb[2]}` : '');
|
|
147
122
|
|
|
148
|
-
const styleSeq = (
|
|
149
|
-
if (
|
|
150
|
-
if (
|
|
151
|
-
if (
|
|
123
|
+
const styleSeq = (fgRgb, bgRgb) => {
|
|
124
|
+
if (fgRgb && bgRgb) return RESET + seq(fgRgb, bgRgb);
|
|
125
|
+
if (fgRgb) return RESET + fg(fgRgb);
|
|
126
|
+
if (bgRgb) return RESET + bg(bgRgb);
|
|
152
127
|
return RESET;
|
|
153
128
|
};
|
|
154
129
|
|
|
@@ -159,17 +134,15 @@ const overlayRange = (line, fromCol, toCol) => {
|
|
|
159
134
|
let out = '';
|
|
160
135
|
let last = null;
|
|
161
136
|
for (const cell of cells) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
fg = cell.bg ?? THEME.ctxBg;
|
|
168
|
-
bg = cell.fg ?? THEME.ctxFg;
|
|
137
|
+
let cellFg = cell.fg;
|
|
138
|
+
let cellBg = cell.bg;
|
|
139
|
+
if (cell.col + cell.width > fromCol && cell.col < toCol) {
|
|
140
|
+
cellFg = cell.bg ?? THEME.ctxBg;
|
|
141
|
+
cellBg = cell.fg ?? THEME.ctxFg;
|
|
169
142
|
}
|
|
170
|
-
const key = `${rgbKey(
|
|
143
|
+
const key = `${rgbKey(cellFg)}|${rgbKey(cellBg)}`;
|
|
171
144
|
if (key !== last) {
|
|
172
|
-
out += styleSeq(
|
|
145
|
+
out += styleSeq(cellFg, cellBg);
|
|
173
146
|
last = key;
|
|
174
147
|
}
|
|
175
148
|
out += cell.ch;
|
|
@@ -177,15 +150,55 @@ const overlayRange = (line, fromCol, toCol) => {
|
|
|
177
150
|
return out;
|
|
178
151
|
};
|
|
179
152
|
|
|
153
|
+
const editorSelection = (view) => {
|
|
154
|
+
const source = view?.compose || view?.codeOverlay;
|
|
155
|
+
if (!source || typeof source.anchor !== 'number') return null;
|
|
156
|
+
const cursor = source.cursor ?? 0;
|
|
157
|
+
if (source.anchor === cursor) return null;
|
|
158
|
+
return { anchor: source.anchor, cursor };
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const spanCols = (hit, lo, hi) => {
|
|
162
|
+
const start = hit.start ?? 0;
|
|
163
|
+
const from = Math.max(lo, start);
|
|
164
|
+
const to = Math.min(hi, hit.limit ?? start);
|
|
165
|
+
if (to <= from) return null;
|
|
166
|
+
const text = hit.text ?? '';
|
|
167
|
+
const c0 = visibleWidth(text.slice(0, Math.max(0, from - start)));
|
|
168
|
+
const c1 = visibleWidth(text.slice(0, Math.max(0, to - start)));
|
|
169
|
+
const scroll = hit.scroll ?? 0;
|
|
170
|
+
const textX = hit.textX ?? 1;
|
|
171
|
+
const room = Math.max(0, (hit.x1 ?? textX) - textX);
|
|
172
|
+
const vis0 = Math.max(c0, scroll);
|
|
173
|
+
const vis1 = Math.min(c1, scroll + room);
|
|
174
|
+
if (vis1 <= vis0) return null;
|
|
175
|
+
const origin = textX - 1;
|
|
176
|
+
return { from: origin + vis0 - scroll, to: origin + vis1 - scroll };
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const markEditorSelection = (rows, view, hits, color) => {
|
|
180
|
+
if (!color || !hits) return rows;
|
|
181
|
+
const sel = editorSelection(view);
|
|
182
|
+
if (!sel) return rows;
|
|
183
|
+
const lo = Math.min(sel.anchor, sel.cursor);
|
|
184
|
+
const hi = Math.max(sel.anchor, sel.cursor);
|
|
185
|
+
const next = rows.slice();
|
|
186
|
+
for (const hit of hits) {
|
|
187
|
+
if (!hit.live || !hit.y) continue;
|
|
188
|
+
const range = spanCols(hit, lo, hi);
|
|
189
|
+
const i = hit.y - 1;
|
|
190
|
+
if (!range || i < 0 || i >= next.length) continue;
|
|
191
|
+
next[i] = overlayRange(next[i], range.from, range.to);
|
|
192
|
+
}
|
|
193
|
+
return next;
|
|
194
|
+
};
|
|
195
|
+
|
|
180
196
|
const overlayRows = (rows, sel) => {
|
|
181
197
|
if (!isRange(sel)) return rows;
|
|
182
|
-
|
|
183
|
-
const next = new Array(length);
|
|
184
|
-
for (let i = 0; i < length; i++) {
|
|
198
|
+
return rows.map((row, i) => {
|
|
185
199
|
const range = lineRange(i, sel);
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
return next;
|
|
200
|
+
return range ? overlayRange(row, range.from, range.to) : row;
|
|
201
|
+
});
|
|
189
202
|
};
|
|
190
203
|
|
|
191
204
|
module.exports = {
|
|
@@ -193,4 +206,5 @@ module.exports = {
|
|
|
193
206
|
extractText,
|
|
194
207
|
overlayRange,
|
|
195
208
|
overlayRows,
|
|
209
|
+
markEditorSelection,
|
|
196
210
|
};
|
package/lib/session/accessors.js
CHANGED
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const bindAlias = (target, name, get, set) => {
|
|
4
|
-
const desc = { configurable: true, enumerable: true, get };
|
|
5
|
-
if (set) desc.set = set;
|
|
6
|
-
Object.defineProperty(target, name, desc);
|
|
7
|
-
};
|
|
8
|
-
|
|
9
3
|
const bindAccessors = (target, owner, names) => {
|
|
10
4
|
for (const name of names) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
Object.defineProperty(target, name, {
|
|
6
|
+
configurable: true,
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: () => owner[name],
|
|
9
|
+
set: (value) => {
|
|
10
|
+
owner[name] = value;
|
|
11
|
+
},
|
|
12
|
+
});
|
|
16
13
|
}
|
|
17
14
|
};
|
|
18
15
|
|
|
19
16
|
const bindGetters = (target, owner, names) => {
|
|
20
17
|
for (const name of names) {
|
|
21
|
-
|
|
18
|
+
Object.defineProperty(target, name, {
|
|
19
|
+
configurable: true,
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: () => owner[name],
|
|
22
|
+
});
|
|
22
23
|
}
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
const descriptors = Object.getOwnPropertyDescriptors(methods);
|
|
27
|
-
const view = Object.defineProperties({}, descriptors);
|
|
28
|
-
bindAccessors(view, state, writable);
|
|
29
|
-
bindGetters(view, state, readonly);
|
|
30
|
-
return view;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
module.exports = { bindAccessors, bindGetters, bindAlias, stateView };
|
|
26
|
+
module.exports = { bindAccessors, bindGetters };
|
package/lib/session/actions.js
CHANGED
|
@@ -6,13 +6,14 @@ const ACTIONS = {
|
|
|
6
6
|
add: ['a'],
|
|
7
7
|
unstage: ['u'],
|
|
8
8
|
revert: ['d'],
|
|
9
|
+
ignore: ['i'],
|
|
9
10
|
commit: ['c'],
|
|
10
11
|
prev: ['left', 'p', 'k'],
|
|
11
12
|
next: ['right', 'n', 'j'],
|
|
12
13
|
check: ['x', ' '],
|
|
13
14
|
layout: ['m'],
|
|
14
15
|
feedback: ['f'],
|
|
15
|
-
|
|
16
|
+
tasks: ['t'],
|
|
16
17
|
code: ['e'],
|
|
17
18
|
branch: ['b'],
|
|
18
19
|
file: ['f'],
|
|
@@ -23,51 +24,79 @@ const ACTION_IDS = Object.keys(ACTIONS);
|
|
|
23
24
|
|
|
24
25
|
const BRANCH_ACTIONS = {
|
|
25
26
|
newBranch: ['n'],
|
|
26
|
-
rebase: ['
|
|
27
|
-
drop: ['
|
|
27
|
+
rebase: ['e'],
|
|
28
|
+
drop: ['delete'],
|
|
28
29
|
pull: ['p'],
|
|
29
30
|
push: ['s'],
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
const COMMIT_ACTIONS = {
|
|
33
34
|
amend: ['a'],
|
|
34
|
-
apply: ['
|
|
35
|
-
reword: ['
|
|
36
|
-
fixup: ['
|
|
37
|
-
drop: ['
|
|
35
|
+
apply: ['p'],
|
|
36
|
+
reword: ['e'],
|
|
37
|
+
fixup: ['x'],
|
|
38
|
+
drop: ['delete'],
|
|
38
39
|
view: ['v'],
|
|
39
|
-
pull: ['p'],
|
|
40
|
-
push: ['s'],
|
|
41
40
|
};
|
|
42
41
|
|
|
43
42
|
const NPM_ACTIONS = {
|
|
44
43
|
npm: ['n'],
|
|
45
44
|
npmEdit: ['e'],
|
|
46
|
-
npmNew: ['
|
|
47
|
-
npmDrop: ['
|
|
48
|
-
npmLogs: ['
|
|
45
|
+
npmNew: ['i'],
|
|
46
|
+
npmDrop: ['delete'],
|
|
47
|
+
npmLogs: ['l'],
|
|
49
48
|
npmStop: ['escape'],
|
|
49
|
+
npmVerbose: ['v'],
|
|
50
50
|
npmRerun: ['r'],
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
const DASH_ACTIONS = {
|
|
54
|
+
dashFiles: ['f'],
|
|
55
|
+
dashDiffs: ['d'],
|
|
56
|
+
dashTasks: ['t'],
|
|
57
|
+
dashBranches: ['b'],
|
|
58
|
+
dashCommits: ['c'],
|
|
59
|
+
dashRun: ['r'],
|
|
60
|
+
dashNpm: ['n'],
|
|
61
|
+
};
|
|
62
|
+
const DASH_IDS = Object.keys(DASH_ACTIONS);
|
|
63
|
+
const DASH_BLOCKS = {
|
|
64
|
+
dashFiles: 'files',
|
|
65
|
+
dashDiffs: 'diffs',
|
|
66
|
+
dashCommits: 'commits',
|
|
67
|
+
dashBranches: 'branches',
|
|
68
|
+
dashNpm: 'npm',
|
|
69
|
+
dashRun: 'run',
|
|
70
|
+
dashTasks: 'tasks',
|
|
71
|
+
};
|
|
72
|
+
const DASH_ALLOWED = [...DASH_IDS, 'quit', 'theme'];
|
|
73
|
+
const DASH_HIDDEN = ACTION_IDS.filter((id) => id !== 'quit');
|
|
74
|
+
|
|
53
75
|
const ACTION_HOT = {
|
|
54
76
|
prev: '←',
|
|
55
77
|
next: '→',
|
|
78
|
+
drop: 'del',
|
|
79
|
+
npmDrop: 'del',
|
|
56
80
|
npmStop: 'esc',
|
|
57
81
|
};
|
|
58
82
|
|
|
59
83
|
const ACTION_LABEL = {
|
|
84
|
+
...DASH_BLOCKS,
|
|
60
85
|
revert: 'drop',
|
|
61
86
|
check: 'x',
|
|
62
87
|
layout: 'mode',
|
|
88
|
+
tasks: 'tasks',
|
|
63
89
|
view: 'view',
|
|
64
90
|
code: 'edit',
|
|
91
|
+
reword: 'edit',
|
|
92
|
+
drop: 'delete',
|
|
65
93
|
newBranch: 'new',
|
|
66
94
|
npmEdit: 'edit',
|
|
67
|
-
npmNew: '
|
|
95
|
+
npmNew: 'insert',
|
|
68
96
|
npmDrop: 'delete',
|
|
69
97
|
npmLogs: 'cleanup',
|
|
70
98
|
npmStop: 'esc',
|
|
99
|
+
npmVerbose: 'verbose',
|
|
71
100
|
npmRerun: 're-run',
|
|
72
101
|
quit: 'q',
|
|
73
102
|
prev: '←',
|
|
@@ -83,7 +112,7 @@ const DIFF_DISABLED = [
|
|
|
83
112
|
'file',
|
|
84
113
|
'diff',
|
|
85
114
|
];
|
|
86
|
-
const UNIT_DISABLED = [...DIFF_DISABLED, 'layout'];
|
|
115
|
+
const UNIT_DISABLED = [...DIFF_DISABLED, 'layout', 'ignore'];
|
|
87
116
|
const FILES_DISABLED = ['layout', 'feedback', 'code'];
|
|
88
117
|
const FILES_HIDDEN = [
|
|
89
118
|
...FILES_DISABLED,
|
|
@@ -93,17 +122,20 @@ const FILES_HIDDEN = [
|
|
|
93
122
|
'commit',
|
|
94
123
|
'file',
|
|
95
124
|
'diff',
|
|
125
|
+
'tasks',
|
|
126
|
+
'branch',
|
|
96
127
|
];
|
|
97
|
-
const FILES_GIT_DISABLED = ['add', 'unstage', 'revert'];
|
|
98
|
-
const
|
|
99
|
-
const
|
|
128
|
+
const FILES_GIT_DISABLED = ['add', 'unstage', 'revert', 'ignore'];
|
|
129
|
+
const FILES_TASKS_DISABLED = [...FILES_GIT_DISABLED, ...FILES_DISABLED];
|
|
130
|
+
const TASKS_DISABLED = [
|
|
100
131
|
'add',
|
|
101
132
|
'unstage',
|
|
102
133
|
'revert',
|
|
134
|
+
'ignore',
|
|
103
135
|
'commit',
|
|
104
136
|
'layout',
|
|
105
137
|
'feedback',
|
|
106
|
-
'
|
|
138
|
+
'tasks',
|
|
107
139
|
'code',
|
|
108
140
|
'branch',
|
|
109
141
|
'file',
|
|
@@ -115,10 +147,11 @@ const BRANCHES_DISABLED = [
|
|
|
115
147
|
'add',
|
|
116
148
|
'unstage',
|
|
117
149
|
'revert',
|
|
150
|
+
'ignore',
|
|
118
151
|
'commit',
|
|
119
152
|
'layout',
|
|
120
153
|
'feedback',
|
|
121
|
-
'
|
|
154
|
+
'tasks',
|
|
122
155
|
'code',
|
|
123
156
|
'check',
|
|
124
157
|
'branch',
|
|
@@ -130,11 +163,11 @@ const BRANCHES_DISABLED = [
|
|
|
130
163
|
const COMMITS_DISABLED = BRANCHES_DISABLED.filter((id) => id !== 'commit');
|
|
131
164
|
const NPM_DISABLED = [...BRANCHES_DISABLED, 'pull', 'push'];
|
|
132
165
|
|
|
133
|
-
const
|
|
134
|
-
!!(item && (item.kind === '
|
|
166
|
+
const isTasksTarget = (item) =>
|
|
167
|
+
!!(item && (item.kind === 'tasks' || item.origin === 'task'));
|
|
135
168
|
|
|
136
169
|
const diffGitDisabled = (item) => {
|
|
137
|
-
if (!item ||
|
|
170
|
+
if (!item || isTasksTarget(item)) return [];
|
|
138
171
|
if (item.origin === 'staged') return ['add'];
|
|
139
172
|
return ['unstage'];
|
|
140
173
|
};
|
|
@@ -171,8 +204,8 @@ const commitGitDisabled = (item) => {
|
|
|
171
204
|
};
|
|
172
205
|
|
|
173
206
|
const disabledActions = (pane, item) => {
|
|
174
|
-
const onTodos =
|
|
175
|
-
if (pane === 'files') return onTodos ?
|
|
207
|
+
const onTodos = isTasksTarget(item);
|
|
208
|
+
if (pane === 'files') return onTodos ? FILES_TASKS_DISABLED : FILES_DISABLED;
|
|
176
209
|
if (pane === 'unit') return [...UNIT_DISABLED, ...diffGitDisabled(item)];
|
|
177
210
|
if (pane === 'branches') {
|
|
178
211
|
return [...BRANCHES_DISABLED, ...branchGitDisabled(item)];
|
|
@@ -181,7 +214,7 @@ const disabledActions = (pane, item) => {
|
|
|
181
214
|
return [...COMMITS_DISABLED, ...commitWriteDisabled(item)];
|
|
182
215
|
}
|
|
183
216
|
if (pane === 'npm') return NPM_DISABLED;
|
|
184
|
-
if (onTodos) return
|
|
217
|
+
if (pane === 'tasks' || onTodos) return TASKS_DISABLED;
|
|
185
218
|
return [...DIFF_DISABLED, ...diffGitDisabled(item)];
|
|
186
219
|
};
|
|
187
220
|
|
|
@@ -203,8 +236,8 @@ const SCROLL = {
|
|
|
203
236
|
home: 'home',
|
|
204
237
|
end: 'end',
|
|
205
238
|
enter: 'open',
|
|
206
|
-
backspace: '
|
|
207
|
-
delete: '
|
|
239
|
+
backspace: 'removeTask',
|
|
240
|
+
delete: 'removeTask',
|
|
208
241
|
};
|
|
209
242
|
|
|
210
243
|
const keysForActions = (actions) => {
|
|
@@ -216,25 +249,26 @@ const keysForActions = (actions) => {
|
|
|
216
249
|
};
|
|
217
250
|
|
|
218
251
|
const PANE_ONLY = ['branch', 'file', 'diff'];
|
|
219
|
-
const
|
|
220
|
-
branch: ACTIONS.branch,
|
|
221
|
-
pull: BRANCH_ACTIONS.pull,
|
|
222
|
-
push: BRANCH_ACTIONS.push,
|
|
223
|
-
npm: NPM_ACTIONS.npm,
|
|
224
|
-
});
|
|
252
|
+
const REVIEW_DROP = { d: 'revert' };
|
|
225
253
|
const BRANCH_KEYS = keysForActions(BRANCH_ACTIONS);
|
|
226
|
-
const COMMIT_KEYS = keysForActions(COMMIT_ACTIONS);
|
|
254
|
+
const COMMIT_KEYS = { ...keysForActions(COMMIT_ACTIONS), c: 'commit' };
|
|
227
255
|
const NPM_KEYS = {
|
|
228
256
|
e: 'npmEdit',
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
257
|
+
i: 'npmNew',
|
|
258
|
+
delete: 'npmDrop',
|
|
259
|
+
l: 'npmLogs',
|
|
232
260
|
};
|
|
261
|
+
const DASH_KEYS = keysForActions(DASH_ACTIONS);
|
|
262
|
+
const SCREEN_KEYS = DASH_KEYS;
|
|
233
263
|
const PANE_KEYS = {
|
|
234
|
-
|
|
264
|
+
dashboard: DASH_KEYS,
|
|
265
|
+
files: REVIEW_DROP,
|
|
266
|
+
diff: REVIEW_DROP,
|
|
267
|
+
unit: REVIEW_DROP,
|
|
235
268
|
branches: BRANCH_KEYS,
|
|
236
269
|
commits: COMMIT_KEYS,
|
|
237
270
|
npm: NPM_KEYS,
|
|
271
|
+
tasks: { delete: 'drop' },
|
|
238
272
|
};
|
|
239
273
|
|
|
240
274
|
const KEY_TO_ACTION = {
|
|
@@ -247,16 +281,13 @@ const KEY_TO_ACTION = {
|
|
|
247
281
|
...HIDDEN_KEYS,
|
|
248
282
|
};
|
|
249
283
|
|
|
250
|
-
const actionFromKey = (key, pane
|
|
284
|
+
const actionFromKey = (key, pane) => {
|
|
251
285
|
if (LIST_PANES.includes(pane) && (key === 'left' || key === 'right')) {
|
|
252
286
|
return null;
|
|
253
287
|
}
|
|
254
288
|
const paneKeys = PANE_KEYS[pane];
|
|
255
289
|
if (paneKeys && paneKeys[key]) return paneKeys[key];
|
|
256
|
-
if (pane
|
|
257
|
-
if (key === 'f' && fileScope !== 'file') return 'file';
|
|
258
|
-
if (key === 'd' && fileScope === 'file') return 'diff';
|
|
259
|
-
}
|
|
290
|
+
if (pane && SCREEN_KEYS[key]) return SCREEN_KEYS[key];
|
|
260
291
|
return KEY_TO_ACTION[key] ?? null;
|
|
261
292
|
};
|
|
262
293
|
|
|
@@ -265,11 +296,10 @@ const actionKeys = (id) =>
|
|
|
265
296
|
BRANCH_ACTIONS[id] ??
|
|
266
297
|
COMMIT_ACTIONS[id] ??
|
|
267
298
|
NPM_ACTIONS[id] ??
|
|
299
|
+
DASH_ACTIONS[id] ??
|
|
268
300
|
[];
|
|
269
301
|
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
const actionLetter = actionHot;
|
|
302
|
+
const actionLetter = (id) => ACTION_HOT[id] ?? actionKeys(id)[0];
|
|
273
303
|
|
|
274
304
|
const buttonWord = (id) => {
|
|
275
305
|
const word = ACTION_LABEL[id] ?? ACTION_HOT[id] ?? id;
|
|
@@ -337,13 +367,6 @@ const confirmKey = (mode, key) => {
|
|
|
337
367
|
return spec.keys[norm] ?? null;
|
|
338
368
|
};
|
|
339
369
|
|
|
340
|
-
const applyConfirm = (mode, key, handlers) => {
|
|
341
|
-
const action = confirmKey(mode, key);
|
|
342
|
-
if (!action) return;
|
|
343
|
-
const handler = handlers[action];
|
|
344
|
-
if (handler) handler();
|
|
345
|
-
};
|
|
346
|
-
|
|
347
370
|
const confirmPrefix = (spec, view) => {
|
|
348
371
|
if (typeof spec.prefix === 'function') return spec.prefix(view);
|
|
349
372
|
return spec.prefix ?? '';
|
|
@@ -354,39 +377,35 @@ const promptFromChoices = (choices) =>
|
|
|
354
377
|
|
|
355
378
|
module.exports = {
|
|
356
379
|
LIST_PANES,
|
|
380
|
+
DASH_IDS,
|
|
381
|
+
DASH_BLOCKS,
|
|
382
|
+
DASH_ALLOWED,
|
|
383
|
+
DASH_HIDDEN,
|
|
357
384
|
ACTIONS,
|
|
358
385
|
ACTION_IDS,
|
|
359
386
|
BRANCH_ACTIONS,
|
|
360
387
|
COMMIT_ACTIONS,
|
|
361
|
-
NPM_ACTIONS,
|
|
362
|
-
ACTION_HOT,
|
|
363
|
-
ACTION_LABEL,
|
|
364
388
|
DIFF_DISABLED,
|
|
365
389
|
UNIT_DISABLED,
|
|
366
390
|
FILES_DISABLED,
|
|
367
391
|
FILES_HIDDEN,
|
|
368
392
|
FILES_GIT_DISABLED,
|
|
369
|
-
|
|
370
|
-
|
|
393
|
+
FILES_TASKS_DISABLED,
|
|
394
|
+
TASKS_DISABLED,
|
|
371
395
|
BRANCHES_DISABLED,
|
|
372
396
|
COMMITS_DISABLED,
|
|
373
397
|
NPM_DISABLED,
|
|
374
|
-
SCROLL,
|
|
375
|
-
PANE_ONLY,
|
|
376
398
|
disabledActions,
|
|
377
399
|
diffGitDisabled,
|
|
378
400
|
branchGitDisabled,
|
|
379
401
|
commitGitDisabled,
|
|
380
402
|
isFixupCommit,
|
|
381
403
|
actionFromKey,
|
|
382
|
-
actionKeys,
|
|
383
|
-
actionHot,
|
|
384
404
|
actionLetter,
|
|
385
405
|
buttonWord,
|
|
386
406
|
CONFIRM,
|
|
387
407
|
CONFIRM_MODE,
|
|
388
408
|
confirmKey,
|
|
389
|
-
applyConfirm,
|
|
390
409
|
confirmPrefix,
|
|
391
410
|
promptFromChoices,
|
|
392
411
|
};
|