Fix indentation of keyword argument arrays/hashes in ruby-mode

* lisp/progmodes/ruby-mode.el (ruby-smie-rules): Check for ':' and
'=>' as previous tokens, and handle symbols ending with ':' to
properly indent keyword argument arrays and hashes when
ruby-bracketed-args-indent is nil.

* lisp/progmodes/ruby-ts-mode.el (ruby-ts--parent-call-or-bol):
Handle arrays/hashes that are children of 'pair' nodes (keyword
arguments) to ensure consistent indentation.

* test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb:
Add test cases for keyword argument arrays and hashes with both
symbol-colon and hash-rocket syntax.

When ruby-bracketed-args-indent is nil, arrays and hashes used as
keyword argument values now indent by ruby-indent-level from the
line start, matching the documented behavior and fixing inconsistent
indentation (bug#74517).

(https://lists.gnu.org/archive/html/emacs-devel/2025-11/msg00939.html)
This commit is contained in:
Aaron Jensen 2025-11-21 21:20:01 -08:00 committed by Dmitry Gutov
parent 36f1fde9b9
commit 16a7051888
3 changed files with 27 additions and 2 deletions

View file

@ -847,7 +847,10 @@ This only affects the output of the command `ruby-toggle-block'."
(`(:before . ,(or "(" "[" "{"))
(cond
((and (not (eq ruby-bracketed-args-indent t))
(smie-rule-prev-p "," "(" "["))
(or (smie-rule-prev-p "," "(" "[" "=>")
(save-excursion
(let ((tok (ruby-smie--backward-token)))
(and tok (string-match ":\\'" tok))))))
(cons 'column (current-indentation)))
((and (equal token "{")
(not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";" "do"))

View file

@ -871,7 +871,11 @@ a statement container is a node that matches
((and
(not (eq ruby-bracketed-args-indent t))
(string-match-p "\\`array\\|hash\\'" (treesit-node-type parent))
(equal (treesit-node-parent parent) found)
(or (equal (treesit-node-parent parent) found)
;; When the array/hash is part of a pair (keyword argument),
;; check if the pair's parent is the found node.
(and (equal (treesit-node-type (treesit-node-parent parent)) "pair")
(equal (treesit-node-parent (treesit-node-parent parent)) found)))
;; Grandparent is not a parenless call.
(or (not (equal (treesit-node-type found) "argument_list"))
(equal (treesit-node-type (treesit-node-child found 0))

View file

@ -37,6 +37,24 @@ def foo
)
end
some_method(arg, include: [
:value1,
:value2
])
some_method(arg, options: {
key: "value"
})
some_method(arg, :include => [
:value1,
:value2
])
some_method(arg, :options => {
:key => "value"
})
# Local Variables:
# ruby-bracketed-args-indent: nil
# End: