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,51 +1,31 @@
1
1
  'use strict';
2
2
 
3
3
  const core = require('./core.js');
4
- const { emit, readString } = core;
4
+ const { emit, wordStyles, scanWhile, stringEnd } = core;
5
5
 
6
- const JSON_LITERAL = {
7
- true: 'literal',
8
- false: 'literal',
9
- null: 'literal',
10
- };
6
+ const JSON_LITERAL = wordStyles({ literal: ['true', 'false', 'null'] });
11
7
 
12
8
  const highlight = (source) => {
13
9
  const out = [];
14
10
  let i = 0;
15
- const n = source.length;
16
- while (i < n) {
11
+ const take = (style, end) => {
12
+ emit(out, style, source.slice(i, end));
13
+ i = end;
14
+ };
15
+ while (i < source.length) {
17
16
  const ch = source[i];
18
17
  if (ch === '"') {
19
- const { text, end } = readString(source, i);
20
- let k = end;
21
- while (k < n && /\s/.test(source[k])) k += 1;
22
- const kind = source[k] === ':' ? 'property' : 'string';
23
- emit(out, kind, text);
24
- i = end;
25
- continue;
26
- }
27
- if (/[0-9-]/.test(ch)) {
28
- let j = i;
29
- while (j < n && /[0-9.eE+-]/.test(source[j])) j += 1;
30
- emit(out, 'number', source.slice(i, j));
31
- i = j;
32
- continue;
33
- }
34
- if (/[a-z]/.test(ch)) {
35
- let j = i;
36
- while (j < n && /[a-z]/.test(source[j])) j += 1;
37
- const word = source.slice(i, j);
38
- emit(out, JSON_LITERAL[word] ?? 'plain', word);
39
- i = j;
40
- continue;
41
- }
42
- if (/[{}[\],:]/.test(ch)) {
43
- emit(out, 'punct', ch);
44
- i += 1;
45
- continue;
18
+ const end = stringEnd(source, i);
19
+ const after = source[scanWhile(source, end, /\s/)];
20
+ take(after === ':' ? 'property' : 'string', end);
21
+ } else if (/[0-9-]/.test(ch)) {
22
+ take('number', scanWhile(source, i, /[0-9.eE+-]/));
23
+ } else if (/[a-z]/.test(ch)) {
24
+ const end = scanWhile(source, i, /[a-z]/);
25
+ take(JSON_LITERAL[source.slice(i, end)] ?? 'plain', end);
26
+ } else {
27
+ take(/[{}[\],:]/.test(ch) ? 'punct' : 'plain', i + 1);
46
28
  }
47
- emit(out, 'plain', ch);
48
- i += 1;
49
29
  }
50
30
  return out;
51
31
  };
@@ -1,48 +1,42 @@
1
1
  'use strict';
2
2
 
3
3
  const core = require('./core.js');
4
- const { emit, highlightLines } = core;
4
+ const { emit, highlightLines, wordStyles } = core;
5
5
 
6
6
  const LOG_DATETIME_RE = new RegExp(
7
7
  '^(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}' +
8
8
  '(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?)',
9
9
  );
10
10
 
11
- const LOG_TAG_STYLE = {
12
- error: 'logError',
13
- err: 'logError',
14
- warn: 'logWarn',
15
- warning: 'logWarn',
16
- info: 'logInfo',
17
- debug: 'logDebug',
18
- log: 'plain',
19
- };
11
+ const LOG_TAG_RE = /^(\s*)(\[[^\]]+\])/;
12
+
13
+ const LOG_TAG_STYLE = wordStyles({
14
+ logError: ['error', 'err'],
15
+ logWarn: ['warn', 'warning'],
16
+ logInfo: ['info'],
17
+ logDebug: ['debug'],
18
+ });
20
19
 
