From: Stefan Monnier Date: Mon, 7 Oct 2013 03:38:26 +0000 (-0400) Subject: * lisp/progmodes/ruby-mode.el: Fix recently added tests. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~1365 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7ccae3b126e1b01814e8bed7f903f5e2b6d448bd;p=emacs.git * lisp/progmodes/ruby-mode.el: Fix recently added tests. (ruby-smie-grammar): Add - and +. (ruby-smie--redundant-do-p, ruby-smie--forward-id) (ruby-smie--backward-id): New functions. (ruby-smie--forward-token, ruby-smie--backward-token): Use them. (ruby-smie-rules): Handle hanging do. Get rid of hack, not needed any more. * test/indent/ruby.rb: Add a few more tests; adjust some indentation. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9211dfe2356..bf8dad1b621 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,13 @@ +2013-10-07 Stefan Monnier + + * progmodes/ruby-mode.el: Fix recently added tests. + (ruby-smie-grammar): Add - and +. + (ruby-smie--redundant-do-p, ruby-smie--forward-id) + (ruby-smie--backward-id): New functions. + (ruby-smie--forward-token, ruby-smie--backward-token): Use them. + (ruby-smie-rules): Handle hanging do. Get rid of hack, not needed + any more. + 2013-10-07 Leo Liu * register.el (register-preview-delay) diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index c1f79eb8711..b8c24e8a690 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -246,7 +246,7 @@ Also ignores spaces after parenthesis when 'space." '((id) (insts (inst) (insts ";" insts)) (inst (exp) (inst "iuwu-mod" exp)) - (exp (exp1) (exp "," exp) (exp "=" exp)) + (exp (exp1) (exp "," exp) (exp "=" exp) (exp "-" exp) (exp "+" exp)) (exp1 (exp2) (exp2 "?" exp1 ":" exp1)) (exp2 ("def" insts "end") ("begin" insts-rescue-insts "end") @@ -274,7 +274,7 @@ Also ignores spaces after parenthesis when 'space." (itheni (insts) (exp "then" insts)) (ielsei (itheni) (itheni "else" insts)) (if-body (ielsei) (if-body "elsif" if-body))) - '((nonassoc "in") (assoc ";") (assoc ",") (right "=")) + '((nonassoc "in") (assoc ";") (assoc ",") (right "=") (assoc "-" "+")) '((assoc "when")) '((assoc "elsif")) '((assoc "rescue" "ensure")) @@ -297,6 +297,11 @@ Also ignores spaces after parenthesis when 'space." (or (equal tok "?") (string-match "\\`\\s." tok)))))))) +(defun ruby-smie--redundant-do-p (&optional skip) + (save-excursion + (if skip (backward-word 1)) + (member (nth 2 (smie-backward-sexp ";")) '("while")))) + (defun ruby-smie--opening-pipe-p () (save-excursion (if (eq ?| (char-before)) (forward-char -1)) @@ -304,6 +309,15 @@ Also ignores spaces after parenthesis when 'space." (or (eq ?\{ (char-before)) (looking-back "\\_ (save-excursion (forward-comment (point-max)) (point)) + (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))) @@ -336,6 +370,9 @@ Also ignores spaces after parenthesis when 'space." ((and (bolp) (not (bobp))) "") ;Presumably a heredoc. (t (let ((tok (smie-default-backward-token))) + (when (eq ?. (char-before)) + (forward-char -1) + (setq tok (concat (ruby-smie--backward-id) "." tok))) (when (and (eq ?: (char-before)) (string-match "\\`\\s." tok)) (forward-char -1) (setq tok (concat ":" tok))) ;; bug#15208. (cond @@ -346,6 +383,16 @@ Also ignores spaces after parenthesis when 'space." (if (ruby-smie--opening-pipe-p) "opening-|" tok)) ((and (equal tok "") (eq ?\\ (char-before)) (looking-at "\n")) (forward-char -1) (ruby-smie--backward-token)) + ((equal tok "do") + (cond + ((not (ruby-smie--redundant-do-p)) tok) + ((> (save-excursion (forward-word 1) + (forward-comment (point-max)) (point)) + (line-end-position)) + (ruby-smie--backward-token)) ;Fully redundant. + (t ";"))) + ((equal tok ".") + (concat (ruby-smie--backward-id) tok)) (t tok))))))) (defun ruby-smie-rules (kind token) @@ -370,24 +417,22 @@ Also ignores spaces after parenthesis when 'space." (if (smie-rule-hanging-p) (smie-rule-parent))) (`(:after . "=") 2) (`(:before . "do") - (when - (save-excursion - (forward-word 1) ;Skip "do" - (skip-chars-forward " \t") - (and (equal (save-excursion (ruby-smie--forward-token)) "opening-|") - (save-excursion (forward-sexp 1) - (skip-chars-forward " \t") - (or (eolp) - (looking-at comment-start-skip))))) + (when (or (smie-rule-hanging-p) + (save-excursion + (forward-word 1) ;Skip "do" + (skip-chars-forward " \t") + (and (equal (save-excursion (ruby-smie--forward-token)) + "opening-|") + (save-excursion (forward-sexp 1) + (skip-chars-forward " \t") + (or (eolp) + (looking-at comment-start-skip)))))) ;; `(column . ,(smie-indent-virtual)) (smie-rule-parent))) (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) 0) (`(:before . ,(or `"when")) (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level - ;; Hack attack: Since newlines are separators, don't try to align args that - ;; appear on a separate line. "" is for the case where the "previous - ;; separator" was not an implicit ";" but the BOB. - (`(:list-intro . ,(or `";" `"")) t))) + )) (defun ruby-imenu-create-index-in-block (prefix beg end) "Create an imenu index of methods inside a block." diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb index e40ef217e54..7c8de323bdb 100644 --- a/test/indent/ruby.rb +++ b/test/indent/ruby.rb @@ -99,6 +99,14 @@ if something == :== do_something end +# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html +d = 4 + 5 + # no '\' needed + 6 + 7 + +# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html +e = 8 + 9 \ + + 10 # '\' needed + begin foo ensure @@ -109,20 +117,27 @@ end MSG = 'Separate every 3 digits in the integer portion of a number' + 'with underscores(_).' -# Examples below fail with SMIE. +class C + def foo + self.end + D.new.class + end +end a = foo(j, k) - - bar_tee + bar_tee while a < b do # "do" is optional foo end desc "foo foo" \ - "bar bar" + "bar bar" foo. bar +# FIXME: is this really valid Ruby? Isn't the newline after "foo" treated as +# an implicit semi-colon? foo .bar