reslop 0.2.4 → 0.2.5

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 (67) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/README.md +1 -2
  3. package/lib/capabilities.js +0 -4
  4. package/lib/clipboard.js +39 -1
  5. package/lib/deps-diff.js +0 -3
  6. package/lib/deps.js +144 -176
  7. package/lib/diff/inline.js +66 -1
  8. package/lib/diff/unit.js +11 -28
  9. package/lib/editor.js +69 -9
  10. package/lib/files.js +17 -16
  11. package/lib/git-deps.js +58 -95
  12. package/lib/github.js +7 -7
  13. package/lib/gitlab.js +3 -3
  14. package/lib/highlight/core.js +11 -0
  15. package/lib/highlight/dot.js +2 -12
  16. package/lib/highlight/log.js +4 -11
  17. package/lib/highlight/txt.js +2 -12
  18. package/lib/keys.js +22 -12
  19. package/lib/manifest.js +0 -4
  20. package/lib/npm-commands.js +1 -22
  21. package/lib/remote.js +1 -7
  22. package/lib/render/branches.js +4 -13
  23. package/lib/render/chrome.js +85 -31
  24. package/lib/render/commits.js +95 -207
  25. package/lib/render/diff.js +31 -1
  26. package/lib/render/files.js +7 -16
  27. package/lib/render/frame.js +95 -110
  28. package/lib/render/notes.js +71 -16
  29. package/lib/render/npm.js +104 -18
  30. package/lib/render/primitives.js +108 -45
  31. package/lib/render/unit.js +4 -1
  32. package/lib/report-parse.js +0 -1
  33. package/lib/report-run.js +0 -1
  34. package/lib/report-test.js +40 -47
  35. package/lib/report-tools.js +0 -7
  36. package/lib/review-merge.js +101 -131
  37. package/lib/review.js +64 -77
  38. package/lib/select.js +52 -0
  39. package/lib/session/actions.js +23 -22
  40. package/lib/session/branches.js +5 -3
  41. package/lib/session/change-actions.js +173 -146
  42. package/lib/session/commit.js +32 -13
  43. package/lib/session/compose.js +120 -77
  44. package/lib/session/dispatch.js +36 -21
  45. package/lib/session/edit-click.js +57 -0
  46. package/lib/session/files-pane.js +24 -24
  47. package/lib/session/items.js +69 -89
  48. package/lib/session/lifecycle.js +31 -96
  49. package/lib/session/load.js +51 -58
  50. package/lib/session/navigation.js +105 -96
  51. package/lib/session/npm.js +158 -77
  52. package/lib/session/ops.js +192 -51
  53. package/lib/session/pointer.js +11 -5
  54. package/lib/session/progress.js +9 -6
  55. package/lib/session/review.js +35 -54
  56. package/lib/session/tasks.js +292 -0
  57. package/lib/session/terminal.js +13 -17
  58. package/lib/session/unit.js +3 -4
  59. package/lib/session/update.js +76 -97
  60. package/lib/session/view.js +17 -14
  61. package/lib/session/watch.js +47 -27
  62. package/lib/session.js +34 -79
  63. package/lib/update.js +1 -5
  64. package/lib/utilities.js +21 -1
  65. package/lib/wrap.js +15 -0
  66. package/package.json +1 -1
  67. package/lib/session/todos.js +0 -293
@@ -1,7 +1,10 @@
1
1
  'use strict';
2
2
 
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+
3
6
  const files = require('../files.js');
4
- const { listPath, isTodoItem, isTodosEntry, isReadOnlyOrigin } = files;
7
+ const { listPath, isTaskItem, isTasksEntry, isReadOnlyOrigin } = files;
5
8
  const items = require('./items.js');
6
9
  const { needsReload, npmBusyKind, sameBlock } = items;
7
10
  const diff = require('../diff/diff.js');
@@ -24,13 +27,63 @@ const COMMANDS = {
24
27
  revert: {
25
28
  match: () => true,
26
29
  },
30
+ ignore: {
31
+ match: () => true,
32
+ },
33
+ };
34
+
35
+ const IGNORE_FILES = ['.gitignore', '.npmignore'];
36
+
37
+ const ignorePatternListed = (text, pattern) => {
38
+ for (const line of `${text ?? ''}`.split('\n')) {
39
+ if (line.trim() === pattern) return true;
40
+ }
41
+ return false;
42
+ };
43
+
44
+ const appendIgnorePattern = (text, pattern) => {
45
+ if (ignorePatternListed(text, pattern)) return text;
46
+ const base = text.length && !text.endsWith('\n') ? `${text}\n` : text;
47
+ return `${base}${pattern}\n`;
48
+ };
49
+
50
+ const appendIgnoreFile = (top, name, pattern) => {
51
+ const abs = path.join(top, name);
52
+ if (name === '.npmignore' && !fs.existsSync(abs)) return false;
53
+ const text = fs.existsSync(abs) ? fs.readFileSync(abs, 'utf8') : '';
54
+ const next = appendIgnorePattern(text, pattern);
55
+ if (next === text) return false;
56
+ fs.writeFileSync(abs, next);
57
+ return true;
58
+ };
59
+
60
+ const ignoreRelPath = (ui, rel) => {
61
+ const pattern = `${rel ?? ''}`.replace(/^\//, '');
62
+ if (!pattern) {
63
+ ui.status = 'not a diff block';
64
+ return;
65
+ }
66
+ let changed = false;
67
+ for (const name of IGNORE_FILES) {
68
+ if (appendIgnoreFile(ui.top, name, pattern)) changed = true;
69
+ }
70
+ if (!changed) {
71
+ ui.status = 'already ignored';
72
+ return;
73
+ }
74
+ ui.ignoreWatch();
75
+ ui.nav.clearSelection();
76
+ ui.reloadAfterChange();
77
+ ui.status = 'ignored';
27
78
  };
28
79
 
80
+ const sameEntry = (entry) => entry;
81
+
29
82
  const keepOrigin = (ui, item, origin) => {
30
83
  ui.collection.keepOrigin(item, origin);
31
84
  const idx = ui.collection.findRestoredIndex({ ...item, origin });
32
85
  if (idx >= 0) ui.nav.index = idx;
33
- if (ui.ignoreWatch) ui.ignoreWatch();
86
+ ui.ignoreWatch();
34
87
  ui.nav.clearSelection();
35
88
  ui.syncReviewPath();
36
89
  ui.syncFileCursor();
@@ -43,11 +96,11 @@ const fileCursorEntry = (ui) => {
43
96
 
44
97
  const fileActionItems = (ui) => {
45
98
  const entry = fileCursorEntry(ui);
46
- if (!entry || isTodosEntry(entry)) return [];
99
+ if (!entry || isTasksEntry(entry)) return [];
47
100
  const rel = entry.path;
48
101
  const selected = [];
49
102
  for (const item of ui.items) {
50
- if (isTodoItem(item)) continue;
103
+ if (isTaskItem(item)) continue;
51
104
  if (listPath(item) !== rel) continue;
52
105
  selected.push(item);
53
106
  }
@@ -57,7 +110,7 @@ const fileActionItems = (ui) => {
57
110
  const activeDiffItem = (ui) => {
58
111
  const item = ui.current();
59
112
  if (!item) return null;
60
- if (isTodoItem(item)) {
113
+ if (isTaskItem(item)) {
61
114
  ui.status = 'not a diff block';
62
115
  return null;
63
116
  }
@@ -140,13 +193,60 @@ const applyBlockAdd = (ui, item) => {
140
193
  keepOrigin(ui, item, 'staged');
141
194
  };
142
195
 
196
+ const enqueueOrigins = (ui, targets, spec) => {
197
+ const writes = new Array(targets.length);
198
+ for (let i = 0; i < targets.length; i++) {
199
+ const current = liveItem(ui, targets[i]);
200
+ writes[i] = current;
201
+ keepOrigin(ui, current, spec.originOf(current));
202
+ }
203
+ if (spec.afterUi) spec.afterUi();
204
+ if (!spec.busy) ui.status = spec.done;
205
+ ui.ops.enqueueLazy({
206
+ kind: spec.busy || spec.done,
207
+ done: spec.done,
208
+ reload: spec.reload === true,
209
+ write: async (top) => {
210
+ for (const item of writes) await spec.write(top, item);
211
+ },
212
+ });
213
+ };
214
+
215
+ const stageLazy = (ui, targets, extra = {}) => {
216
+ const busy = extra.busy || '';
217
+ const repo = ui.repo;
218
+ enqueueOrigins(ui, targets, {
219
+ done: 'staged',
220
+ busy,
221
+ reload: extra.reload === true,
222
+ originOf: () => 'staged',
223
+ afterUi: extra.afterUi,
224
+ write: (top, item) => {
225
+ if (busy && repo.addAsync) return repo.addAsync(top, item);
226
+ return repo.add(top, item);
227
+ },
228
+ });
229
+ };
230
+
231
+ const unstageLazy = (ui, targets, extra = {}) => {
232
+ const repo = ui.repo;
233
+ enqueueOrigins(ui, targets, {
234
+ done: 'unstaged',
235
+ busy: '',
236
+ originOf: nextUnstageOrigin,
237
+ afterUi: extra.afterUi,
238
+ write: (top, item) => repo.unstage(top, item),
239
+ });
240
+ };
241
+
143
242
  const onBlockAdd = (ui, item) => {
144
243
  const busy = npmBusyKind(item);
145
244
  const repo = ui.repo;
146
- if (ui.uiOpen && busy && repo.addAsync) {
147
- const after = () => applyBlockAdd(ui, item);
148
- const write = (top) => repo.addAsync(top, item);
149
- return void ui.ops.runBusy(busy, 'staged', write, after);
245
+ if (ui.uiOpen) {
246
+ return void stageLazy(ui, [item], {
247
+ busy,
248
+ reload: needsReload(item),
249
+ });
150
250
  }
151
251
  applyGit(
152
252
  ui,
@@ -160,6 +260,7 @@ const onBlockAdd = (ui, item) => {
160
260
  };
161
261
 
162
262
  const onBlockUnstage = (ui, item) => {
263
+ if (ui.uiOpen) return void unstageLazy(ui, [item]);
163
264
  const origin = nextUnstageOrigin(item);
164
265
  const repo = ui.repo;
165
266
  applyGit(
@@ -171,6 +272,12 @@ const onBlockUnstage = (ui, item) => {
171
272
  );
172
273
  };
173
274
 
275
+ const dismissReloadable = (ui, targets) => {
276
+ for (const item of targets) {
277
+ if (needsReload(item)) ui.collection.dismiss(item);
278
+ }
279
+ };
280
+
174
281
  const onBlockRevert = (ui, item) => {
175
282
  const repo = ui.repo;
176
283
  applyGit(
@@ -179,7 +286,7 @@ const onBlockRevert = (ui, item) => {
179
286
  'dropped',
180
287
  (top, current) => repo.revert(top, current),
181
288
  () => {
182
- if (needsReload(item)) ui.collection.dismiss(item);
289
+ dismissReloadable(ui, [item]);
183
290
  ui.reloadAfterChange();
184
291
  },
185
292
  );
@@ -195,6 +302,7 @@ const onBlockCommand = (ui, name) => {
195
302
  const command = COMMANDS[name];
196
303
  const item = activeDiffItem(ui);
197
304
  if (!guardWritable(ui, item)) return;
305
+ if (name === 'ignore') return void ignoreRelPath(ui, listPath(item));
198
306
  if (!command.match(item)) {
199
307
  ui.status = command.skipStatus;
200
308
  return;
@@ -202,109 +310,83 @@ const onBlockCommand = (ui, name) => {
202
310
  BLOCK[name](ui, item);
203
311
  };
204
312
 
205
- const writeFileAddAsync = (ui, targets) => async (top) => {
206
- const repo = ui.repo;
207
- for (const item of targets) {
208
- const current = liveItem(ui, item);
209
- await repo.addAsync(top, current);
210
- keepOrigin(ui, current, 'staged');
313
+ const stageTargets = (ui, targets, after = null) => {
314
+ const reload = targets.some(needsReload);
315
+ const busy = targets.map(npmBusyKind).find((kind) => kind) || '';
316
+ if (ui.uiOpen) {
317
+ return void stageLazy(ui, targets, { busy, reload, afterUi: after });
211
318
  }
319
+ const keepStaged = (entry) => keepOrigin(ui, entry, 'staged');
320
+ const result = applyFileGit(ui, targets, 'staged', ui.repo.add, keepStaged);
321
+ if (reconcilePartial(ui, result)) return;
322
+ if (reload) ui.reloadAfterChange();
323
+ if (after) after();
212
324
  };
213
325
 
214
- const afterFileAdd = (ui, rel, proposed) => () => {
215
- if (proposed) {
216
- return void ui.reloadAfterChange(() => selectNextFileAfter(ui, rel));
217
- }
218
- selectNextFileAfter(ui, rel);
219
- };
220
-
221
- const onFileAdd = (ui) => {
222
- const selected = fileActionItems(ui);
223
- if (!selected.length) {
224
- ui.status = 'not a diff block';
225
- return;
226
- }
227
- if (!guardWritable(ui, selected[0])) return;
228
- const rel = listPath(selected[0]);
229
- const targets = selected.filter(COMMANDS.add.match);
230
- if (!targets.length) {
231
- ui.status = 'already staged';
232
- selectNextFileAfter(ui, rel);
233
- return;
234
- }
235
- const proposed = targets.some(needsReload);
236
- const busy = targets.map(npmBusyKind).find((kind) => kind);
237
- const repo = ui.repo;
238
- if (ui.uiOpen && busy && repo.addAsync) {
239
- const write = writeFileAddAsync(ui, targets);
240
- const after = afterFileAdd(ui, rel, proposed);
241
- return void ui.ops.runBusy(busy, 'staged', write, after);
242
- }
326
+ const unstageTargets = (ui, targets, after = null) => {
327
+ if (ui.uiOpen) return void unstageLazy(ui, targets, { afterUi: after });
328
+ const keepUnstaged = (entry) =>
329
+ keepOrigin(ui, entry, nextUnstageOrigin(entry));
243
330
  const result = applyFileGit(
244
331
  ui,
245
332
  targets,
246
- 'staged',
247
- (top, current) => repo.add(top, current),
248
- (item) => keepOrigin(ui, item, 'staged'),
333
+ 'unstaged',
334
+ ui.repo.unstage,
335
+ keepUnstaged,
249
336
  );
250
337
  if (reconcilePartial(ui, result)) return;
251
- if (proposed) ui.reloadAfterChange();
252
- selectNextFileAfter(ui, rel);
338
+ if (after) after();
253
339
  };
254
340
 
255
- const onFileUnstage = (ui) => {
256
- const selected = fileActionItems(ui);
257
- if (!selected.length) {
258
- ui.status = 'not a diff block';
259
- return;
260
- }
261
- if (!guardWritable(ui, selected[0])) return;
262
- const rel = listPath(selected[0]);
263
- const targets = selected.filter(COMMANDS.unstage.match);
264
- if (!targets.length) {
265
- ui.status = 'not staged';
266
- selectNextFileAfter(ui, rel);
267
- return;
268
- }
269
- const repo = ui.repo;
341
+ const revertTargets = (ui, targets) => {
342
+ dismissReloadable(ui, targets);
270
343
  const result = applyFileGit(
271
344
  ui,
272
345
  targets,
273
- 'unstaged',
274
- (top, current) => repo.unstage(top, current),
275
- (item) => keepOrigin(ui, item, nextUnstageOrigin(item)),
346
+ 'dropped',
347
+ ui.repo.revert,
348
+ sameEntry,
276
349
  );
277
- if (reconcilePartial(ui, result)) return;
278
- selectNextFileAfter(ui, rel);
350
+ if (!result.ok && !result.completed.length) return;
351
+ ui.reloadAfterChange();
279
352
  };
280
353
 
281
- const onFileRevert = (ui) => {
282
- const selected = fileActionItems(ui);
283
- if (!selected.length) {
284
- ui.status = 'not a diff block';
285
- return;
286
- }
287
- if (!guardWritable(ui, selected[0])) return;
288
- const rel = listPath(selected[0]);
289
- for (const item of selected) {
290
- if (needsReload(item)) ui.collection.dismiss(item);
291
- }
292
- let ok = false;
354
+ const revertFile = (ui, rel, selected, after) => {
355
+ dismissReloadable(ui, selected);
293
356
  try {
294
357
  ui.repo.revertFile(ui.top, rel, selected);
295
358
  ui.status = 'dropped';
296
- ok = true;
297
359
  } catch (error) {
298
360
  ui.status = error.message;
361
+ return void ui.reloadAfterChange();
299
362
  }
300
- const after = ok ? () => selectNextFileAfter(ui, rel) : null;
301
363
  ui.reloadAfterChange(after);
302
364
  };
303
365
 
304
- const FILE = {
305
- add: onFileAdd,
306
- unstage: onFileUnstage,
307
- revert: onFileRevert,
366
+ const TARGETS = {
367
+ add: stageTargets,
368
+ unstage: unstageTargets,
369
+ revert: revertTargets,
370
+ };
371
+
372
+ const onFileCommand = (ui, name) => {
373
+ const selected = fileActionItems(ui);
374
+ if (!selected.length) {
375
+ ui.status = 'not a diff block';
376
+ return;
377
+ }
378
+ if (!guardWritable(ui, selected[0])) return;
379
+ const rel = listPath(selected[0]);
380
+ const next = () => selectNextFileAfter(ui, rel);
381
+ if (name === 'ignore') return void ignoreRelPath(ui, rel);
382
+ if (name === 'revert') return void revertFile(ui, rel, selected, next);
383
+ const command = COMMANDS[name];
384
+ const targets = selected.filter(command.match);
385
+ if (!targets.length) {
386
+ ui.status = command.skipStatus;
387
+ return void next();
388
+ }
389
+ TARGETS[name](ui, targets, next);
308
390
  };
309
391
 
310
392
  const hunkActionItems = (ui, item) => {
@@ -318,62 +400,6 @@ const hunkActionItems = (ui, item) => {
318
400
  return selected;
319
401
  };
320
402
 
321
- const onUnitAdd = (ui, targets) => {
322
- const proposed = targets.some(needsReload);
323
- const busy = targets.map(npmBusyKind).find((kind) => kind);
324
- const repo = ui.repo;
325
- if (ui.uiOpen && busy && repo.addAsync) {
326
- const write = writeFileAddAsync(ui, targets);
327
- const after = () => {
328
- if (proposed) ui.reloadAfterChange();
329
- };
330
- return void ui.ops.runBusy(busy, 'staged', write, after);
331
- }
332
- const result = applyFileGit(
333
- ui,
334
- targets,
335
- 'staged',
336
- (top, current) => repo.add(top, current),
337
- (entry) => keepOrigin(ui, entry, 'staged'),
338
- );
339
- if (reconcilePartial(ui, result)) return;
340
- if (proposed) ui.reloadAfterChange();
341
- };
342
-
343
- const onUnitUnstage = (ui, targets) => {
344
- const repo = ui.repo;
345
- const result = applyFileGit(
346
- ui,
347
- targets,
348
- 'unstaged',
349
- (top, current) => repo.unstage(top, current),
350
- (entry) => keepOrigin(ui, entry, nextUnstageOrigin(entry)),
351
- );
352
- reconcilePartial(ui, result);
353
- };
354
-
355
- const onUnitRevert = (ui, targets) => {
356
- for (const item of targets) {
357
- if (needsReload(item)) ui.collection.dismiss(item);
358
- }
359
- const repo = ui.repo;
360
- const result = applyFileGit(
361
- ui,
362
- targets,
363
- 'dropped',
364
- (top, current) => repo.revert(top, current),
365
- (entry) => entry,
366
- );
367
- if (!result.ok && !result.completed.length) return;
368
- ui.reloadAfterChange();
369
- };
370
-
371
- const UNIT = {
372
- add: onUnitAdd,
373
- unstage: onUnitUnstage,
374
- revert: onUnitRevert,
375
- };
376
-
377
403
  const onUnitCommand = (ui, name) => {
378
404
  const command = COMMANDS[name];
379
405
  const item = activeDiffItem(ui);
@@ -384,11 +410,11 @@ const onUnitCommand = (ui, name) => {
384
410
  ui.status = command.skipStatus ?? 'not a diff block';
385
411
  return;
386
412
  }
387
- UNIT[name](ui, targets);
413
+ TARGETS[name](ui, targets);
388
414
  };
389
415
 
390
416
  const onCommand = (ui, name) => {
391
- if (ui.nav.pane === 'files') return void FILE[name](ui);
417
+ if (ui.nav.pane === 'files') return void onFileCommand(ui, name);
392
418
  if (ui.nav.pane === 'unit') return void onUnitCommand(ui, name);
393
419
  onBlockCommand(ui, name);
394
420
  };
@@ -398,6 +424,7 @@ const createChangeActions = (ui) => ({
398
424
  onAdd: () => onCommand(ui, 'add'),
399
425
  onUnstage: () => onCommand(ui, 'unstage'),
400
426
  onRevert: () => onCommand(ui, 'revert'),
427
+ onIgnore: () => onCommand(ui, 'ignore'),
401
428
  });
402
429
 
403
430
  module.exports = { createChangeActions };
@@ -43,6 +43,13 @@ const briefCommit = (ui) => ui.commits.commitView !== 'full';
43
43
 
44
44
  const joinMessage = (line, rest) => (rest ? `${line}\n${rest}` : line);
45
45
 
46
+ const tidyCommitMessage = (message) => {
47
+ const lines = `${message ?? ''}`.split('\n').map((line) => line.trim());
48
+ while (lines.length && lines[0] === '') lines.shift();
49
+ while (lines.length && lines[lines.length - 1] === '') lines.pop();
50
+ return lines.join('\n');
51
+ };
52
+
46
53
  const keepBriefBody = (ui, text) => {
47
54
  if (!briefCommit(ui)) return text;
48
55
  const parts = splitMessage(text);
@@ -91,6 +98,24 @@ const clampCommitCursor = (api) => {
91
98
  if (nav.commitCursor > last) nav.commitCursor = Math.max(0, last);
92
99
  };
93
100
 
101
+ const commitIndexForView = (api) => {
102
+ const ui = api.ui;
103
+ if (hasStagedChanges(ui)) return 0;
104
+ const list = listedCommits(api.state.commits);
105
+ const want = `${ui.rev ?? ''}`;
106
+ const short = `${ui.revShort ?? ''}`;
107
+ if (!want && !short) return 0;
108
+ for (let i = 0; i < list.length; i++) {
109
+ const entry = list[i];
110
+ if (!entry || entry.pending) continue;
111
+ const sha = `${entry.sha ?? ''}`;
112
+ const brief = `${entry.shortSha ?? ''}`;
113
+ if (want && sha === want) return i;
114
+ if (short && (brief === short || sha.startsWith(short))) return i;
115
+ }
116
+ return 0;
117
+ };
118
+
94
119
  const refreshCommitList = (api) => {
95
120
  const repo = api.ui.repo;
96
121
  if (!repo.listCommits) return;
@@ -121,10 +146,12 @@ const showCommits = (api) => {
121
146
  api.ui.status = error.message;
122
147
  return;
123
148
  }
124
- api.ui.nav.commitCursor = 0;
125
- api.ui.nav.pane = 'commits';
149
+ const nav = api.ui.nav;
150
+ nav.commitCursor = commitIndexForView(api);
151
+ nav.pane = 'commits';
152
+ nav.resetListScroll('commits');
126
153
  api.ui.status = '';
127
- api.ui.nav.clearSelection();
154
+ nav.clearSelection();
128
155
  };
129
156
 
130
157
  const onCommitMove = (api, delta) => {
@@ -183,7 +210,7 @@ const onCommit = (api) => {
183
210
  };
184
211
 
185
212
  const openLoadedDiff = (ui) => {
186
- ui.nav.todoOpen = false;
213
+ ui.nav.tasksOpen = false;
187
214
  ui.nav.scroll = 0;
188
215
  ui.nav.index = 0;
189
216
  ui.nav.pane = ui.items.length ? 'diff' : 'files';
@@ -252,12 +279,6 @@ const onFixup = (api) => {
252
279
  startGitCommit(api, 'fixup');
253
280
  };
254
281
 
255
- const cancelCommit = (api) => {
256
- api.ui.mode = 'review';
257
- api.ui.composer.state.commitKind = null;
258
- api.ui.status = '';
259
- };
260
-
261
282
  const finishAsyncCommit = (api, kind, message, done, write) => {
262
283
  const ui = api.ui;
263
284
  ui.composer.closeCompose();
@@ -321,6 +342,7 @@ const finishGitCommit = (api) => {
321
342
  if (isInPlaceCommit(kind) && briefCommit(ui)) {
322
343
  message = joinMessage(message, ui.composer.state.commitBody);
323
344
  }
345
+ message = tidyCommitMessage(message);
324
346
  if (!message.trim()) {
325
347
  ui.status = 'empty commit message';
326
348
  return;
@@ -412,8 +434,6 @@ const createCommitController = (ui) => {
412
434
  onCommitMove: (delta) => onCommitMove(api, delta),
413
435
  onShowDiff: () => showSelectedDiff(api),
414
436
  onView: () => onView(api),
415
- cancelCommit: () => cancelCommit(api),
416
- startGitCommit: (kind) => startGitCommit(api, kind),
417
437
  finishGitCommit: () => finishGitCommit(api),
418
438
  refresh: () => refreshCommitList(api),
419
439
  onDropCommit: () => onDropCommit(api),
@@ -425,7 +445,6 @@ const createCommitController = (ui) => {
425
445
  };
426
446
 
427
447
  module.exports = {
428
- COMMIT_STATUS,
429
448
  hasStagedChanges,
430
449
  createCommitController,
431
450
  listedCommits,