###############################
# Core EditorConfig Options   #
###############################

root = true

# All files
[*]
indent_style = space

# Code files
[*.{cs,csx}]
indent_size = 4
insert_final_newline = false
charset = utf-8-bom

# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2

# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2

# JSON files
[*.{json,travis.yml}]
indent_size = 2

# JS and CSS
[*.{js,css}]
indent_style = space
indent_size = 2

# min files don't reformatting
[*.min.*]
trim_trailing_whitespace    = false
insert_final_newline        = false

###############################
# .NET Coding Conventions     #
###############################

[*.{cs,vb}]
# Organize usings
dotnet_sort_system_directives_first         = true
dotnet_separate_import_directive_groups     = false

# this. preferences
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

# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members  = true:suggestion
dotnet_style_predefined_type_for_member_access              = true:suggestion

# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators     = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators     = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators          = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators                 = never_if_unnecessary:silent

# Modifier preferences
dotnet_style_require_accessibility_modifiers    = always:suggestion
dotnet_style_readonly_field                     = false:suggestion

# Expression-level preferences
dotnet_style_object_initializer                                     = true:suggestion
dotnet_style_collection_initializer                                 = true:suggestion
dotnet_style_explicit_tuple_names                                   = true:suggestion
dotnet_style_null_propagation                                       = true:suggestion
dotnet_style_coalesce_expression                                    = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method    = true:silent
dotnet_style_prefer_inferred_tuple_names                            = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names            = false:suggestion
dotnet_style_prefer_auto_properties                                 = true:silent
dotnet_style_prefer_conditional_expression_over_assignment          = true:silent
dotnet_style_prefer_conditional_expression_over_return              = true:silent

###############################
# Naming Conventions          #
###############################

# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization               = pascal_case

dotnet_naming_style.camel_case_style.capitalization                = camel_case

dotnet_naming_style.upper_case_style.capitalization                = all_upper
dotnet_naming_style.upper_case_style.word_separator                = _

dotnet_naming_style.prefix_interface_with_i_style.required_prefix  = I
dotnet_naming_style.prefix_interface_with_i_style.capitalization   = pascal_case

dotnet_naming_style.private_field_style.required_prefix            = _
dotnet_naming_style.private_field_style.capitalization             = camel_case

# Use all upper for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity  = warning
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols   = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style     = upper_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds             = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities   = *
dotnet_naming_symbols.constant_fields.required_modifiers           = const

# Use PascalCase for public fields
dotnet_naming_rule.pascal_case_for_public_fields.severity          = warning
dotnet_naming_rule.pascal_case_for_public_fields.symbols           = public_fields
dotnet_naming_rule.pascal_case_for_public_fields.style             = pascal_case_style
dotnet_naming_symbols.public_fields.applicable_kinds               = field
dotnet_naming_symbols.public_fields.applicable_accessibilities     = public

# Interfaces must be PascalCase and have an I prefix
dotnet_naming_rule.interface_rule.severity                         = warning
dotnet_naming_rule.interface_rule.symbols                          = interface_group
dotnet_naming_rule.interface_rule.style                            = prefix_interface_with_i_style
dotnet_naming_symbols.interface_group.applicable_kinds             = interface

# Private fields must be camelCase and have an _ prefix
dotnet_naming_rule.private_field_with_.severity                     = warning
dotnet_naming_rule.private_field_with_.symbols                      = private_fields
dotnet_naming_rule.private_field_with_.style                        = private_field_style
dotnet_naming_symbols.private_fields.applicable_accessibilities     = private,protected
dotnet_naming_symbols.private_fields.applicable_kinds               = field

# Async methods should have "Async" suffix
dotnet_naming_rule.async_methods_end_in_async.severity              = suggestion
dotnet_naming_rule.async_methods_end_in_async.symbols               = any_async_methods
dotnet_naming_rule.async_methods_end_in_async.style                 = end_in_async

dotnet_naming_symbols.any_async_methods.applicable_kinds            = method
dotnet_naming_symbols.any_async_methods.applicable_accessibilities  = *
dotnet_naming_symbols.any_async_methods.required_modifiers          = async

dotnet_naming_style.end_in_async.required_prefix                    = 
dotnet_naming_style.end_in_async.required_suffix                    = Async
dotnet_naming_style.end_in_async.capitalization                     = pascal_case
dotnet_naming_style.end_in_async.word_separator                     = 

# Classes, structs, methods, enums, events, properties, namespaces, delegates must be PascalCase
dotnet_naming_rule.general_naming.severity                         = warning
dotnet_naming_rule.general_naming.symbols                          = general
dotnet_naming_rule.general_naming.style                            = pascal_case_style
dotnet_naming_symbols.general.applicable_kinds                     = class,struct,enum,property,method,event,delegate,namespace
dotnet_naming_symbols.general.applicable_accessibilities           = *

# Use PascalCase for type parameters
dotnet_naming_rule.pascal_case_for_type_parameters.severity          = suggestion
dotnet_naming_rule.pascal_case_for_type_parameters.symbols           = type_parameters
dotnet_naming_rule.pascal_case_for_type_parameters.style             = pascal_case_style
dotnet_naming_symbols.type_parameters.applicable_kinds               = type_parameter

# Everything else is camelCase
dotnet_naming_rule.everything_else_naming.severity                 = warning
dotnet_naming_rule.everything_else_naming.symbols                  = everything_else
dotnet_naming_rule.everything_else_naming.style                    = camel_case_style
dotnet_naming_symbols.everything_else.applicable_kinds             = *
dotnet_naming_symbols.everything_else.applicable_accessibilities   = *

###############################
# C# Code Style Rules         #
###############################

[*.cs]
# var preferences
csharp_style_var_for_built_in_types         = true:suggestion
csharp_style_var_when_type_is_apparent      = true:suggestion
csharp_style_var_elsewhere                  = true:suggestion

# Expression-bodied members
csharp_style_expression_bodied_methods          = false:suggestion
csharp_style_expression_bodied_constructors     = false:suggestion
csharp_style_expression_bodied_operators        = false:suggestion
csharp_style_expression_bodied_properties       = true:suggestion
csharp_style_expression_bodied_indexers         = true:suggestion
csharp_style_expression_bodied_accessors        = true:suggestion

# Pattern-matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion

# Null-checking preferences
csharp_style_throw_expression           = true:suggestion
csharp_style_conditional_delegate_call  = true:suggestion

# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion

# Expression-level preferences
csharp_prefer_braces                                = false:suggestion
csharp_style_deconstructed_variable_declaration     = true:suggestion
csharp_prefer_simple_default_expression             = true:suggestion
csharp_style_pattern_local_over_anonymous_function  = true:suggestion
csharp_style_inlined_variable_declaration           = true:suggestion

###############################
# C# Formatting Rules         #
###############################

# New line preferences
csharp_new_line_before_open_brace                       = all
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

# Indentation preferences
csharp_indent_case_contents     = true
csharp_indent_switch_labels     = true
csharp_indent_labels            = no_change

# Space preferences
csharp_space_after_cast                                                     = false
csharp_space_after_keywords_in_control_flow_statements                      = true
csharp_space_between_method_call_parameter_list_parentheses                 = false
csharp_space_between_method_declaration_parameter_list_parentheses          = false
csharp_space_between_parentheses                                            = false
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_empty_parameter_list_parentheses    = false
csharp_space_between_method_call_name_and_opening_parenthesis               = false
csharp_space_between_method_call_empty_parameter_list_parentheses           = false
csharp_space_after_comma                                                    = true
csharp_space_after_dot                                                      = false

# Wrapping preferences
csharp_preserve_single_line_statements  = false
csharp_preserve_single_line_blocks      = true
