Skip to content

Commit 71b577f

Browse files
Bas van Kervelkaralabe
authored andcommitted
[release/1.4.7] console: ignore round and curly brackets in strings when determining indentation level
(cherry picked from commit dbcdf83)
1 parent a93d63d commit 71b577f

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

console/console.go

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,11 @@ func (c *Console) Interactive() {
331331
// Append the line to the input and check for multi-line interpretation
332332
input += line + "\n"
333333

334-
indents = strings.Count(input, "{") + strings.Count(input, "(") - strings.Count(input, "}") - strings.Count(input, ")")
334+
indents = countIndents(input)
335335
if indents <= 0 {
336336
prompt = c.prompt
337337
} else {
338-
prompt = strings.Repeat("..", indents*2) + " "
338+
prompt = strings.Repeat(".", indents*3) + " "
339339
}
340340
// If all the needed lines are present, save the command and run
341341
if indents <= 0 {
@@ -354,6 +354,49 @@ func (c *Console) Interactive() {
354354
}
355355
}
356356

357+
// countIndents returns the number of identations for the given input.
358+
// In case of invalid input such as var a = } the result can be negative.
359+
func countIndents(input string) int {
360+
var (
361+
indents = 0
362+
inString = false
363+
strOpenChar = ' ' // keep track of the string open char to allow var str = "I'm ....";
364+
charEscaped = false // keep track if the previous char was the '\' char, allow var str = "abc\"def";
365+
)
366+
367+
for _, c := range input {
368+
switch c {
369+
case '\\':
370+
// indicate next char as escaped when in string and previous char isn't escaping this backslash
371+
if !charEscaped && inString {
372+
charEscaped = true
373+
}
374+
case '\'', '"':
375+
if inString && !charEscaped && strOpenChar == c { // end string
376+
inString = false
377+
} else if !inString && !charEscaped { // begin string
378+
inString = true
379+
strOpenChar = c
380+
}
381+
charEscaped = false
382+
case '{', '(':
383+
if !inString { // ignore brackets when in string, allow var str = "a{"; without indenting
384+
indents++
385+
}
386+
charEscaped = false
387+
case '}', ')':
388+
if !inString {
389+
indents--
390+
}
391+
charEscaped = false
392+
default:
393+
charEscaped = false
394+
}
395+
}
396+
397+
return indents
398+
}
399+
357400
// Execute runs the JavaScript file specified as the argument.
358401
func (c *Console) Execute(path string) error {
359402
return c.jsre.Exec(path)

console/console_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,49 @@ func TestPrettyError(t *testing.T) {
294294
t.Fatalf("pretty error mismatch: have %s, want %s", output, want)
295295
}
296296
}
297+
298+
// Tests that tests if the number of indents for JS input is calculated correct.
299+
func TestIndenting(t *testing.T) {
300+
testCases := []struct {
301+
input string
302+
expectedIndentCount int
303+
}{
304+
{`var a = 1;`, 0},
305+
{`"some string"`, 0},
306+
{`"some string with (parentesis`, 0},
307+
{`"some string with newline
308+
("`, 0},
309+
{`function v(a,b) {}`, 0},
310+
{`function f(a,b) { var str = "asd("; };`, 0},
311+
{`function f(a) {`, 1},
312+
{`function f(a, function(b) {`, 2},
313+
{`function f(a, function(b) {
314+
var str = "a)}";
315+
});`, 0},
316+
{`function f(a,b) {
317+
var str = "a{b(" + a, ", " + b;
318+
}`, 0},
319+
{`var str = "\"{"`, 0},
320+
{`var str = "'("`, 0},
321+
{`var str = "\\{"`, 0},
322+
{`var str = "\\\\{"`, 0},
323+
{`var str = 'a"{`, 0},
324+
{`var obj = {`, 1},
325+
{`var obj = { {a:1`, 2},
326+
{`var obj = { {a:1}`, 1},
327+
{`var obj = { {a:1}, b:2}`, 0},
328+
{`var obj = {}`, 0},
329+
{`var obj = {
330+
a: 1, b: 2
331+
}`, 0},
332+
{`var test = }`, -1},
333+
{`var str = "a\""; var obj = {`, 1},
334+
}
335+
336+
for i, tt := range testCases {
337+
counted := countIndents(tt.input)
338+
if counted != tt.expectedIndentCount {
339+
t.Errorf("test %d: invalid indenting: have %d, want %d", i, counted, tt.expectedIndentCount)
340+
}
341+
}
342+
}

0 commit comments

Comments
 (0)