editorconfig / editorconfig

EditorConfig universal issue tracker and wiki
http://editorconfig.org
3.2k stars 103 forks source link

AutoCrlf support (end_of_line = native) #226

Closed otac0n closed 7 years ago

otac0n commented 9 years ago

Git supports checking files out with native line endings.

You can specify this per file type, as well, using a .gitattributes file:

* text=auto

I would like to be able to support this similarly in my .editorconfig files.

I recommend adding an option native to end_of_line, indicating that the file should be forced to use native line endings:

[*]
end_of_line = native

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

jednano commented 9 years ago

I love the idea. Or os would be another name for it.

[*]
end_of_line = os
xuhdev commented 9 years ago

I would support the idea with native option. This is also useful to fit svn.

xuhdev commented 9 years ago

@treyhunner @sindresorhus What do you think?

treyhunner commented 9 years ago

I like the idea except that it makes a project-wide assumption about a user-configurable git setting.

If the user does not have that option set in .gitattributes, this won't behave as expected.

xuhdev commented 9 years ago

@treyhunner .gitattributes can also be project specific so it shouldn't matter IMO.

otac0n commented 9 years ago

@treyhunner I agree. I suggest we put a warning in the docs that it should be accompanied by the proper configuration of your source control provider (if checked in).

treyhunner commented 9 years ago

I hadn't realized you could make a local .gitattributes. I agree with @otac0n's suggestion to clarify the suggested usage of this property in the docs.

I'm :+1: on this but some community input would be nice.

Mpdreamz commented 9 years ago

+1 on native

xuhdev commented 9 years ago

Even the current cr, lf, crlf stuff conflicts with the default settings of some svn clients (native line ending). We should have probably done something about it but it's not too late now.

sindresorhus commented 9 years ago

:-1: The whole point of EditorConfig is to enforce consistency, not just between files, but users and systems.

theoy commented 9 years ago

:+1::+1::+1: support for native line endings. The syntax is less important for me, but I am frequently hit on this with projects where some of the dev team are on Macs and others are on Windows boxes. I'm about to commit a change in our repo to stop using the end_of_line option because it's the wrong design for our team as it stands currently.

@sindresorhus - I love consistency as well, but for better or worse Windows and Unix/Mac have large ecosystems that rely upon linebreak styles that match the OS convention. Git's autocrlf support does the right thing for repositories whose working directories are accessed by a single OS... which is the majority case, I would bet :smile:

jednano commented 9 years ago

Where I get bit on this is projects with LF line endings, configured with end_of_line = lf and then ReSharper inserts a block of code for me with CRLFs (apparently, not configurable), which means next time I open the file in Visual Studio I get a prompt telling me I have mixed line endings. Super frustrating!

If the above feature were introduced, a configuration could include 2 files:

Together, this configuration would allow a Windows user like me to checkout files as CRLF, allow my editor to go crazy with os-native line endings, no mixed line endings would ever be introduced and I will still be submitting code with LF line endings.

rhuijben commented 8 years ago

Subversion will usually automatically fix up line-endings of file towards the setting applied there as long as they are consistent. Using some 'native' would allow me to set a value (enabling this fix-up), while currently I always have to set a flag that is wrong for users on some platforms.

jednano commented 8 years ago

@xuhdev maybe we should move forward with end_of_line = native? It sounds like people are in agreement of the usefulness of this setting.

xuhdev commented 8 years ago

@jedmao Sure. In this case, we only need to update the documentation and add support to browsers. What do you think, @treyhunner ?

maoueh commented 8 years ago

I would like to bring back attention to this post. Adding a native would definitely be a big win for people using project specific .gitattributes to ensure line ending consistency. When file get the text attributes, files are checked-out to working tree using platform's native line ending. In this mode, at least on Windows, if in the working tree the line ending changes to LF (even just one line), git emits a warning when adding file to repository:

$ git add mixed_file.js
warning: LF will be replaced by CRLF in .mixed_file.js. The file will have its original line endings in your working directory..

Hence, if end_of_line = lf is set, when a line is added via the configured editor, line ending will be LF which will then cause a warning to be emitted by git. I would be delighted if this native option could be added and ready to contribute.

That being said, by completely removing the end_of_line setting from the config file, I guess what line ending to put is left to the editor's default choice which is usually to use native line ending (at least on Atom and Eclipse). That could be seen as a workaround until (if) native option is added.

