aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/ruby-mode.el
diff options
context:
space:
mode:
authorStefan Monnier2013-10-12 16:40:50 -0400
committerStefan Monnier2013-10-12 16:40:50 -0400
commit650fa7bfb4143c3f6f46939982ae7e8f69e806f7 (patch)
tree0bb784e4d142bf8592141448742a83afd87ff406 /lisp/progmodes/ruby-mode.el
parent46e5e833d91758f31fbbea3c894cd0c90e78c484 (diff)
downloademacs-650fa7bfb4143c3f6f46939982ae7e8f69e806f7.tar.gz
emacs-650fa7bfb4143c3f6f46939982ae7e8f69e806f7.zip
* lisp/progmodes/ruby-mode.el (ruby-smie-grammar): Add rule for paren-free
method calls (bug#bug#15594). (ruby-smie--args-separator-p): New function. (ruby-smie--forward-token, ruby-smie--backward-token): Use it to recognize paren-free method calls.
Diffstat (limited to 'lisp/progmodes/ruby-mode.el')
-rw-r--r--lisp/progmodes/ruby-mode.el81
1 files changed, 51 insertions, 30 deletions
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 2f922162586..dfc93a21b40 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -246,7 +246,8 @@ Also ignores spaces after parenthesis when 'space."
246 '((id) 246 '((id)
247 (insts (inst) (insts ";" insts)) 247 (insts (inst) (insts ";" insts))
248 (inst (exp) (inst "iuwu-mod" exp)) 248 (inst (exp) (inst "iuwu-mod" exp))
249 (exp (exp1) (exp "," exp) (exp "=" exp) (exp "-" exp) (exp "+" exp)) 249 (exp (exp1) (exp "," exp) (exp "=" exp) (exp "-" exp) (exp "+" exp)
250 (id " @ " exp))
250 (exp1 (exp2) (exp2 "?" exp1 ":" exp1)) 251 (exp1 (exp2) (exp2 "?" exp1 ":" exp1))
251 (exp2 ("def" insts "end") 252 (exp2 ("def" insts "end")
252 ("begin" insts-rescue-insts "end") 253 ("begin" insts-rescue-insts "end")
@@ -274,7 +275,8 @@ Also ignores spaces after parenthesis when 'space."
274 (itheni (insts) (exp "then" insts)) 275 (itheni (insts) (exp "then" insts))
275 (ielsei (itheni) (itheni "else" insts)) 276 (ielsei (itheni) (itheni "else" insts))
276 (if-body (ielsei) (if-body "elsif" if-body))) 277 (if-body (ielsei) (if-body "elsif" if-body)))
277 '((nonassoc "in") (assoc ";") (assoc ",") (right "=") (assoc "-" "+")) 278 '((nonassoc "in") (assoc ";") (right " @ ")
279 (assoc ",") (right "=") (assoc "-" "+"))
278 '((assoc "when")) 280 '((assoc "when"))
279 '((assoc "elsif")) 281 '((assoc "elsif"))
280 '((assoc "rescue" "ensure")) 282 '((assoc "rescue" "ensure"))
@@ -316,6 +318,12 @@ Also ignores spaces after parenthesis when 'space."
316 (or (eq ?\{ (char-before)) 318 (or (eq ?\{ (char-before))
317 (looking-back "\\_<do" (- (point) 2))))) 319 (looking-back "\\_<do" (- (point) 2)))))
318 320
321(defun ruby-smie--args-separator-p (pos)
322 (and
323 (eq ?w (char-syntax (char-before)))
324 (< pos (point-max))
325 (memq (char-syntax (char-after pos)) '(?w ?\"))))
326
319(defun ruby-smie--forward-id () 327(defun ruby-smie--forward-id ()
320 (when (and (not (eobp)) 328 (when (and (not (eobp))
321 (eq ?w (char-syntax (char-after)))) 329 (eq ?w (char-syntax (char-after))))
@@ -326,35 +334,42 @@ Also ignores spaces after parenthesis when 'space."
326 tok))) 334 tok)))
327 335
328(defun ruby-smie--forward-token () 336(defun ruby-smie--forward-token ()
329 (skip-chars-forward " \t") 337 (let ((pos (point)))
330 (cond 338 (skip-chars-forward " \t")
331 ((looking-at "\\s\"") "") ;A heredoc or a string. 339 (cond
332 ((and (looking-at "[\n#]") 340 ((looking-at "\\s\"") "") ;A heredoc or a string.
333 (ruby-smie--implicit-semi-p)) ;Only add implicit ; when needed. 341 ((and (looking-at "[\n#]")
334 (if (eolp) (forward-char 1) (forward-comment 1)) 342 (ruby-smie--implicit-semi-p)) ;Only add implicit ; when needed.
335 ";") 343 (if (eolp) (forward-char 1) (forward-comment 1))
336 (t 344 ";")
337 (forward-comment (point-max)) 345 (t
338 (if (looking-at ":\\s.+") 346 (forward-comment (point-max))
339 (progn (goto-char (match-end 0)) (match-string 0)) ;; bug#15208. 347 (cond
340 (let ((tok (smie-default-forward-token))) 348 ((looking-at ":\\s.+")
341 (cond 349 (goto-char (match-end 0)) (match-string 0)) ;; bug#15208.
342 ((member tok '("unless" "if" "while" "until")) 350 ((and (< pos (point))
343 (if (save-excursion (forward-word -1) (ruby-smie--bosp)) 351 (save-excursion
344 tok "iuwu-mod")) 352 (ruby-smie--args-separator-p (prog1 (point) (goto-char pos)))))
345 ((equal tok "|") 353 " @ ")
346 (if (ruby-smie--opening-pipe-p) "opening-|" tok)) 354 (t
347 ((and (equal tok "") (looking-at "\\\\\n")) 355 (let ((tok (smie-default-forward-token)))
348 (goto-char (match-end 0)) (ruby-smie--forward-token))
349 ((equal tok "do")
350 (cond 356 (cond
351 ((not (ruby-smie--redundant-do-p 'skip)) tok) 357 ((member tok '("unless" "if" "while" "until"))
352 ((> (save-excursion (forward-comment (point-max)) (point)) 358 (if (save-excursion (forward-word -1) (ruby-smie--bosp))
353 (line-end-position)) 359 tok "iuwu-mod"))
354 (ruby-smie--forward-token)) ;Fully redundant. 360 ((equal tok "|")
355 (t ";"))) 361 (if (ruby-smie--opening-pipe-p) "opening-|" tok))
356 ((equal tok ".") (concat tok (ruby-smie--forward-id))) 362 ((and (equal tok "") (looking-at "\\\\\n"))
357 (t tok))))))) 363 (goto-char (match-end 0)) (ruby-smie--forward-token))
364 ((equal tok "do")
365 (cond
366 ((not (ruby-smie--redundant-do-p 'skip)) tok)
367 ((> (save-excursion (forward-comment (point-max)) (point))
368 (line-end-position))
369 (ruby-smie--forward-token)) ;Fully redundant.
370 (t ";")))
371 ((equal tok ".") (concat tok (ruby-smie--forward-id)))
372 (t tok)))))))))
358 373
359(defun ruby-smie--backward-id () 374(defun ruby-smie--backward-id ()
360 (when (and (not (bobp)) 375 (when (and (not (bobp))
@@ -372,6 +387,12 @@ Also ignores spaces after parenthesis when 'space."
372 ((and (> pos (line-end-position)) (ruby-smie--implicit-semi-p)) 387 ((and (> pos (line-end-position)) (ruby-smie--implicit-semi-p))
373 (skip-chars-forward " \t") ";") 388 (skip-chars-forward " \t") ";")
374 ((and (bolp) (not (bobp))) "") ;Presumably a heredoc. 389 ((and (bolp) (not (bobp))) "") ;Presumably a heredoc.
390 ((and (> pos (point)) (not (bolp))
391 (ruby-smie--args-separator-p pos))
392 ;; We have "ID SPC ID", which is a method call, but it binds less tightly
393 ;; than commas, since a method call can also be "ID ARG1, ARG2, ARG3".
394 ;; In some textbooks, "e1 @ e2" is used to mean "call e1 with arg e2".
395 " @ ")
375 (t 396 (t
376 (let ((tok (smie-default-backward-token))) 397 (let ((tok (smie-default-backward-token)))
377 (when (eq ?. (char-before)) 398 (when (eq ?. (char-before))