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.
- package/CHANGELOG.md +12 -1
- package/LICENSE +1 -1
- package/README.md +11 -11
- package/bin/reslop.js +3 -8
- package/lib/ansi.js +32 -19
- package/lib/capabilities.js +8 -8
- package/lib/cli.js +40 -74
- package/lib/clipboard.js +39 -47
- package/lib/dashboard/git.js +128 -0
- package/lib/dashboard/model.js +332 -0
- package/lib/dashboard/npm.js +193 -0
- package/lib/dashboard/tree.js +278 -0
- package/lib/deps-diff.js +197 -402
- package/lib/deps.js +113 -240
- package/lib/detect.js +8 -18
- package/lib/diff/align.js +41 -113
- package/lib/diff/diff.js +12 -43
- package/lib/diff/display.js +25 -36
- package/lib/diff/edit.js +6 -20
- package/lib/diff/inline.js +76 -144
- package/lib/diff/items.js +33 -47
- package/lib/diff/parse.js +28 -56
- package/lib/diff/patch.js +12 -33
- package/lib/diff/unit.js +79 -178
- package/lib/editor.js +52 -69
- package/lib/files.js +71 -89
- package/lib/git-branches.js +254 -416
- package/lib/git-deps.js +147 -272
- package/lib/git-reword-todo.js +5 -13
- package/lib/git-worktree.js +141 -212
- package/lib/git.js +21 -49
- package/lib/github.js +67 -181
- package/lib/gitlab.js +40 -90
- package/lib/highlight/bash.js +55 -177
- package/lib/highlight/core.js +155 -141
- package/lib/highlight/css.js +25 -58
- package/lib/highlight/csv.js +19 -37
- package/lib/highlight/dart.js +72 -213
- package/lib/highlight/dot.js +14 -14
- package/lib/highlight/html.js +42 -63
- package/lib/highlight/js.js +177 -506
- package/lib/highlight/json.js +17 -37
- package/lib/highlight/log.js +19 -25
- package/lib/highlight/txt.js +7 -10
- package/lib/highlight.js +17 -46
- package/lib/keys.js +49 -82
- package/lib/manifest.js +67 -126
- package/lib/npm-commands.js +120 -169
- package/lib/remote.js +140 -190
- package/lib/render/branches.js +63 -61
- package/lib/render/chrome.js +220 -333
- package/lib/render/commits.js +160 -361
- package/lib/render/dash-activity.js +212 -0
- package/lib/render/dash-blocks.js +245 -0
- package/lib/render/dash-table.js +290 -0
- package/lib/render/dashboard.js +62 -0
- package/lib/render/diff.js +123 -258
- package/lib/render/files.js +40 -85
- package/lib/render/frame.js +78 -117
- package/lib/render/notes.js +139 -210
- package/lib/render/npm.js +213 -177
- package/lib/render/present.js +4 -11
- package/lib/render/primitives.js +72 -174
- package/lib/render/render.js +5 -14
- package/lib/render/report.js +43 -0
- package/lib/render/tiles.js +260 -0
- package/lib/render/unit.js +15 -31
- package/lib/report-model.js +110 -33
- package/lib/report-parse.js +56 -37
- package/lib/report-render.js +102 -59
- package/lib/report-run.js +87 -77
- package/lib/report-test.js +221 -99
- package/lib/report-tools.js +96 -154
- package/lib/review-merge.js +33 -41
- package/lib/review.js +68 -129
- package/lib/runs.js +225 -0
- package/lib/select.js +53 -91
- package/lib/session/accessors.js +14 -21
- package/lib/session/actions.js +61 -43
- package/lib/session/branches.js +166 -222
- package/lib/session/change-actions.js +49 -119
- package/lib/session/commit.js +274 -355
- package/lib/session/compose.js +556 -714
- package/lib/session/dashboard.js +385 -0
- package/lib/session/dispatch.js +162 -170
- package/lib/session/files-pane.js +76 -44
- package/lib/session/items.js +6 -17
- package/lib/session/lifecycle.js +393 -466
- package/lib/session/load.js +1 -14
- package/lib/session/navigation.js +2 -2
- package/lib/session/npm.js +403 -420
- package/lib/session/ops.js +5 -13
- package/lib/session/pointer.js +16 -14
- package/lib/session/progress.js +39 -30
- package/lib/session/review.js +1 -3
- package/lib/session/tasks.js +276 -235
- package/lib/session/templates.js +51 -59
- package/lib/session/terminal.js +85 -132
- package/lib/session/view.js +47 -81
- package/lib/session/watch.js +196 -212
- package/lib/session.js +81 -161
- package/lib/update.js +44 -111
- package/lib/utilities.js +46 -88
- package/lib/wrap.js +29 -55
- package/package.json +1 -1
package/lib/highlight/json.js
CHANGED
|
@@ -1,51 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const core = require('./core.js');
|
|
4
|
-
const { emit,
|
|
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
|
|
16
|
-
|
|
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
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
};
|
package/lib/highlight/log.js
CHANGED
|
@@ -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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
26
|
-
if (
|
|
27
|
-
emit(out, 'logDate',
|
|
28
|
-
rest = rest.slice(
|
|
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 =
|
|
28
|
+
const tag = LOG_TAG_RE.exec(rest);
|
|
31
29
|
if (tag) {
|
|
32
30
|
emit(out, 'plain', tag[1]);
|
|
33
|
-
const name = tag[2].
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
package/lib/highlight/txt.js
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
|
10
|
-
const SKIP = ['core.js'];
|
|
6
|
+
const PLUGIN_NAMES = words('bash css csv dart dot html js json log txt');
|
|
11
7
|
|
|
12
|
-
const
|
|
13
|
-
|
|
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
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
45
|
+
const style = typeof token.style === 'string' && token.style;
|
|
69
46
|
pieces.push({
|
|
70
47
|
text: tokenText.slice(tokenOff, tokenOff + n),
|
|
71
|
-
style:
|
|
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
|
-
|
|
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 {
|
|
7
|
-
const {
|
|
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 {
|
|
11
|
-
const {
|
|
12
|
-
const {
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
73
|
+
return modifiedKey(base, params[1]);
|
|
93
74
|
};
|
|
94
75
|
|
|
95
|
-
const
|
|
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
|
-
|
|
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 =
|
|
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'
|
|
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
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
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
|
|
123
|
+
if (rest.length < 3) return NEED_MORE;
|
|
142
124
|
const key = CSI_KEYS[rest[2]];
|
|
143
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
152
|
+
events.push({ type: 'key', key: `ctrl-${letter}` });
|
|
176
153
|
i += 1;
|
|
177
154
|
continue;
|
|
178
155
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
};
|