Regards, Matt

forbjok commented 8 years ago

I support end_of_line = native.

Although it would be ideal if we could just force LF everywhere, some editors - Visual Studio in particular - just don't properly support it and tend to create mixed indentation. Being able to use native line endings for those files is a better solution than to force everyone to use CRLF just because some editors can't deal with LF.

danielweck commented 7 years ago

+1 for this feature request. I use eclint to verify files checked-out from GitHub repositories, but on Windows end_of_line = lf fails because of Git's default CRLF config. I am now using end_of_line = crlf lf and it seems to work. https://github.com/jedmao/eclint#end_of_line https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#end_of_line

kfsone commented 7 years ago

This is a deal breaker for some projects where it is important that files be edited according to the local platform.

Consider a cross-platform UI designer written in LanguageX which generates language files and scripts for the current platform, but they are not committed to the repos.

It could have a win32 and an osx folder for generating to, but that's not feeling very cross-platform, is it?

It would make more sense for it's .editorconfig to have "[.x] end-of-line=lf" and "[.sh] end-of-line=lf" and "[.bat] end-of-line = crlf" but finish with "[.cpp] end-of-line = native"

The keyword doesn't have to be native, it could be "platform" or "local" or something, "native" is just the word people who are using svn/git/perforce/etc will be looking for.

There are plenty of other use cases, but this is just one I can see off the top of my head. A way of saying: You should ALWAYS use the same carriage return setting on any machine you work on.

markwoon commented 7 years ago

@xuhdev Any chance of this moving forward?

florianb commented 7 years ago

In my opinion this issue is not relevant anymore since this can be achieved by explicitly setting

end_of_line = unset

Let's close that issue.

theoy commented 7 years ago

@florianb

In my opinion this issue is not relevant anymore since this can be achieved by explicitly setting end_of_line = unset

I'm not sure what's changed to make this less important -- there seems to be a lot of traction for this feature, just discussion on what the keyword for the setting's value should be (whether it's os, native, or autocrlf).

