From 1d1c86daf7d8999a1e82e3bbcf0ca5717286a217 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 7 Nov 2013 05:02:01 +0200 Subject: [PATCH] * lisp/progmodes/ruby-mode.el (ruby-smie--implicit-semi-p): No implicit semi after "^", "and" or "or". (ruby-smie-grammar): New tokens: "and" and "or". (ruby-smie--args-separator-p): Fix the check for tokens at POS. Exclude "and" and "or". Remove "do" in order to work around token priorities. (ruby-smie-rules): Add all infix tokens. Handle the case of beginning-of-buffer. --- lisp/ChangeLog | 11 ++++++++++- lisp/progmodes/ruby-mode.el | 33 +++++++++++++++++++-------------- test/indent/ruby.rb | 12 ++++++++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index bbd86b51bc6..edb37fa3d39 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,7 +1,16 @@ 2013-11-07 Dmitry Gutov * progmodes/ruby-mode.el (ruby-smie-grammar): Lower priority of - "." compared to "do". + "." compared to " @ ". This incidentally fixes some indentation + examples with "do". + (ruby-smie--implicit-semi-p): No implicit semi after "^", "and" or + "or". + (ruby-smie-grammar): New tokens: "and" and "or". + (ruby-smie--args-separator-p): Fix the check for tokens at POS. + Exclude "and" and "or". Remove "do" in order to work around token + priorities. + (ruby-smie-rules): Add all infix tokens. Handle the case of + beginning-of-buffer. 2013-11-06 Glenn Morris diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index b5020344872..05fac2b42f2 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -329,7 +329,8 @@ explicitly declared in magic comment." (nonassoc "==" "===" "!=") (nonassoc "=~" "!~") (left "<<" ">>") - (left "&&" "||")))))) + (left "&&" "||") + (left "and" "or")))))) (defun ruby-smie--bosp () (save-excursion (skip-chars-backward " \t") @@ -340,7 +341,7 @@ explicitly declared in magic comment." (skip-chars-backward " \t") (not (or (bolp) (and (memq (char-before) - '(?\; ?- ?+ ?* ?/ ?: ?. ?, ?\[ ?\( ?\{ ?\\ ?& ?> ?< ?% ?~)) + '(?\; ?- ?+ ?* ?/ ?: ?. ?, ?\[ ?\( ?\{ ?\\ ?& ?> ?< ?% ?~ ?^)) ;; Make sure it's not the end of a regexp. (not (eq (car (syntax-after (1- (point)))) 7))) (and (eq (char-before) ?\?) @@ -349,8 +350,8 @@ explicitly declared in magic comment." (string-match "\\`\\s." (save-excursion (ruby-smie--backward-token)))) (and (eq (car (syntax-after (1- (point)))) 2) - (equal (save-excursion (ruby-smie--backward-token)) - "iuwu-mod")) + (member (save-excursion (ruby-smie--backward-token)) + '("iuwu-mod" "and" "or"))) (save-excursion (forward-comment 1) (eq (char-after) ?.)))))) @@ -375,13 +376,15 @@ explicitly declared in magic comment." ;; This isn't very important most of the time, though. (and (memq (preceding-char) '(?! ??)) (eq (char-syntax (char-before (1- (point)))) '?w))) - (or (and (eq (char-syntax (char-after pos)) ?w) - (not (looking-at (regexp-opt '("unless" "if" "while" "until" - "else" "elsif" "do" "end") - 'symbols)))) - (memq (syntax-after pos) '(7 15)) - (save-excursion - (goto-char pos) + (save-excursion + (goto-char pos) + (or (and (eq (char-syntax (char-after)) ?w) + ;; FIXME: Also "do". But alas, that breaks some + ;; indentation cases. + (not (looking-at (regexp-opt '("unless" "if" "while" "until" + "else" "elsif" "end" "and" "or") + 'symbols)))) + (memq (syntax-after pos) '(7 15)) (looking-at "\\s(\\|[-+!~:]\\sw"))))) (defun ruby-smie--at-dot-call () @@ -504,7 +507,6 @@ explicitly declared in magic comment." (let ((state (smie-backward-sexp 'halfsexp))) (when (eq t (car state)) (goto-char (cadr state)))) (cons 'column (smie-indent-virtual))))) - (`(:after . ,(or "=" "iuwu-mod")) 2) (`(:after . " @ ") (smie-rule-parent)) (`(:before . "do") (smie-rule-parent)) (`(,(or :before :after) . ".") @@ -513,8 +515,11 @@ explicitly declared in magic comment." (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) 0) (`(:before . ,(or `"when")) (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level - (`(:after . "+") ;FIXME: Probably applicable to most infix operators. - (if (smie-rule-parent-p ";") ruby-indent-level)) + (`(:after . ,(or "=" "iuwu-mod" "+" "-" "*" "/" "&&" "||" "%" "**" "^" "&" + "<=>" ">" "<" ">=" "<=" "==" "===" "!=" "<<" ">>" + "+=" "-=" "*=" "/=" "%=" "**=" "&=" "|=" "^=" + "<<=" ">>=" "&&=" "||=" "and" "or")) + (if (smie-rule-parent-p ";" nil) ruby-indent-level)) )) (defun ruby-imenu-create-index-in-block (prefix beg end) diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb index 3d881edcba9..31ad32e1eac 100644 --- a/test/indent/ruby.rb +++ b/test/indent/ruby.rb @@ -207,6 +207,12 @@ end foo + bar +foo and + bar + +foo ^ + bar + foo_bar_tee(1, 2, 3) .qux .bar @@ -245,3 +251,9 @@ end bar.foo do bar end + +# Examples below still fail with `ruby-use-smie' on: + +bar.foo(tee) do # "." is parent to "do"; it shouldn't be. + bar +end -- 2.39.2