Skip to content

Commit

Permalink
Interesting quick hack for comma-first formatting
Browse files Browse the repository at this point in the history
This doesn't try to fight the user but given the opportunity it will put commas at the start of lines instead of the ends.

Related to #245
  • Loading branch information
bitwiseman committed Jan 30, 2015
1 parent a13f8ce commit 2a6d95f
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 4 deletions.
41 changes: 38 additions & 3 deletions js/lib/beautify.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@
opt.wrap_line_length = (options.wrap_line_length === undefined) ? 0 : parseInt(options.wrap_line_length, 10);
opt.e4x = (options.e4x === undefined) ? false : options.e4x;
opt.end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
opt.comma_first = (options.comma_first === undefined) ? false : options.comma_first;


// force opt.space_after_anon_function to true if opt.jslint_happy
Expand Down Expand Up @@ -441,6 +442,16 @@
}

function print_token(printable_token) {
if (opt.comma_first && last_type === 'TK_COMMA'
&& output.just_added_newline()) {
if(output.previous_line.last() === ',') {
output.previous_line.pop();
print_token_line_indentation();
output.add_token(',');
output.space_before_token = true;
}
}

printable_token = printable_token || current_token.text;
print_token_line_indentation();
output.add_token(printable_token);
Expand Down Expand Up @@ -1021,6 +1032,11 @@
print_newline(false, true);
} else {
output.space_before_token = true;
// for comma-first, we want to allow a newline before the comma
// to turn into a newline after the comma, which we will fixup later
if (opt.comma_first) {
allow_wrap_or_preserved_newline();
}
}
return;
}
Expand All @@ -1035,6 +1051,11 @@
} else {
// EXPR or DO_BLOCK
output.space_before_token = true;
// for comma-first, we want to allow a newline before the comma
// to turn into a newline after the comma, which we will fixup later
if (opt.comma_first) {
allow_wrap_or_preserved_newline();
}
}

}
Expand Down Expand Up @@ -1249,9 +1270,19 @@
}

this.push = function(input) {
_items.push(input);
_character_count += input.length;
_empty = false;
_items.push(input);
_character_count += input.length;
_empty = false;
}

this.pop = function() {
var item = null;
if (!_empty) {
item = _items.pop();
_character_count -= item.length;
_empty = _items.length === 0;
}
return item;
}

this.remove_indent = function() {
Expand Down Expand Up @@ -1290,6 +1321,7 @@
var lines =[];
this.baseIndentString = baseIndentString;
this.indent_string = indent_string;
this.previous_line = null;
this.current_line = null;
this.space_before_token = false;

Expand All @@ -1304,6 +1336,7 @@
}

if (force_newline || !this.just_added_newline()) {
this.previous_line = this.current_line;
this.current_line = new OutputLine(this);
lines.push(this.current_line);
return true;
Expand Down Expand Up @@ -1380,6 +1413,8 @@
this.current_line = lines[lines.length - 1]
this.current_line.trim();
}

this.previous_line = lines.length > 1 ? lines[lines.length - 2] : null;
}

this.just_added_newline = function() {
Expand Down
1 change: 1 addition & 0 deletions js/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ var fs = require('fs'),
"wrap_line_length": Number,
"e4x": Boolean,
"end_with_newline": Boolean,
"comma_first": Boolean,
// CSS-only
"selector_separator_newline": Boolean,
"newline_between_rules": Boolean,
Expand Down
34 changes: 34 additions & 0 deletions js/test/beautify-javascript-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,40 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
test_fragment(' \n\nreturn .5\n\n\n\n', ' return .5');
test_fragment('\n', '');

// Comma-first option - (c0 = "\n, ", c1 = "\n , ", c2 = "\n , ", c3 = "\n , ")
opts.comma_first = true;
bt('{a:1, b:2}', '{\n a: 1\n , b: 2\n}');
bt('var a=1, b=c[d], e=6;', 'var a = 1\n , b = c[d]\n , e = 6;');
bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e');
bt('for(var a=1,b=2,\nc=3;d<3;d++)\ne', 'for (var a = 1, b = 2\n , c = 3; d < 3; d++)\n e');
bt('function foo() {\n return [\n "one"\n , "two"\n ];\n}');
bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , [7, 8]\n]');
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , [7, 8]\n]');
bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , function() {}\n , [7, 8]\n]');
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , [7, 8]\n]');
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]');
bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c\n , function() {}\n , function() {}\n , d\n]');
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]');
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]');
bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\n [\n ["1", "2"]\n , ["3", "4"]\n ]\n , [\n ["5", "6", "7"]\n , ["8", "9", "0"]\n ]\n , [\n ["1", "2", "3"]\n , ["4", "5", "6", "7"]\n , ["8", "9", "0"]\n ]\n]');

