reslop 0.1.8 → 0.2.0
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/README.md +27 -38
- package/bin/reslop.js +2 -2
- package/lib/ansi.js +6 -2
- package/lib/api.js +2 -2
- package/lib/capabilities.js +10 -14
- package/lib/cli.js +28 -47
- package/lib/clipboard.js +1 -1
- package/lib/deps-diff.js +712 -0
- package/lib/deps.js +556 -32
- package/lib/detect.js +1 -7
- package/lib/diff/align.js +7 -10
- package/lib/diff/diff.js +53 -0
- package/lib/diff/display.js +5 -4
- package/lib/diff/inline.js +26 -21
- package/lib/diff/items.js +6 -4
- package/lib/diff/patch.js +1 -3
- package/lib/diff/unit.js +392 -0
- package/lib/files.js +34 -8
- package/lib/{git/branches.js → git-branches.js} +103 -10
- package/lib/{git/dependencies.js → git-deps.js} +111 -38
- package/lib/git.js +592 -65
- package/lib/github.js +28 -197
- package/lib/gitlab.js +24 -195
- package/lib/highlight/bash.js +1 -3
- package/lib/highlight/css.js +1 -3
- package/lib/highlight/js.js +11 -14
- package/lib/highlight.js +6 -9
- package/lib/keys.js +22 -9
- package/lib/manifest.js +330 -0
- package/lib/remote.js +374 -0
- package/lib/render/branches.js +34 -66
- package/lib/render/chrome.js +57 -22
- package/lib/render/commits.js +85 -0
- package/lib/render/diff.js +16 -16
- package/lib/render/files.js +29 -37
- package/lib/render/frame.js +29 -13
- package/lib/render/notes.js +4 -3
- package/lib/render/primitives.js +46 -1
- package/lib/{render.js → render/render.js} +6 -7
- package/lib/render/unit.js +41 -0
- package/lib/review.js +750 -14
- package/lib/select.js +5 -10
- package/lib/session/accessors.js +9 -1
- package/lib/session/actions.js +93 -36
- package/lib/session/branches.js +130 -144
- package/lib/session/change-actions.js +206 -124
- package/lib/session/commit.js +217 -62
- package/lib/session/compose.js +158 -13
- package/lib/session/dispatch.js +109 -55
- package/lib/session/files-pane.js +145 -142
- package/lib/session/items.js +131 -34
- package/lib/session/lifecycle.js +82 -42
- package/lib/session/load.js +19 -33
- package/lib/session/navigation.js +15 -3
- package/lib/session/ops.js +28 -41
- package/lib/session/pointer.js +58 -54
- package/lib/session/review.js +23 -37
- package/lib/session/terminal.js +6 -12
- package/lib/session/todos.js +8 -12
- package/lib/session/unit.js +208 -0
- package/lib/session/update.js +33 -46
- package/lib/session/view.js +82 -11
- package/lib/session/watch.js +11 -19
- package/lib/session.js +29 -226
- package/lib/source.js +3 -3
- package/lib/update.js +40 -75
- package/lib/{git/proc.js → utilities.js} +75 -11
- package/lib/wrap.js +1 -3
- package/package.json +2 -2
- package/lib/deps/changes.js +0 -331
- package/lib/deps/items.js +0 -131
- package/lib/deps/manifest.js +0 -145
- package/lib/deps/merge.js +0 -120
- package/lib/deps/proposals.js +0 -164
- package/lib/deps/reports.js +0 -180
- package/lib/deps/rows.js +0 -177
- package/lib/deps/scan.js +0 -138
- package/lib/deps/usage.js +0 -68
- package/lib/deps/versions.js +0 -119
- package/lib/diff.js +0 -33
- package/lib/git/changes.js +0 -164
- package/lib/git/read.js +0 -253
- package/lib/git/run.js +0 -100
- package/lib/npm/commands.js +0 -100
- package/lib/remote/changes.js +0 -37
- package/lib/remote/headers.js +0 -36
- package/lib/remote/http.js +0 -122
- package/lib/remote/notes.js +0 -94
- package/lib/review/format.js +0 -434
- package/lib/review/storage.js +0 -150
- package/lib/review/store.js +0 -178
- package/lib/review/templates.js +0 -49
- package/lib/session/origins.js +0 -7
- package/lib/sys.js +0 -84
package/lib/session/ops.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { stateView } = require('./accessors.js');
|
|
4
|
+
|
|
3
5
|
const ASYNC_WITHOUT_UI = ['pull', 'push'];
|
|
4
6
|
|
|
5
7
|
const pickRepoWrite = (repo, name, uiOpen) => {
|
|
@@ -18,7 +20,7 @@ const pickRepoWrite = (repo, name, uiOpen) => {
|
|
|
18
20
|
};
|
|
19
21
|
};
|
|
20
22
|
|
|
21
|
-
const createOpsRunner = (
|
|
23
|
+
const createOpsRunner = (ui) => {
|
|
22
24
|
const state = {
|
|
23
25
|
gitBusy: false,
|
|
24
26
|
busy: '',
|
|
@@ -31,53 +33,46 @@ const createOpsRunner = (options) => {
|
|
|
31
33
|
|
|
32
34
|
const setBusy = (kind) => {
|
|
33
35
|
state.busy = kind;
|
|
34
|
-
|
|
36
|
+
ui.startProgress();
|
|
35
37
|
};
|
|
36
38
|
|
|
37
39
|
const clearBusy = () => {
|
|
38
40
|
state.busy = '';
|
|
39
|
-
|
|
41
|
+
ui.stopProgress();
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
const runRepo = (label, write) => {
|
|
43
45
|
try {
|
|
44
|
-
write(
|
|
45
|
-
|
|
46
|
+
write(ui.top);
|
|
47
|
+
ui.status = label;
|
|
46
48
|
return true;
|
|
47
49
|
} catch (error) {
|
|
48
|
-
|
|
50
|
+
ui.status = error.message;
|
|
49
51
|
return false;
|
|
50
52
|
}
|
|
51
53
|
};
|
|
52
54
|
|
|
53
55
|
const finishBusy = (done, after) => {
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (options.getMode() === 'confirmPush') {
|
|
59
|
-
options.paint();
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (!options.getStatus() && after) after();
|
|
63
|
-
if (!options.getStatus() && !state.busy) options.setStatus(done);
|
|
64
|
-
options.paint();
|
|
56
|
+
if (ui.done || ui.mode === 'confirmPush') return void ui.paint();
|
|
57
|
+
if (!ui.status && after) after();
|
|
58
|
+
if (!ui.status && !state.busy) ui.status = done;
|
|
59
|
+
ui.paint();
|
|
65
60
|
};
|
|
66
61
|
|
|
67
62
|
const runBusy = async (kind, done, write, after) => {
|
|
68
63
|
if (state.gitBusy) return;
|
|
69
64
|
state.gitBusy = true;
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
ui.status = '';
|
|
66
|
+
ui.progressFrame = 0;
|
|
72
67
|
setBusy(kind);
|
|
73
|
-
|
|
68
|
+
ui.paint();
|
|
74
69
|
try {
|
|
75
|
-
await write(
|
|
70
|
+
await write(ui.top);
|
|
76
71
|
} catch (error) {
|
|
77
72
|
if (error.rejected && kind !== 'force pushing') {
|
|
78
|
-
|
|
73
|
+
ui.mode = 'confirmPush';
|
|
79
74
|
} else {
|
|
80
|
-
|
|
75
|
+
ui.status = error.message;
|
|
81
76
|
}
|
|
82
77
|
} finally {
|
|
83
78
|
clearBusy();
|
|
@@ -86,25 +81,17 @@ const createOpsRunner = (options) => {
|
|
|
86
81
|
finishBusy(done, after);
|
|
87
82
|
};
|
|
88
83
|
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
return stateView(
|
|
85
|
+
state,
|
|
86
|
+
{
|
|
87
|
+
reset,
|
|
88
|
+
setBusy,
|
|
89
|
+
clearBusy,
|
|
90
|
+
runRepo,
|
|
91
|
+
runBusy,
|
|
92
92
|
},
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
get busy() {
|
|
97
|
-
return state.busy;
|
|
98
|
-
},
|
|
99
|
-
set busy(value) {
|
|
100
|
-
state.busy = value;
|
|
101
|
-
},
|
|
102
|
-
reset,
|
|
103
|
-
setBusy,
|
|
104
|
-
clearBusy,
|
|
105
|
-
runRepo,
|
|
106
|
-
runBusy,
|
|
107
|
-
};
|
|
93
|
+
['gitBusy', 'busy'],
|
|
94
|
+
);
|
|
108
95
|
};
|
|
109
96
|
|
|
110
97
|
module.exports = { ASYNC_WITHOUT_UI, pickRepoWrite, createOpsRunner };
|
package/lib/session/pointer.js
CHANGED
|
@@ -2,50 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
const { extractText, isRange } = require('../select.js');
|
|
4
4
|
const { hitAction } = require('../keys.js');
|
|
5
|
+
const { copyText } = require('../clipboard.js');
|
|
5
6
|
|
|
6
|
-
const mouseCell = (
|
|
7
|
-
const size =
|
|
7
|
+
const mouseCell = (ui, event) => {
|
|
8
|
+
const size = ui.lastSize ?? ui.getSize();
|
|
8
9
|
const x = Math.min(Math.max(1, event.x), size.width);
|
|
9
10
|
const y = Math.min(Math.max(1, event.y), size.height);
|
|
10
11
|
return { x, y };
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
const onPress = (
|
|
14
|
-
const nav =
|
|
15
|
-
const cell = mouseCell(
|
|
14
|
+
const onPress = (ui, event) => {
|
|
15
|
+
const nav = ui.nav;
|
|
16
|
+
const cell = mouseCell(ui, event);
|
|
16
17
|
nav.mouseAnchor = cell;
|
|
17
18
|
nav.pendingClick = null;
|
|
18
19
|
nav.selection = null;
|
|
19
|
-
const frame =
|
|
20
|
+
const frame = ui.lastFrame;
|
|
20
21
|
if (frame && cell.y === frame.height) {
|
|
21
22
|
nav.pendingClick = hitAction(frame.buttons, cell.x - 1);
|
|
22
23
|
}
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
const onDrag = (
|
|
26
|
-
const nav =
|
|
26
|
+
const onDrag = (ui, event) => {
|
|
27
|
+
const nav = ui.nav;
|
|
27
28
|
if (!nav.mouseAnchor) return;
|
|
28
29
|
nav.pendingClick = null;
|
|
29
30
|
nav.selection = {
|
|
30
31
|
start: nav.mouseAnchor,
|
|
31
|
-
end: mouseCell(
|
|
32
|
+
end: mouseCell(ui, event),
|
|
32
33
|
};
|
|
33
34
|
};
|
|
34
35
|
|
|
35
|
-
const clickButton = (
|
|
36
|
-
const nav =
|
|
37
|
-
const frame =
|
|
36
|
+
const clickButton = (ui, cell, clickId) => {
|
|
37
|
+
const nav = ui.nav;
|
|
38
|
+
const frame = ui.lastFrame;
|
|
38
39
|
if (!clickId || !frame || isRange(nav.selection)) return false;
|
|
39
40
|
const id = hitAction(frame.buttons, cell.x - 1);
|
|
40
41
|
if (id === clickId && cell.y === frame.height) {
|
|
41
|
-
|
|
42
|
+
ui.dispatch(id);
|
|
42
43
|
}
|
|
43
44
|
nav.selection = null;
|
|
44
45
|
return true;
|
|
45
46
|
};
|
|
46
47
|
|
|
47
|
-
const clickHit = (
|
|
48
|
-
const nav =
|
|
48
|
+
const clickHit = (ui, hits, cell, onHit) => {
|
|
49
|
+
const nav = ui.nav;
|
|
49
50
|
if (!hits || isRange(nav.selection)) return false;
|
|
50
51
|
const x = cell.x - 1;
|
|
51
52
|
const hit = hits.find((row) => {
|
|
@@ -54,101 +55,104 @@ const clickHit = (options, hits, cell, onHit) => {
|
|
|
54
55
|
return x >= row.x0 && x < row.x1;
|
|
55
56
|
});
|
|
56
57
|
if (!hit) return false;
|
|
57
|
-
onHit(
|
|
58
|
+
onHit(ui, hit);
|
|
58
59
|
nav.selection = null;
|
|
59
60
|
return true;
|
|
60
61
|
};
|
|
61
62
|
|
|
62
|
-
const copySelection = (
|
|
63
|
-
const nav =
|
|
64
|
-
const frame =
|
|
63
|
+
const copySelection = (ui) => {
|
|
64
|
+
const nav = ui.nav;
|
|
65
|
+
const frame = ui.lastFrame;
|
|
65
66
|
if (!isRange(nav.selection) || !frame) return;
|
|
66
67
|
const text = extractText(frame.rows, nav.selection);
|
|
67
68
|
if (!text) return;
|
|
68
|
-
const ok =
|
|
69
|
-
|
|
69
|
+
const ok = copyText(text, ui.stdout);
|
|
70
|
+
ui.status = ok ? 'copied' : 'copy failed';
|
|
70
71
|
};
|
|
71
72
|
|
|
72
73
|
const RELEASE_TARGETS = [
|
|
73
74
|
{
|
|
74
75
|
match: () => true,
|
|
75
76
|
hits: 'statusHits',
|
|
76
|
-
onHit: (
|
|
77
|
-
if (hit.id === 'branch')
|
|
78
|
-
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
options.confirmChoice(hit.id);
|
|
77
|
+
onHit: (ui, hit) => {
|
|
78
|
+
if (hit.id === 'branch') return void ui.gitBranches.onBranch();
|
|
79
|
+
ui.input.confirmChoice(hit.id);
|
|
82
80
|
},
|
|
83
81
|
},
|
|
84
82
|
{
|
|
85
|
-
match: (
|
|
83
|
+
match: (ui) => ui.pane === 'files',
|
|
86
84
|
hits: 'fileHits',
|
|
87
|
-
onHit: (
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
onHit: (ui, hit) => {
|
|
86
|
+
ui.nav.fileCursor = hit.cursor;
|
|
87
|
+
ui.filesPane.onOpenFile();
|
|
90
88
|
},
|
|
91
89
|
},
|
|
92
90
|
{
|
|
93
|
-
match: (
|
|
91
|
+
match: (ui) => ui.pane === 'branches',
|
|
94
92
|
hits: 'fileHits',
|
|
95
|
-
onHit: (
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
onHit: (ui, hit) => {
|
|
94
|
+
ui.nav.branchCursor = hit.cursor;
|
|
95
|
+
ui.gitBranches.onCheckoutBranch();
|
|
98
96
|
},
|
|
99
97
|
},
|
|
100
98
|
{
|
|
101
|
-
match: (
|
|
99
|
+
match: (ui) => ui.pane === 'commits',
|
|
100
|
+
hits: 'fileHits',
|
|
101
|
+
onHit: (ui, hit) => {
|
|
102
|
+
ui.nav.commitCursor = hit.cursor;
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
match: (ui) => ui.pane === 'diff',
|
|
102
107
|
hits: 'todoHits',
|
|
103
|
-
onHit: (
|
|
108
|
+
onHit: (ui, hit) => ui.composer.onTodoHit(hit.cursor),
|
|
104
109
|
},
|
|
105
110
|
{
|
|
106
|
-
match: (
|
|
111
|
+
match: (ui) => ui.mode === 'compose',
|
|
107
112
|
hits: 'templateHits',
|
|
108
|
-
onHit: (
|
|
113
|
+
onHit: (ui, hit) => ui.selectTemplate(hit.cursor),
|
|
109
114
|
},
|
|
110
115
|
];
|
|
111
116
|
|
|
112
|
-
const onRelease = (
|
|
113
|
-
const nav =
|
|
114
|
-
const cell = mouseCell(
|
|
117
|
+
const onRelease = (ui, event) => {
|
|
118
|
+
const nav = ui.nav;
|
|
119
|
+
const cell = mouseCell(ui, event);
|
|
115
120
|
if (nav.mouseAnchor) {
|
|
116
121
|
nav.selection = { start: nav.mouseAnchor, end: cell };
|
|
117
122
|
}
|
|
118
123
|
const clickId = nav.pendingClick;
|
|
119
124
|
nav.pendingClick = null;
|
|
120
125
|
nav.mouseAnchor = null;
|
|
121
|
-
if (clickButton(
|
|
122
|
-
const frame =
|
|
126
|
+
if (clickButton(ui, cell, clickId)) return;
|
|
127
|
+
const frame = ui.lastFrame;
|
|
123
128
|
for (const target of RELEASE_TARGETS) {
|
|
124
|
-
if (!target.match(
|
|
129
|
+
if (!target.match(ui)) continue;
|
|
125
130
|
const hits = frame?.[target.hits];
|
|
126
|
-
const opened = clickHit(
|
|
131
|
+
const opened = clickHit(ui, hits, cell, target.onHit);
|
|
127
132
|
if (opened) return;
|
|
128
133
|
}
|
|
129
|
-
copySelection(
|
|
134
|
+
copySelection(ui);
|
|
130
135
|
};
|
|
131
136
|
|
|
132
137
|
const POINTER_HANDLERS = {
|
|
133
|
-
wheelUp: (
|
|
134
|
-
wheelDown: (
|
|
138
|
+
wheelUp: (ui) => ui.filesPane.onScroll(-1),
|
|
139
|
+
wheelDown: (ui) => ui.filesPane.onScroll(1),
|
|
135
140
|
press: onPress,
|
|
136
141
|
drag: onDrag,
|
|
137
142
|
release: onRelease,
|
|
138
143
|
};
|
|
139
144
|
|
|
140
|
-
const handle = (
|
|
145
|
+
const handle = (ui, event) => {
|
|
141
146
|
const kind = event.kind;
|
|
142
147
|
const handler = POINTER_HANDLERS[kind];
|
|
143
148
|
if (!handler) return;
|
|
144
149
|
const isWheel = kind === 'wheelUp' || kind === 'wheelDown';
|
|
145
150
|
if (!isWheel && event.btn !== 0 && event.btn !== undefined) return;
|
|
146
|
-
handler(
|
|
151
|
+
handler(ui, event);
|
|
147
152
|
};
|
|
148
153
|
|
|
149
|
-
const createPointer = (
|
|
150
|
-
handle: (event) => handle(
|
|
151
|
-
mouseCell: (event) => mouseCell(options, event),
|
|
154
|
+
const createPointer = (ui) => ({
|
|
155
|
+
handle: (event) => handle(ui, event),
|
|
152
156
|
});
|
|
153
157
|
|
|
154
158
|
module.exports = { createPointer };
|
package/lib/session/review.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { createStore, applyImportedNotes, setStatus } = store;
|
|
5
|
-
const storage = require('../review/storage.js');
|
|
6
|
-
const { listReviewNames, loadTemplates, resolveReviewPath } = storage;
|
|
7
|
-
const { loadReview, flushReview } = storage;
|
|
3
|
+
const { stateView } = require('./accessors.js');
|
|
8
4
|
|
|
9
|
-
const
|
|
10
|
-
|
|
5
|
+
const review = require('../review.js');
|
|
6
|
+
const { createStore, applyImportedNotes, setStatus } = review;
|
|
7
|
+
const { listReviewNames, loadTemplates, resolveReviewPath } = review;
|
|
8
|
+
const { loadReview, flushReview } = review;
|
|
9
|
+
|
|
10
|
+
const createReviewController = () => {
|
|
11
11
|
const state = {
|
|
12
12
|
store: null,
|
|
13
13
|
didResume: false,
|
|
@@ -21,15 +21,11 @@ const createReviewController = (options) => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const init = (dir, date, extra = {}) => {
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const resolved = resolveReviewPath(dir, date, names, {
|
|
28
|
-
forceNew,
|
|
29
|
-
readFileSync: io.readFileSync,
|
|
30
|
-
});
|
|
24
|
+
const names = listReviewNames(dir);
|
|
25
|
+
const templates = loadTemplates(dir);
|
|
26
|
+
const resolved = resolveReviewPath(dir, date, names, extra);
|
|
31
27
|
if (resolved.resume) {
|
|
32
|
-
state.store = loadReview(resolved.reviewPath, templates
|
|
28
|
+
state.store = loadReview(resolved.reviewPath, templates);
|
|
33
29
|
state.didResume = true;
|
|
34
30
|
return state.store;
|
|
35
31
|
}
|
|
@@ -49,13 +45,7 @@ const createReviewController = (options) => {
|
|
|
49
45
|
const flush = (force = false) => {
|
|
50
46
|
if (!state.store) return { ok: true, wrote: false };
|
|
51
47
|
try {
|
|
52
|
-
const
|
|
53
|
-
const mkdirSync = io.mkdirSync;
|
|
54
|
-
const wrote = flushReview(state.store, {
|
|
55
|
-
writeFileSync,
|
|
56
|
-
mkdirSync,
|
|
57
|
-
force,
|
|
58
|
-
});
|
|
48
|
+
const wrote = flushReview(state.store, force);
|
|
59
49
|
return { ok: true, wrote };
|
|
60
50
|
} catch (error) {
|
|
61
51
|
return { ok: false, wrote: false, error };
|
|
@@ -67,22 +57,18 @@ const createReviewController = (options) => {
|
|
|
67
57
|
return flush();
|
|
68
58
|
};
|
|
69
59
|
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
return stateView(
|
|
61
|
+
state,
|
|
62
|
+
{
|
|
63
|
+
reset,
|
|
64
|
+
init,
|
|
65
|
+
applyImported,
|
|
66
|
+
flush,
|
|
67
|
+
finishQuit,
|
|
76
68
|
},
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
reset,
|
|
81
|
-
init,
|
|
82
|
-
applyImported,
|
|
83
|
-
flush,
|
|
84
|
-
finishQuit,
|
|
85
|
-
};
|
|
69
|
+
[],
|
|
70
|
+
['store', 'didResume', 'importedRemote'],
|
|
71
|
+
);
|
|
86
72
|
};
|
|
87
73
|
|
|
88
74
|
module.exports = { createReviewController };
|
package/lib/session/terminal.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { presentRows, presentCursor } = require('../render.js');
|
|
4
|
-
const { listen, watchResize } = require('../
|
|
3
|
+
const { presentRows, presentCursor } = require('../render/render.js');
|
|
4
|
+
const { listen, watchResize } = require('../utilities.js');
|
|
5
5
|
|
|
6
6
|
const ENTER_TERM = '\x1b[?1049h\x1b[?25l\x1b[?7l\x1b[?1002h\x1b[?1006h';
|
|
7
7
|
const LEAVE_TERM =
|
|
@@ -18,14 +18,16 @@ const hasTimer = (api, name) => api.timers.has(name);
|
|
|
18
18
|
const stopTimer = (api, name) => {
|
|
19
19
|
const id = api.timers.get(name);
|
|
20
20
|
if (id === undefined) return;
|
|
21
|
-
|
|
21
|
+
clearInterval(id);
|
|
22
22
|
api.timers.delete(name);
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const startTimer = (api, name, fn, ms) => {
|
|
26
26
|
if (api.state.disposed) return;
|
|
27
27
|
if (api.timers.has(name)) return;
|
|
28
|
-
|
|
28
|
+
const id = setInterval(fn, ms);
|
|
29
|
+
if (id && typeof id.unref === 'function') id.unref();
|
|
30
|
+
api.timers.set(name, id);
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
const restartTimer = (api, name, fn, ms) => {
|
|
@@ -118,8 +120,6 @@ const createTerminal = (options) => {
|
|
|
118
120
|
stdin: options.stdin ?? null,
|
|
119
121
|
stdout: options.stdout,
|
|
120
122
|
proc: options.proc ?? process,
|
|
121
|
-
setIntervalFn: options.setInterval ?? setInterval,
|
|
122
|
-
clearIntervalFn: options.clearInterval ?? clearInterval,
|
|
123
123
|
timers: new Map(),
|
|
124
124
|
disposers: [],
|
|
125
125
|
state,
|
|
@@ -131,18 +131,12 @@ const createTerminal = (options) => {
|
|
|
131
131
|
get lastSize() {
|
|
132
132
|
return state.lastSize;
|
|
133
133
|
},
|
|
134
|
-
get lastPresentedCursor() {
|
|
135
|
-
return state.lastPresentedCursor;
|
|
136
|
-
},
|
|
137
134
|
get carry() {
|
|
138
135
|
return state.carry;
|
|
139
136
|
},
|
|
140
137
|
set carry(value) {
|
|
141
138
|
state.carry = value;
|
|
142
139
|
},
|
|
143
|
-
get isOpen() {
|
|
144
|
-
return state.open;
|
|
145
|
-
},
|
|
146
140
|
get disposed() {
|
|
147
141
|
return state.disposed;
|
|
148
142
|
},
|
package/lib/session/todos.js
CHANGED
|
@@ -48,17 +48,19 @@ const isDraftCompose = (api) => {
|
|
|
48
48
|
const todoTexts = (api) => {
|
|
49
49
|
const nav = api.nav;
|
|
50
50
|
if (!nav.todoOpen) return [];
|
|
51
|
-
const
|
|
51
|
+
const todos = listTodos(api);
|
|
52
|
+
const texts = new Array(todos.length + 1);
|
|
52
53
|
const { state } = api;
|
|
53
54
|
const editingTodo = state.composeKind === 'todo';
|
|
54
55
|
const editingId = editingTodo ? state.composeTodoId : null;
|
|
55
|
-
for (
|
|
56
|
+
for (let i = 0; i < todos.length; i++) {
|
|
57
|
+
const todo = todos[i];
|
|
56
58
|
const live = editingId === todo.id && state.editor;
|
|
57
59
|
const text = live ? state.editor.text : todo.text;
|
|
58
|
-
texts
|
|
60
|
+
texts[i] = checkLabel(text, todo.done);
|
|
59
61
|
}
|
|
60
62
|
const draft = isDraftCompose(api) && state.editor ? state.editor.text : '';
|
|
61
|
-
texts.
|
|
63
|
+
texts[todos.length] = checkLabel(draft, false);
|
|
62
64
|
return texts;
|
|
63
65
|
};
|
|
64
66
|
|
|
@@ -126,10 +128,7 @@ const editFocusedTodo = (api) => {
|
|
|
126
128
|
if (!api.nav.todoOpen) return;
|
|
127
129
|
const todos = listTodos(api);
|
|
128
130
|
const todo = todos[clampedTodoFocus(api)];
|
|
129
|
-
if (!todo)
|
|
130
|
-
startDraftCompose(api);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
131
|
+
if (!todo) return void startDraftCompose(api);
|
|
133
132
|
api.open('todo', todo.text, todo.id);
|
|
134
133
|
};
|
|
135
134
|
|
|
@@ -234,10 +233,7 @@ const commitTodo = (api, text) => {
|
|
|
234
233
|
const id = api.state.composeTodoId;
|
|
235
234
|
const todos = notes.todos;
|
|
236
235
|
const prev = id === null ? null : todos.find((entry) => entry.id === id);
|
|
237
|
-
if (prev)
|
|
238
|
-
setTodoText(notes, id, text);
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
236
|
+
if (prev) return void setTodoText(notes, id, text);
|
|
241
237
|
if (!text.trim()) return;
|
|
242
238
|
const todo = addTodo(notes, TODO_FILE, text);
|
|
243
239
|
api.state.composeTodoId = todo.id;
|