From 16a70518880ef8f54bd853020f1606d3abf04d8e Mon Sep 17 00:00:00 2001 From: Aaron Jensen Date: Fri, 21 Nov 2025 21:20:01 -0800 Subject: [PATCH] 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) --- lisp/progmodes/ruby-mode.el | 5 ++++- lisp/progmodes/ruby-ts-mode.el | 6 +++++- .../ruby-bracketed-args-indent.rb | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index b1104bf88a0..67ed863235b 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -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")) diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 03ea6616ae1..8d4499fb4ad 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -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)) diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb b/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb index c1aaff78ac9..27905f757d5 100644 --- a/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb +++ b/test/lisp/progmodes/ruby-mode-resources/ruby-bracketed-args-indent.rb @@ -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: