Commit cfef16c0 authored by Dmitry Gutov's avatar Dmitry Gutov
Browse files

* lisp/progmodes/ruby-mode.el (ruby-smie-grammar): Add (almost) all

infix operators.
(ruby-smie--implicit-semi-p): Add new operator chars.
parent 8c1ae481
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
......
......@@ -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) ?\?)
......
......@@ -182,6 +182,10 @@ def foo
tee
}
if foo +
bar
end
# Examples below still fail with `ruby-use-smie' on:
foo +
......@@ -194,10 +198,6 @@ def foo
foo_bar_tee(1, 2, 3)
.qux
if foo &&
bar
end
method !arg1,
arg2
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment