From 18cacc392d076dfd78b58e842116c0c578aaf3c7 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Tue, 22 Oct 2013 02:25:59 +0400 Subject: [PATCH] * lisp/progmodes/ruby-mode.el (ruby-smie-grammar): Remove outdated TODO. Add "." after " @ ". (ruby-smie--at-dot-call): New function. Checks if point at method call with explicit target. (ruby-smie--forward-token, ruby-smie--backward-token): Prepend "." to the method name tokens when it precedes them. (ruby-smie--backward-id, ruby-smie--forward-id): Remove. (ruby-smie-rules): Add rule for indentation before and after "." token. --- lisp/ChangeLog | 12 ++++++++++ lisp/progmodes/ruby-mode.el | 47 ++++++++++++++----------------------- test/indent/ruby.rb | 17 +++++++++++--- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 2ee8799f62b..9a00661aef9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2013-10-21 Dmitry Gutov + + * progmodes/ruby-mode.el (ruby-smie-grammar): Remove outdated + TODO. Add "." after " @ ". + (ruby-smie--at-dot-call): New function. Checks if point at method + call with explicit target. + (ruby-smie--forward-token, ruby-smie--backward-token): Prepend "." + to the method name tokens when it precedes them. + (ruby-smie--backward-id, ruby-smie--forward-id): Remove. + (ruby-smie-rules): Add rule for indentation before and after "." + token. + 2013-10-21 Stefan Monnier * textmodes/remember.el (remember-diary-extract-entries): diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 280016317e7..a6e54701ffe 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -251,7 +251,6 @@ explicitly declared in magic comment." ;; Here's a simplified BNF grammar, for reference: ;; http://www.cse.buffalo.edu/~regan/cse305/RubyBNF.pdf (defconst ruby-smie-grammar - ;; FIXME: Add support for Cucumber. (smie-prec2->grammar (smie-merge-prec2s (smie-bnf->prec2 @@ -259,7 +258,8 @@ explicitly declared in magic comment." (insts (inst) (insts ";" insts)) (inst (exp) (inst "iuwu-mod" exp)) (exp (exp1) (exp "," exp) (exp "=" exp) - (id " @ " exp)) + (id " @ " exp) + (exp "." exp)) (exp1 (exp2) (exp2 "?" exp1 ":" exp1)) (exp2 ("def" insts "end") ("begin" insts-rescue-insts "end") @@ -288,7 +288,7 @@ explicitly declared in magic comment." (ielsei (itheni) (itheni "else" insts)) (if-body (ielsei) (if-body "elsif" if-body))) '((nonassoc "in") (assoc ";") (right " @ ") - (assoc ",") (right "=")) + (assoc ",") (right "=") (assoc ".")) '((assoc "when")) '((assoc "elsif")) '((assoc "rescue" "ensure")) @@ -354,14 +354,10 @@ explicitly declared in magic comment." (eq (char-syntax (char-before (1- (point)))) '?w))) (memq (char-syntax (char-after pos)) '(?w ?\")))) -(defun ruby-smie--forward-id () - (when (and (not (eobp)) - (eq ?w (char-syntax (char-after)))) - (let ((tok (smie-default-forward-token))) - (when (eq ?. (char-after)) - (forward-char 1) - (setq tok (concat tok "." (ruby-smie--forward-id)))) - tok))) +(defun ruby-smie--at-dot-call () + (and (eq ?w (char-syntax (char-after))) + (eq (char-before) ?.) + (not (eq (char-before (1- (point))) ?.)))) (defun ruby-smie--forward-token () (let ((pos (point))) @@ -382,7 +378,10 @@ explicitly declared in magic comment." (ruby-smie--args-separator-p (prog1 (point) (goto-char pos))))) " @ ") (t - (let ((tok (smie-default-forward-token))) + (let ((dot (ruby-smie--at-dot-call)) + (tok (smie-default-forward-token))) + (when dot + (setq tok (concat "." tok))) (cond ((member tok '("unless" "if" "while" "until")) (if (save-excursion (forward-word -1) (ruby-smie--bosp)) @@ -398,18 +397,8 @@ explicitly declared in magic comment." (line-end-position)) (ruby-smie--forward-token)) ;Fully redundant. (t ";"))) - ((equal tok ".") (concat tok (ruby-smie--forward-id))) (t tok))))))))) -(defun ruby-smie--backward-id () - (when (and (not (bobp)) - (eq ?w (char-syntax (char-before)))) - (let ((tok (smie-default-backward-token))) - (when (eq ?. (char-before)) - (forward-char -1) - (setq tok (concat (ruby-smie--backward-id) "." tok))) - tok))) - (defun ruby-smie--backward-token () (let ((pos (point))) (forward-comment (- (point))) @@ -424,9 +413,9 @@ explicitly declared in magic comment." ;; In some textbooks, "e1 @ e2" is used to mean "call e1 with arg e2". " @ ") (t - (let ((tok (smie-default-backward-token))) - (when (eq ?. (char-before)) - (forward-char -1) + (let ((tok (smie-default-backward-token)) + (dot (ruby-smie--at-dot-call))) + (when dot (setq tok (concat "." tok))) (when (and (eq ?: (char-before)) (string-match "\\`\\s." tok)) (forward-char -1) (setq tok (concat ":" tok))) ;; bug#15208. @@ -446,11 +435,6 @@ explicitly declared in magic comment." (line-end-position)) (ruby-smie--backward-token)) ;Fully redundant. (t ";"))) - ;; FIXME: We shouldn't merge the dot with preceding token here - ;; either, but not doing that breaks indentation of hanging - ;; method calls with dot on the first line. - ((equal tok ".") - (concat (ruby-smie--backward-id) tok)) (t tok))))))) (defun ruby-smie-rules (kind token) @@ -495,6 +479,9 @@ explicitly declared in magic comment." (`(:after . ,(or "=" "iuwu-mod")) 2) (`(:after . " @ ") (smie-rule-parent)) (`(:before . "do") (smie-rule-parent)) + (`(,(or :before :after) . ".") + (unless (smie-rule-parent-p ".") + (smie-rule-parent ruby-indent-level))) (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) 0) (`(:before . ,(or `"when")) (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb index c9ec8bd3723..5c47eea0baf 100644 --- a/test/indent/ruby.rb +++ b/test/indent/ruby.rb @@ -189,15 +189,16 @@ end foo + bar +foo_bar_tee(1, 2, 3) + .qux + .bar + # Examples below still fail with `ruby-use-smie' on: foo = [1, 2, 3].map do |i| i + 1 end -foo_bar_tee(1, 2, 3) - .qux - method !arg1, arg2 @@ -209,3 +210,13 @@ method :foo, method (a + b), c + +foo do + bar + .tee +end + +def bar + foo + .baz +end -- 2.39.2