21
20
  const highlightLogLine = (line) => {
22
- if (!line) return [];
23
21
  const out = [];
24
22
  let rest = line;
25
- const dm = rest.match(LOG_DATETIME_RE);
26
- if (dm) {
27
- emit(out, 'logDate', dm[1]);
28
- rest = rest.slice(dm[1].length);
23
+ const date = LOG_DATETIME_RE.exec(rest);
24
+ if (date) {
25
+ emit(out, 'logDate', date[1]);
26
+ rest = rest.slice(date[1].length);
29
27
  }
30
- const tag = rest.match(/^(\s*)(\[[^\]]+\])/);
28
+ const tag = LOG_TAG_RE.exec(rest);
31
29
  if (tag) {
32
30
  emit(out, 'plain', tag[1]);
33
- const name = tag[2].replace(/^\[|\]$/g, '').toLowerCase();
31
+ const name = tag[2].slice(1, -1).toLowerCase();
34
32
  emit(out, LOG_TAG_STYLE[name] || 'plain', tag[2]);
35
33
  rest = rest.slice(tag[0].length);
36
34
  }
37
- if (rest.includes('\t')) {
38
- const parts = rest.split('\t');
39
- for (let i = 0; i < parts.length; i += 1) {
40
- if (i) emit(out, 'plain', '\t');
41
- emit(out, `logCol${i}`, parts[i]);
42
- }
43
- return out;
35
+ const columns = rest.split('\t');
36
+ for (let i = 0; i < columns.length; i += 1) {
37
+ if (i) emit(out, 'plain', '\t');
38
+ emit(out, `logCol${i}`, columns[i]);
44
39
  }
45
- if (rest) emit(out, 'logCol0', rest);
46
40
  return out;
47
41
  };
48
42
 
@@ -3,20 +3,17 @@
3
3
  const core = require('./core.js');
4
4
  const { emit, highlightLines } = core;
5
5
 
6
+ const URL_RE = /https?:\/\/[^\s<>"']+|www\.[^\s<>"']+/g;
7
+
6
8
  const highlightTxtLine = (line) => {
7
- if (!line) return [];
8
9
  const out = [];
9
- const re = /(https?:\/\/[^\s<>"']+|www\.[^\s<>"']+)/g;
10
10
  let last = 0;
11
- let m = re.exec(line);
12
- while (m !== null) {
13
- if (m.index > last) emit(out, 'plain', line.slice(last, m.index));
14
- emit(out, 'string', m[0]);
15
- last = m.index + m[0].length;
16
- m = re.exec(line);
11
+ for (const match of line.matchAll(URL_RE)) {
12
+ emit(out, 'plain', line.slice(last, match.index));
13
+ emit(out, 'string', match[0]);
14
+ last = match.index + match[0].length;
17
15
  }
18
- if (last < line.length) emit(out, 'plain', line.slice(last));
19
- if (!out.length) emit(out, 'plain', line);
16
+ emit(out, 'plain', line.slice(last));
20
17
  return out;
21
18
  };
22
19
 
package/lib/highlight.js CHANGED
@@ -1,40 +1,21 @@
1
1
  'use strict';
2
2
 
3
- const fs = require('node:fs');
4
- const path = require('node:path');
5
-
6
3
  const core = require('./highlight/core.js');
7
- const { tokensText } = core;
4
+ const { tokensText, words } = core;
8
5
 
9
- const PLUGIN_DIR = path.join(__dirname, 'highlight');
10
- const SKIP = ['core.js'];
6
+ const PLUGIN_NAMES = words('bash css csv dart dot html js json log txt');
11
7
 
12
- const loadPlugins = () => {
13
- const names = fs
14
- .readdirSync(PLUGIN_DIR)
15
- .filter((name) => name.endsWith('.js') && !SKIP.includes(name));
16
- names.sort();
17
- return names.map((file) => require(path.join(PLUGIN_DIR, file)));
18
- };
8
+ const HIGHLIGHTERS = Object.create(null);
9
+ const LANG = Object.create(null);
19
10
 
20
- const indexPlugins = (plugins) => {
21
- const highlighters = Object.create(null);
22
- const lang = Object.create(null);
23
- for (const plugin of plugins) {
24
- for (const id of plugin.langs) {
25
- highlighters[id] = plugin.highlight;
26
- lang[id] = id;
27
- }
28
- const aliases = plugin.aliases ?? {};
29
- for (const name of Object.keys(aliases)) lang[name] = aliases[name];
11
+ for (const name of PLUGIN_NAMES) {
12
+ const plugin = require(`./highlight/${name}.js`);
13
+ for (const id of plugin.langs) {
14
+ HIGHLIGHTERS[id] = plugin.highlight;
15
+ LANG[id] = id;
30
16
  }
31
- return { highlighters, lang };
32
- };
33
-
34
- const PLUGINS = loadPlugins();
35
- const registry = indexPlugins(PLUGINS);
36
- const HIGHLIGHTERS = registry.highlighters;
37
- const LANG = registry.lang;
17
+ Object.assign(LANG, plugin.aliases);
18
+ }
38
19
 
39
20
  const mapLang = (name) => {
40
21
  if (!name) return 'txt';
@@ -42,10 +23,8 @@ const mapLang = (name) => {
42
23
  };
43
24
 
44
25
  const tokenize = (lang, source) => {
45
- const text = source ?? '';
46
26
  const key = mapLang(lang);
47
- const highlight = HIGHLIGHTERS[key] || HIGHLIGHTERS.txt;
48
- return highlight(text, key);
27
+ return HIGHLIGHTERS[key](source ?? '', key);
49
28
  };
50
29
 
51
30
  const overlayTokens = (tokens, spans) => {
@@ -61,14 +40,12 @@ const overlayTokens = (tokens, spans) => {
61
40
  const span = diff[spanIndex];
62
41
  const tokenText = token.text ?? '';
63
42
  const spanText = span.text ?? '';
64
- const tokenLeft = tokenText.length - tokenOff;
65
- const spanLeft = spanText.length - spanOff;
66
- const n = Math.min(tokenLeft, spanLeft);
43
+ const n = Math.min(tokenText.length - tokenOff, spanText.length - spanOff);
67
44
  if (n > 0) {
68
- const name = typeof token.style === 'string' ? token.style : 'plain';
45
+ const style = typeof token.style === 'string' && token.style;
69
46
  pieces.push({
70
47
  text: tokenText.slice(tokenOff, tokenOff + n),
71
- style: name || 'plain',
48
+ style: style || 'plain',
72
49
  changed: span.changed === true,
73
50
  });
74
51
  }
@@ -83,21 +60,15 @@ const overlayTokens = (tokens, spans) => {
83
60
  spanOff = 0;
84
61
  }
85
62
  }
86
- while (spanIndex < diff.length) {
63
+ for (; spanIndex < diff.length; spanIndex++) {
87
64
  const span = diff[spanIndex];
88
65
  const text = (span.text ?? '').slice(spanOff);
89
66
  if (text) {
90
67
  pieces.push({ text, style: 'plain', changed: span.changed === true });
91
68
  }
92
- spanIndex += 1;
93
69
  spanOff = 0;
94
70
  }
95
71
  return pieces;
96
72
  };
97
73
 
98
- module.exports = {
99
- tokensText,
100
- tokenize,
101
- overlayTokens,
102
- mapLang,
103
- };
74
+ module.exports = { tokensText, tokenize, overlayTokens, mapLang };
package/lib/keys.js CHANGED
@@ -3,15 +3,13 @@
3
3
  const actions = require('./session/actions.js');
4
4
 
5
5
  const { ACTIONS, ACTION_IDS, BRANCH_ACTIONS, COMMIT_ACTIONS } = actions;
6
- const { DIFF_DISABLED, FILES_DISABLED, FILES_GIT_DISABLED } = actions;
7
- const { FILES_HIDDEN, FILES_TASKS_DISABLED } = actions;
6
+ const { DASH_IDS, DASH_HIDDEN } = actions;
7
+ const { DIFF_DISABLED, FILES_GIT_DISABLED, FILES_HIDDEN } = actions;
8
8
  const { TASKS_DISABLED, BRANCHES_DISABLED } = actions;
9
9
  const { COMMITS_DISABLED, UNIT_DISABLED, NPM_DISABLED } = actions;
10
- const { disabledActions, diffGitDisabled, branchGitDisabled } = actions;
11
- const { commitGitDisabled } = actions;
12
- const { actionFromKey, actionHot, actionLetter, buttonWord } = actions;
13
- const { CONFIRM, CONFIRM_MODE, confirmKey, applyConfirm } = actions;
14
- const { confirmPrefix, promptFromChoices } = actions;
10
+ const { diffGitDisabled, branchGitDisabled, commitGitDisabled } = actions;
11
+ const { actionLetter, buttonWord } = actions;
12
+ const { CONFIRM, confirmPrefix, promptFromChoices } = actions;
15
13
 
16
14
  const CSI_KEYS = {
17
15
  A: 'up',
@@ -48,34 +46,17 @@ const MOUSE_WHEEL = {
48
46
  65: 'wheelDown',
49
47
  };
50
48
 
51
- const parseCsiSeq = (rest) => {
52
- const body = rest.slice(2);
53
- let i = 0;
54
- while (i < body.length) {
55
- const code = body.charCodeAt(i);
56
- if (code >= 64 && code <= 126) break;
57
- i += 1;
58
- }
59
- if (i >= body.length) {
60
- if (rest.length > CSI_MAX) {
61
- return { event: { type: 'key', key: 'escape' }, eat: 1 };
62
- }
63
- return { needMore: true };
64
- }
65
- return { params: body.slice(0, i), final: body[i], eat: 2 + i + 1 };
66
- };
49
+ const NEED_MORE = { needMore: true };
67
50
 
68
- const modifierBits = (modText) => {
69
- const mod = parseInt(modText, 10);
70
- if (!Number.isFinite(mod)) return 0;
71
- return mod - 1;
72
- };
51
+ const keyAt = (key, end) => ({ event: { type: 'key', key }, end });
73
52
 
74
- const modifiedKey = (base, bits) => {
53
+ const modifiedKey = (base, modText) => {
75
54
  const arrow =
76
55
  base === 'left' || base === 'right' || base === 'up' || base === 'down';
77
56
  const end = base === 'home' || base === 'end';
78
57
  if (!arrow && !end) return base;
58
+ const mod = parseInt(modText, 10);
59
+ const bits = Number.isFinite(mod) ? mod - 1 : 0;
79
60
  const ctrl = (bits & 4) !== 0;
80
61
  const shift = (bits & 1) !== 0;
81
62
  if (ctrl && shift && arrow) return `ctrl-shift-${base}`;
@@ -89,15 +70,28 @@ const keyFromCsi = (paramsText, final) => {
89
70
  const base = final === '~' ? CSI_TILDE[params[0]] : CSI_KEYS[final];
90
71
  if (!base) return null;
91
72
  if (params.length < 2) return base;
92
- return modifiedKey(base, modifierBits(params[1]));
73
+ return modifiedKey(base, params[1]);
93
74
  };
94
75
 
95
- const mouseKindFromButton = (button, press) => {
76
+ const parseCsi = (rest, start) => {
77
+ let i = 2;
78
+ while (i < rest.length) {
79
+ const code = rest.charCodeAt(i);
80
+ if (code >= 64 && code <= 126) break;
81
+ i += 1;
82
+ }
83
+ if (i >= rest.length) {
84
+ return rest.length > CSI_MAX ? keyAt('escape', start + 1) : NEED_MORE;
85
+ }
86
+ const key = keyFromCsi(rest.slice(2, i), rest[i]);
87
+ return key ? keyAt(key, start + i + 1) : keyAt('escape', start + 1);
88
+ };
89
+
90
+ const mouseKind = (button, press) => {
96
91
  const wheel = MOUSE_WHEEL[button];
97
92
  if (wheel) return wheel;
98
93
  if (!press) return 'release';
99
- if (button & 32) return 'drag';
100
- return 'press';
94
+ return button & 32 ? 'drag' : 'press';
101
95
  };
102
96
 
103
97
  const parseMouse = (body, flag) => {
@@ -110,81 +104,60 @@ const parseMouse = (body, flag) => {
110
104
  return null;
111
105
  }
112
106
  const press = flag === 'M';
113
- const kind = mouseKindFromButton(button, press);
107
+ const kind = mouseKind(button, press);
114
108
  return { type: 'mouse', button, x, y, press, kind, btn: button & 3 };
115
109
  };
116
110
 
117
111
  const parseEsc = (text, start) => {
118
112
  const rest = text.slice(start);
119
- if (rest === '\x1b') return { needMore: true };
120
- if (rest.startsWith('\x1b[') && rest.length === 2) return { needMore: true };
113
+ if (rest === '\x1b' || rest === '\x1b[') return NEED_MORE;
121
114
  if (rest.startsWith('\x1b[<')) {
122
115
  const endM = rest.search(/[Mm]/);
123
- if (endM < 0) return { needMore: true };
124
- const kind = rest[endM];
125
- const body = rest.slice(3, endM);
126
- const mouse = parseMouse(body, kind);
127
- if (!mouse) {
128
- return { event: { type: 'key', key: 'escape' }, end: start + endM + 1 };
129
- }
130
- return { event: mouse, end: start + endM + 1 };
131
- }
132
- if (rest.startsWith('\x1b[')) {
133
- const csi = parseCsiSeq(rest);
134
- if (csi.needMore) return csi;
135
- if (csi.event) return { event: csi.event, end: start + csi.eat };
136
- const key = keyFromCsi(csi.params, csi.final);
137
- if (key) return { event: { type: 'key', key }, end: start + csi.eat };
138
- return { event: { type: 'key', key: 'escape' }, end: start + 1 };
116
+ if (endM < 0) return NEED_MORE;
117
+ const mouse = parseMouse(rest.slice(3, endM), rest[endM]);
118
+ const end = start + endM + 1;
119
+ return mouse ? { event: mouse, end } : keyAt('escape', end);
139
120
  }
121
+ if (rest.startsWith('\x1b[')) return parseCsi(rest, start);
140
122
  if (rest.startsWith('\x1bO')) {
141
- if (rest.length < 3) return { needMore: true };
123
+ if (rest.length < 3) return NEED_MORE;
142
124
  const key = CSI_KEYS[rest[2]];
143
- if (key) return { event: { type: 'key', key }, end: start + 3 };
144
- return { event: { type: 'key', key: 'escape' }, end: start + 1 };
125
+ return key ? keyAt(key, start + 3) : keyAt('escape', start + 1);
145
126
  }
146
- return { event: { type: 'key', key: 'escape' }, end: start + 1 };
127
+ return keyAt('escape', start + 1);
147
128
  };
148
129
 
149
130
  const decodeChunk = (text, carry = '') => {
150
131
  const source = carry + text;
151
- const events = new Array(source.length);
152
- let n = 0;
132
+ const events = [];
153
133
  let i = 0;
154
134
  while (i < source.length) {
155
135
  const ch = source[i];
156
136
  if (ch === '\x1b') {
157
137
  const parsed = parseEsc(source, i);
158
- if (parsed.needMore) {
159
- events.length = n;
160
- return { events, carry: source.slice(i) };
161
- }
162
- events[n++] = parsed.event;
138
+ if (parsed.needMore) return { events, carry: source.slice(i) };
139
+ events.push(parsed.event);
163
140
  i = parsed.end;
164
141
  continue;
165
142
  }
166
143
  const named = LITERAL_KEY[ch];
144
+ const code = source.charCodeAt(i);
167
145
  if (named) {
168
- events[n++] = { type: 'key', key: named };
146
+ events.push({ type: 'key', key: named });
169
147
  i += 1;
170
148
  continue;
171
149
  }
172
- const code = source.charCodeAt(i);
173
150
  if (code >= 1 && code <= 26) {
174
151
  const letter = String.fromCharCode(96 + code);
175
- events[n++] = { type: 'key', key: `ctrl-${letter}` };
152
+ events.push({ type: 'key', key: `ctrl-${letter}` });
176
153
  i += 1;
177
154
  continue;
178
155
  }
179
- if (code >= 0xd800 && code <= 0xdbff && i + 1 < source.length) {
180
- events[n++] = { type: 'key', key: source.slice(i, i + 2) };
181
- i += 2;
182
- continue;
183
- }
184
- events[n++] = { type: 'key', key: ch };
185
- i += 1;
156
+ const isPair = code >= 0xd800 && code <= 0xdbff && i + 1 < source.length;
157
+ const size = isPair ? 2 : 1;
158
+ events.push({ type: 'key', key: source.slice(i, i + size) });
159
+ i += size;
186
160
  }
187
- events.length = n;
188
161
  return { events, carry: '' };
189
162
  };
190
163
 
@@ -198,32 +171,26 @@ const hitAction = (hits, x) => {
198
171
  module.exports = {
199
172
  ACTIONS,
200
173
  ACTION_IDS,
174
+ DASH_IDS,
175
+ DASH_HIDDEN,
201
176
  BRANCH_ACTIONS,
202
177
  COMMIT_ACTIONS,
203
178
  DIFF_DISABLED,
204
- FILES_DISABLED,
205
179
  FILES_HIDDEN,
206
180
  FILES_GIT_DISABLED,
207
- FILES_TASKS_DISABLED,
208
181
  TASKS_DISABLED,
209
182
  BRANCHES_DISABLED,
210
183
  COMMITS_DISABLED,
211
184
  NPM_DISABLED,
212
185
  UNIT_DISABLED,
213
- disabledActions,
214
186
  diffGitDisabled,
215
187
  branchGitDisabled,
216
188
  commitGitDisabled,
217
189
  decodeChunk,
218
- actionFromKey,
219
- actionHot,
220
190
  actionLetter,
221
191
  buttonWord,
222
192
  hitAction,
223
193
  CONFIRM,
224
- CONFIRM_MODE,
225
- confirmKey,
226
- applyConfirm,
227
194
  confirmPrefix,
228
195
  promptFromChoices,
229
196
  };