aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2013-10-21 09:54:18 +0400
committerDmitry Gutov2013-10-21 09:54:18 +0400
commitcfef16c08413b62d33a380d41916be1003380b71 (patch)
treef90ed9063ad94b866f63df313f223d594fdbc31b
parent8c1ae48154e4c6935da3120362ea535f0dddfec5 (diff)
downloademacs-cfef16c08413b62d33a380d41916be1003380b71.tar.gz
emacs-cfef16c08413b62d33a380d41916be1003380b71.zip
* lisp/progmodes/ruby-mode.el (ruby-smie-grammar): Add (almost) all
infix operators. (ruby-smie--implicit-semi-p): Add new operator chars.
-rw-r--r--lisp/ChangeLog3
-rw-r--r--lisp/progmodes/ruby-mode.el99
-rw-r--r--test/indent/ruby.rb8
3 files changed, 66 insertions, 44 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c57ac41171c..e9de6a7669c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,8 @@
12013-10-21 Dmitry Gutov <dgutov@yandex.ru> 12013-10-21 Dmitry Gutov <dgutov@yandex.ru>
2 2
3 * progmodes/ruby-mode.el (ruby-smie-grammar): Add (almost) all infix operators.
4 (ruby-smie--implicit-semi-p): Add new operator chars.
5
3 * progmodes/ruby-mode.el (ruby-mode-map): Add binding for 6 * progmodes/ruby-mode.el (ruby-mode-map): Add binding for
4 `smie-down-list'. 7 `smie-down-list'.
5 (ruby-smie--args-separator-p): Check that there's no newline 8 (ruby-smie--args-separator-p): Check that there's no newline
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 6abc525f705..fcbe4fdb7c4 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -248,48 +248,67 @@ explicitly declared in magic comment."
248 248
249(require 'smie) 249(require 'smie)
250 250
251;; Here's a simplified BNF grammar, for reference:
252;; http://www.cse.buffalo.edu/~regan/cse305/RubyBNF.pdf
251(defconst ruby-smie-grammar 253(defconst ruby-smie-grammar
252 ;; FIXME: Add support for Cucumber. 254 ;; FIXME: Add support for Cucumber.
253 (smie-prec2->grammar 255 (smie-prec2->grammar
254 (smie-bnf->prec2 256 (smie-merge-prec2s
255 '((id) 257 (smie-bnf->prec2
256 (insts (inst) (insts ";" insts)) 258 '((id)
257 (inst (exp) (inst "iuwu-mod" exp)) 259 (insts (inst) (insts ";" insts))
258 (exp (exp1) (exp "," exp) (exp "=" exp) (exp "-" exp) (exp "+" exp) 260 (inst (exp) (inst "iuwu-mod" exp))
259 (id " @ " exp)) 261 (exp (exp1) (exp "," exp) (exp "=" exp)
260 (exp1 (exp2) (exp2 "?" exp1 ":" exp1)) 262 (id " @ " exp))
261 (exp2 ("def" insts "end") 263 (exp1 (exp2) (exp2 "?" exp1 ":" exp1))
262 ("begin" insts-rescue-insts "end") 264 (exp2 ("def" insts "end")
263 ("do" insts "end") 265 ("begin" insts-rescue-insts "end")
264 ("class" insts "end") ("module" insts "end") 266 ("do" insts "end")
265 ("for" for-body "end") 267 ("class" insts "end") ("module" insts "end")
266 ("[" expseq "]") 268 ("for" for-body "end")
267 ("{" hashvals "}") 269 ("[" expseq "]")
268 ("{" insts "}") 270 ("{" hashvals "}")
269 ("while" insts "end") 271 ("{" insts "}")
270 ("until" insts "end") 272 ("while" insts "end")
271 ("unless" insts "end") 273 ("until" insts "end")
272 ("if" if-body "end") 274 ("unless" insts "end")
273 ("case" cases "end")) 275 ("if" if-body "end")
274 (formal-params ("opening-|" exp "|")) 276 ("case" cases "end"))
275 (for-body (for-head ";" insts)) 277 (formal-params ("opening-|" exp "|"))
276 (for-head (id "in" exp)) 278 (for-body (for-head ";" insts))
277 (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts). 279 (for-head (id "in" exp))
278 (cases "when" cases) (insts "else" insts)) 280 (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts).
279 (expseq (exp) );;(expseq "," expseq) 281 (cases "when" cases) (insts "else" insts))
280 (hashvals (id "=>" exp1) (hashvals "," hashvals)) 282 (expseq (exp) );;(expseq "," expseq)
281 (insts-rescue-insts (insts) 283 (hashvals (id "=>" exp1) (hashvals "," hashvals))
282 (insts-rescue-insts "rescue" insts-rescue-insts) 284 (insts-rescue-insts (insts)
283 (insts-rescue-insts "ensure" insts-rescue-insts)) 285 (insts-rescue-insts "rescue" insts-rescue-insts)
284 (itheni (insts) (exp "then" insts)) 286 (insts-rescue-insts "ensure" insts-rescue-insts))
285 (ielsei (itheni) (itheni "else" insts)) 287 (itheni (insts) (exp "then" insts))
286 (if-body (ielsei) (if-body "elsif" if-body))) 288 (ielsei (itheni) (itheni "else" insts))
287 '((nonassoc "in") (assoc ";") (right " @ ") 289 (if-body (ielsei) (if-body "elsif" if-body)))
288 (assoc ",") (right "=") (assoc "-" "+")) 290 '((nonassoc "in") (assoc ";") (right " @ ")
289 '((assoc "when")) 291 (assoc ",") (right "="))
290 '((assoc "elsif")) 292 '((assoc "when"))
291 '((assoc "rescue" "ensure")) 293 '((assoc "elsif"))
292 '((assoc ","))))) 294 '((assoc "rescue" "ensure"))
295 '((assoc ",")))
296
297 (smie-precs->prec2
298 '((right "=")
299 (right "+=" "-=" "*=" "/=" "%=" "**=" "&=" "|=" "^="
300 "<<=" ">>=" "&&=" "||=")
301 (left ".." "...")
302 (left "+" "-")
303 (left "*" "/" "%" "**")
304 ;; (left "|") ; FIXME: Conflicts with | after block parameters.
305 (left "^" "&")
306 (nonassoc "<=>")
307 (nonassoc ">" ">=" "<" "<=")
308 (nonassoc "==" "===" "!=")
309 (nonassoc "=~" "!~")
310 (left "<<" ">>")
311 (left "&&" "||"))))))
293 312
294(defun ruby-smie--bosp () 313(defun ruby-smie--bosp ()
295 (save-excursion (skip-chars-backward " \t") 314 (save-excursion (skip-chars-backward " \t")
@@ -300,7 +319,7 @@ explicitly declared in magic comment."
300 (skip-chars-backward " \t") 319 (skip-chars-backward " \t")
301 (not (or (bolp) 320 (not (or (bolp)
302 (and (memq (char-before) 321 (and (memq (char-before)
303 '(?\; ?- ?+ ?* ?/ ?: ?. ?, ?\[ ?\( ?\{ ?\\)) 322 '(?\; ?- ?+ ?* ?/ ?: ?. ?, ?\[ ?\( ?\{ ?\\ ?& ?> ?< ?% ?~))
304 ;; Make sure it's not the end of a regexp. 323 ;; Make sure it's not the end of a regexp.
305 (not (eq (car (syntax-after (1- (point)))) 7))) 324 (not (eq (car (syntax-after (1- (point)))) 7)))
306 (and (eq (char-before) ?\?) 325 (and (eq (char-before) ?\?)
diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb
index 56966ebb8c0..c898dbc5cf8 100644
--- a/test/indent/ruby.rb
+++ b/test/indent/ruby.rb
@@ -182,6 +182,10 @@ and_this_one(has) { |block, parameters|
182 tee 182 tee
183} 183}
184 184
185if foo +
186 bar
187end
188
185# Examples below still fail with `ruby-use-smie' on: 189# Examples below still fail with `ruby-use-smie' on:
186 190
187foo + 191foo +
@@ -194,10 +198,6 @@ end
194foo_bar_tee(1, 2, 3) 198foo_bar_tee(1, 2, 3)
195 .qux 199 .qux
196 200
197if foo &&
198 bar
199end
200
201method !arg1, 201method !arg1,
202 arg2 202 arg2
203 203