aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-10-12 16:40:50 -0400
committerStefan Monnier2013-10-12 16:40:50 -0400
commit650fa7bfb4143c3f6f46939982ae7e8f69e806f7 (patch)
tree0bb784e4d142bf8592141448742a83afd87ff406
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.
-rw-r--r--lisp/ChangeLog6
-rw-r--r--lisp/progmodes/ruby-mode.el81
-rw-r--r--test/indent/ruby.rb4
3 files changed, 61 insertions, 30 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 20271be89b0..380b48adafc 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,11 @@
12013-10-12 Stefan Monnier <monnier@iro.umontreal.ca> 12013-10-12 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * progmodes/ruby-mode.el (ruby-smie-grammar): Add rule for paren-free
4 method calls (bug#bug#15594).
5 (ruby-smie--args-separator-p): New function.
6 (ruby-smie--forward-token, ruby-smie--backward-token): Use it to
7 recognize paren-free method calls.
8
3 * isearch.el (isearch-pre-command-hook): Don't build in knowledge about 9 * isearch.el (isearch-pre-command-hook): Don't build in knowledge about
4 internals of universal-argument. 10 internals of universal-argument.
5 11
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))
diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb
index 287cbfd0ec4..67584c01c7a 100644
--- a/test/indent/ruby.rb
+++ b/test/indent/ruby.rb
@@ -170,3 +170,7 @@ foo_bar_tee(1, 2, 3)
170if foo && 170if foo &&
171 bar 171 bar
172end 172end
173
174method1 arg1, # bug#15594
175 method2 arg2,
176 arg3