From: Dmitry Gutov Date: Thu, 19 Jan 2023 01:38:58 +0000 (+0200) Subject: ruby-ts-mode: Handle indent in parenless calls much closer to ruby-mode X-Git-Tag: emacs-29.0.90~674 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f2bedf695c15da93e8e240ad11a350a8dc8b5549;p=emacs.git ruby-ts-mode: Handle indent in parenless calls much closer to ruby-mode * lisp/progmodes/ruby-ts-mode.el (ruby-ts--parent-call-or-bol): New function. (ruby-ts--indent-rules): Use it for cases which need special anchoring logic when inside a parenless method call. Remove the ad-hoc handling of pair-hash-pair etc indentation, which was there only for the parenless cases, apparently. Have "No paren, ruby-parenless-call-arguments-indent is nil" case align to the statement, if only because ruby-mode does that. * test/lisp/progmodes/ruby-ts-mode-tests.el: Run indent test for ruby-parenless-call-arguments-indent.rb. --- diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 27e5d002881..3a6d513c330 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -680,14 +680,15 @@ a statement container is a node that matches ;; 2) With paren, 1st arg on next line ((and (query "(argument_list \"(\" _ @indent)") (node-is ")")) - parent-bol 0) + ruby-ts--parent-call-or-bol 0) ((query "(argument_list \"(\" _ @indent)") - parent-bol ruby-indent-level) + ruby-ts--parent-call-or-bol ruby-indent-level) ;; 3) No paren, ruby-parenless-call-arguments-indent is t ((and ruby-ts--parenless-call-arguments-indent-p (parent-is "argument_list")) first-sibling 0) ;; 4) No paren, ruby-parenless-call-arguments-indent is nil - ((parent-is "argument_list") (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level) + ((parent-is "argument_list") + (ruby-ts--bol ruby-ts--statement-ancestor) ruby-indent-level) ;; Old... probably too simple ((parent-is "block_parameters") first-sibling 1) @@ -718,27 +719,10 @@ a statement container is a node that matches ((and ruby-ts--same-line-hash-array-p (parent-is "array")) (nth-sibling 0 ruby-ts--true) 0) - ;; NOTE to folks trying to understand my insanity... - ;; I having trouble understanding the "logic" of why things - ;; are indented like they are so I am adding special cases - ;; hoping at some point I will be struck by lightning. - ((and (n-p-gp "}" "hash" "pair") - (not ruby-ts--same-line-hash-array-p)) - grand-parent 0) - ((and (n-p-gp "pair" "hash" "pair") - (not ruby-ts--same-line-hash-array-p)) - grand-parent ruby-indent-level) - ((and (n-p-gp "}" "hash" "method") - (not ruby-ts--same-line-hash-array-p)) - grand-parent 0) - ((and (n-p-gp "pair" "hash" "method") - (not ruby-ts--same-line-hash-array-p)) - grand-parent ruby-indent-level) - - ((match "}" "hash") parent-bol 0) - ((parent-is "hash") parent-bol ruby-indent-level) - ((match "]" "array") parent-bol 0) - ((parent-is "array") parent-bol ruby-indent-level) + ((match "}" "hash") ruby-ts--parent-call-or-bol 0) + ((parent-is "hash") ruby-ts--parent-call-or-bol ruby-indent-level) + ((match "]" "array") ruby-ts--parent-call-or-bol 0) + ((parent-is "array") ruby-ts--parent-call-or-bol ruby-indent-level) ((match ")" "parenthesized_statements") parent-bol 0) ((parent-is "parenthesized_statements") parent-bol ruby-indent-level) @@ -798,9 +782,46 @@ a statement container is a node that matches (goto-char (treesit-node-start parent)) (when (string-match-p ruby-ts--statement-container-regexp (treesit-node-type (treesit-node-parent parent))) + ;; Hack alert: it's not the proper place to alter the offset. + ;; Redoing the analysis in the OFFSET form seems annoying, + ;; though. (**) (forward-char ruby-indent-level)) (point))) +(defun ruby-ts--parent-call-or-bol (_not parent _bol &rest _) + (let* ((parent-bol (save-excursion + (goto-char (treesit-node-start parent)) + (back-to-indentation) + (point))) + (found + (treesit-parent-until + parent + (lambda (node) + (or (<= (treesit-node-start node) parent-bol) + (and + ;; Parenless call. + (equal (treesit-node-type node) "argument_list") + (not (equal (treesit-node-type + (treesit-node-child node 0)) + "("))))) + t))) + (cond + ;; No parenless call found on the current line. + ((<= (treesit-node-start found) parent-bol) + parent-bol) + ;; Parenless call found: indent to stmt with offset. + ((not ruby-parenless-call-arguments-indent) + (save-excursion + (goto-char (treesit-node-start + (ruby-ts--statement-ancestor found))) + ;; (**) Same. + (+ (point) ruby-indent-level))) + ;; Indent to the parenless call args beginning. + (t + (save-excursion + (goto-char (treesit-node-start found)) + (point)))))) + (defun ruby-ts--after-op-indent-p (&rest _) ruby-after-operator-indent) diff --git a/test/lisp/progmodes/ruby-ts-mode-tests.el b/test/lisp/progmodes/ruby-ts-mode-tests.el index 1d2cfbfb901..d34c235e82b 100644 --- a/test/lisp/progmodes/ruby-ts-mode-tests.el +++ b/test/lisp/progmodes/ruby-ts-mode-tests.el @@ -255,6 +255,7 @@ The whitespace before and including \"|\" on each line is removed." (ruby-ts-deftest-indent "ruby-block-indent.rb") (ruby-ts-deftest-indent "ruby-method-call-indent.rb") (ruby-ts-deftest-indent "ruby-method-params-indent.rb") +(ruby-ts-deftest-indent "ruby-parenless-call-arguments-indent.rb") (provide 'ruby-ts-mode-tests)