Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support comma first style of variable declaration #245

Closed
mrchief opened this issue Apr 23, 2013 · 27 comments
Closed

Support comma first style of variable declaration #245

mrchief opened this issue Apr 23, 2013 · 27 comments

Comments

@mrchief
Copy link

mrchief commented Apr 23, 2013

Allow code to be formatted like this:

var a = 1
  , b = "somethign else"
  , isAwesome = true;

And apparently, we have a somewhat ready patch available. Would be great if this can get included in here!

@evocateur
Copy link
Contributor

Considering we support both JS and Python, the patch (which is severely out of date) is incomplete, at best.

We're open to pull requests, but I personally consider "comma-first" an anti-pattern. At its core, js-beautifier is opinionated about how JS should look, with reasonable options that largely conform to widely-accepted "idiomatic" JS. Comma-first is, in my opinion, not beautiful, nor is it widely-accepted. What's more, it will severely complicate the beautifier code (which is already incredibly complicated) for very little gain.

With indent=4 set, which indentation is appropriate? From a consistency standpoint, I would argue this:

var a = 1
    , b = "foo"
    , c = false;

Which is clearly not the expected output. And how would it look with tab indents?

Where does the semi-colon live? At the end? Nowhere? (I've seen both, and more)

@bitwiseman
Copy link
Member

This gist is just as out-of-date, but makes for easier understanding of the desired change: https://gist.github.com/nemtsov/2864266/revisions

This is similar to #80, so I thought the reasons for it might be the same - easier diffing and reordering.

But in this scenario, unlike #80, there is a viable workaround that meets those requirements:

var a = 1;
var b = "foo";
var c = false;

It is slightlly more verbose, but not horrendous.

Of course, if someone implements #80, the simplest change would probably cover this scenario as well.
As @evocateur said, pull requests welcome.

@mrchief
Copy link
Author

mrchief commented Apr 24, 2013

@evocateur: You're entitled to your opinion and I respect that. Personally I've always disliked comma first style but throughout years, I've come to appreciate the ease of moving, taking out (commenting, deleting etc.) and as @bitwiseman says - diffing. So I'm willing to leave this as an option and let the user do whatever he prefers. Sometimes, its not in his hands and he has to go by already set standards. Yeah, fugly but reality!

@bitwiseman: At any level of indent (2 or 4), I guess this is how it should look:

var a = 1
  , b = "foo"
  , c = false;

I think this is also consistent with how some of SQL editors (where comma first is more prevalent) do it.

And while I'm not advocating promoting bad layouts, I guess there is always a fine line between being idiomatic and dogmatic (think Crockford here). Comma first may not be prevalent because many of the formatters don't support it, whatever may be their reason.

You're more familiar with the state of affairs code-wise so I perfectly agree your ROI argument. Nevertheless, I thought of asking so that we can get these things out in the open, have a quorum to discuss things and if there is demand from community, maybe you guys can rethink about it.

P.S. I spent a couple of hours trying to see if I can quickly spin off something and wasn't very successful. Maybe I'll give it a shot some other time.

@evocateur
Copy link
Contributor

@mrchief My apologies for being brusque yesterday, I was taking a break from a frustrating debugging session. You make good points, and I want to be clear that I respect your choice as well. I myself attempt to maintain the style of a given project if I'm contributing a patch (comma-first, no-semicolons, other wackiness), and I do agree that options like these can at the very least help enforce a little bit of consistency in the projects that choose to employ them.

@tgirardi
Copy link

+1. I use the comma-first pattern for it's advantages when diffing and merging.

As for the position of the semi-colon: I put it in a newline, in line with the var keyword, like this:

var a
  , b
  , c
;

I've seen several projects that use the same pattern.

Also, IMHO, i think it would be nice to be able to keep each variable in a separate line, even-though a value is not given next to the declaration. In the example above, the beautifier would group everything in one line var a, b, c; which also breaks the whole purpose of using comma fist style.

@lukemartin
Copy link

+1 for comma-first support.

At 2-space indentation, it's the tidiest way of arranging variables:

var foo = true
  , bar = 'hello'
  , something;

@evocateur
Copy link
Contributor

What about 4 spaces per tab? Actual tabs?

On Fri, Nov 8, 2013 at 9:36 AM, Luke Martin notifications@github.com
wrote:

+1 for comma-first support.
At 2-space indentation, it's the tidiest way of arranging variables
var foo = true
, bar = 'hello'

, something;

Reply to this email directly or view it on GitHub:
#245 (comment)

@lukemartin
Copy link

I guess the crux of the comma-first issue actually comes down to tab preference.

I use 2-space tabs, and comma-before is the only way to arrange variables without adding unnecessary whitespace (~ represent extra spaces added to make things line up):

// eww
var foo = true,
  ~~bar = 'hello',
  ~~something;

// yum
var foo = true
  , bar = 'hello'
  , something;

Conversely, if you use 4-space tabs, comma-before is going to look bad, and you naturally won't care about support for it.

// also eww
var foo = true
    , bar = 'hello'
    , something;

So there's discussion about comma-before being easier to comment and debug and blah blah blah. But to me, it just comes down to aesthetics. I use 2-space tabs, so I need to use comma-before. Currently I can't use beautify because I have a preference for 2-space tabs.

Now I know I'm probably in a minority, and I'm absolutely not demanding support for my little preference. I was just adding my +1 to the conversation. I might even look at adding support myself if I get the time.

Cheers :)

