reslop 0.1.9 → 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.
Files changed (96) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/README.md +3 -1
  3. package/bin/reslop.js +2 -2
  4. package/lib/ansi.js +148 -5
  5. package/lib/api.js +4 -2
  6. package/lib/capabilities.js +13 -14
  7. package/lib/cli.js +38 -49
  8. package/lib/clipboard.js +1 -1
  9. package/lib/{deps/changes.js → deps-diff.js} +309 -19
  10. package/lib/deps.js +498 -29
  11. package/lib/detect.js +1 -7
  12. package/lib/diff/align.js +7 -10
  13. package/lib/diff/diff.js +53 -0
  14. package/lib/diff/display.js +5 -4
  15. package/lib/diff/inline.js +26 -21
  16. package/lib/diff/items.js +6 -4
  17. package/lib/diff/patch.js +1 -3
  18. package/lib/diff/unit.js +392 -0
  19. package/lib/files.js +5 -8
  20. package/lib/{git/branches.js → git-branches.js} +191 -11
  21. package/lib/{git/dependencies.js → git-deps.js} +111 -38
  22. package/lib/git-reword-todo.js +20 -0
  23. package/lib/git.js +606 -68
  24. package/lib/github.js +28 -197
  25. package/lib/gitlab.js +24 -195
  26. package/lib/highlight/bash.js +1 -3
  27. package/lib/highlight/css.js +1 -3
  28. package/lib/highlight/js.js +11 -14
  29. package/lib/highlight.js +6 -9
  30. package/lib/keys.js +14 -8
  31. package/lib/manifest.js +330 -0
  32. package/lib/remote.js +374 -0
  33. package/lib/render/branches.js +18 -100
  34. package/lib/render/chrome.js +71 -14
  35. package/lib/render/commits.js +69 -60
  36. package/lib/render/diff.js +20 -20
  37. package/lib/render/files.js +6 -34
  38. package/lib/render/frame.js +36 -13
  39. package/lib/render/notes.js +26 -8
  40. package/lib/render/primitives.js +99 -11
  41. package/lib/{render.js → render/render.js} +8 -8
  42. package/lib/render/unit.js +41 -0
  43. package/lib/review-merge.js +270 -0
  44. package/lib/review.js +782 -14
  45. package/lib/select.js +5 -10
  46. package/lib/session/accessors.js +9 -1
  47. package/lib/session/actions.js +61 -18
  48. package/lib/session/branches.js +116 -128
  49. package/lib/session/change-actions.js +202 -123
  50. package/lib/session/commit.js +201 -115
  51. package/lib/session/compose.js +181 -15
  52. package/lib/session/dispatch.js +110 -60
  53. package/lib/session/files-pane.js +156 -148
  54. package/lib/session/items.js +22 -30
  55. package/lib/session/lifecycle.js +151 -54
  56. package/lib/session/load.js +19 -33
  57. package/lib/session/navigation.js +12 -1
  58. package/lib/session/ops.js +28 -41
  59. package/lib/session/pointer.js +57 -57
  60. package/lib/session/review.js +23 -37
  61. package/lib/session/terminal.js +6 -12
  62. package/lib/session/todos.js +37 -13
  63. package/lib/session/unit.js +208 -0
  64. package/lib/session/update.js +33 -46
  65. package/lib/session/view.js +78 -9
  66. package/lib/session/watch.js +128 -24
  67. package/lib/session.js +22 -246
  68. package/lib/source.js +3 -3
  69. package/lib/update.js +40 -75
  70. package/lib/{git/proc.js → utilities.js} +75 -11
  71. package/lib/wrap.js +1 -3
  72. package/package.json +2 -2
  73. package/lib/deps/items.js +0 -134
  74. package/lib/deps/manifest.js +0 -152
  75. package/lib/deps/merge.js +0 -120
  76. package/lib/deps/proposals.js +0 -164
  77. package/lib/deps/reports.js +0 -180
  78. package/lib/deps/rows.js +0 -176
  79. package/lib/deps/scan.js +0 -138
  80. package/lib/deps/usage.js +0 -68
  81. package/lib/deps/versions.js +0 -119
  82. package/lib/diff.js +0 -33
  83. package/lib/git/changes.js +0 -164
  84. package/lib/git/read.js +0 -253
  85. package/lib/git/run.js +0 -100
  86. package/lib/npm/commands.js +0 -100
  87. package/lib/remote/changes.js +0 -37
  88. package/lib/remote/headers.js +0 -36
  89. package/lib/remote/http.js +0 -122
  90. package/lib/remote/notes.js +0 -94
  91. package/lib/review/format.js +0 -434
  92. package/lib/review/storage.js +0 -150
  93. package/lib/review/store.js +0 -178
  94. package/lib/review/templates.js +0 -49
  95. package/lib/session/origins.js +0 -7
  96. package/lib/sys.js +0 -84
package/lib/select.js CHANGED
@@ -145,8 +145,6 @@ const parseCells = (line) => {
145
145
 
146
146
  const rgbKey = (rgb) => (rgb ? `${rgb[0]},${rgb[1]},${rgb[2]}` : '');
147
147
 
148
- const styleKey = (fg, bg) => `${rgbKey(fg)}|${rgbKey(bg)}`;
149
-
150
148
  const styleSeq = (fg, bg) => {
151
149
  if (fg && bg) return RESET + seq(fg, bg);
152
150
  if (fg) return RESET + ansi.fg(fg);
@@ -169,7 +167,7 @@ const overlayRange = (line, fromCol, toCol) => {
169
167
  fg = cell.bg ?? THEME.ctxBg;
170
168
  bg = cell.fg ?? THEME.ctxFg;
171
169
  }
172
- const key = styleKey(fg, bg);
170
+ const key = `${rgbKey(fg)}|${rgbKey(bg)}`;
173
171
  if (key !== last) {
174
172
  out += styleSeq(fg, bg);
175
173
  last = key;
@@ -181,14 +179,11 @@ const overlayRange = (line, fromCol, toCol) => {
181
179
 
182
180
  const overlayRows = (rows, sel) => {
183
181
  if (!isRange(sel)) return rows;
184
- const next = [];
185
- for (let i = 0; i < rows.length; i++) {
182
+ const { length } = rows;
183
+ const next = new Array(length);
184
+ for (let i = 0; i < length; i++) {
186
185
  const range = lineRange(i, sel);
187
- if (!range) {
188
- next.push(rows[i]);
189
- continue;
190
- }
191
- next.push(overlayRange(rows[i], range.from, range.to));
186
+ next[i] = range ? overlayRange(rows[i], range.from, range.to) : rows[i];
192
187
  }
193
188
  return next;
194
189
  };
@@ -22,4 +22,12 @@ const bindGetters = (target, owner, names) => {
22
22
  }
23
23
  };
24
24
 
25
- module.exports = { bindAccessors, bindGetters, bindAlias };
25
+ const stateView = (state, methods, writable = [], readonly = []) => {
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 };
@@ -7,11 +7,14 @@ const ACTIONS = {
7
7
  commit: ['c'],
8
8
  prev: ['left', 'p', 'k'],
9
9
  next: ['right', 'n', 'j'],
10
+ check: ['x', ' '],
10
11
  layout: ['m'],
11
12
  feedback: ['f'],
12
13
  todo: ['t'],
13
14
  code: ['e'],
14
15
  branch: ['b'],
16
+ file: ['f'],
17
+ diff: ['d'],
15
18
  quit: ['q', 'ctrl-c'],
16
19
  };
17
20
  const ACTION_IDS = Object.keys(ACTIONS);
@@ -26,8 +29,12 @@ const BRANCH_ACTIONS = {
26
29
 
27
30
  const COMMIT_ACTIONS = {
28
31
  amend: ['a'],
32
+ apply: ['a'],
33
+ reword: ['r'],
29
34
  fixup: ['f'],
30
35
  drop: ['d'],
36
+ pull: ['p'],
37
+ push: ['s'],
31
38
  };
32
39
 
33
40
  const ACTION_HOT = {
@@ -37,6 +44,7 @@ const ACTION_HOT = {
37
44
 
38
45
  const ACTION_LABEL = {
39
46
  revert: 'drop',
47
+ check: 'x',
40
48
  layout: 'mode',
41
49
  code: 'edit',
42
50
  newBranch: 'new',
@@ -45,9 +53,26 @@ const ACTION_LABEL = {
45
53
  next: '→',
46
54
  };
47
55
 
48
- const DIFF_DISABLED = ['commit', 'branch', 'pull', 'push'];
56
+ const DIFF_DISABLED = [
57
+ 'check',
58
+ 'commit',
59
+ 'branch',
60
+ 'pull',
61
+ 'push',
62
+ 'file',
63
+ 'diff',
64
+ ];
65
+ const UNIT_DISABLED = [...DIFF_DISABLED, 'layout'];
49
66
  const FILES_DISABLED = ['layout', 'feedback', 'code'];
50
- const FILES_HIDDEN = [...FILES_DISABLED, 'prev', 'next', 'commit'];
67
+ const FILES_HIDDEN = [
68
+ ...FILES_DISABLED,
69
+ 'check',
70
+ 'prev',
71
+ 'next',
72
+ 'commit',
73
+ 'file',
74
+ 'diff',
75
+ ];
51
76
  const FILES_GIT_DISABLED = ['add', 'unstage', 'revert'];
52
77
  const FILES_TODO_DISABLED = [...FILES_GIT_DISABLED, ...FILES_DISABLED];
53
78
  const TODO_DISABLED = [
@@ -60,6 +85,8 @@ const TODO_DISABLED = [
60
85
  'todo',
61
86
  'code',
62
87
  'branch',
88
+ 'file',
89
+ 'diff',
63
90
  'pull',
64
91
  'push',
65
92
  ];
@@ -72,7 +99,10 @@ const BRANCHES_DISABLED = [
72
99
  'feedback',
73
100
  'todo',
74
101
  'code',
102
+ 'check',
75
103
  'branch',
104
+ 'file',
105
+ 'diff',
76
106
  'prev',
77
107
  'next',
78
108
  ];
@@ -84,11 +114,12 @@ const COMMITS_DISABLED = [
84
114
  'feedback',
85
115
  'todo',
86
116
  'code',
117
+ 'check',
87
118
  'branch',
119
+ 'file',
120
+ 'diff',
88
121
  'prev',
89
122
  'next',
90
- 'pull',
91
- 'push',
92
123
  ];
93
124
 
94
125
  const isTodosTarget = (item) =>
@@ -108,13 +139,17 @@ const branchGitDisabled = (item) => {
108
139
  return off;
109
140
  };
110
141
 
142
+ const isFixupCommit = (item) =>
143
+ `${item && item.subject ? item.subject : ''}`.startsWith('fixup!');
144
+
111
145
  const commitWriteDisabled = (item) => {
112
- if (!item || !item.sha) return ['amend', 'fixup', 'drop'];
146
+ if (!item || !item.sha) return ['amend', 'apply', 'reword', 'fixup', 'drop'];
113
147
  return [];
114
148
  };
115
149
 
116
150
  const commitGitDisabled = (item) => {
117
- const off = commitWriteDisabled(item);
151
+ const off = [...commitWriteDisabled(item)];
152
+ if (!isFixupCommit(item)) off.push('apply');
118
153
  if (item && item.canCommit === true) return off;
119
154
  return [...off, 'commit', 'fixup'];
120
155
  };
@@ -122,6 +157,7 @@ const commitGitDisabled = (item) => {
122
157
  const disabledActions = (pane, item) => {
123
158
  const onTodos = isTodosTarget(item);
124
159
  if (pane === 'files') return onTodos ? FILES_TODO_DISABLED : FILES_DISABLED;
160
+ if (pane === 'unit') return [...UNIT_DISABLED, ...diffGitDisabled(item)];
125
161
  if (pane === 'branches') {
126
162
  return [...BRANCHES_DISABLED, ...branchGitDisabled(item)];
127
163
  }
@@ -132,6 +168,10 @@ const disabledActions = (pane, item) => {
132
168
  return [...DIFF_DISABLED, ...diffGitDisabled(item)];
133
169
  };
134
170
 
171
+ const HIDDEN_KEYS = {
172
+ l: 'theme',
173
+ };
174
+
135
175
  const SCROLL = {
136
176
  up: 'scrollUp',
137
177
  down: 'scrollDown',
@@ -151,11 +191,9 @@ const SCROLL = {
151
191
  };
152
192
 
153
193
  const KEY_TO_ACTION = {};
154
- const PANE_ONLY = ['branch'];
194
+ const PANE_ONLY = ['branch', 'file', 'diff'];
155
195
  const FILES_KEYS = {};
156
- for (const id of PANE_ONLY) {
157
- for (const key of ACTIONS[id]) FILES_KEYS[key] = id;
158
- }
196
+ for (const key of ACTIONS.branch) FILES_KEYS[key] = 'branch';
159
197
  for (const id of BRANCH_REMOTE) {
160
198
  for (const key of BRANCH_ACTIONS[id]) FILES_KEYS[key] = id;
161
199
  }
@@ -179,13 +217,20 @@ for (const id of ACTION_IDS) {
179
217
  }
180
218
 
181
219
  for (const key of Object.keys(SCROLL)) KEY_TO_ACTION[key] = SCROLL[key];
220
+ for (const key of Object.keys(HIDDEN_KEYS)) {
221
+ KEY_TO_ACTION[key] = HIDDEN_KEYS[key];
222
+ }
182
223
 
183
- const actionFromKey = (key, pane) => {
224
+ const actionFromKey = (key, pane, fileScope) => {
184
225
  const listPane =
185
226
  pane === 'files' || pane === 'branches' || pane === 'commits';
186
227
  if (listPane && (key === 'left' || key === 'right')) return null;
187
228
  const paneKeys = PANE_KEYS[pane];
188
229
  if (paneKeys && paneKeys[key]) return paneKeys[key];
230
+ if (pane === 'files') {
231
+ if (key === 'f' && fileScope !== 'file') return 'file';
232
+ if (key === 'd' && fileScope === 'file') return 'diff';
233
+ }
189
234
  return KEY_TO_ACTION[key] ?? null;
190
235
  };
191
236
 
@@ -194,12 +239,10 @@ const actionKeys = (id) =>
194
239
 
195
240
  const actionHot = (id) => ACTION_HOT[id] ?? actionKeys(id)[0];
196
241
 
197
- const actionLabel = (id) => ACTION_LABEL[id] ?? ACTION_HOT[id] ?? id;
198
-
199
242
  const actionLetter = actionHot;
200
243
 
201
244
  const buttonWord = (id) => {
202
- const word = actionLabel(id);
245
+ const word = ACTION_LABEL[id] ?? ACTION_HOT[id] ?? id;
203
246
  const mark = actionLetter(id);
204
247
  if (word.includes(mark)) return word;
205
248
  return `${mark}${word}`;
@@ -257,13 +300,11 @@ const CONFIRM = {
257
300
 
258
301
  const CONFIRM_MODE = Object.keys(CONFIRM);
259
302
 
260
- const normalizeConfirmKey = (key) =>
261
- key.length === 1 ? key.toLowerCase() : key;
262
-
263
303
  const confirmKey = (mode, key) => {
264
304
  const spec = CONFIRM[mode];
265
305
  if (!spec) return null;
266
- return spec.keys[normalizeConfirmKey(key)] ?? null;
306
+ const norm = key.length === 1 ? key.toLowerCase() : key;
307
+ return spec.keys[norm] ?? null;
267
308
  };
268
309
 
269
310
  const applyConfirm = (mode, key, handlers) => {
@@ -289,6 +330,7 @@ module.exports = {
289
330
  ACTION_HOT,
290
331
  ACTION_LABEL,
291
332
  DIFF_DISABLED,
333
+ UNIT_DISABLED,
292
334
  FILES_DISABLED,
293
335
  FILES_HIDDEN,
294
336
  FILES_GIT_DISABLED,
@@ -302,6 +344,7 @@ module.exports = {
302
344
  diffGitDisabled,
303
345
  branchGitDisabled,
304
346
  commitGitDisabled,
347
+ isFixupCommit,
305
348
  actionFromKey,
306
349
  actionKeys,
307
350
  actionHot,