Skip to content

Commit 94803f5

Browse files
authored
Fix input handling for (function() => { ... (#7)
The implementation assumed that in cases like the above input, everything before the `()` would be highlighted the same regardless of what follows afterwards, however, for `function`, the parentheses have actual meaning. Therefore, only remove `()` for code highlighting input size reduction if they are: - Not the last match in the code, or - Followed by something that definitely terminates the input block, i.e. a closing bracket, quote, etc. Fixes: https://jira.mongodb.org/browse/MONGOSH-759
1 parent 26a48e3 commit 94803f5

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

lib/pretty-repl.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,26 @@ class PrettyREPLServer extends repl.REPLServer {
177177
// - matching pairs of "", with only non-"\, \\, and \" preceded by an even number of \ in between
178178
// - matching pairs of ``, with only non-`{}\, \\ and \` preceded by an even number of \ in between
179179
const re = /\([^\(\)\[\]\{\}`'"]*\)|\[[^\(\)\[\]\{\}`'"]*\]|\{[^\(\)\[\]\{\}`'"]*\}|'([^'\\]|(?<=[^\\](\\\\)*)\\'|\\\\)*'|"([^"\\]|(?<=[^\\](\\\\)*)\\"|\\\\)*"|`([^\{\}`\\]|(?<=[^\\](\\\\)*)\\`|\\\\)*`/g;
180-
return str.replace(re, '');
180+
// Match the regexp against the input. If there are no matches, we can just return.
181+
const matches = [...str.matchAll(re)];
182+
if (matches.length === 0) {
183+
return str;
184+
}
185+
// Remove all but the last, non-nested pair of (), because () can affect
186+
// whether the previous word is seen as a keyword.
187+
// E.g.: When input is `function() {`, do not replace the ().
188+
// When input is `{ foo(); }`, do replace the `()`, then afterwards the `{ ... }`.
189+
let startsReplaceIndex = matches.length - 1;
190+
const lastMatch = matches[matches.length - 1];
191+
if (lastMatch[0].startsWith('(') && !str.substr(lastMatch.index + lastMatch[0].length).match(/[\)\]\}`'"]/)) {
192+
startsReplaceIndex--;
193+
}
194+
for (let i = startsReplaceIndex; i >= 0; i--) {
195+
// Replace str1<match>str2 with str1str2. Go backwards so that the match
196+
// indices into the string remain valid.
197+
str = str.substr(0, matches[i].index) + str.substr(matches[i].index + matches[i][0].length);
198+
}
199+
return str;
181200
});
182201
}
183202

test/index.spec.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ test('memoizeStringTransformerMethod', t => {
104104
});
105105

106106
test('stripCompleteJSStructures', t => {
107-
t.plan(6);
107+
t.plan(10);
108108
const { stdin } = stdio();
109109
const output = new PassThrough();
110110
output.isTTY = true;
@@ -119,6 +119,10 @@ test('stripCompleteJSStructures', t => {
119119
t.equal(prettyRepl._stripCompleteJSStructures(String.raw `"abc\"def"`), '');
120120
t.equal(prettyRepl._stripCompleteJSStructures(String.raw `"abc\\"def"`), 'def"');
121121
t.equal(prettyRepl._stripCompleteJSStructures(String.raw `"a\\\\bc\\"def"`), 'def"');
122+
t.equal(prettyRepl._stripCompleteJSStructures('(function {}'), '(function ');
123+
t.equal(prettyRepl._stripCompleteJSStructures('(function() {'), '(function() {');
124+
t.equal(prettyRepl._stripCompleteJSStructures('(function() => {'), '(function() => {');
125+
t.equal(prettyRepl._stripCompleteJSStructures('(function() => {}'), '(function => ');
122126
});
123127

124128
test('full pass-through test', t => {

0 commit comments

Comments
 (0)