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

[clang-format] Support .clang-format-ignore file #52975

Closed
mkurdej opened this issue Jan 4, 2022 · 14 comments · Fixed by #76327
Closed

[clang-format] Support .clang-format-ignore file #52975

mkurdej opened this issue Jan 4, 2022 · 14 comments · Fixed by #76327
Assignees
Labels
clang-format enhancement Improving things as opposed to bug fixing, e.g. new or missing feature

Comments

@mkurdej
Copy link
Member

mkurdej commented Jan 4, 2022

An idea split from #27467.
The gist is to be able to specify files that should not be formatted.
It could work in a similar way as .gitignore files (possibly the same syntax).

@mkurdej mkurdej added enhancement Improving things as opposed to bug fixing, e.g. new or missing feature clang-format labels Jan 4, 2022
@mydeveloperday
Copy link
Contributor

I like this idea, I often have generated files that I don't want to clang-format. (resource.h).

I notice clang-power tools has this capability built in. PowerTools

@thoni56
Copy link

thoni56 commented Jul 12, 2022

I too, like this. I was googling for a way to do just that, ignore generated files although they match the pattern clang-format usually would format. One example is C source generated from Yacc.

@Badokas
Copy link

Badokas commented Aug 6, 2022

I was looking online how to ignore formatting for 3rd party code in specific folders and bumped into this issue. +1 for this feature!

@hrandib
Copy link

hrandib commented Aug 29, 2022

Another case is to exclude 3rd party submodule without polluting it with another .clang-format file just to ignore, +1 from me

@benner
Copy link

benner commented Aug 9, 2023

Another case is to exclude 3rd party submodule without polluting it with another .clang-format file just to ignore, +1 from me

this is exactly why I want this too

@Hadatko
Copy link

Hadatko commented Oct 18, 2023

+1

@owenca owenca self-assigned this Dec 7, 2023
@owenca
Copy link
Contributor

owenca commented Dec 9, 2023

I've come up with the following spec for the .clang-format-ignore file:

  • A blank line is skipped.
  • Leading and trailing spaces of a line are trimmed.
  • A line starting with a hash (#) is a comment.
  • A non-comment line is a single pattern.
  • The slash (/) is used as the directory separator.
  • A pattern is relative to the directory of the .clang-format-ignore file (or the root directory if the pattern starts with a slash).
  • If a pattern ends with a slash, all files in a directory are ignored.
  • If a pattern is a single dot (.), all files in the directory of the .clang-format-ignore file are ignored.
  • Patterns follow the glob rules POSIX 2.13.1, 2.13.2, and Rule 1 of 2.13.3.
  • A pattern is negated if it starts with a bang (!).

Multiple .clang-format-ignore files are supported similar to the .clang-format files, with a lower directory level file overriding voiding the higher level ones.

@owenca
Copy link
Contributor

owenca commented Dec 9, 2023

@bersbersbers
Copy link

A pattern is relative to ... the root directory if the pattern starts with a slash

Is that intentionally different from how .gitignore files work? https://git-scm.com/docs/gitignore

with a lower directory level file overriding the higher level ones

This appears a little unclear. Does the file override the other file, meaning, all of that other file's patterns are ignored, or are the patterns merged (that would be .gitignore behavior).

@HazardyKnusperkeks
Copy link
Contributor

* A pattern is relative to the directory of the `.clang-format-ignore` file (or the root directory if the pattern starts with a slash).

Do we need support for absolute paths? That should be an anti-pattern for code repositories.
Also, then you would need a way to define absolute paths on windows.

I'm not against this feature, but I really don't think its that useful resp. one should spent time on implementing it.

You want to disable formatting of a single source file? // clang-format off in that file.
You want to disable formatting for third party code? .clang-format with DisableFormat: true in that directory resp. your directory for all 3rd party code (that's what I'm doing)
You want to disable formatting of generated code? Same as above, eventually you need to move such files in a separate directory. (Which is in my opinion also a good idea.)

@owenca
Copy link
Contributor

owenca commented Dec 9, 2023

A pattern is relative to ... the root directory if the pattern starts with a slash

Is that intentionally different from how .gitignore files work? https://git-scm.com/docs/gitignore

Yes.

with a lower directory level file overriding the higher level ones

This appears a little unclear. Does the file override the other file, meaning, all of that other file's patterns are ignored, or are the patterns merged (that would be .gitignore behavior).

The former. I've updated the wording in the spec above.

@owenca
Copy link
Contributor

owenca commented Dec 9, 2023

Do we need support for absolute paths?

No, but I need to handle it instead of letting it be skipped silently. Also, I want to match the behavior (more or less) of running ls <pattern> in the directory of the .clang-format-ignore file.

I'm not against this feature, but I really don't think its that useful resp. one should spent time on implementing it.

I agree that absolute path patterns are not very useful, but we need to handle it for completeness. BTW, I have already implemented it without much extra work, and it has negligible impact on performance. 🙂

You want to disable formatting of a single source file? // clang-format off in that file.

That doesn't always work well in practice. See e.g. #27467.

@owenca
Copy link
Contributor

owenca commented Dec 10, 2023

I've removed the support for patterns with a trailing slash to simplify the spec and avoid possible confusions. To match all files in a directory, use e.g. foo/bar/*. To match all files in the directory of the .clang-format-ignore file, use *.

@owenca
Copy link
Contributor

owenca commented Dec 22, 2023

Update: I'll wrap this up as soon as #76021 is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang-format enhancement Improving things as opposed to bug fixing, e.g. new or missing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants