reslop 0.2.5 → 0.2.7

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