reslop 0.2.0 → 0.2.1
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 +2 -1
- package/lib/ansi.js +144 -3
- package/lib/api.js +2 -0
- package/lib/capabilities.js +6 -0
- package/lib/cli.js +10 -2
- package/lib/git-branches.js +185 -6
- package/lib/git-reword-todo.js +20 -0
- package/lib/git.js +20 -3
- package/lib/render/branches.js +4 -32
- package/lib/render/chrome.js +47 -5
- package/lib/render/commits.js +63 -1
- package/lib/render/diff.js +4 -4
- package/lib/render/frame.js +13 -1
- package/lib/render/notes.js +22 -5
- package/lib/render/primitives.js +54 -11
- package/lib/render/render.js +3 -3
- package/lib/review-merge.js +270 -0
- package/lib/review.js +38 -6
- package/lib/session/actions.js +30 -3
- package/lib/session/commit.js +101 -8
- package/lib/session/compose.js +48 -27
- package/lib/session/dispatch.js +6 -0
- package/lib/session/files-pane.js +17 -3
- package/lib/session/lifecycle.js +113 -16
- package/lib/session/pointer.js +4 -1
- package/lib/session/todos.js +29 -1
- package/lib/session/watch.js +120 -8
- package/lib/session.js +1 -0
- package/package.json +2 -2
package/lib/render/chrome.js
CHANGED
|
@@ -39,6 +39,7 @@ const BUSY_PROGRESS = [
|
|
|
39
39
|
'rebasing',
|
|
40
40
|
'dropping',
|
|
41
41
|
'committing',
|
|
42
|
+
'rewording',
|
|
42
43
|
'force pushing',
|
|
43
44
|
];
|
|
44
45
|
|
|
@@ -62,6 +63,8 @@ const INFO_STATUS = [
|
|
|
62
63
|
'unified',
|
|
63
64
|
'mixed',
|
|
64
65
|
'side-by-side',
|
|
66
|
+
'dark',
|
|
67
|
+
'light',
|
|
65
68
|
'saved',
|
|
66
69
|
'reloaded',
|
|
67
70
|
'not a diff block',
|
|
@@ -69,6 +72,7 @@ const INFO_STATUS = [
|
|
|
69
72
|
'diff mode',
|
|
70
73
|
'committed',
|
|
71
74
|
'amended',
|
|
75
|
+
'reworded',
|
|
72
76
|
'fixup',
|
|
73
77
|
'updated',
|
|
74
78
|
'updating reslop',
|
|
@@ -91,6 +95,7 @@ const INFO_STATUS = [
|
|
|
91
95
|
'checked out',
|
|
92
96
|
'created',
|
|
93
97
|
'empty branch name',
|
|
98
|
+
'empty commit message',
|
|
94
99
|
];
|
|
95
100
|
const INFO_PREFIX = ['checked out ', 'created ', 'rebased onto ', 'dropped '];
|
|
96
101
|
|
|
@@ -162,7 +167,22 @@ const headerTarget = (view) => {
|
|
|
162
167
|
return { path: entry.name, origin, n, total };
|
|
163
168
|
}
|
|
164
169
|
if (pane === 'commits') {
|
|
170
|
+
const compose = view.compose;
|
|
165
171
|
const commits = view.commits ?? [];
|
|
172
|
+
if (compose && compose.kind === 'commit') {
|
|
173
|
+
const path = `${compose.text || ''}`.replaceAll('\n', ' ');
|
|
174
|
+
if (compose.commitKind === 'amend' || compose.commitKind === 'reword') {
|
|
175
|
+
const cursor = view.commitCursor ?? 0;
|
|
176
|
+
const entry = commits[cursor];
|
|
177
|
+
const total = commits.length;
|
|
178
|
+
const n = total ? cursor + 1 : 0;
|
|
179
|
+
if (!entry) return { path, origin: 'commit', n, total };
|
|
180
|
+
const origin = entry.head ? 'HEAD' : 'commit';
|
|
181
|
+
return { path, origin, n, total };
|
|
182
|
+
}
|
|
183
|
+
const total = commits.length + 1;
|
|
184
|
+
return { path, origin: 'new', n: 1, total };
|
|
185
|
+
}
|
|
166
186
|
const cursor = view.commitCursor ?? 0;
|
|
167
187
|
const entry = commits[cursor];
|
|
168
188
|
const total = commits.length;
|
|
@@ -191,10 +211,29 @@ const headerTarget = (view) => {
|
|
|
191
211
|
};
|
|
192
212
|
};
|
|
193
213
|
|
|
214
|
+
const headerScreen = (view) => {
|
|
215
|
+
const pane = view.pane ?? 'diff';
|
|
216
|
+
if (pane === 'branches') return 'branches';
|
|
217
|
+
if (pane === 'commits') return 'commits';
|
|
218
|
+
if (pane === 'files') {
|
|
219
|
+
const files = view.files ?? [];
|
|
220
|
+
const entry = files[view.fileCursor ?? 0];
|
|
221
|
+
if (isTodosEntry(entry)) return TODO_FILE;
|
|
222
|
+
return '';
|
|
223
|
+
}
|
|
224
|
+
if (view.item && view.item.origin === 'todo') return TODO_FILE;
|
|
225
|
+
return '';
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const headerLabel = (view, target) => headerScreen(view) || target.path;
|
|
229
|
+
|
|
230
|
+
const headerSep = (view) => (headerScreen(view) ? ': ' : '/');
|
|
231
|
+
|
|
194
232
|
const headerPrefix = (view) => {
|
|
195
233
|
const repo = view.repoName || '';
|
|
196
|
-
const
|
|
197
|
-
|
|
234
|
+
const target = headerTarget(view);
|
|
235
|
+
const label = headerLabel(view, target);
|
|
236
|
+
if (repo && label) return ` ${LOGO} reslop: ${repo}${headerSep(view)}`;
|
|
198
237
|
if (repo) return ` ${LOGO} reslop: ${repo} `;
|
|
199
238
|
return ` ${LOGO} reslop: `;
|
|
200
239
|
};
|
|
@@ -205,13 +244,14 @@ const headerSuffix = ({ origin, n, total }) =>
|
|
|
205
244
|
const headerText = (view) => {
|
|
206
245
|
const prefix = headerPrefix(view);
|
|
207
246
|
const target = headerTarget(view);
|
|
208
|
-
|
|
247
|
+
const label = headerLabel(view, target);
|
|
248
|
+
return `${prefix}${label}${headerSuffix(target)}`;
|
|
209
249
|
};
|
|
210
250
|
|
|
211
251
|
const headerPieces = (view, width) => {
|
|
212
252
|
const repo = view.repoName || '';
|
|
213
253
|
const target = headerTarget(view);
|
|
214
|
-
const path = target
|
|
254
|
+
const path = headerLabel(view, target);
|
|
215
255
|
const suffix = headerSuffix(target);
|
|
216
256
|
const right = ' ';
|
|
217
257
|
const chrome = ` ${LOGO} reslop: `;
|
|
@@ -224,7 +264,9 @@ const headerPieces = (view, width) => {
|
|
|
224
264
|
if (repo) {
|
|
225
265
|
pieces.push({ text: repo, role: 'repo' });
|
|
226
266
|
if (path) {
|
|
227
|
-
|
|
267
|
+
const sep = headerSep(view);
|
|
268
|
+
const role = sep === '/' ? 'slash' : 'chrome';
|
|
269
|
+
pieces.push({ text: sep, role });
|
|
228
270
|
} else {
|
|
229
271
|
pieces.push({ text: ' ', role: 'chrome' });
|
|
230
272
|
}
|
package/lib/render/commits.js
CHANGED
|
@@ -55,10 +55,72 @@ const paintCommitRow = (entry, width, color, selected, cols) => {
|
|
|
55
55
|
return out + edge;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
const paintCommitEdit = (compose, width, color, entry, cols) => {
|
|
59
|
+
const text = `${compose.text ?? ''}`.replaceAll('\n', ' ');
|
|
60
|
+
if (entry && cols) {
|
|
61
|
+
const row = paintCommitRow(
|
|
62
|
+
{ ...entry, subject: text },
|
|
63
|
+
width,
|
|
64
|
+
color,
|
|
65
|
+
true,
|
|
66
|
+
cols,
|
|
67
|
+
);
|
|
68
|
+
const inner = Math.max(1, width - COMMIT_EDGE - COMMIT_TAIL);
|
|
69
|
+
const prefix = ` ${FILE_MARK} `;
|
|
70
|
+
const lead = ' ';
|
|
71
|
+
const parts = padColumns(commitRowFields(entry), cols, COMMIT_COL_ALIGN);
|
|
72
|
+
const suffix = joinColumns(parts, cols);
|
|
73
|
+
const rest = Math.max(1, inner - visibleWidth(prefix + lead + suffix));
|
|
74
|
+
const clipped = truncateVisible(text, rest);
|
|
75
|
+
const prefixW = visibleWidth(prefix + lead);
|
|
76
|
+
const col = Math.min(compose.cursor ?? 0, visibleWidth(clipped));
|
|
77
|
+
return {
|
|
78
|
+
row,
|
|
79
|
+
cursor: { x: prefixW + col + 1 },
|
|
80
|
+
at: 'replace',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const inner = Math.max(1, width - COMMIT_EDGE);
|
|
84
|
+
const prefix = ` ${FILE_MARK} `;
|
|
85
|
+
const lead = ' ';
|
|
86
|
+
const prefixW = visibleWidth(prefix + lead);
|
|
87
|
+
const rest = Math.max(1, inner - prefixW);
|
|
88
|
+
const clipped = truncateVisible(text, rest);
|
|
89
|
+
const pad = Math.max(0, rest - visibleWidth(clipped));
|
|
90
|
+
const gap = ' '.repeat(pad);
|
|
91
|
+
const fgRgb = THEME.chromeFg;
|
|
92
|
+
const bgRgb = THEME.buttonBg;
|
|
93
|
+
const nameFg = THEME.buttonHotFg;
|
|
94
|
+
const edge = fill(COMMIT_EDGE, fgRgb, THEME.ctxBg, color);
|
|
95
|
+
let row = `${prefix}${lead}${clipped}${gap}${edge}`;
|
|
96
|
+
if (color) {
|
|
97
|
+
row = `${seq(fgRgb, bgRgb)}${EL}`;
|
|
98
|
+
row += paint(prefix, fgRgb, bgRgb, color);
|
|
99
|
+
row += paint(lead, nameFg, bgRgb, color);
|
|
100
|
+
row += paint(clipped, nameFg, bgRgb, color);
|
|
101
|
+
row += paint(gap, fgRgb, bgRgb, color);
|
|
102
|
+
row += edge;
|
|
103
|
+
}
|
|
104
|
+
const col = Math.min(compose.cursor ?? 0, visibleWidth(clipped));
|
|
105
|
+
return { row, cursor: { x: prefixW + col + 1 }, at: 'start' };
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const commitEditRow = (compose, commits, cursor, width, color, cols) => {
|
|
109
|
+
if (!compose || compose.kind !== 'commit') return null;
|
|
110
|
+
if (compose.commitKind === 'amend' || compose.commitKind === 'reword') {
|
|
111
|
+
const entry = commits[cursor];
|
|
112
|
+
if (!entry) return null;
|
|
113
|
+
return paintCommitEdit(compose, width, color, entry, cols);
|
|
114
|
+
}
|
|
115
|
+
return paintCommitEdit(compose, width, color);
|
|
116
|
+
};
|
|
117
|
+
|
|
58
118
|
const paintBodyCommits = (view, width, color, bodyH, headerLines) => {
|
|
59
119
|
const commits = view.commits ?? [];
|
|
60
120
|
const cols = measureColumns(commits, commitRowFields, COMMIT_COL_ALIGN);
|
|
61
121
|
const cursor = view.commitCursor ?? 0;
|
|
122
|
+
const compose = view.compose;
|
|
123
|
+
const extra = commitEditRow(compose, commits, cursor, width, color, cols);
|
|
62
124
|
const paintRow = (entry, rowWidth, rowColor, selected) =>
|
|
63
125
|
paintCommitRow(entry, rowWidth, rowColor, selected, cols);
|
|
64
126
|
const painted = paintCursorList(
|
|
@@ -69,7 +131,7 @@ const paintBodyCommits = (view, width, color, bodyH, headerLines) => {
|
|
|
69
131
|
bodyH,
|
|
70
132
|
headerLines,
|
|
71
133
|
paintRow,
|
|
72
|
-
|
|
134
|
+
extra,
|
|
73
135
|
view.listScroll,
|
|
74
136
|
);
|
|
75
137
|
return paneResult({
|
package/lib/render/diff.js
CHANGED
|
@@ -78,8 +78,8 @@ const STAGED_STYLES = {
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
const SOFT_WRAP = ['warn', 'note'];
|
|
81
|
-
const
|
|
82
|
-
const
|
|
81
|
+
const delCharBg = () => ansi.bg(THEME.delCharBg);
|
|
82
|
+
const addCharBg = () => ansi.bg(THEME.addCharBg);
|
|
83
83
|
|
|
84
84
|
const paintSpans = (pieces, lineStyle, budget, color) => {
|
|
85
85
|
let out = '';
|
|
@@ -298,8 +298,8 @@ const paintBodyDiff = (view, width, color) => {
|
|
|
298
298
|
};
|
|
299
299
|
|
|
300
300
|
module.exports = {
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
delCharBg,
|
|
302
|
+
addCharBg,
|
|
303
303
|
paintDiffLine,
|
|
304
304
|
codeInnerWidth,
|
|
305
305
|
paintBodyDiff,
|
package/lib/render/frame.js
CHANGED
|
@@ -88,6 +88,7 @@ const mapBodyCursor = (cursor, shift, scroll, headerLines, shown) => {
|
|
|
88
88
|
const windowBody = (view, width, color, bodyH, headerLines, paintedBody) => {
|
|
89
89
|
const sourceBody = paintedBody.body;
|
|
90
90
|
const sourceOwners = paintedBody.todoOwners;
|
|
91
|
+
const sourceChecks = paintedBody.todoChecks ?? [];
|
|
91
92
|
const splitBody = paintedBody.splitBody === true;
|
|
92
93
|
const pane = view.pane ?? 'diff';
|
|
93
94
|
const listPane = LIST_PANES.includes(pane);
|
|
@@ -109,6 +110,13 @@ const windowBody = (view, width, color, bodyH, headerLines, paintedBody) => {
|
|
|
109
110
|
for (let i = 0; i < sourceOwners.length; i++) {
|
|
110
111
|
todoOwners[ownerAt++] = sourceOwners[i];
|
|
111
112
|
}
|
|
113
|
+
const checkLead = lead && sourceChecks.length;
|
|
114
|
+
const todoChecks = new Array(sourceChecks.length + (checkLead ? 1 : 0));
|
|
115
|
+
let checkAt = 0;
|
|
116
|
+
if (checkLead) todoChecks[checkAt++] = false;
|
|
117
|
+
for (let i = 0; i < sourceChecks.length; i++) {
|
|
118
|
+
todoChecks[checkAt++] = sourceChecks[i];
|
|
119
|
+
}
|
|
112
120
|
const scrollRaw = view.scroll ?? 0;
|
|
113
121
|
const scrollMax = Math.max(0, body.length - bodyH);
|
|
114
122
|
const scroll = listPane ? 0 : Math.min(scrollRaw, scrollMax);
|
|
@@ -120,7 +128,11 @@ const windowBody = (view, width, color, bodyH, headerLines, paintedBody) => {
|
|
|
120
128
|
for (let i = 0; i < copied; i++) {
|
|
121
129
|
const owner = todoOwners[scroll + i];
|
|
122
130
|
if (owner === undefined || owner === null) continue;
|
|
123
|
-
|
|
131
|
+
const y = headerLines + i + 1;
|
|
132
|
+
if (todoChecks[scroll + i]) {
|
|
133
|
+
todoHits.push({ y, cursor: owner, x0: 1, x1: 4, check: true });
|
|
134
|
+
}
|
|
135
|
+
todoHits.push({ y, cursor: owner });
|
|
124
136
|
}
|
|
125
137
|
const cursor = mapBodyCursor(
|
|
126
138
|
paintedBody.cursor,
|
package/lib/render/notes.js
CHANGED
|
@@ -11,7 +11,7 @@ const { THEME, visibleWidth, truncateVisible, seq, EL, RESET, BOLD } = ansi;
|
|
|
11
11
|
const { paintBar, paintCheckBar, windowRows } = primitives;
|
|
12
12
|
const { LIST_PANES, CHECK_LEAD, paneResult } = primitives;
|
|
13
13
|
|
|
14
|
-
const NOTE_COMPOSE = ['feedback'
|
|
14
|
+
const NOTE_COMPOSE = ['feedback'];
|
|
15
15
|
const INPUT_MAX = 4;
|
|
16
16
|
const NOTE_MAX = 4;
|
|
17
17
|
const NOTE_PAD = 1;
|
|
@@ -57,6 +57,7 @@ const paintTodoList = (texts, focus, width, color, edit) => {
|
|
|
57
57
|
const inner = todoInnerWidth(width);
|
|
58
58
|
const rows = [];
|
|
59
59
|
const owners = [];
|
|
60
|
+
const checks = [];
|
|
60
61
|
let cursor = null;
|
|
61
62
|
for (let i = 0; i < texts.length; i++) {
|
|
62
63
|
const selected = i === focus;
|
|
@@ -65,14 +66,22 @@ const paintTodoList = (texts, focus, width, color, edit) => {
|
|
|
65
66
|
const text = texts[i];
|
|
66
67
|
const wrapped = wrapTodoItem(text, inner);
|
|
67
68
|
const rowStart = rows.length;
|
|
68
|
-
for (
|
|
69
|
-
|
|
69
|
+
for (let line = 0; line < wrapped.length; line++) {
|
|
70
|
+
const painted = paintCheckBar(
|
|
71
|
+
` ${wrapped[line]}`,
|
|
72
|
+
width,
|
|
73
|
+
fgRgb,
|
|
74
|
+
bgRgb,
|
|
75
|
+
color,
|
|
76
|
+
);
|
|
77
|
+
rows.push(painted);
|
|
70
78
|
owners.push(i);
|
|
79
|
+
checks.push(line === 0);
|
|
71
80
|
}
|
|
72
81
|
if (!edit || !selected) continue;
|
|
73
82
|
cursor = todoCursor(text, edit, inner, rowStart);
|
|
74
83
|
}
|
|
75
|
-
return { rows, owners, cursor };
|
|
84
|
+
return { rows, owners, checks, cursor };
|
|
76
85
|
};
|
|
77
86
|
|
|
78
87
|
const noteInnerWidth = (width) => Math.max(1, width - NOTE_PAD * 2);
|
|
@@ -184,13 +193,21 @@ const paintBodyTodo = (view, width, color) => {
|
|
|
184
193
|
const caption = paintTodoCaption(width, color);
|
|
185
194
|
const body = [caption, ...painted.rows];
|
|
186
195
|
const todoOwners = [null, ...painted.owners];
|
|
196
|
+
const todoChecks = [false, ...painted.checks];
|
|
187
197
|
let cursor = null;
|
|
188
198
|
if (painted.cursor) {
|
|
189
199
|
cursor = { x: painted.cursor.x, row: painted.cursor.row + 1 };
|
|
190
200
|
}
|
|
191
201
|
const fileHits = [];
|
|
192
202
|
const splitBody = false;
|
|
193
|
-
return paneResult({
|
|
203
|
+
return paneResult({
|
|
204
|
+
body,
|
|
205
|
+
fileHits,
|
|
206
|
+
todoOwners,
|
|
207
|
+
todoChecks,
|
|
208
|
+
cursor,
|
|
209
|
+
splitBody,
|
|
210
|
+
});
|
|
194
211
|
};
|
|
195
212
|
|
|
196
213
|
module.exports = {
|
package/lib/render/primitives.js
CHANGED
|
@@ -104,6 +104,13 @@ const listWindowStart = (focus, offset, listH, count) => {
|
|
|
104
104
|
return start;
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
const extraIdx = (extraRow, cursor, count) => {
|
|
108
|
+
if (!extraRow) return -1;
|
|
109
|
+
if (extraRow.at === 'start') return 0;
|
|
110
|
+
if (extraRow.at === 'replace') return extraRow.index ?? cursor;
|
|
111
|
+
return count;
|
|
112
|
+
};
|
|
113
|
+
|
|
107
114
|
const paintCursorList = (
|
|
108
115
|
items,
|
|
109
116
|
cursor,
|
|
@@ -112,15 +119,16 @@ const paintCursorList = (
|
|
|
112
119
|
bodyH,
|
|
113
120
|
headerLines,
|
|
114
121
|
paintRow,
|
|
115
|
-
|
|
122
|
+
extraRow,
|
|
116
123
|
offset = 0,
|
|
117
124
|
) => {
|
|
118
125
|
const pad = bodyH >= FILE_LIST_PAD * 2 + 1 ? FILE_LIST_PAD : 0;
|
|
119
126
|
const listH = bodyH - pad * 2;
|
|
120
|
-
const
|
|
127
|
+
const inserting = extraRow && extraRow.at === 'start';
|
|
128
|
+
const extra = extraRow && extraRow.at !== 'replace' ? 1 : 0;
|
|
121
129
|
const count = items.length + extra;
|
|
122
|
-
const
|
|
123
|
-
const focus =
|
|
130
|
+
const extraAt = extraIdx(extraRow, cursor, items.length);
|
|
131
|
+
const focus = extraRow ? extraAt : cursor;
|
|
124
132
|
const start = listWindowStart(focus, offset, listH, count);
|
|
125
133
|
const blank = paintBodyFill(width, color, 'files');
|
|
126
134
|
const body = [];
|
|
@@ -129,19 +137,20 @@ const paintCursorList = (
|
|
|
129
137
|
if (pad) body.push(blank);
|
|
130
138
|
for (let i = 0; i < listH; i++) {
|
|
131
139
|
const idx = start + i;
|
|
132
|
-
if (
|
|
133
|
-
body.push(
|
|
134
|
-
if (
|
|
135
|
-
textCursor = { x:
|
|
140
|
+
if (extraRow && idx === extraAt) {
|
|
141
|
+
body.push(extraRow.row);
|
|
142
|
+
if (extraRow.cursor) {
|
|
143
|
+
textCursor = { x: extraRow.cursor.x, row: body.length - 1 };
|
|
136
144
|
}
|
|
137
145
|
continue;
|
|
138
146
|
}
|
|
139
|
-
const
|
|
147
|
+
const itemIdx = inserting ? idx - 1 : idx;
|
|
148
|
+
const entry = items[itemIdx];
|
|
140
149
|
if (!entry) break;
|
|
141
|
-
const selected =
|
|
150
|
+
const selected = extraRow ? false : itemIdx === cursor;
|
|
142
151
|
body.push(paintRow(entry, width, color, selected));
|
|
143
152
|
const y = headerLines + pad + i + 1;
|
|
144
|
-
fileHits.push({ y, cursor:
|
|
153
|
+
fileHits.push({ y, cursor: itemIdx });
|
|
145
154
|
}
|
|
146
155
|
if (pad) body.push(blank);
|
|
147
156
|
return { body, fileHits, cursor: textCursor, offset: start };
|
|
@@ -171,10 +180,43 @@ const paintBracketName = (label, nameFg, wrapFg, bgRgb, color, nameBold) => {
|
|
|
171
180
|
);
|
|
172
181
|
};
|
|
173
182
|
|
|
183
|
+
const paintListEdit = (compose, width, color, edgeW) => {
|
|
184
|
+
const inner = Math.max(1, width - edgeW);
|
|
185
|
+
const prefix = ` ${FILE_MARK} `;
|
|
186
|
+
const prefixW = visibleWidth(prefix);
|
|
187
|
+
const rest = Math.max(1, inner - prefixW);
|
|
188
|
+
const text = `${compose.text ?? ''}`.replaceAll('\n', ' ');
|
|
189
|
+
const label = `[${text}]`;
|
|
190
|
+
const clipped = truncateVisible(label, rest);
|
|
191
|
+
const pad = Math.max(0, rest - visibleWidth(clipped));
|
|
192
|
+
const left = `${prefix}${clipped}${' '.repeat(pad)}`;
|
|
193
|
+
const fgRgb = THEME.chromeFg;
|
|
194
|
+
const bgRgb = THEME.buttonBg;
|
|
195
|
+
const edge = fill(edgeW, fgRgb, THEME.ctxBg, color);
|
|
196
|
+
let row = `${left}${edge}`;
|
|
197
|
+
if (color) {
|
|
198
|
+
const gap = ' '.repeat(pad);
|
|
199
|
+
row = `${seq(fgRgb, bgRgb)}${EL}`;
|
|
200
|
+
row += paint(prefix, fgRgb, bgRgb, color);
|
|
201
|
+
row += paintBracketName(
|
|
202
|
+
clipped,
|
|
203
|
+
THEME.buttonHotFg,
|
|
204
|
+
THEME.mutedFg,
|
|
205
|
+
bgRgb,
|
|
206
|
+
color,
|
|
207
|
+
);
|
|
208
|
+
row += paint(gap, fgRgb, bgRgb, color);
|
|
209
|
+
row += edge;
|
|
210
|
+
}
|
|
211
|
+
const col = Math.min((compose.cursor ?? 0) + 1, visibleWidth(clipped));
|
|
212
|
+
return { row, cursor: { x: prefixW + col + 1 } };
|
|
213
|
+
};
|
|
214
|
+
|
|
174
215
|
const paneResult = (fields) => ({
|
|
175
216
|
body: fields.body,
|
|
176
217
|
fileHits: fields.fileHits,
|
|
177
218
|
todoOwners: fields.todoOwners,
|
|
219
|
+
todoChecks: fields.todoChecks ?? [],
|
|
178
220
|
cursor: fields.cursor ?? null,
|
|
179
221
|
splitBody: fields.splitBody === true,
|
|
180
222
|
listScroll: fields.listScroll ?? 0,
|
|
@@ -239,6 +281,7 @@ module.exports = {
|
|
|
239
281
|
paintBodyFill,
|
|
240
282
|
windowRows,
|
|
241
283
|
paintCursorList,
|
|
284
|
+
paintListEdit,
|
|
242
285
|
branchLabel,
|
|
243
286
|
paintBracketName,
|
|
244
287
|
paneResult,
|
package/lib/render/render.js
CHANGED
|
@@ -9,7 +9,7 @@ const { renderFrame } = require('./frame.js');
|
|
|
9
9
|
const { QUIT_PROMPT, PUSH_PROMPT } = chrome;
|
|
10
10
|
const { updatePrompt, dropPrompt } = chrome;
|
|
11
11
|
const { formatBusyStatus, headerText, layoutButtons } = chrome;
|
|
12
|
-
const {
|
|
12
|
+
const { delCharBg, addCharBg, paintDiffLine, codeInnerWidth } = diff;
|
|
13
13
|
const { todoInnerWidth, todoBodyWidth, noteInnerWidth } = notes;
|
|
14
14
|
const { presentCursor, presentRows } = present;
|
|
15
15
|
|
|
@@ -18,8 +18,8 @@ module.exports = {
|
|
|
18
18
|
PUSH_PROMPT,
|
|
19
19
|
updatePrompt,
|
|
20
20
|
dropPrompt,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
delCharBg,
|
|
22
|
+
addCharBg,
|
|
23
23
|
paintDiffLine,
|
|
24
24
|
headerText,
|
|
25
25
|
layoutButtons,
|