diff --git a/changelog/fix_indentation_in_class_and_module_children.md b/changelog/fix_indentation_in_class_and_module_children.md new file mode 100644 index 00000000000..05b4e0abbec --- /dev/null +++ b/changelog/fix_indentation_in_class_and_module_children.md @@ -0,0 +1 @@ +* [#9886](https://github.com/rubocop/rubocop/pull/9886): Fix indentation in Style/ClassAndModuleChildren. ([@markburns][]) diff --git a/lib/rubocop/cop/style/class_and_module_children.rb b/lib/rubocop/cop/style/class_and_module_children.rb index 063661192f9..52a5123e639 100644 --- a/lib/rubocop/cop/style/class_and_module_children.rb +++ b/lib/rubocop/cop/style/class_and_module_children.rb @@ -84,6 +84,7 @@ def add_trailing_end(corrector, node, padding) def compact_definition(corrector, node) compact_node(corrector, node) remove_end(corrector, node.body) + unindent(corrector, node) end def compact_node(corrector, node) @@ -114,6 +115,19 @@ def remove_end(corrector, body) corrector.remove(range) end + def configured_indentation_width + config.for_badge(Layout::IndentationWidth.badge).fetch('Width', 2) + end + + def unindent(corrector, node) + return if node.body.children.last.nil? + + column_delta = configured_indentation_width - leading_spaces(node.body.children.last).size + return if column_delta.zero? + + AlignmentCorrector.correct(corrector, processed_source, node, column_delta) + end + def leading_spaces(node) node.source_range.source_line[/\A\s*/] end diff --git a/spec/rubocop/cop/style/class_and_module_children_spec.rb b/spec/rubocop/cop/style/class_and_module_children_spec.rb index 03ee4027021..3f998f1aed6 100644 --- a/spec/rubocop/cop/style/class_and_module_children_spec.rb +++ b/spec/rubocop/cop/style/class_and_module_children_spec.rb @@ -210,12 +210,43 @@ class FooClass::BarClass module FooModule ^^^^^^^^^ Use compact module/class definition instead of nested style. module BarModule + def method_example + end end end RUBY expect_correction(<<~RUBY) module FooModule::BarModule + def method_example + end + end + RUBY + end + + it 'correctly indents heavily nested children' do + expect_offense(<<~RUBY) + module FooModule + ^^^^^^^^^ Use compact module/class definition instead of nested style. + module BarModule + module BazModule + module QuxModule + CONST = 1 + + def method_example + end + end + end + end + end + RUBY + + expect_correction(<<~RUBY) + module FooModule::BarModule::BazModule::QuxModule + CONST = 1 + + def method_example + end end RUBY end