@asdf23
Copy link

asdf23 commented Nov 8, 2013

I would like to see this for json objects.

var a = ({
     a: 1
    ,b: 2
});

@mrchief
Copy link
Author

mrchief commented Nov 12, 2013

@lukemartin That is an interesting perspective! 👍

@domdoescode
Copy link

Another +1 for comma first support, for variable declaration as well as array and objects - https://gist.github.com/isaacs/357981

@tgirardi
Copy link

I've been working on a patch to support this feature "on demand" (the user can enable or disable the option of using comma first with a setting I've created).

I've achieved the following formatting for variable declaration (using 2 spaces):

var firstVar = 1
  , secondVar = 2
  , thirdVar = 3
;

But I have some doubts.

How should we treat arrays, objects and arguments declarations? Lately I've been using the following format:

myArray = [
  item1
, item2
, item3
];

myObject = {
  prop1: 1
, prop2: 2
, prop3: 3
}

Which, as you can see, is not exactly the same as the variable declaration formatting: this last one includes a +1 indentation level for the second variable (notice the two spaces before the comma that are not present before the comma for "item2" nor for the one for "prop2"). Var declarations use this extra indentation in order to align in the same column the start of each variable name as stated by @lukemartin.

The reasons for using the formatting shown on the above code are:

1.- To avoid the linting errors that would be thrown by jshint (indentation errors). For example:

myArray = [
    item1
  , item2
];

Throws "Expected ] to have an indentation at 3, instead at 1". If we follow the suggestion, we get a very ugly result.

2.- To maintain the advantage of aligning the start of each property name, array item, etc. For example:

myArray = [
  item1
  , item2
];

Also doesn't produce a linting error, but doesn't look as nice as the examples above.

With a more clear idea of how I should treat those cases I could finish the implementation of this feature and issue a Pull Request.

@joeybaker
Copy link

Is it possible to support all the above? Everything you listed is technically "comma first".

@tgirardi
Copy link

I believe it could be possible, but it would be necessary to implement more settings that would allow the user to achieve the desired result. For example, it would be necessary to tell the formatter if you want to use 2 indentation levels for arrays, objects and arguments or just one.

I think it would be better to achieve the basic functionality first, and then extend it with more settings. I believe i would have no problem implementing those in a second patch.

@bitwiseman
Copy link
Member

As you say, basic functionality is fine. It is a non-goal of this project to support all formatting options. 😄

// 2-space indents
var itemA = 1
  , itemB: 2
  , itemC: 3;

myObj = {
  itemA: 1
  , itemB: 2
}

myArray = [
  item1
  , item2
];

// 4-space indents
var itemA = 1
    , itemB: 2
    , itemC: 3;

myObj = {
    itemA: 1
    , itemB: 2
}

myArray = [
    item1
    , item2
];

These should keep your code simple, the formatting consistent no matter what indents are used, and lets us close this issue, and open a new issue for "Columnize comma-first identifiers" (or whatever) that can be spec'd and implemented separately.

I look forward to seeing your pull request!

@lukemartin
Copy link

@tgirardi Great work. Can't wait to try this out.

tgirardi added a commit to tgirardi/js-beautify that referenced this issue Dec 17, 2013
Support "comma first" style when declaring variables or properties
inside an object, as discussed on issue beautifier#245.

The proposed solution is based on changing the order of the newline
(before / after the comma) depending on the value for the new option
"comma_first". The proposed command line argument for this option
is "-F" or "--comma_first").

It is also necessary to modify the indentation string used for some
particular lines, in order to include the comma as part of the
indentation string and achieve the desired result regarding
indentation (in some cases it is easier to think of the comma as part
of the indentation string, in replace of a whitespace).

TODO 1: tests for this feature

TODO 2: implement the feature in the python version (I prefer to get
feedback for this commit first and, once the feature's JS code is
considered correct, then proceed with the py code).

TODO 3: in the future, other variations for the indentation pattern,
for object properties, could be allowed. The currently allowed one
looks like this:

{
  prop1: 1
, prop2: 2
, prop3: 3
}

Another version could be:

{
    prop1: 1
  , prop2: 2
  , prop3: 3
}

In "other words", the first property is double indented. However, it
must be noted that jslint errors related with the indentation could
arise (tested with JSHint).
@tgirardi
Copy link

All Feedback welcomed :-) !!!

My idea is to adjust the code until it is considered as the correct solution and then proceed with the following TODO list:

1.- Create tests for this new feature
2.- Apply feature on the Python version (If anyone volunters for this, even better! ... I don't have much experience with python).
3.- Discuss other possible variations of comma-first styles

@lewisdiamond
Copy link

4-spaces indent

var x = a
    , y = b
;
obj = {
    attr1: "value1"
    , attr2: "value2"
    , attr3: "value3"
};

The variable names and attribute names need not to be lined up. This doesn't affect readability at all. In my opinion, the main reason for using column-first is to make commenting, removing and inserting lines easier. It just happens to line up when using 2-spaces indent.

The semi-column should be on its own line after the declaration of multiple variables to make it easier to append a new variable after 'y'. In this case in VIM, 'o' + ', z = c' instead of '$a,' + 'z = c'

@tgirardi
Copy link

tgirardi commented Jul 9, 2014

@lewisdiamond I agree with your semi-colon comment. Having it in it's own line ensures that the last variable can also be easily edited (remove, replace, insert line after/before, etc).

But it's also been noted that:

1.- Its not the goal of the project to support all kinds of formatting.
2.- Adding too much complexity at once is a bad idea. So it could be better to keep this feature as simple as possible first and start improving it after it has reached a release state and been tested for some time

@olsonpm
Copy link
Contributor

olsonpm commented Jan 15, 2015

+1 for comma first support, and I agree with lewisdiamond's sentiment that ensuring tabs line up properly should not be the end goal as there are pragmatic reasons for the comma-first style. I would love support for json as well. Currently I have a hack in the global js-beautify code to do a lot of punctuation-first alternatives (for ternary operators was a must).

bitwiseman added a commit that referenced this issue Jan 30, 2015
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

Conflicts:
	js/lib/beautify.js
	js/lib/cli.js
@bitwiseman
Copy link
Member

To everyone who +1'd this: please take a look at branch https://github.com/beautify-web/js-beautify/tree/feature/comma-first .

Tell me if this is a sufficient first step towards what you want that I should add it to the next release.

bitwiseman added a commit that referenced this issue Jan 30, 2015
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
@bitwiseman
Copy link
Member

@olsonpm
Copy link
Contributor

olsonpm commented Mar 3, 2015

I will spend 30 minutes on it tonight and respond with thoughts. Thanks for following up.

@bitwiseman bitwiseman modified the milestone: v1.5.5 Mar 4, 2015
@olsonpm
Copy link
Contributor

olsonpm commented Mar 4, 2015

Got around to it this morning. It all looks good to me due to your tests. I have a personal branch with a lot of operator first functionality - I put my comma-first tests through your branch and they all passed no problem which is great news.

When I created my personal branch, I decided the comma-first operator would be passive, meaning the following:

var a,
    b;

would not be changed. You clearly stated this is not the case in the commit message, I just feel it's worth discussing with others what behavior they'd expect if they chose to use opt.comma_first.

Another thing, <Output>.previous_line and flags.previous_text are the same thing I believe, which was confusing to me at first but made sense in how you used it.

Other than that, the main difference between our implementations is that you opted to modify the previous line. I was trying not to "go back and edit things" because I thought it was more confusing to develop. Now your way is more concise than mine - it is easily read and you commented everything. The existing code also edits previous tokens so your code is perfectly in line - honestly I'm just bringing it up because I'd like to know what your thoughts are. In short, my opinion is that this program would be much easier to debug if tokens were only in charge of the white space ahead of them based on next tokens.

Thanks for addressing this!

Edit: My mistake - <Output>.previous_line and flags.previous_text are completely different.

@bitwiseman
Copy link
Member

Forward-only is preferable. I looked at the hairball of how and where we decide what to do with/about commas, there are already places that we trim the output back to get them in the right place. I decided to do something a little simplistic, get some tests in that verify the simplistic behavior and then see about tuning and refactor it later.

The example you mention:

var a,
    b;

Would be an example of tuning that could be discussed later.

@olsonpm
Copy link
Contributor

olsonpm commented Mar 4, 2015

Sounds good. I appreciate the feedback.

@bitwiseman
Copy link
Member

And thank you very much for looking it over. If you have any tests you want to add that would be a great help.

@bitwiseman bitwiseman added this to the v1.5.5 milestone Mar 4, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants