A .editorconfig file can apply to any language. It is used by an IDE to enforce coding conventions.
In .Net, file .editorconfig is located at solution/project root.
.editorconfig uses INI format.
.editorconfig files should be UTF-8 encoded, with LF or CRLF line separators
[editorconfig.org]
.editorconfig files can be used in a hierarchy.
Lower-level configs override higher-level configs.
Set "root=true" in the preamble to say "don't look for a high-level config, this is it".
Anywhere a .editorconfig is found when in your project, the IDE searches upward in the directories until it finds a "root" or reaches the root of the filesystem.
.editorconfig files are read top-to-bottom.
Lower-down rules can override higher-up rules.
Leading whitespaces are ignored.
Lines can be:
- blank
- comments
- section header
- key-value pair
The preamble is everything above the first Section Header.
Optional.
Setting "root=true" means don't search in parent directories for more .editorconfig. This is the root.
# http://editorconfig.org
root = true
Comments are lines starting with ; or #
Only full-line comments are allowed
Section headers are enclosed in [ ]
- uses / as path separator on all operating systems
Section name is the text between the [ ]
Section names are filepath Globs and support pattern matching
- * for any string of characters, except for path separators
- ** for any string of characters
- ? for any single character
- [abc] for any single character in the defined group
- [!abc] for any single character not in the defined group
- {s1,s2,s3} for any string defined in the set
- {num1..num2} for any integer defined in the range (negatives are allowed)
- \ to escape a special character
- Section names have a max length of 4096
- Non-existing directories will not cause an error
Ex:
[*] will apply to all files in the project
[*.md] will apply to all Markdown files in the project
[*.{cs,vb}] will apply to all CS and all VB files in the project
A section is all the lines from one section header to the next, or to the end of file.
Key-Value pair looks like Key=Value or Key = Value
- strings are not enclosed in "quotes"
Any key-value pair can be disregarded with an unset command
# set a value
insert_final_newline = true
# ignore that value
insert_final_newline = unset
# http://editorconfig.org
root = true
# Global settings
[*]
max_line_length = 0
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
# Markdown
[*.md]
trim_trailing_whitespace = false
# Dotnet code style settings
[*.{cs,vb}]
indent_size = 4
indent_style = tab
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_event = false:error
Key-Value pairs recognised by all parsers.
[editorconfig Specification]
Only use in the preamble. Specify this file as the root config.
root = true
# use hard tabs
indent_style = tab
# use soft tabs
indent_style = space
Defines the number of indent characters to use at each level.
# whole number
indent_size = 4
# use the tab_width value
indent_size = tab
Defines the number of columns (characters widths) used to represent a tab.
Defaults to indent_size if tab_width is not specified.
# whole number
tab_width = 4
# carriage return
end_of_line = cr
# carriage return + line feed
end_of_line = crlf
# line feed
end_of_line = lf
charset = latin1
charset = utf-8
charset = utf-8-bom
charset = utf-16be
charset = utf-16le
# remove whitespace that preceeds a newline
trim_trailing_whitespace = true
# leave the whitespace as is
trim_trailing_whitespace = false
# ensure file's last character is a newline
insert_final_newline = true
# doesn't care
insert_final_newline = false
Key-Value pairs recognised by .Net IDEs.
[documentation]
Value format is "value:severity".
error - violation causes compiler error (this does not stop a build)
warning - violation causes compiler warning
suggestion - violation causes a suggestion (such as three gray dots under the code)
silent - violation causes nothing, but suggestion appears in the Refactorings menu, and auto-generated code uses this style
aka refactoring
none - violation causes nothing, but auto-generated code uses this style
"true" means you should qualify members with the "this" keyword. ("me" is the Visual Basic version of "this")
"false" means you should not qualify members with the "this" keyword.
[*.{cs,vb}]
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
"true" means you should say "int" instead of "Int32".
"false" means you should say "Int32" instead of "int".
[*.{cs,vb}]
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
Should accessibility modifiers be specified? (private, public, protected)
[*.{cs,vb}]
dotnet_style_require_accessibility_modifiers = always:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
dotnet_style_require_accessibility_modifiers = never:suggestion
dotnet_style_require_accessibility_modifiers = omit_if_default:suggestion
"for_non_interface_members" currently works the same as "always".
When this rule is set, it is set to an ordered list of modifiers. This is the order preferred in the code.
[*.cs]
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
[*.vb]
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
Should a field that CAN be marked "readonly", be marked such?
[*.{cs,vb}]
dotnet_style_readonly_field = true:warning
Prefer "a + (b * c)" over "a + b * c"
[*.{cs,vb}]
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:silent
Prefer "(a < b) == (c > d)" over "a < b == c > d"
[*.{cs,vb}]
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:silent
Prefer "a || (b && c)" over "a || b && c"
[*.{cs,vb}]
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:silent
Prefer "(a.b).Length" over "a.b.Length"
[*.{cs,vb}]
dotnet_style_parentheses_in_other_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
[*.{cs,vb}]
# prefer var c = new Customer() { Age = 21 };
dotnet_style_object_initializer = true:suggestion
# prefer var c = new Customer(); c.Age = 21;
dotnet_style_object_initializer = false:suggestion
[*.{cs,vb}]
# prefer var list = new List<int> { 1, 2, 3 };
dotnet_style_collection_initializer = true:suggestion
# prefer var list = new List<int>(); list.Add(1); list.Add(2); list.Add(3);
dotnet_style_collection_initializer = false:suggestion
[*.{cs,vb}]
# prefer (string name, int age) customer = GetCustomer(); var name = customer.name;
dotnet_style_explicit_tuple_names = true:suggestion
# prefer (string name, int age) customer = GetCustomer(); var name = customer.Item1;
dotnet_style_explicit_tuple_names = false:suggestion
[*.{cs,vb}]
# prefer var tuple = (age, name);
dotnet_style_prefer_inferred_tuple_names = true:suggestion
# prefer var tuple = (age: age, name: name);
dotnet_style_prefer_inferred_tuple_names = false:suggestion
[*.{cs,vb}]
# prefer var anon = new { age, name };
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
# prefer var anon = new { age = age, name = name };
dotnet_style_prefer_inferred_anonymous_type_member_names = false:suggestion
[*.{cs,vb}]
# prefer private int Age { get; }
dotnet_style_prefer_auto_properties = true:silent
# prefer private int age; public int Age { get { return age; } }
dotnet_style_prefer_auto_properties = false:silent
[*.{cs,vb}]
# prefer if (value is null) return;
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
# prefer if (object.ReferenceEquals(value, null)) return;
dotnet_style_prefer_is_null_check_over_reference_equality_method = false:suggestion
[*.{cs,vb}]
# prefer string s = expr ? "hello" : "world";
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
# prefer string s; if (expr) { s = "hello"; } else { s = "world"; }
dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion
[*.{cs,vb}]
# prefer return expr ? "hello" : "world"
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
# prefer if (expr) { return "hello"; } else { return "world"; }
dotnet_style_prefer_conditional_expression_over_return = false:suggestion
[*.{cs,vb}]
# prefer x += 1;
dotnet_style_prefer_compound_assignment = true:suggestion
# prefer x = x + 1;
dotnet_style_prefer_compound_assignment = false:suggestion
[*.cs]
# prefer void DoWork(CancellationToken cancellationToken = default) { ... }
csharp_prefer_simple_default_expression = true:suggestion
# prefer void DoWork(CancellationToken cancellationToken = default(CancellationToken)) { ... }
csharp_prefer_simple_default_expression = false:suggestion
[*.{cs,vb}]
# prefer var v = x ?? y;
dotnet_style_coalesce_expression = true:suggestion
# prefer var v = x != null ? x : y;
dotnet_style_coalesce_expression = false:suggestion
[*.{cs,vb}]
# prefer var v = o?.ToString();
dotnet_style_null_propagation = true:suggestion
# prefer var v = o == null ? null : o.ToString();
dotnet_style_null_propagation = false:suggestion
[*.cs]
# prefer this.s = s ?? throw new ArgumentNullException(nameof(s));
csharp_style_throw_expression = true:suggestion
# prefer if (s == null) { throw new ArgumentNullException(nameof(s)); } this.s = s;
csharp_style_throw_expression = false:suggestion
[*.cs]
# prefer func?.Invoke(args);
csharp_style_conditional_delegate_call = true:suggestion
# prefer if (func != null) { func(args); }
csharp_style_conditional_delegate_call = false:suggestion
Prefer that unused method parameters are removed from the method signature.
[*.{cs,vb}]
# apply to all methods
dotnet_code_quality_unused_parameters = all:suggestion
# apply to non-public methods only
dotnet_code_quality_unused_parameters = non_public:suggestion
[*.{cs}]
# prefer var x = 5;
csharp_style_var_for_built_in_types = true:suggestion
# prefer int x = 5;
csharp_style_var_for_built_in_types = false:suggestion
[*.{cs}]
# prefer var obj = new Customer();
csharp_style_var_when_type_is_apparent = true:suggestion
# prefer Customer obj = new Customer();
csharp_style_var_when_type_is_apparent = false:suggestion
[*.{cs}]
# prefer var f = this.Init();
csharp_style_var_elsewhere = true:suggestion
# prefer bool f = this.Init();
csharp_style_var_elsewhere = false:suggestion
"true" means the expression-body is preferred over block-body.
"false" means the block-body is preferred over the expression-body.
"when_on_single_line" means expression-body is preferred when it results in a single line.
[*.{cs}]
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_accessors = true:suggestion
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
[*.{cs}]
# prefer if (o is int i) {...}
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
# prefer if (o is int) {var i = (int)o; ... }
csharp_style_pattern_matching_over_is_with_cast_check = false:suggestion
[*.{cs}]
# prefer if (o is string s) {...}
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# prefer var s = o as string; if (s != null) {...}
csharp_style_pattern_matching_over_as_with_null_check = false:suggestion
[*.{cs}]
# prefer if (int.TryParse(value, out int i) {...}
csharp_style_inlined_variable_declaration = true:suggestion
# prefer int i; if (int.TryParse(value, out i) {...}
csharp_style_inlined_variable_declaration = false:suggestion
"true" means use curly braces even around single-line blocks.
"false" means don't use curly braces if the compiler does not require them.
"when_multiline" means use curly braces around multi-line blocks.
[*.{cs}]
csharp_prefer_braces = true:suggestion
csharp_prefer_braces = false:suggestion
csharp_prefer_braces = when_multiline:suggestion
[*.{cs}]
# prefer _ = System.Convert.ToInt32("35");
csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
# prefer var unused = Convert.ToInt32("35");
csharp_style_unused_value_expression_statement_preference = unused_local_variable:suggestion
[*.{cs}]
# prefer _ = wordCount.TryGetValue(searchWord, out var count);
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
# prefer var unused = wordCount.TryGetValue(searchWord, out var count);
csharp_style_unused_value_assignment_preference = unused_local_variable:suggestion
[*.{cs}]
# prefer var index = names[^1];
csharp_style_prefer_index_operator = true:suggestion
# prefer var index = names[names.Length - 1];
csharp_style_prefer_index_operator = false:suggestion
[*.{cs}]
# prefer var sub = sentence[0..^4];
csharp_style_prefer_range_operator = true:suggestion
# prefer var sub = sentence.Substring(0, sentence.Length - 4);
csharp_style_prefer_range_operator = false:suggestion
[*.{cs}]
# prefer var (name, age) = GetPersonTuple(); (int x, int y) = GetPointTuple();
csharp_style_deconstructed_variable_declaration = true:suggestion
# prefer var person = GetPersonTuple(); (int x, int y) point = GetPointTuple();
csharp_style_deconstructed_variable_declaration = false:suggestion
[*.{cs}]
# prefer int fibonacci(int n) { return n <= 1 ? 1 : fibonacci(n-1) + fibonacci(n-2); }
csharp_style_pattern_local_over_anonymous_function = true:suggestion
# prefer Func<int, int> fibonacci = null; fibonacci = (int n) => { return n <= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); };
csharp_style_pattern_local_over_anonymous_function = false:suggestion
"outside_namespace" means using statements should be placed outside the namespace.
"inside_namespace" means using statements should be placed inside the namespace.
[*.{cs}]
csharp_using_directive_placement = outside_namespace:suggestion
csharp_using_directive_placement = inside_namespace:suggestion
"true" means local functions should be explicitly declared static.
[*.{cs}]
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_static_local_function = false:suggestion
[*.{cs}]
# prefer using var a = b;
csharp_prefer_simple_using_statement = true:suggestion
# prefer using (var a = b) { }
csharp_prefer_simple_using_statement = false:suggestion
[*.{cs}]
# prefer return x switch { 1 => 1 * 1, 2 => 2 * 2, _ => 0, };
csharp_style_prefer_switch_expression = true:suggestion
# prefer switch (x) { case 1: return 1 * 1; case 2: return 2 * 2; default: return 0; }
csharp_style_prefer_switch_expression = false:suggestion
Key-Value pairs recognised by .Net IDEs.
[documentation]
"true" means sort System.* directives alphabetically and place above all others.
[*.{cs,vb}]
dotnet_sort_system_directives_first = true
dotnet_sort_system_directives_first = false
"true" means insert a blank line between groups of using directives, based on their root namespace.
[*.{cs,vb}]
dotnet_separate_import_directive_groups = true
dotnet_separate_import_directive_groups = false
When should an opening brace { be placed on a new line? Specify "all", "none", or a specific list of elements that the rule applies to.
[*.cs]
csharp_new_line_before_open_brace = all
csharp_new_line_before_open_brace = none
csharp_new_line_before_open_brace = accessors, anonymous_methods, anonymous_types, control_blocks, events, indexers, lambdas, local_functions, methods, object_collection_array_initializers, properties, types
"true" means these statements should start on a new line.
[*.cs]
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
"true" means these statements should be indented extra.
[*.cs]
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = true
csharp_indent_block_contents = true
csharp_indent_braces = true
csharp_indent_case_contents_when_block = true
"true" means spaces should be inserted.
[*.cs]
csharp_space_after_cast = true
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_parentheses = control_flow_statements, type_casts
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_parameter_list_parentheses = true
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = true
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_after_comma = true
csharp_space_before_comma = false
csharp_space_after_dot = false
csharp_space_before_dot = false
csharp_space_after_semicolon_in_for_statement = true
csharp_space_before_semicolon_in_for_statement = false
csharp_space_around_declaration_statements = false
csharp_space_before_open_square_brackets = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_square_brackets = false
"true" means if multiple statements are on one line, keep it that way.
Ex: int i = 0; string name = "John";
[*.cs]
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_statements = false
"true" means if multiple statements are on one line in a block, keep it that way.
Ex: public int Foo { get; set; }
[*.cs]
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_blocks = false
Key-Value pairs recognised by .Net IDEs.
[documentation]
(VS 2019)
The order of these rules does not matter (assuming them don't directly overwrite each other).
They will be auto-sorted from most-general to most-specific.
A rule may require several key-value pairs to fully define, so the parse supports naming a group of pairs.
Generic example:
# define a rule group
dotnet_naming_rule.<rule_title>.symbols = <symbol_title>
# specify the rules for a group
dotnet_nameing_symbols.<symbol_title>.applicable_kinds = values
Specific example:
[*.{cs,vb}]
# this is all one rule group "public_members_must_be_capitalized"
dotnet_naming_rule.public_members_must_be_capitalized.symbols = public_symbols
dotnet_naming_symbols.public_symbols.applicable_kinds = property,method,field,event,delegate
dotnet_naming_symbols.public_symbols.applicable_accessibilities = public
dotnet_naming_symbols.public_symbols.required_modifiers = readonly
dotnet_naming_rule.public_members_must_be_capitalized.style = first_word_upper_case_style
dotnet_naming_style.first_word_upper_case_style.capitalization = first_word_upper
dotnet_naming_rule.public_members_must_be_capitalized.severity = suggestion
List which kinds of symbols your rule applies to.
# specify all symbols
dotnet_naming_symbols.<my_symbol_title>.applicable_kinds = *
# specify a list of symbols
dotnet_naming_symbols.<my_symbol_title>.applicable_kinds = namespace, class, struct, interface, enum, property, method, field, event, delegate, parameter, type_parameter, local, local_function
List which accessibility levels your rule applies to.
# specify all accessibility levels
dotnet_naming_symbols.<my_symbol_title>.applicable_accessibilities = *
# specify a list of accessibility levels
dotnet_naming_symbols.<my_symbol_title>.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected, local
"local" means "defined inside a method", such as local functions and local variables.
(optional - default is to match any modifiers)
List which modifiers of symbols your rule applies to.
Your rule will only apply to elements that have all the modifiers you specify.
# specify a list of modifiers
dotnet_naming_symbols.<my_symbol_title>.required_modifiers = abstract, async, const, readonly, static
"static" rules also apply to const elements because const is implicitly static. This can be overriden with a specific "const" rule.
Specify the naming convention for the elements you've selected.
dotnet_naming_rule.<my_rule_title>.style = <my_style_title>
You must specify a capitalization style for your rule, otherwise the entire rule might be ignored.
# requires prefix
dotnet_naming_style.<my_style_title>.required_prefix = my_prefix
# requires suffix
dotnet_naming_style.<my_style_title>.required_suffix = my_suffix
# requires separator
dotnet_naming_style.<my_style_title>.word_separator = my_char
# requires capitalization
dotnet_naming_style.<my_style_title>.capitalization = pascel_case
dotnet_naming_style.<my_style_title>.capitalization = camel_case
dotnet_naming_style.<my_style_title>.capitalization = first_word_upper
dotnet_naming_style.<my_style_title>.capitalization = all_upper
dotnet_naming_style.<my_style_title>.capitalization = all_lower
error - violation causes compiler error (this does not stop a build)
warning - violation causes compiler warning
suggestion - violation causes a suggestion (such as three gray dots under the code)
silent - violation causes nothing, but suggestion appears in the Refactorings menu, and auto-generated code uses this style
aka refactoring
none - violation causes nothing, but auto-generated code uses this style
dotnet_naming_rule.<my_rule_title>.severity = error