diff --git a/etc/NEWS b/etc/NEWS index cded60cca63..fdf01592e10 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2761,6 +2761,9 @@ project-dedicated or global) is specified by the new --- *** Support for endless methods. +--- +*** New user option 'ruby-method-params-indent'. + ** Eshell +++ diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index ed6044280ea..d4e6a25e5b3 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -267,6 +267,24 @@ ruby-align-chained-calls :safe 'booleanp :version "24.4") +(defcustom ruby-method-params-indent t + "Indentation style of multiline method parameters. + +When t, the whole list with parentheses is indented against the +method name. + +When a number, indent the parameters this many columns against +the beginning of the method (the \"def\" keyword). + +The value nil means the same as 0. + +Only has effect when `ruby-use-smie' is t." + :type '(choice (const :tag "Indent against method name" t) + (number :tag "Indent specified number of columns against def") + (const :tag "Indent to def" nil)) + :safe (lambda (val) (or (memq val '(t nil)) (numberp val))) + :version 29.1) + (defcustom ruby-deep-arglist t "Deep indent lists in parenthesis when non-nil. Also ignores spaces after parenthesis when `space'. @@ -659,9 +677,12 @@ ruby-smie-rules (unless (or (eolp) (forward-comment 1)) (cons 'column (current-column))))) ('(:before . " @ ") - (save-excursion - (skip-chars-forward " \t") - (cons 'column (current-column)))) + (if (or (eq ruby-method-params-indent t) + (not (smie-rule-parent-p "def" "def="))) + (save-excursion + (skip-chars-forward " \t") + (cons 'column (current-column))) + (smie-rule-parent (or ruby-method-params-indent 0)))) ('(:before . "do") (ruby-smie--indent-to-stmt)) ('(:before . ".") (if (smie-rule-sibling-p) diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby-method-params-indent.rb b/test/lisp/progmodes/ruby-mode-resources/ruby-method-params-indent.rb new file mode 100644 index 00000000000..2b665797397 --- /dev/null +++ b/test/lisp/progmodes/ruby-mode-resources/ruby-method-params-indent.rb @@ -0,0 +1,18 @@ +class C + def self.foo( + baz, + bar + ) = + what + + def foo=( + baz, + bar + ) + hello + end +end + +# Local Variables: +# ruby-method-params-indent: 0 +# End: diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb index 5636a4fc0e2..61b75c0c7f2 100644 --- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb +++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb @@ -536,3 +536,7 @@ def foo=( hello end end + +# Local Variables: +# ruby-method-params-indent: t +# End: diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el index 9be01dc78f9..ad9fc3dad4d 100644 --- a/test/lisp/progmodes/ruby-mode-tests.el +++ b/test/lisp/progmodes/ruby-mode-tests.el @@ -943,7 +943,7 @@ ruby-imenu-with-private-modifier "Blub#bye" "Blub#hiding"))))) -(ert-deftest ruby--indent/converted-from-manual-test () +(ert-deftest ruby--indent/run-manual-test () :tags '(:expensive-test) ;; Converted from manual test. (let ((buf (find-file-noselect (ert-resource-file "ruby.rb")))) @@ -954,6 +954,17 @@ ruby--indent/converted-from-manual-test (should (equal (buffer-string) orig)))) (kill-buffer buf)))) +(ert-deftest ruby--indent/run-manual-test-method-params-indent () + :tags '(:expensive-test) + ;; Converted from manual test. + (let ((buf (find-file-noselect (ert-resource-file "ruby-method-params-indent.rb")))) + (unwind-protect + (with-current-buffer buf + (let ((orig (buffer-string))) + (indent-region (point-min) (point-max)) + (should (equal (buffer-string) orig)))) + (kill-buffer buf)))) + (ert-deftest ruby--test-chained-indentation () (with-temp-buffer (ruby-mode)