Having an unset value is a consolation prize, but it doesn't help ensure consistency in a codebase. Using something like native/OS means that the code files will always be consistently openable/viewable by all of the OS's text editing/rendering tools (since people may use different tools to do diffs, or different CLI's -- e.g. on Windows you may be using CMD.EXE, PowerShell, or cygwin).

I think this is clearly a usability win for the community that supports contributing to codebases from multiple host operating systems.

florianb commented 7 years ago

I'm sorry, i should have elaborated on this. Adding a "native" option doesn't define anything since the same file opened in different contexts would lead to undefined behavior. And the Editorconfig's purpose is to "define and maintain consistent coding styles between different editors and IDEs". I'd say preserving a specific coding style across environments is exactly what Editorconfig aims for.

Allowing end_of_line having a "native" option would lead to unexpected behavior. If you'd like to preserve the behavior of underlying environments, do not define the setting at all or explicitly "unset" it.

In my opinion the whole issue is out of scope of Editorconfig.

jednano commented 7 years ago

@florianb what you're saying is not actually true, assuming the setting is used in tandem with .gitattributes * text=auto. See https://github.com/editorconfig/editorconfig/issues/226#issuecomment-131959429

Personally, I would use this setting. It would eliminate some issues I've had cloning projects on Windows.

florianb commented 7 years ago

I guess i really misunderstand what the Editorconfig is actually standardizing.

In my personal opinion,

  1. Editorconfig should be respected by every text-manipulating tool in the dev-chain (even ReSharper seems to respect Editorconfig in its actual version).
  2. I don't get the problem about your issue - why even let ReSharper rewrite to another line-ending? And why consider introducing undefined behavior to a standard which addresses the probably biggest hassle in the modern history of computational text editing?
  3. A unconfigured platform specific editor should already fall back to "native" and if not, you could explicitly "fall back" to the native line ending via an additional editorconfig in a higher directory.
  4. This discussion lasts since 2015 without any action for months. Probably 50 people out of thousands of users have this kind of issue. Which is a small user base compared to the amount of people which might once wonder why line endings from one pull to another start behaving strange again.

However - let's invoke action or close it. This issue isn't going to get more mature.

kfsone commented 7 years ago

@florianb Vis your point #4: I suspect there's a nuance behind that. It's very much a cross-platform matter rather than cross-application, which means it will more immediately result in a team being aware that there have been many attempts at solving standardization like this before and leading people to move on without leaving comments etc. This is part opine and part observation of how my current team promptly moved on when I suggested editorconfig.

Problem use case: Team ABC comprises 3 users: User A edits on her MS Surface, User B edits on her Linux box, User C edits on his Macbook.

Any current editorconfig end-of-line value is wrong for this scenario.

Workaround #1: Do not set "root=true" for any .editorconfig in the project, and host all project-related material under a folder that contains an ".editorconfig" with a platform specific "end-of-line" setting. Flaws: May discourage still-relevant configs like "[*.bat] end-of-line: crlf", adds an external dependency/management setting, may result in individuals inappropriately tweaking their "local" or "personal" .editorconfig.

Workaround #2: Do not use end-of-line in .editorconfig. Flaws: Adds a 'but' to the team sales pitch and reduces value of editorconfig.

Note: Python addresses this issue with the 'u' suffix for 'universal newlines'.

jednano commented 7 years ago

@sindresorhus you make a good point about EditorConfig enforcing consistency between systems. I think in a world where version control didn't exist, an end_of_line = native setting would be a bad choice. That doesn't mean we shouldn't support the option though. It just means we should advise against it for projects that aren't under version control or aren't using a feature like * text=auto.

With projects under version control, however, and using * text=auto, I think it changes the game a bit. No longer do we have to be so concerned about "between systems" when Git handles it for us. In this case, we have a unique opportunity to leverage those features by allowing the end of line sequence to match the native OS.

Interestingly, this means that even developers that aren't using an EditorConfig-supported editor will benefit from the setting too, because their editor will probably default to the native OS line endings anyway. This means the likelihood for a user to be tripped up by something end-of-line-related goes down.

To me, the focus of EditorConfig shouldn't be so black and white. Instead, we should be focused more on the user and doing our best to ensure the user doesn't have to mess with settings or configurations to hit the ground running on a new project.

What do you think?

sindresorhus commented 7 years ago

I disagree, and I stand by https://github.com/editorconfig/editorconfig/issues/226#issuecomment-120536850.

theoy commented 7 years ago

I agree with @jedmao -- there is still a lot of value in having end_of_line = native, in that it would keep all tools on the same operating system consistent in their line endings (and potentially help autofix files with inconsistent line endings).

It's just unfortunate that for text/code files, that line endings have differed across operating systems for a very long time. However, many protocols and designs have accepted that, and expect conversion whenever transferring files between OS's (whether that's FTP, or Git, etc.).

I think it would be a mistake for editorconfig to try to impose an exact binary equivalence on all operating systems, and potentially break interoperability between text viewers -- especially when it feels like the goal of editor config was to improve interoperability.

So in my mind, a support of end_of_line = native means that smarter, editorconfig-aware tools would help ensure that lines are most interoperable across all tools on Windows (including ones with less fanciful support like Notepad, or CMD.exe).

kfsone commented 7 years ago

@theoy Specifically: "end_of_line = native" means "Editors should honor platform-specific line endings, transfer tools should perform conversion". This setting translates perfectly well to, e.g, git, scp or ftp once this exists.

jednano commented 7 years ago

@xuhdev, @treyhunner and @Mpdreamz and myself have said 👍 to this feature for a tally of 4. Have any of you changed your mind after the discussion that followed?

@sindresorhus and @florianb have said 👎 to this feature for a tally of 2. They remain resolute.

I feel like this feature should have a unanimous vote, so if it doesn't, I won't push it any longer. @xuhdev, how do you want to proceed? Should we close the issue or go by a majority vote?

xuhdev commented 7 years ago

@jedmao How about initiating a voting procedure? Can you do this, please? I think you are probably more informed on this issue than I do.

kfsone commented 7 years ago

@florianb "I don't get the problem about your issue - why even let ReSharper rewrite to another line-ending? And why consider introducing undefined behavior to a standard which addresses the probably biggest hassle in the modern history of computational text editing?"

You've either not worked cross-platform or you haven't fully thought this thru, a common mistake on developers who overlook mobile development (iOS = mac line endings, Android = linux). And on Windows, a Visual Studio developer may be concurrently working with many platforms at once.

So we aren't asking to introduce it. We're asking for the ability to specify it explicitly.

I have .xaml files that I explicitly want to have platform-specific line endings. I want git to convert them when I check them out on a mac and put them back in git's "native" format on the repos, so that when I check them out on windows they aren't going to annoy visual studio or any of the tools I work with under windows.

That means I also want my IDE and editors to use the native line endings on those files.

But under Windows, in Visual Studio, I have files that I explicitly want to honor a specific platform - I have files that I may edit under Windows in VS while targetting android or iOS. I will be working on them in an alien/host OS and not transferring them. They should always have the target platform line endings.

kfsone commented 7 years ago

@jedmao +1 👍 from me.

jednano commented 7 years ago

@xuhdev, voting is open at https://github.com/editorconfig/editorconfig/issues/327

florianb commented 7 years ago

@kfsone that is my opinion, don't make general assumptions.

XAML files are XML-files, if anything in your XAML-consuming development chain needs something like "native" line endings the used XML-parser is not standard-conform. Go on and file a bug wherever a XAML file with mixed EOLs fails.

jednano commented 7 years ago

It's been a while since I've used Visual Studio, but I remember it would always change the line endings of solution files whenever you open a project. It was terribly annoying and I think the people fighting for this feature are Windows developers. This is just one example of the pains.

jednano commented 7 years ago

@johan the discussion should be here. You're right that it would create a random mess, if used improperly, but the same could be said for end_of_line = lf in combination with .gitattributes * text=auto, as I've seen in a previous project. It was a complete mess.

My point is that we simply need to educate people on the dangers of this setting if used incorrectly; yet, still give the feature to those who need it.

theoy commented 7 years ago

My point is that we simply need to educate people on the dangers of this setting if used incorrectly; yet, still give the feature to those who need it. --@jedmao

Totally agree. I don't think this takes away from users who would prefer a different value (e.g. always insist on lf or crlf). But it would be very valuable to projects that support both Windows and Linux/Mac, and have some sort of facility to convert linebreaks during file transfer (e.g. in Git/FTP/scp).

markwoon commented 7 years ago

Those who are not in favor of end_of_line = native are using a lot of "perfect world" arguments. For those who are fortunate enough to only have to deal with Mac/Linux or Windows, or work with amazing tool chains/editors/libraries, that's great.

But for those of us who don't this is a huge pain in the rear.

Git has had to deal with end of line issues as well and they've come up with a solution that works. It would be nice if editorconfig aligns with it. In my perfect world, we would have end_of_line = gitattributes and I just have to specify eol settings for my group/project in one central place.

jednano commented 7 years ago

I think I might have figured out a configuration that overcomes the desire to have this end_of_line = native setting.

@theoy, @markwoon, @kfsone, @danielweck, @forbjok, tell me if this works for you —

.gitattributes

*               text=auto
*.vcproj    text eol=crlf
  1. Ensures that all text files that any contributor introduces to the repository have their line endings normalized.
  2. Normalizes .vcproj files, ensuring that .vcproj files have CRLF in the working directory.

Combine that with the following EditorConfig configuration:

.editorconfig

root = true;

[*]
end_of_line = lf
# etc.

[*.vcproj]
end_of_line = crlf

Conclusion

Even if someone on Mac/Linux w/o an EditorConfig plugin inadvertently adds LF line endings to *.vcproj files, it doesn't matter, because they get normalized once they are added. Windows users can't possibly mess this up. Even if they don't have an EditorConfig plugin, everything will remain CRLF for *.vcproj files.

Problem solved?

See https://git-scm.com/docs/gitattributes#_end_of_line_conversion

maoueh commented 7 years ago

* text=auto usually converts to crlf on Windows and lf on Unix/Mac OS X. Having end_of_line = lf with * text=auto does work only on Unix/Mac OS X and would fail Windows.

On Windows, this would leave you with a file diff on 100% of the line because Git (on Windows with * text=auto) expect the file to be in crlf and now it's in lf.

maoueh commented 7 years ago

Just to give more precision about how it works with git. When git checkout files to your filesystem, it inspect the git attributes of the file (git-check-attr <path>). If the file is flag a text=auto, before writing to filesystem, git converts the line ending of the file to native platform line ending so crlf on Windows.

On the opposite operation, a commit, when git records the information back to it's database, it converts back from platform native to lf internally.

Git being loose, it's possible to force certain file to have a specific line ending forced. That what you do when specifying *.vcproj text eol=crlf, you are specifying that all *.vcproj have the attribute text as well as the attribute eol=crlf which forces git to always checkout using crlf even when cloned on Unix.

For people having an editor that works well with LF on Windows, it's possible to configure .gitattributes to checkout always using lf:

* text=auto eol=lf

...

That way, eol=lf is force by default for all files types, forcing git to checkin in lf and checkout to filesystem in lf also, even on Windows.

Why it's important to have end_of_line = native? Just to have the freedom to choose how you want file ending to be handled. I had to deal with bad editors on Windows that were not liking lf, so as a team, we had decided to use gitattributes * text=auto to auto-convert to correct line ending.

The unset solution I read above is a compromise IMO, I see native as being more clear and more sure, specially if it has the same effect has not being set at all.

kfsone commented 7 years ago

Again: What people will is just remove "root = true" from their project top-level and have their developers maintain snowflake .editorconfigs above that with their local platform settings.

Please, please, please put the eol-religion aside, because some of us just have to live with it.

Question: Why do you have an indent setting? Because it differs between editors even on the same platform.

Question: Why do you have an 'eol-style' setting in the first place?

xuhdev commented 7 years ago

EditorConfig is designed to enforce consistent coding style in the first place. Now the core question is, are native EOLs part of a consistent coding style? I think this is the basic question that resolves the problem.

If there is no other automation tools, it seems that native EOLs are not part of a consistent coding style—editing on different platforms leads to different coding style. However, if coupled with a version control system (VCS) with some settings, enforcing native EOLs on different platforms actually lead to a consistent coding style in a consistent coding style in the meta-level/central repository. In this sense, It seems that a native EOL does some sort of consistent coding style enforcing.

At this point, I think the core question is: Does enforcing consistent coding style in the meta-level/central repository within the scope of EditorConfig? The meaning of enforcing a consistent coding style to make all future checkout/clone of the code consistent, but I would leave whether checkouts/clones on different platforms lead to different EOLs is considered consistent to further open discussion. I would give a "yes" to this question, albeit I can see disagreement here.

Regarding the unset issue, I don't think it is relevant here: unset really means no relevant editor settings, which is different from enforcing the editor to use a setting.

treyhunner commented 7 years ago

I'm not sure end_of_line = native really fixes this issue because if a user's core.autocrlf setting isn't set correctly in their global .gitconfig, there's still a problem.

So end_of_line = native doesn't seem like something that should be project-level because control over git's core.crlf = input isn't project-level.

It seems like this type of control shouldn't be stored in a project's .editorconfig file but customized at the editor-level. For example if a user wants EditorConfig to ignore the end_of_line setting because it's interacting with their git configuration poorly, allowing that feature of their EditorConfig plugin to be disabled might be reasonable.

jednano commented 7 years ago

@treyhunner it doesn't require a core.autocrlf setting. It can be paired with .gitattributes * text=auto, which doesn't require a user configuration.

Edit: Also, end_of_line = native doesn't have to be project-level, just like Git and EditorConfig don't have to be project level. Those configurations can reside anywhere.

kfsone commented 7 years ago

Not everyone uses git, besides, surely a plugon could be written for it to support editorconfig. But this is still relevant to a universe of cross-platform developers, such as mobile.

Again, I ask: why is there an eol-style setting in the first place, what issue is it intended to solve? If the user is using git to manage eols what is editorconfig's role?

kfsone commented 7 years ago

Not everyone uses git, besides, surely a plugon could be written for it to support editorconfig. But this is still relevant to a universe of cross-platform developers, such as mobile.

Again, I ask: why is there an eol-style setting in the first place, what issue is it intended to solve? If the user is using git to manage eols what is editorconfig's role?

florianb commented 7 years ago

In my opinion Editorconfig explicitly specifies a perfect world on a project level, where necessary.

The end_of_line setting enforces a specific end of line across the the covered files and involved environments. And i believe the first purpose to use Editorconfig is the wish to enforce such file-attributes across all environments to avoid any discussions about what we're talking about when formatting files.

I know that Editorconfig isn't supported on all levels of the development chain (the standard lacks f.e. specific instructions for linters, version control systems and so on). But wherever i we're facing the pain that the current Editorconfig standard isn't working as intended i see it as our task to decide if that problem has its origins in a inappropriate set of Editorconfig-rules or a missing or wrong implementation of the involved tools.

So much as i regret these kind of problems (and i know that my previous comments didn't seem to give that impression) i think it is necessary to fix that in the involved toolchain.