// Comma-first option - (c0 = ",\n", c1 = ",\n ", c2 = ",\n ", c3 = ",\n ")
opts.comma_first = false;
bt('{a:1, b:2}', '{\n a: 1,\n b: 2\n}');
bt('var a=1, b=c[d], e=6;', 'var a = 1,\n b = c[d],\n e = 6;');
bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e');
bt('for(var a=1,b=2,\nc=3;d<3;d++)\ne', 'for (var a = 1, b = 2,\n c = 3; d < 3; d++)\n e');
bt('function foo() {\n return [\n "one",\n "two"\n ];\n}');
bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]');
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]');
bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n function() {},\n [7, 8]\n]');
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]');
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]');
bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c,\n function() {},\n function() {},\n d\n]');
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]');
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]');
bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\n [\n ["1", "2"],\n ["3", "4"]\n ],\n [\n ["5", "6", "7"],\n ["8", "9", "0"]\n ],\n [\n ["1", "2", "3"],\n ["4", "5", "6", "7"],\n ["8", "9", "0"]\n ]\n]');

// New Test Suite

// Old tests
Expand Down
34 changes: 34 additions & 0 deletions python/jsbeautifier/tests/testjsbeautifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,40 @@ def unicode_char(value):
test_fragment(' \n\nreturn .5\n\n\n\n', ' return .5')
test_fragment('\n', '')

# Comma-first option - (c0 = "\n, ", c1 = "\n , ", c2 = "\n , ", c3 = "\n , ")
self.options.comma_first = true
bt('{a:1, b:2}', '{\n a: 1\n , b: 2\n}')
bt('var a=1, b=c[d], e=6;', 'var a = 1\n , b = c[d]\n , e = 6;')
bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e')
bt('for(var a=1,b=2,\nc=3;d<3;d++)\ne', 'for (var a = 1, b = 2\n , c = 3; d < 3; d++)\n e')
bt('function foo() {\n return [\n "one"\n , "two"\n ];\n}')
bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , [7, 8]\n]')
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , [7, 8]\n]')
bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , function() {}\n , [7, 8]\n]')
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2]\n , [4, 5]\n , function() {}\n , [7, 8]\n]')
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]')
bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c\n , function() {}\n , function() {}\n , d\n]')
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]')
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]')
bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\n [\n ["1", "2"]\n , ["3", "4"]\n ]\n , [\n ["5", "6", "7"]\n , ["8", "9", "0"]\n ]\n , [\n ["1", "2", "3"]\n , ["4", "5", "6", "7"]\n , ["8", "9", "0"]\n ]\n]')

# Comma-first option - (c0 = ",\n", c1 = ",\n ", c2 = ",\n ", c3 = ",\n ")
self.options.comma_first = false
bt('{a:1, b:2}', '{\n a: 1,\n b: 2\n}')
bt('var a=1, b=c[d], e=6;', 'var a = 1,\n b = c[d],\n e = 6;')
bt('for(var a=1,b=2,c=3;d<3;d++)\ne', 'for (var a = 1, b = 2, c = 3; d < 3; d++)\n e')
bt('for(var a=1,b=2,\nc=3;d<3;d++)\ne', 'for (var a = 1, b = 2,\n c = 3; d < 3; d++)\n e')
bt('function foo() {\n return [\n "one",\n "two"\n ];\n}')
bt('a=[[1,2],[4,5],[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]')
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]')
bt('a=[[1,2],[4,5],function(){},function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n function() {},\n [7, 8]\n]')
bt('a=[[1,2],[4,5],function(){},[7,8]]', 'a = [\n [1, 2],\n [4, 5],\n function() {},\n [7, 8]\n]')
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]')
bt('a=[b,c,\nfunction(){},function(){},d]', 'a = [b, c,\n function() {},\n function() {},\n d\n]')
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]')
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]')
bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]', '[\n [\n ["1", "2"],\n ["3", "4"]\n ],\n [\n ["5", "6", "7"],\n ["8", "9", "0"]\n ],\n [\n ["1", "2", "3"],\n ["4", "5", "6", "7"],\n ["8", "9", "0"]\n ]\n]')

