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.
Files changed (105) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/LICENSE +1 -1
  3. package/README.md +11 -11
  4. package/bin/reslop.js +3 -8
  5. package/lib/ansi.js +32 -19
  6. package/lib/capabilities.js +8 -8
  7. package/lib/cli.js +40 -74
  8. package/lib/clipboard.js +39 -47
  9. package/lib/dashboard/git.js +128 -0
  10. package/lib/dashboard/model.js +332 -0
  11. package/lib/dashboard/npm.js +193 -0
  12. package/lib/dashboard/tree.js +278 -0
  13. package/lib/deps-diff.js +197 -402
  14. package/lib/deps.js +113 -240
  15. package/lib/detect.js +8 -18
  16. package/lib/diff/align.js +41 -113
  17. package/lib/diff/diff.js +12 -43
  18. package/lib/diff/display.js +25 -36
  19. package/lib/diff/edit.js +6 -20
  20. package/lib/diff/inline.js +76 -144
  21. package/lib/diff/items.js +33 -47
  22. package/lib/diff/parse.js +28 -56
  23. package/lib/diff/patch.js +12 -33
  24. package/lib/diff/unit.js +79 -178
  25. package/lib/editor.js +52 -69
  26. package/lib/files.js +71 -89
  27. package/lib/git-branches.js +254 -416
  28. package/lib/git-deps.js +147 -272
  29. package/lib/git-reword-todo.js +5 -13
  30. package/lib/git-worktree.js +141 -212
  31. package/lib/git.js +21 -49
  32. package/lib/github.js +67 -181
  33. package/lib/gitlab.js +40 -90
  34. package/lib/highlight/bash.js +55 -177
  35. package/lib/highlight/core.js +155 -141
  36. package/lib/highlight/css.js +25 -58
  37. package/lib/highlight/csv.js +19 -37
  38. package/lib/highlight/dart.js +72 -213
  39. package/lib/highlight/dot.js +14 -14
  40. package/lib/highlight/html.js +42 -63
  41. package/lib/highlight/js.js +177 -506
  42. package/lib/highlight/json.js +17 -37
  43. package/lib/highlight/log.js +19 -25
  44. package/lib/highlight/txt.js +7 -10
  45. package/lib/highlight.js +17 -46
  46. package/lib/keys.js +49 -82
  47. package/lib/manifest.js +67 -126
  48. package/lib/npm-commands.js +120 -169
  49. package/lib/remote.js +140 -190
  50. package/lib/render/branches.js +63 -61
  51. package/lib/render/chrome.js +220 -333
  52. package/lib/render/commits.js +160 -361
  53. package/lib/render/dash-activity.js +212 -0
  54. package/lib/render/dash-blocks.js +245 -0
  55. package/lib/render/dash-table.js +290 -0
  56. package/lib/render/dashboard.js +62 -0
  57. package/lib/render/diff.js +123 -258
  58. package/lib/render/files.js +40 -85
  59. package/lib/render/frame.js +78 -117
  60. package/lib/render/notes.js +139 -210
  61. package/lib/render/npm.js +213 -177
  62. package/lib/render/present.js +4 -11
  63. package/lib/render/primitives.js +72 -174
  64. package/lib/render/render.js +5 -14
  65. package/lib/render/report.js +43 -0
  66. package/lib/render/tiles.js +260 -0
  67. package/lib/render/unit.js +15 -31
  68. package/lib/report-model.js +110 -33
  69. package/lib/report-parse.js +56 -37
  70. package/lib/report-render.js +102 -59
  71. package/lib/report-run.js +87 -77
  72. package/lib/report-test.js +221 -99
  73. package/lib/report-tools.js +96 -154
  74. package/lib/review-merge.js +33 -41
  75. package/lib/review.js +68 -129
  76. package/lib/runs.js +225 -0
  77. package/lib/select.js +53 -91
  78. package/lib/session/accessors.js +14 -21
  79. package/lib/session/actions.js +61 -43
  80. package/lib/session/branches.js +166 -222
  81. package/lib/session/change-actions.js +49 -119
  82. package/lib/session/commit.js +274 -355
  83. package/lib/session/compose.js +556 -714
  84. package/lib/session/dashboard.js +385 -0
  85. package/lib/session/dispatch.js +162 -170
  86. package/lib/session/files-pane.js +76 -44
  87. package/lib/session/items.js +6 -17
  88. package/lib/session/lifecycle.js +393 -466
  89. package/lib/session/load.js +1 -14
  90. package/lib/session/navigation.js +2 -2
  91. package/lib/session/npm.js +403 -420
  92. package/lib/session/ops.js +5 -13
  93. package/lib/session/pointer.js +16 -14
  94. package/lib/session/progress.js +39 -30
  95. package/lib/session/review.js +1 -3
  96. package/lib/session/tasks.js +276 -235
  97. package/lib/session/templates.js +51 -59
  98. package/lib/session/terminal.js +85 -132
  99. package/lib/session/view.js +47 -81
  100. package/lib/session/watch.js +196 -212
  101. package/lib/session.js +81 -161
  102. package/lib/update.js +44 -111
  103. package/lib/utilities.js +46 -88
  104. package/lib/wrap.js +29 -55
  105. package/package.json +1 -1
