diff --git a/changelog/fix_autocorrect_for_first_hash_element_indentation.md b/changelog/fix_autocorrect_for_first_hash_element_indentation.md new file mode 100644 index 00000000000..04a9ea88dc1 --- /dev/null +++ b/changelog/fix_autocorrect_for_first_hash_element_indentation.md @@ -0,0 +1 @@ +* [#10751](https://github.com/rubocop/rubocop/issues/10751): Fix autocorrect for Layout/FirstHashElementIndentation. ([@j-miyake][]) diff --git a/lib/rubocop/cop/mixin/multiline_element_indentation.rb b/lib/rubocop/cop/mixin/multiline_element_indentation.rb index 6e4349b619b..f90f5cde6cc 100644 --- a/lib/rubocop/cop/mixin/multiline_element_indentation.rb +++ b/lib/rubocop/cop/mixin/multiline_element_indentation.rb @@ -51,7 +51,8 @@ def indent_base(left_brace, left_parenthesis) return [left_brace.column, :left_brace_or_bracket] if style == brace_alignment_style pair = hash_pair_where_value_beginning_with(left_brace) - if pair && key_and_value_begin_on_same_line?(pair) && pair.right_sibling + if pair && key_and_value_begin_on_same_line?(pair) && + right_sibling_begins_on_subsequent_line?(pair) return [pair.loc.column, :parent_hash_key] end @@ -79,6 +80,10 @@ def key_and_value_begin_on_same_line?(pair) same_line?(pair.key, pair.value) end + def right_sibling_begins_on_subsequent_line?(pair) + pair.right_sibling && (pair.last_line < pair.right_sibling.first_line) + end + def detected_styles(actual_column, offset, left_parenthesis, left_brace) base_column = actual_column - configured_indentation_width - offset detected_styles_for_column(base_column, left_parenthesis, left_brace) diff --git a/spec/rubocop/cop/layout/first_array_element_indentation_spec.rb b/spec/rubocop/cop/layout/first_array_element_indentation_spec.rb index 92f16e1c32f..0b85c9bff27 100644 --- a/spec/rubocop/cop/layout/first_array_element_indentation_spec.rb +++ b/spec/rubocop/cop/layout/first_array_element_indentation_spec.rb @@ -301,6 +301,19 @@ RUBY end + it 'accepts indent based on the preceding left parenthesis ' \ + 'when the right bracket and its following pair is on the same line' do + expect_no_offenses(<<~RUBY) + func(:x, y: [ + :a, + :b + ], z: [ + :c, + :d + ]) + RUBY + end + it 'accepts indent based on the left brace when the outer hash key and ' \ 'the left bracket is not on the same line' do expect_no_offenses(<<~RUBY) @@ -403,6 +416,19 @@ RUBY end + it 'accepts indent based on the start of the line where the left bracket is' \ + 'when the right bracket and its following pair is on the same line' do + expect_no_offenses(<<~RUBY) + func(:x, y: [ + :a, + :b + ], z: [ + :c, + :d + ]) + RUBY + end + it 'accepts indent based on the left brace when the outer hash key and ' \ 'the left bracket is not on the same line' do expect_no_offenses(<<~RUBY) @@ -489,7 +515,20 @@ RUBY end - it 'accepts indent based on the left brace when the outer hash key and ' \ + it 'accepts indent based on the start of the line where the left bracket is' \ + 'when the right bracket and its following pair is on the same line' do + expect_no_offenses(<<~RUBY) + func :x, y: [ + :a, + :b + ], z: [ + :c, + :d + ] + RUBY + end + + it 'accepts indent based on the left bracket when the outer hash key and ' \ 'the left bracket is not on the same line' do expect_no_offenses(<<~RUBY) func x: diff --git a/spec/rubocop/cop/layout/first_hash_element_indentation_spec.rb b/spec/rubocop/cop/layout/first_hash_element_indentation_spec.rb index 74e99c9fd23..a850b79e965 100644 --- a/spec/rubocop/cop/layout/first_hash_element_indentation_spec.rb +++ b/spec/rubocop/cop/layout/first_hash_element_indentation_spec.rb @@ -385,6 +385,19 @@ RUBY end + it 'accepts indent based on the preceding left parenthesis' \ + 'when the right brace and its following pair is on the same line' do + expect_no_offenses(<<~RUBY) + func(:x, y: { + a: 1, + b: 2 + }, z: { + c: 1, + d: 2 + }) + RUBY + end + it 'accepts indent based on the left brace when the outer hash key and ' \ 'the left brace is not on the same line' do expect_no_offenses(<<~RUBY) @@ -487,6 +500,19 @@ RUBY end + it 'accepts indent based on the start of the line where the left brace is' \ + 'when the right brace and its following pair is on the same line' do + expect_no_offenses(<<~RUBY) + func(:x, y: { + a: 1, + b: 2 + }, z: { + c: 1, + d: 2 + }) + RUBY + end + it 'accepts indent based on the left brace when the outer hash key and ' \ 'the left brace is not on the same line' do expect_no_offenses(<<~RUBY) @@ -534,7 +560,7 @@ end it 'registers an offense for the first inner hash member not based on the start of line ' \ - 'where the outer hash key is when no other outer hash members follow' do + 'when the outer hash pair has no following siblings' do expect_offense(<<~RUBY) func x: :foo, y: { a: 1, b: 2 } @@ -574,6 +600,19 @@ RUBY end + it 'accepts indent based on the start of the line where the left brace is' \ + 'when the right brace and its following pair is on the same line' do + expect_no_offenses(<<~RUBY) + func :x, y: { + a: 1, + b: 2 + }, z: { + c: 1, + d: 2 + } + RUBY + end + it 'accepts indent based on the left brace when the outer hash key and ' \ 'the left brace is not on the same line' do expect_no_offenses(<<~RUBY)