diff options
| author | Dmitry Gutov | 2013-10-21 09:54:18 +0400 |
|---|---|---|
| committer | Dmitry Gutov | 2013-10-21 09:54:18 +0400 |
| commit | cfef16c08413b62d33a380d41916be1003380b71 (patch) | |
| tree | f90ed9063ad94b866f63df313f223d594fdbc31b | |
| parent | 8c1ae48154e4c6935da3120362ea535f0dddfec5 (diff) | |
| download | emacs-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/ChangeLog | 3 | ||||
| -rw-r--r-- | lisp/progmodes/ruby-mode.el | 99 | ||||
| -rw-r--r-- | test/indent/ruby.rb | 8 |
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 @@ | |||
| 1 | 2013-10-21 Dmitry Gutov <dgutov@yandex.ru> | 1 | 2013-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 | ||
| 185 | if foo + | ||
| 186 | bar | ||
| 187 | end | ||
| 188 | |||
| 185 | # Examples below still fail with `ruby-use-smie' on: | 189 | # Examples below still fail with `ruby-use-smie' on: |
| 186 | 190 | ||
| 187 | foo + | 191 | foo + |
| @@ -194,10 +198,6 @@ end | |||
| 194 | foo_bar_tee(1, 2, 3) | 198 | foo_bar_tee(1, 2, 3) |
| 195 | .qux | 199 | .qux |
| 196 | 200 | ||
| 197 | if foo && | ||
| 198 | bar | ||
| 199 | end | ||
| 200 | |||
| 201 | method !arg1, | 201 | method !arg1, |
| 202 | arg2 | 202 | arg2 |
| 203 | 203 | ||