@@ -1,256 +1,200 @@
1
1
  'use strict';
2
2
 
3
- const accessors = require('./accessors.js');
4
- const { stateView } = accessors;
5
-
6
3
  const ops = require('./ops.js');
7
4
  const { pickRepoWrite } = ops;
8
5
 
9
- const selectedBranch = (api) => {
10
- const cursor = api.ui.nav.branchCursor;
11
- return api.state.branches[cursor];
12
- };
13
-
14
- const refreshBranchList = (api) => {
15
- const repo = api.ui.repo;
16
- if (!repo.listBranches) return;
17
- try {
18
- api.state.branches = repo.listBranches(api.ui.top);
19
- } catch (error) {
20
- api.ui.status = error.message;
21
- return;
6
+ class BranchController {
7
+ constructor(ui) {
8
+ this.ui = ui;
9
+ this.reset();
22
10
  }
23
- const last = api.state.branches.length - 1;
24
- const nav = api.ui.nav;
25
- if (nav.branchCursor > last) nav.branchCursor = Math.max(0, last);
26
- };
27
11
 
28
- const refreshAfterWrite = (api, extra = {}) => {
29
- refreshBranchList(api);
30
- api.ui.commits.refresh();
31
- api.ui.refreshFromRepo({ keepEmpty: true, ...extra });
32
- };
12
+ reset() {
13
+ this.branches = [];
14
+ this.dropName = '';
15
+ }
33
16
 
34
- const onBranch = (api) => {
35
- if (api.ui.mode === 'compose') return;
36
- if (!api.ui.commits.canCommit()) return;
37
- const repo = api.ui.repo;
38
- const caps = api.ui.capabilities;
39
- if (!caps.branches || !repo.listBranches) {
40
- api.ui.status = 'read only';
41
- return;
17
+ selected() {
18
+ return this.branches[this.ui.nav.branchCursor];
42
19
  }
43
- try {
44
- api.state.branches = repo.listBranches(api.ui.top);
45
- } catch (error) {
46
- api.ui.status = error.message;
47
- return;
20
+
21
+ canWrite() {
22
+ return this.ui.nav.pane === 'branches' && this.ui.commits.canCommit();
48
23
  }
49
- const current = api.state.branches.findIndex((entry) => entry.current);
50
- const nav = api.ui.nav;
51
- nav.branchCursor = current < 0 ? 0 : current;
52
- nav.pane = 'branches';
53
- nav.resetListScroll('branches');
54
- api.ui.status = '';
55
- nav.clearSelection();
56
- };
57
24
 
58
- const onBranchMove = (api, delta) => {
59
- const branches = api.state.branches;
60
- if (!branches.length) {
61
- api.ui.status = 'nothing to review';
62
- return;
25
+ loadBranches() {
26
+ const ui = this.ui;
27
+ try {
28
+ this.branches = ui.repo.listBranches(ui.top);
29
+ return true;
30
+ } catch (error) {
31
+ ui.status = error.message;
32
+ return false;
33
+ }
63
34
  }
64
- const next = Math.min(
65
- branches.length - 1,
66
- Math.max(0, api.ui.nav.branchCursor + delta),
67
- );
68
- if (next === api.ui.nav.branchCursor) return;
69
- api.ui.nav.branchCursor = next;
70
- api.ui.status = '';
71
- };
72
35
 
73
- const checkoutAsync = (api, name, done, write) => {
74
- api.ui.showFiles();
75
- const run = (top) => write(top, name);
76
- const after = () =>
77
- api.ui.refreshFromRepo({ keepEmpty: true, doneStatus: done });
78
- return void api.ui.ops.runBusy('checking out', done, run, after);
79
- };
36
+ refreshAfterWrite(extra = {}) {
37
+ if (this.ui.repo.listBranches && this.loadBranches()) {
38
+ const last = this.branches.length - 1;
39
+ const nav = this.ui.nav;
40
+ if (nav.branchCursor > last) nav.branchCursor = Math.max(0, last);
41
+ }
42
+ this.ui.commits.refresh();
43
+ this.ui.refreshFromRepo({ keepEmpty: true, ...extra });
44
+ }
80
45
 
81
- const onCheckoutBranch = (api) => {
82
- if (!api.ui.commits.canCommit()) return;
83
- const entry = selectedBranch(api);
84
- if (!entry) return;
85
- if (entry.current) return void api.ui.showFiles();
86
- const name = entry.name;
87
- const done = `checked out ${name}`;
88
- const uiOpen = api.ui.uiOpen;
89
- const picked = pickRepoWrite(api.ui.repo, 'checkout', uiOpen);
90
- if (picked.async) {
91
- return void checkoutAsync(api, name, done, picked.write);
46
+ runWrite(name, args, kind, done) {
47
+ const after = (extra) => this.refreshAfterWrite(extra);
48
+ this.ui.ops.runWrite(name, args, kind, done, after);
92
49
  }
93
- const ok = api.ui.ops.runRepo(done, (top) => {
94
- api.ui.repo.checkout(top, name);
95
- });
96
- if (!ok) return;
97
- api.ui.showFiles();
98
- api.ui.refreshFromRepo({ keepEmpty: true });
99
- if (!api.ui.status) api.ui.status = done;
100
- };
101
50
 
102
- const onRebaseBranch = (api) => {
103
- if (api.ui.nav.pane !== 'branches') return;
104
- if (!api.ui.commits.canCommit()) return;
105
- const entry = selectedBranch(api);
106
- if (!entry || entry.current) return;
107
- const onto = entry.name;
108
- const done = `rebased onto ${onto}`;
109
- api.ui.ops.runWrite('rebase', [onto], 'rebasing', done, (extra) =>
110
- refreshAfterWrite(api, extra),
111
- );
112
- };
51
+ onBranch() {
52
+ const ui = this.ui;
53
+ if (ui.mode === 'compose') return;
54
+ if (!ui.commits.canCommit()) return;
55
+ if (!ui.capabilities.branches || !ui.repo.listBranches) {
56
+ ui.status = 'read only';
57
+ return;
58
+ }
59
+ if (!this.loadBranches()) return;
60
+ const current = this.branches.findIndex((entry) => entry.current);
61
+ const nav = ui.nav;
62
+ nav.branchCursor = current < 0 ? 0 : current;
63
+ nav.pane = 'branches';
64
+ nav.resetListScroll('branches');
65
+ ui.status = '';
66
+ nav.clearSelection();
67
+ }
113
68
 
114
- const onDropBranch = (api) => {
115
- if (api.ui.nav.pane !== 'branches') return;
116
- if (!api.ui.commits.canCommit()) return;
117
- const entry = selectedBranch(api);
118
- if (!entry || entry.current) return;
119
- api.state.dropName = entry.name;
120
- api.ui.mode = 'confirmDrop';
121
- api.ui.status = '';
122
- };
69
+ onBranchMove(delta) {
70
+ const nav = this.ui.nav;
71
+ if (!this.branches.length) {
72
+ this.ui.status = 'nothing to review';
73
+ return;
74
+ }
75
+ const last = this.branches.length - 1;
76
+ const next = Math.min(last, Math.max(0, nav.branchCursor + delta));
77
+ if (next === nav.branchCursor) return;
78
+ nav.branchCursor = next;
79
+ this.ui.status = '';
80
+ }
123
81
 
124
- const cancelDropBranch = (api) => {
125
- api.ui.mode = 'review';
126
- api.state.dropName = '';
127
- api.ui.status = '';
128
- };
82
+ onCheckoutBranch() {
83
+ const ui = this.ui;
84
+ if (!ui.commits.canCommit()) return;
85
+ const entry = this.selected();
86
+ if (!entry) return;
87
+ if (entry.current) return void ui.showFiles();
88
+ const name = entry.name;
89
+ const after = (extra) => ui.refreshFromRepo({ keepEmpty: true, ...extra });
90
+ const leave = () => ui.showFiles();
91
+ const done = `checked out ${name}`;
92
+ ui.ops.runWrite('checkout', [name], 'checking out', done, after, leave);
93
+ }
129
94
 
130
- const confirmDropBranch = (api) => {
131
- const name = api.state.dropName;
132
- api.ui.mode = 'review';
133
- api.state.dropName = '';
134
- if (!name) return;
135
- const done = `dropped ${name}`;
136
- api.ui.ops.runWrite('drop', [name], 'dropping', done, (extra) =>
137
- refreshAfterWrite(api, extra),
138
- );
139
- };
95
+ finishCreateBranch() {
96
+ const ui = this.ui;
97
+ const editor = ui.composer.editor;
98
+ const name = editor ? editor.text.trim() : '';
99
+ if (!name) {
100
+ ui.status = 'empty branch name';
101
+ return;
102
+ }
103
+ const after = (extra) => this.refreshAfterWrite(extra);
104
+ const leave = () => {
105
+ ui.composer.closeCompose();
106
+ ui.showFiles();
107
+ };
108
+ const done = `created ${name}`;
109
+ ui.ops.runWrite(
110
+ 'createBranch',
111
+ [name],
112
+ 'creating branch',
113
+ done,
114
+ after,
115
+ leave,
116
+ );
117
+ }
140
118
 
141
- const onNewBranch = (api) => {
142
- if (api.ui.nav.pane !== 'branches') return;
143
- if (!api.ui.commits.canCommit()) return;
144
- api.ui.composer.openCompose('branch', '');
145
- };
119
+ onRebaseBranch() {
120
+ if (!this.canWrite()) return;
121
+ const entry = this.selected();
122
+ if (!entry || entry.current) return;
123
+ const onto = entry.name;
124
+ this.runWrite('rebase', [onto], 'rebasing', `rebased onto ${onto}`);
125
+ }
146
126
 
147
- const createAsync = (api, name, done, write) => {
148
- api.ui.composer.closeCompose();
149
- api.ui.showFiles();
150
- const run = (top) => write(top, name);
151
- const after = () => refreshAfterWrite(api, { doneStatus: done });
152
- return void api.ui.ops.runBusy('creating branch', done, run, after);
153
- };
127
+ onDropBranch() {
128
+ if (!this.canWrite()) return;
129
+ const entry = this.selected();
130
+ if (!entry || entry.current) return;
131
+ this.dropName = entry.name;
132
+ this.ui.mode = 'confirmDrop';
133
+ this.ui.status = '';
134
+ }
154
135
 
155
- const finishCreateBranch = (api) => {
156
- const editor = api.ui.composer.state.editor;
157
- const name = editor ? editor.text.trim() : '';
158
- if (!name) {
159
- api.ui.status = 'empty branch name';
160
- return;
136
+ cancelDropBranch() {
137
+ this.ui.mode = 'review';
138
+ this.dropName = '';
139
+ this.ui.status = '';
161
140
  }
162
- const done = `created ${name}`;
163
- const uiOpen = api.ui.uiOpen;
164
- const picked = pickRepoWrite(api.ui.repo, 'createBranch', uiOpen);
165
- if (picked.async) {
166
- return void createAsync(api, name, done, picked.write);
141
+
142
+ confirmDropBranch() {
143
+ const name = this.dropName;
144
+ this.ui.mode = 'review';
145
+ this.dropName = '';
146
+ if (name) this.runWrite('drop', [name], 'dropping', `dropped ${name}`);
167
147
  }
168
- const ok = api.ui.ops.runRepo(done, (top) => {
169
- api.ui.repo.createBranch(top, name);
170
- });
171
- if (!ok) return;
172
- api.ui.composer.closeCompose();
173
- api.ui.showFiles();
174
- refreshAfterWrite(api);
175
- if (!api.ui.status) api.ui.status = done;
176
- };
177
148
 
178
- const onPull = (api) => {
179
- if (!api.ui.commits.canCommit()) return;
180
- api.ui.ops.runWrite('pull', [], 'pulling', 'pulled', (extra) =>
181
- refreshAfterWrite(api, extra),
182
- );
183
- };
149
+ onNewBranch() {
150
+ if (this.canWrite()) this.ui.composer.openCompose('branch', '');
151
+ }
184
152
 
185
- const startPush = (api, force) => {
186
- if (!api.ui.commits.canCommit()) return;
187
- const done = force ? 'force pushed' : 'pushed';
188
- const kind = force ? 'force pushing' : 'pushing';
189
- const repo = api.ui.repo;
190
- const picked = pickRepoWrite(repo, 'push', api.ui.uiOpen);
191
- if (picked.async) {
192
- const write = (top) => picked.write(top, force);
193
- const after = () => refreshAfterWrite(api);
194
- return void api.ui.ops.runBusy(kind, done, write, after);
153
+ onPull() {
154
+ if (this.ui.commits.canCommit()) {
155
+ this.runWrite('pull', [], 'pulling', 'pulled');
156
+ }
195
157
  }
196
- try {
197
- repo.push(api.ui.top, force);
198
- } catch (error) {
199
- if (error.rejected && !force) {
200
- api.ui.mode = 'confirmPush';
201
- api.ui.status = '';
158
+
159
+ startPush(force) {
160
+ const ui = this.ui;
161
+ if (!ui.commits.canCommit()) return;
162
+ const done = force ? 'force pushed' : 'pushed';
163
+ const kind = force ? 'force pushing' : 'pushing';
164
+ const picked = pickRepoWrite(ui.repo, 'push', ui.uiOpen);
165
+ if (picked.async) {
166
+ const write = (top) => picked.write(top, force);
167
+ const after = () => this.refreshAfterWrite();
168
+ return void ui.ops.runBusy(kind, done, write, after);
169
+ }
170
+ try {
171
+ ui.repo.push(ui.top, force);
172
+ } catch (error) {
173
+ if (error.rejected && !force) {
174
+ ui.mode = 'confirmPush';
175
+ ui.status = '';
176
+ return;
177
+ }
178
+ ui.status = error.message;
202
179
  return;
203
180
  }
204
- api.ui.status = error.message;
205
- return;
181
+ this.refreshAfterWrite();
182
+ ui.status = done;
206
183
  }
207
- refreshAfterWrite(api);
208
- api.ui.status = done;
209
- };
210
-
211
- const onPush = (api) => startPush(api, false);
212
-
213
- const onForcePush = (api) => {
214
- api.ui.mode = 'review';
215
- startPush(api, true);
216
- };
217
184
 
218
- const cancelPush = (api) => {
219
- api.ui.mode = 'review';
220
- api.ui.status = '';
221
- };
185
+ onPush() {
186
+ this.startPush(false);
187
+ }
222
188
 
223
- const reset = (state) => {
224
- state.branches = [];
225
- state.dropName = '';
226
- };
189
+ onForcePush() {
190
+ this.ui.mode = 'review';
191
+ this.startPush(true);
192
+ }
227
193
 
228
- const createBranchController = (ui) => {
229
- const state = {
230
- branches: [],
231
- dropName: '',
232
- };
233
- const api = { ui, state };
234
- return stateView(
235
- state,
236
- {
237
- reset: () => reset(state),
238
- onBranch: () => onBranch(api),
239
- onBranchMove: (delta) => onBranchMove(api, delta),
240
- onCheckoutBranch: () => onCheckoutBranch(api),
241
- onRebaseBranch: () => onRebaseBranch(api),
242
- onDropBranch: () => onDropBranch(api),
243
- cancelDropBranch: () => cancelDropBranch(api),
244
- confirmDropBranch: () => confirmDropBranch(api),
245
- onNewBranch: () => onNewBranch(api),
246
- finishCreateBranch: () => finishCreateBranch(api),
247
- onPull: () => onPull(api),
248
- onPush: () => onPush(api),
249
- onForcePush: () => onForcePush(api),
250
- cancelPush: () => cancelPush(api),
251
- },
252
- ['branches', 'dropName'],
253
- );
254
- };
194
+ cancelPush() {
195
+ this.ui.mode = 'review';
196
+ this.ui.status = '';
197
+ }
198
+ }
255
199
 
256
- module.exports = { createBranchController };
200
+ module.exports = { BranchController };