aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-10-06 23:38:26 -0400
committerStefan Monnier2013-10-06 23:38:26 -0400
commit7ccae3b126e1b01814e8bed7f903f5e2b6d448bd (patch)
treec27b63b78e52c5aa573a46e9a9b94affc015c543
parentc8af480df782d6ff2d99f34a1672b8640dfb673f (diff)
downloademacs-7ccae3b126e1b01814e8bed7f903f5e2b6d448bd.tar.gz
emacs-7ccae3b126e1b01814e8bed7f903f5e2b6d448bd.zip
* lisp/progmodes/ruby-mode.el: Fix recently added tests.
(ruby-smie-grammar): Add - and +. (ruby-smie--redundant-do-p, ruby-smie--forward-id) (ruby-smie--backward-id): New functions. (ruby-smie--forward-token, ruby-smie--backward-token): Use them. (ruby-smie-rules): Handle hanging do. Get rid of hack, not needed any more. * test/indent/ruby.rb: Add a few more tests; adjust some indentation.
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/progmodes/ruby-mode.el85
-rw-r--r--test/indent/ruby.rb21
3 files changed, 93 insertions, 23 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9211dfe2356..bf8dad1b621 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
12013-10-07 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * progmodes/ruby-mode.el: Fix recently added tests.
4 (ruby-smie-grammar): Add - and +.
5 (ruby-smie--redundant-do-p, ruby-smie--forward-id)
6 (ruby-smie--backward-id): New functions.
7 (ruby-smie--forward-token, ruby-smie--backward-token): Use them.
8 (ruby-smie-rules): Handle hanging do. Get rid of hack, not needed
9 any more.
10
12013-10-07 Leo Liu <sdl.web@gmail.com> 112013-10-07 Leo Liu <sdl.web@gmail.com>
2 12
3 * register.el (register-preview-delay) 13 * register.el (register-preview-delay)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index c1f79eb8711..b8c24e8a690 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -246,7 +246,7 @@ 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)) 249 (exp (exp1) (exp "," exp) (exp "=" exp) (exp "-" exp) (exp "+" exp))
250 (exp1 (exp2) (exp2 "?" exp1 ":" exp1)) 250 (exp1 (exp2) (exp2 "?" exp1 ":" exp1))
251 (exp2 ("def" insts "end") 251 (exp2 ("def" insts "end")
252 ("begin" insts-rescue-insts "end") 252 ("begin" insts-rescue-insts "end")
@@ -274,7 +274,7 @@ Also ignores spaces after parenthesis when 'space."
274 (itheni (insts) (exp "then" insts)) 274 (itheni (insts) (exp "then" insts))
275 (ielsei (itheni) (itheni "else" insts)) 275 (ielsei (itheni) (itheni "else" insts))
276 (if-body (ielsei) (if-body "elsif" if-body))) 276 (if-body (ielsei) (if-body "elsif" if-body)))
277 '((nonassoc "in") (assoc ";") (assoc ",") (right "=")) 277 '((nonassoc "in") (assoc ";") (assoc ",") (right "=") (assoc "-" "+"))
278 '((assoc "when")) 278 '((assoc "when"))
279 '((assoc "elsif")) 279 '((assoc "elsif"))
280 '((assoc "rescue" "ensure")) 280 '((assoc "rescue" "ensure"))
@@ -297,6 +297,11 @@ Also ignores spaces after parenthesis when 'space."
297 (or (equal tok "?") 297 (or (equal tok "?")
298 (string-match "\\`\\s." tok)))))))) 298 (string-match "\\`\\s." tok))))))))
299 299
300(defun ruby-smie--redundant-do-p (&optional skip)
301 (save-excursion
302 (if skip (backward-word 1))
303 (member (nth 2 (smie-backward-sexp ";")) '("while"))))
304
300(defun ruby-smie--opening-pipe-p () 305(defun ruby-smie--opening-pipe-p ()
301 (save-excursion 306 (save-excursion
302 (if (eq ?| (char-before)) (forward-char -1)) 307 (if (eq ?| (char-before)) (forward-char -1))
@@ -304,6 +309,15 @@ Also ignores spaces after parenthesis when 'space."
304 (or (eq ?\{ (char-before)) 309 (or (eq ?\{ (char-before))
305 (looking-back "\\_<do" (- (point) 2))))) 310 (looking-back "\\_<do" (- (point) 2)))))
306 311
312(defun ruby-smie--forward-id ()
313 (when (and (not (eobp))
314 (eq ?w (char-syntax (char-after))))
315 (let ((tok (smie-default-forward-token)))
316 (when (eq ?. (char-after))
317 (forward-char 1)
318 (setq tok (concat tok "." (ruby-smie--forward-id))))
319 tok)))
320
307(defun ruby-smie--forward-token () 321(defun ruby-smie--forward-token ()
308 (skip-chars-forward " \t") 322 (skip-chars-forward " \t")
309 (cond 323 (cond
@@ -316,17 +330,37 @@ Also ignores spaces after parenthesis when 'space."
316 (forward-comment (point-max)) 330 (forward-comment (point-max))
317 (if (looking-at ":\\s.+") 331 (if (looking-at ":\\s.+")
318 (progn (goto-char (match-end 0)) (match-string 0)) ;; bug#15208. 332 (progn (goto-char (match-end 0)) (match-string 0)) ;; bug#15208.
319 (let ((tok (smie-default-forward-token))) 333 (let ((tok (smie-default-forward-token)))
320 (cond 334 (when (eq ?. (char-after))
321 ((member tok '("unless" "if" "while" "until")) 335 (forward-char 1)
322 (if (save-excursion (forward-word -1) (ruby-smie--bosp)) 336 (setq tok (concat tok "." (ruby-smie--forward-id))))
323 tok "iuwu-mod")) 337 (cond
338 ((member tok '("unless" "if" "while" "until"))
339 (if (save-excursion (forward-word -1) (ruby-smie--bosp))
340 tok "iuwu-mod"))
324 ((equal tok "|") 341 ((equal tok "|")
325 (if (ruby-smie--opening-pipe-p) "opening-|" tok)) 342 (if (ruby-smie--opening-pipe-p) "opening-|" tok))
326 ((and (equal tok "") (looking-at "\\\\\n")) 343 ((and (equal tok "") (looking-at "\\\\\n"))
327 (goto-char (match-end 0)) (ruby-smie--forward-token)) 344 (goto-char (match-end 0)) (ruby-smie--forward-token))
345 ((equal tok "do")
346 (cond
347 ((not (ruby-smie--redundant-do-p 'skip)) tok)
348 ((> (save-excursion (forward-comment (point-max)) (point))
349 (line-end-position))
350 (ruby-smie--forward-token)) ;Fully redundant.
351 (t ";")))
352 ((equal tok ".") (concat tok (ruby-smie--forward-id)))
328 (t tok))))))) 353 (t tok)))))))
329 354
355(defun ruby-smie--backward-id ()
356 (when (and (not (bobp))
357 (eq ?w (char-syntax (char-before))))
358 (let ((tok (smie-default-backward-token)))
359 (when (eq ?. (char-before))
360 (forward-char -1)
361 (setq tok (concat (ruby-smie--backward-id) "." tok)))
362 tok)))
363
330(defun ruby-smie--backward-token () 364(defun ruby-smie--backward-token ()
331 (let ((pos (point))) 365 (let ((pos (point)))
332 (forward-comment (- (point))) 366 (forward-comment (- (point)))
@@ -336,6 +370,9 @@ Also ignores spaces after parenthesis when 'space."
336 ((and (bolp) (not (bobp))) "") ;Presumably a heredoc. 370 ((and (bolp) (not (bobp))) "") ;Presumably a heredoc.
337 (t 371 (t
338 (let ((tok (smie-default-backward-token))) 372 (let ((tok (smie-default-backward-token)))
373 (when (eq ?. (char-before))
374 (forward-char -1)
375 (setq tok (concat (ruby-smie--backward-id) "." tok)))
339 (when (and (eq ?: (char-before)) (string-match "\\`\\s." tok)) 376 (when (and (eq ?: (char-before)) (string-match "\\`\\s." tok))
340 (forward-char -1) (setq tok (concat ":" tok))) ;; bug#15208. 377 (forward-char -1) (setq tok (concat ":" tok))) ;; bug#15208.
341 (cond 378 (cond
@@ -346,6 +383,16 @@ Also ignores spaces after parenthesis when 'space."
346 (if (ruby-smie--opening-pipe-p) "opening-|" tok)) 383 (if (ruby-smie--opening-pipe-p) "opening-|" tok))
347 ((and (equal tok "") (eq ?\\ (char-before)) (looking-at "\n")) 384 ((and (equal tok "") (eq ?\\ (char-before)) (looking-at "\n"))
348 (forward-char -1) (ruby-smie--backward-token)) 385 (forward-char -1) (ruby-smie--backward-token))
386 ((equal tok "do")
387 (cond
388 ((not (ruby-smie--redundant-do-p)) tok)
389 ((> (save-excursion (forward-word 1)
390 (forward-comment (point-max)) (point))
391 (line-end-position))
392 (ruby-smie--backward-token)) ;Fully redundant.
393 (t ";")))
394 ((equal tok ".")
395 (concat (ruby-smie--backward-id) tok))
349 (t tok))))))) 396 (t tok)))))))
350 397
351(defun ruby-smie-rules (kind token) 398(defun ruby-smie-rules (kind token)
@@ -370,24 +417,22 @@ Also ignores spaces after parenthesis when 'space."
370 (if (smie-rule-hanging-p) (smie-rule-parent))) 417 (if (smie-rule-hanging-p) (smie-rule-parent)))
371 (`(:after . "=") 2) 418 (`(:after . "=") 2)
372 (`(:before . "do") 419 (`(:before . "do")
373 (when 420 (when (or (smie-rule-hanging-p)
374 (save-excursion 421 (save-excursion
375 (forward-word 1) ;Skip "do" 422 (forward-word 1) ;Skip "do"
376 (skip-chars-forward " \t") 423 (skip-chars-forward " \t")
377 (and (equal (save-excursion (ruby-smie--forward-token)) "opening-|") 424 (and (equal (save-excursion (ruby-smie--forward-token))
378 (save-excursion (forward-sexp 1) 425 "opening-|")
379 (skip-chars-forward " \t") 426 (save-excursion (forward-sexp 1)
380 (or (eolp) 427 (skip-chars-forward " \t")
381 (looking-at comment-start-skip))))) 428 (or (eolp)
429 (looking-at comment-start-skip))))))
382 ;; `(column . ,(smie-indent-virtual)) 430 ;; `(column . ,(smie-indent-virtual))
383 (smie-rule-parent))) 431 (smie-rule-parent)))
384 (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) 0) 432 (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) 0)
385 (`(:before . ,(or `"when")) 433 (`(:before . ,(or `"when"))
386 (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level 434 (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level
387 ;; Hack attack: Since newlines are separators, don't try to align args that 435 ))
388 ;; appear on a separate line. "" is for the case where the "previous
389 ;; separator" was not an implicit ";" but the BOB.
390 (`(:list-intro . ,(or `";" `"")) t)))
391 436
392(defun ruby-imenu-create-index-in-block (prefix beg end) 437(defun ruby-imenu-create-index-in-block (prefix beg end)
393 "Create an imenu index of methods inside a block." 438 "Create an imenu index of methods inside a block."
diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb
index e40ef217e54..7c8de323bdb 100644
--- a/test/indent/ruby.rb
+++ b/test/indent/ruby.rb
@@ -99,6 +99,14 @@ if something == :==
99 do_something 99 do_something
100end 100end
101 101
102# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
103d = 4 + 5 + # no '\' needed
104 6 + 7
105
106# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
107e = 8 + 9 \
108 + 10 # '\' needed
109
102begin 110begin
103 foo 111 foo
104ensure 112ensure
@@ -109,20 +117,27 @@ end
109MSG = 'Separate every 3 digits in the integer portion of a number' + 117MSG = 'Separate every 3 digits in the integer portion of a number' +
110 'with underscores(_).' 118 'with underscores(_).'
111 119
112# Examples below fail with SMIE. 120class C
121 def foo
122 self.end
123 D.new.class
124 end
125end
113 126
114a = foo(j, k) - 127a = foo(j, k) -
115 bar_tee 128 bar_tee
116 129
117while a < b do # "do" is optional 130while a < b do # "do" is optional
118 foo 131 foo
119end 132end
120 133
121desc "foo foo" \ 134desc "foo foo" \
122 "bar bar" 135 "bar bar"
123 136
124foo. 137foo.
125 bar 138 bar
126 139
140# FIXME: is this really valid Ruby? Isn't the newline after "foo" treated as
141# an implicit semi-colon?
127foo 142foo
128 .bar 143 .bar