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.
- package/CHANGELOG.md +22 -1
- package/LICENSE +1 -1
- package/README.md +11 -11
- package/bin/reslop.js +3 -8
- package/lib/ansi.js +72 -19
- package/lib/api.js +1 -1
- package/lib/capabilities.js +8 -8
- package/lib/cli.js +61 -75
- package/lib/clipboard.js +39 -47
- package/lib/dashboard/git.js +128 -0
- package/lib/dashboard/model.js +357 -0
- package/lib/dashboard/npm.js +290 -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 +79 -91
- package/lib/find.js +61 -0
- package/lib/git-branches.js +254 -416
- package/lib/git-deps.js +148 -272
- package/lib/git-reword-todo.js +5 -13
- package/lib/git-worktree.js +161 -214
- 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 +75 -83
- 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 +412 -347
- package/lib/render/commits.js +160 -361
- package/lib/render/dash-activity.js +212 -0
- package/lib/render/dash-blocks.js +496 -0
- package/lib/render/dash-table.js +295 -0
- package/lib/render/dashboard.js +62 -0
- package/lib/render/diff.js +123 -258
- package/lib/render/files.js +60 -86
- package/lib/render/frame.js +82 -117
- package/lib/render/notes.js +150 -210
- package/lib/render/npm.js +213 -177
- package/lib/render/packages.js +93 -0
- package/lib/render/present.js +4 -11
- package/lib/render/primitives.js +77 -172
- package/lib/render/render.js +5 -14
- package/lib/render/report.js +43 -0
- package/lib/render/repos.js +226 -0
- package/lib/render/search.js +25 -0
- package/lib/render/tiles.js +355 -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 +69 -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 +189 -65
- package/lib/session/branches.js +164 -222
- package/lib/session/change-actions.js +49 -119
- package/lib/session/commit.js +298 -352
- package/lib/session/compose.js +572 -715
- package/lib/session/dashboard.js +530 -0
- package/lib/session/dispatch.js +197 -171
- package/lib/session/files-pane.js +92 -45
- package/lib/session/find.js +94 -0
- package/lib/session/items.js +6 -17
- package/lib/session/lifecycle.js +420 -466
- package/lib/session/load.js +1 -14
- package/lib/session/navigation.js +4 -2
- package/lib/session/npm.js +403 -420
- package/lib/session/ops.js +5 -13
- package/lib/session/packages.js +143 -0
- package/lib/session/pointer.js +30 -14
- package/lib/session/progress.js +39 -30
- package/lib/session/review.js +1 -3
- package/lib/session/tasks.js +277 -236
- package/lib/session/templates.js +51 -59
- package/lib/session/terminal.js +85 -132
- package/lib/session/view.js +59 -80
- package/lib/session/watch.js +201 -212
- package/lib/session/workspace.js +455 -0
- package/lib/session.js +95 -161
- package/lib/update.js +44 -111
- package/lib/utilities.js +46 -88
- package/lib/workspace.js +166 -0
- 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,14 @@
|
|
|
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,
|
|
14
|
-
const { confirmPrefix, promptFromChoices } = actions;
|
|
10
|
+
const { diffGitDisabled, branchGitDisabled, commitGitDisabled } = actions;
|
|
11
|
+
const { entryHasDiff, lineHasDiff, withoutMoves } = actions;
|
|
12
|
+
const { actionLetter, buttonWord } = actions;
|
|
13
|
+
const { CONFIRM, confirmPrefix, promptFromChoices } = actions;
|
|
15
14
|
|
|
16
15
|
const CSI_KEYS = {
|
|
17
16
|
A: 'up',
|
|
@@ -22,14 +21,35 @@ const CSI_KEYS = {
|
|
|
22
21
|
F: 'end',
|
|
23
22
|
};
|
|
24
23
|
|
|
24
|
+
const SS3_KEYS = {
|
|
25
|
+
...CSI_KEYS,
|
|
26
|
+
P: 'f1',
|
|
27
|
+
Q: 'f2',
|
|
28
|
+
R: 'f3',
|
|
29
|
+
S: 'f4',
|
|
30
|
+
};
|
|
31
|
+
|
|
25
32
|
const CSI_TILDE = {
|
|
26
33
|
1: 'home',
|
|
34
|
+
2: 'insert',
|
|
27
35
|
3: 'delete',
|
|
28
36
|
4: 'end',
|
|
29
37
|
5: 'pageUp',
|
|
30
38
|
6: 'pageDown',
|
|
31
39
|
7: 'home',
|
|
32
40
|
8: 'end',
|
|
41
|
+
11: 'f1',
|
|
42
|
+
12: 'f2',
|
|
43
|
+
13: 'f3',
|
|
44
|
+
14: 'f4',
|
|
45
|
+
15: 'f5',
|
|
46
|
+
17: 'f6',
|
|
47
|
+
18: 'f7',
|
|
48
|
+
19: 'f8',
|
|
49
|
+
20: 'f9',
|
|
50
|
+
21: 'f10',
|
|
51
|
+
23: 'f11',
|
|
52
|
+
24: 'f12',
|
|
33
53
|
};
|
|
34
54
|
|
|
35
55
|
const CSI_MAX = 16;
|
|
@@ -48,34 +68,17 @@ const MOUSE_WHEEL = {
|
|
|
48
68
|
65: 'wheelDown',
|
|
49
69
|
};
|
|
50
70
|
|
|
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
|
-
};
|
|
71
|
+
const NEED_MORE = { needMore: true };
|
|
67
72
|
|
|
68
|
-
const
|
|
69
|
-
const mod = parseInt(modText, 10);
|
|
70
|
-
if (!Number.isFinite(mod)) return 0;
|
|
71
|
-
return mod - 1;
|
|
72
|
-
};
|
|
73
|
+
const keyAt = (key, end) => ({ event: { type: 'key', key }, end });
|
|
73
74
|
|
|
74
|
-
const modifiedKey = (base,
|
|
75
|
+
const modifiedKey = (base, modText) => {
|
|
75
76
|
const arrow =
|
|
76
77
|
base === 'left' || base === 'right' || base === 'up' || base === 'down';
|
|
77
78
|
const end = base === 'home' || base === 'end';
|
|
78
79
|
if (!arrow && !end) return base;
|
|
80
|
+
const mod = parseInt(modText, 10);
|
|
81
|
+
const bits = Number.isFinite(mod) ? mod - 1 : 0;
|
|
79
82
|
const ctrl = (bits & 4) !== 0;
|
|
80
83
|
const shift = (bits & 1) !== 0;
|
|
81
84
|
if (ctrl && shift && arrow) return `ctrl-shift-${base}`;
|
|
@@ -89,15 +92,28 @@ const keyFromCsi = (paramsText, final) => {
|
|
|
89
92
|
const base = final === '~' ? CSI_TILDE[params[0]] : CSI_KEYS[final];
|
|
90
93
|
if (!base) return null;
|
|
91
94
|
if (params.length < 2) return base;
|
|
92
|
-
return modifiedKey(base,
|
|
95
|
+
return modifiedKey(base, params[1]);
|
|
93
96
|
};
|
|
94
97
|
|
|
95
|
-
const
|
|
98
|
+
const parseCsi = (rest, start) => {
|
|
99
|
+
let i = 2;
|
|
100
|
+
while (i < rest.length) {
|
|
101
|
+
const code = rest.charCodeAt(i);
|
|
102
|
+
if (code >= 64 && code <= 126) break;
|
|
103
|
+
i += 1;
|
|
104
|
+
}
|
|
105
|
+
if (i >= rest.length) {
|
|
106
|
+
return rest.length > CSI_MAX ? keyAt('escape', start + 1) : NEED_MORE;
|
|
107
|
+
}
|
|
108
|
+
const key = keyFromCsi(rest.slice(2, i), rest[i]);
|
|
109
|
+
return key ? keyAt(key, start + i + 1) : keyAt('escape', start + 1);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const mouseKind = (button, press) => {
|
|
96
113
|
const wheel = MOUSE_WHEEL[button];
|
|
97
114
|
if (wheel) return wheel;
|
|
98
115
|
if (!press) return 'release';
|
|
99
|
-
|
|
100
|
-
return 'press';
|
|
116
|
+
return button & 32 ? 'drag' : 'press';
|
|
101
117
|
};
|
|
102
118
|
|
|
103
119
|
const parseMouse = (body, flag) => {
|
|
@@ -110,81 +126,60 @@ const parseMouse = (body, flag) => {
|
|
|
110
126
|
return null;
|
|
111
127
|
}
|
|
112
128
|
const press = flag === 'M';
|
|
113
|
-
const kind =
|
|
129
|
+
const kind = mouseKind(button, press);
|
|
114
130
|
return { type: 'mouse', button, x, y, press, kind, btn: button & 3 };
|
|
115
131
|
};
|
|
116
132
|
|
|
117
133
|
const parseEsc = (text, start) => {
|
|
118
134
|
const rest = text.slice(start);
|
|
119
|
-
if (rest === '\x1b'
|
|
120
|
-
if (rest.startsWith('\x1b[') && rest.length === 2) return { needMore: true };
|
|
135
|
+
if (rest === '\x1b' || rest === '\x1b[') return NEED_MORE;
|
|
121
136
|
if (rest.startsWith('\x1b[<')) {
|
|
122
137
|
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 };
|
|
138
|
+
if (endM < 0) return NEED_MORE;
|
|
139
|
+
const mouse = parseMouse(rest.slice(3, endM), rest[endM]);
|
|
140
|
+
const end = start + endM + 1;
|
|
141
|
+
return mouse ? { event: mouse, end } : keyAt('escape', end);
|
|
139
142
|
}
|
|
143
|
+
if (rest.startsWith('\x1b[')) return parseCsi(rest, start);
|
|
140
144
|
if (rest.startsWith('\x1bO')) {
|
|
141
|
-
if (rest.length < 3) return
|
|
142
|
-
const key =
|
|
143
|
-
|
|
144
|
-
return { event: { type: 'key', key: 'escape' }, end: start + 1 };
|
|
145
|
+
if (rest.length < 3) return NEED_MORE;
|
|
146
|
+
const key = SS3_KEYS[rest[2]];
|
|
147
|
+
return key ? keyAt(key, start + 3) : keyAt('escape', start + 1);
|
|
145
148
|
}
|
|
146
|
-
return
|
|
149
|
+
return keyAt('escape', start + 1);
|
|
147
150
|
};
|
|
148
151
|
|
|
149
152
|
const decodeChunk = (text, carry = '') => {
|
|
150
153
|
const source = carry + text;
|
|
151
|
-
const events =
|
|
152
|
-
let n = 0;
|
|
154
|
+
const events = [];
|
|
153
155
|
let i = 0;
|
|
154
156
|
while (i < source.length) {
|
|
155
157
|
const ch = source[i];
|
|
156
158
|
if (ch === '\x1b') {
|
|
157
159
|
const parsed = parseEsc(source, i);
|
|
158
|
-
if (parsed.needMore) {
|
|
159
|
-
|
|
160
|
-
return { events, carry: source.slice(i) };
|
|
161
|
-
}
|
|
162
|
-
events[n++] = parsed.event;
|
|
160
|
+
if (parsed.needMore) return { events, carry: source.slice(i) };
|
|
161
|
+
events.push(parsed.event);
|
|
163
162
|
i = parsed.end;
|
|
164
163
|
continue;
|
|
165
164
|
}
|
|
166
165
|
const named = LITERAL_KEY[ch];
|
|
166
|
+
const code = source.charCodeAt(i);
|
|
167
167
|
if (named) {
|
|
168
|
-
events
|
|
168
|
+
events.push({ type: 'key', key: named });
|
|
169
169
|
i += 1;
|
|
170
170
|
continue;
|
|
171
171
|
}
|
|
172
|
-
const code = source.charCodeAt(i);
|
|
173
172
|
if (code >= 1 && code <= 26) {
|
|
174
173
|
const letter = String.fromCharCode(96 + code);
|
|
175
|
-
events
|
|
174
|
+
events.push({ type: 'key', key: `ctrl-${letter}` });
|
|
176
175
|
i += 1;
|
|
177
176
|
continue;
|
|
178
177
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
events[n++] = { type: 'key', key: ch };
|
|
185
|
-
i += 1;
|
|
178
|
+
const isPair = code >= 0xd800 && code <= 0xdbff && i + 1 < source.length;
|
|
179
|
+
const size = isPair ? 2 : 1;
|
|
180
|
+
events.push({ type: 'key', key: source.slice(i, i + size) });
|
|
181
|
+
i += size;
|
|
186
182
|
}
|
|
187
|
-
events.length = n;
|
|
188
183
|
return { events, carry: '' };
|
|
189
184
|
};
|
|
190
185
|
|
|
@@ -198,32 +193,29 @@ const hitAction = (hits, x) => {
|
|
|
198
193
|
module.exports = {
|
|
199
194
|
ACTIONS,
|
|
200
195
|
ACTION_IDS,
|
|
196
|
+
DASH_IDS,
|
|
197
|
+
DASH_HIDDEN,
|
|
201
198
|
BRANCH_ACTIONS,
|
|
202
199
|
COMMIT_ACTIONS,
|
|
203
200
|
DIFF_DISABLED,
|
|
204
|
-
FILES_DISABLED,
|
|
205
201
|
FILES_HIDDEN,
|
|
206
202
|
FILES_GIT_DISABLED,
|
|
207
|
-
FILES_TASKS_DISABLED,
|
|
208
203
|
TASKS_DISABLED,
|
|
209
204
|
BRANCHES_DISABLED,
|
|
210
205
|
COMMITS_DISABLED,
|
|
211
206
|
NPM_DISABLED,
|
|
212
207
|
UNIT_DISABLED,
|
|
213
|
-
disabledActions,
|
|
214
208
|
diffGitDisabled,
|
|
209
|
+
entryHasDiff,
|
|
210
|
+
lineHasDiff,
|
|
211
|
+
withoutMoves,
|
|
215
212
|
branchGitDisabled,
|
|
216
213
|
commitGitDisabled,
|
|
217
214
|
decodeChunk,
|
|
218
|
-
actionFromKey,
|
|
219
|
-
actionHot,
|
|
220
215
|
actionLetter,
|
|
221
216
|
buttonWord,
|
|
222
217
|
hitAction,
|
|
223
218
|
CONFIRM,
|
|
224
|
-
CONFIRM_MODE,
|
|
225
|
-
confirmKey,
|
|
226
|
-
applyConfirm,
|
|
227
219
|
confirmPrefix,
|
|
228
220
|
promptFromChoices,
|
|
229
221
|
};
|