]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/progmodes/ruby-mode.el (ruby-smie-grammar): Add (almost) all
authorDmitry Gutov <dgutov@yandex.ru>
Mon, 21 Oct 2013 05:54:18 +0000 (09:54 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Mon, 21 Oct 2013 05:54:18 +0000 (09:54 +0400)
infix operators.
(ruby-smie--implicit-semi-p): Add new operator chars.

lisp/ChangeLog
lisp/progmodes/ruby-mode.el
test/indent/ruby.rb

index c57ac41171cbcc290167a75ecf239e630648bd22..e9de6a7669c4f84184e95223acaeb49573bbfb27 100644 (file)
@@ -1,5 +1,8 @@
 2013-10-21  Dmitry Gutov  <dgutov@yandex.ru>
 
+       * progmodes/ruby-mode.el (ruby-smie-grammar): Add (almost) all infix operators.
+       (ruby-smie--implicit-semi-p): Add new operator chars.
+
        * progmodes/ruby-mode.el (ruby-mode-map): Add binding for
        `smie-down-list'.
        (ruby-smie--args-separator-p): Check that there's no newline
index 6abc525f705588bc93bc819f509108d4c4fa4ce9..fcbe4fdb7c4bc750779b445d7cf2aa6fd3b54c90 100644 (file)
@@ -248,48 +248,67 @@ explicitly declared in magic comment."
 
 (require 'smie)
 
+;; 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-bnf->prec2
-    '((id)
-      (insts (inst) (insts ";" insts))
-      (inst (exp) (inst "iuwu-mod" exp))
-      (exp  (exp1) (exp "," exp) (exp "=" exp) (exp "-" exp)  (exp "+" exp)
-            (id " @ " exp))
-      (exp1 (exp2) (exp2 "?" exp1 ":" exp1))
-      (exp2 ("def" insts "end")
-            ("begin" insts-rescue-insts "end")
-            ("do" insts "end")
-            ("class" insts "end") ("module" insts "end")
-            ("for" for-body "end")
-            ("[" expseq "]")
-            ("{" hashvals "}")
-            ("{" insts "}")
-            ("while" insts "end")
-            ("until" insts "end")
-            ("unless" insts "end")
-            ("if" if-body "end")
-            ("case"  cases "end"))
-      (formal-params ("opening-|" exp "|"))
-      (for-body (for-head ";" insts))
-      (for-head (id "in" exp))
-      (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts).
-             (cases "when" cases) (insts "else" insts))
-      (expseq (exp) );;(expseq "," expseq)
-      (hashvals (id "=>" exp1) (hashvals "," hashvals))
-      (insts-rescue-insts (insts)
-                          (insts-rescue-insts "rescue" insts-rescue-insts)
-                          (insts-rescue-insts "ensure" insts-rescue-insts))
-      (itheni (insts) (exp "then" insts))
-      (ielsei (itheni) (itheni "else" insts))
-      (if-body (ielsei) (if-body "elsif" if-body)))
-    '((nonassoc "in") (assoc ";") (right " @ ")
-      (assoc ",") (right "=") (assoc "-" "+"))
-    '((assoc "when"))
-    '((assoc "elsif"))
-    '((assoc "rescue" "ensure"))
-    '((assoc ",")))))
+   (smie-merge-prec2s
+    (smie-bnf->prec2
+     '((id)
+       (insts (inst) (insts ";" insts))
+       (inst (exp) (inst "iuwu-mod" exp))
+       (exp  (exp1) (exp "," exp) (exp "=" exp)
+             (id " @ " exp))
+       (exp1 (exp2) (exp2 "?" exp1 ":" exp1))
+       (exp2 ("def" insts "end")
+             ("begin" insts-rescue-insts "end")
+             ("do" insts "end")
+             ("class" insts "end") ("module" insts "end")
+             ("for" for-body "end")
+             ("[" expseq "]")
+             ("{" hashvals "}")
+             ("{" insts "}")
+             ("while" insts "end")
+             ("until" insts "end")
+             ("unless" insts "end")
+             ("if" if-body "end")
+             ("case"  cases "end"))
+       (formal-params ("opening-|" exp "|"))
+       (for-body (for-head ";" insts))
+       (for-head (id "in" exp))
+       (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts).
+              (cases "when" cases) (insts "else" insts))
+       (expseq (exp) );;(expseq "," expseq)
+       (hashvals (id "=>" exp1) (hashvals "," hashvals))
+       (insts-rescue-insts (insts)
+                           (insts-rescue-insts "rescue" insts-rescue-insts)
+                           (insts-rescue-insts "ensure" insts-rescue-insts))
+       (itheni (insts) (exp "then" insts))
+       (ielsei (itheni) (itheni "else" insts))
+       (if-body (ielsei) (if-body "elsif" if-body)))
+     '((nonassoc "in") (assoc ";") (right " @ ")
+       (assoc ",") (right "="))
+     '((assoc "when"))
+     '((assoc "elsif"))
+     '((assoc "rescue" "ensure"))
+     '((assoc ",")))
+
+    (smie-precs->prec2
+     '((right "=")
+       (right "+=" "-=" "*=" "/=" "%=" "**=" "&=" "|=" "^="
+              "<<=" ">>=" "&&=" "||=")
+       (left ".." "...")
+       (left "+" "-")
+       (left "*" "/" "%" "**")
+       ;; (left "|") ; FIXME: Conflicts with | after block parameters.
+       (left "^" "&")
+       (nonassoc "<=>")
+       (nonassoc ">" ">=" "<" "<=")
+       (nonassoc "==" "===" "!=")
+       (nonassoc "=~" "!~")
+       (left "<<" ">>")
+       (left "&&" "||"))))))
 
 (defun ruby-smie--bosp ()
   (save-excursion (skip-chars-backward " \t")
@@ -300,7 +319,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) ?\?)
index 56966ebb8c04589997512dbcdef58672c9334012..c898dbc5cf816e0b88fc409d8cf7e4bfc355f725 100644 (file)
@@ -182,6 +182,10 @@ and_this_one(has) { |block, parameters|
   tee
 }
 
+if foo +
+   bar
+end
+
 # Examples below still fail with `ruby-use-smie' on:
 
 foo +
@@ -194,10 +198,6 @@ end
 foo_bar_tee(1, 2, 3)
   .qux
 
-if foo &&
-    bar
-end
-
 method !arg1,
        arg2