# New Test Suite

# Old tests
Expand Down
48 changes: 47 additions & 1 deletion test/data/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,52 @@ exports.test_data = {
{ fragment: ' \n\nreturn .5\n\n\n\n', output: ' return .5{{eof}}' },
{ fragment: '\n', output: '{{eof}}' }
],
}, {
name: "Comma-first option",
description: "Put commas at the start of lines instead of the end",
matrix: [
{
options: [
{ name: "comma_first", value: "true" }
],
c0: '\\n, ',
c1: '\\n , ',
c2: '\\n , ',
c3: '\\n , '
}, {
options: [
{ name: "comma_first", value: "false" }
],
c0: ',\\n',
c1: ',\\n ',
c2: ',\\n ',
c3: ',\\n '
}
],
tests: [
{ input: '{a:1, b:2}', output: "{\n a: 1{{c1}}b: 2\n}" },
{ input: 'var a=1, b=c[d], e=6;', output: 'var a = 1{{c1}}b = c[d]{{c1}}e = 6;' },
{ input: "for(var a=1,b=2,c=3;d<3;d++)\ne", output: "for (var a = 1, b = 2, c = 3; d < 3; d++)\n e" },
{ input: "for(var a=1,b=2,\nc=3;d<3;d++)\ne", output: "for (var a = 1, b = 2{{c2}}c = 3; d < 3; d++)\n e" },
{ input: 'function foo() {\n return [\n "one"{{c2}}"two"\n ];\n}' },
{ input: 'a=[[1,2],[4,5],[7,8]]', output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}[7, 8]\n]" },
{ input: 'a=[[1,2],[4,5],function(){},[7,8]]',
output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}function() {}{{c1}}[7, 8]\n]" },
{ input: 'a=[[1,2],[4,5],function(){},function(){},[7,8]]',
output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}function() {}{{c1}}function() {}{{c1}}[7, 8]\n]" },
{ input: 'a=[[1,2],[4,5],function(){},[7,8]]',
output: "a = [\n [1, 2]{{c1}}[4, 5]{{c1}}function() {}{{c1}}[7, 8]\n]" },
{ input: 'a=[b,c,function(){},function(){},d]',
output: "a = [b, c, function() {}, function() {}, d]" },
{ input: 'a=[b,c,\nfunction(){},function(){},d]',
output: "a = [b, c{{c1}}function() {}{{c1}}function() {}{{c1}}d\n]" },
{ input: 'a=[a[1],b[4],c[d[7]]]', output: "a = [a[1], b[4], c[d[7]]]" },
{ input: '[1,2,[3,4,[5,6],7],8]', output: "[1, 2, [3, 4, [5, 6], 7], 8]" },

{ input: '[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
output: '[\n [\n ["1", "2"]{{c2}}["3", "4"]\n ]{{c1}}[\n ["5", "6", "7"]{{c2}}["8", "9", "0"]\n ]{{c1}}[\n ["1", "2", "3"]{{c2}}["4", "5", "6", "7"]{{c2}}["8", "9", "0"]\n ]\n]' },

],
}, {
name: "New Test Suite"
},
Expand Down Expand Up @@ -295,7 +341,7 @@ exports.test_data = {
{ comment: 'regexps',
input: 'a(/abc\\\\/\\\\/def/);b()', output: "a(/abc\\\\/\\\\/def/);\nb()" },
{ input: 'a(/a[b\\\\[\\\\]c]d/);b()', output: "a(/a[b\\\\[\\\\]c]d/);\nb()" },
{ comment: 'incomplete char class', fragment: 'a(/a[b\\\\[', output: "a(/a[b\\\\[" },
{ comment: 'incomplete char class', fragment: 'a(/a[b\\\\[', output: "a(/a[b\\\\[" },

{ comment: 'allow unescaped / in char classes',
input: 'a(/[a/b]/);b()', output: "a(/[a/b]/);\nb()" },
Expand Down

0 comments on commit 2a6d95f

Please sign in to comment.