+2013-02-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ * progmodes/ruby-mode.el (ruby-move-to-block): Improve
+ performance. Instead of recalculating indentation fully for each
+ line, sum up indentation depth based only on visited lines.
+ (ruby-parse-partial): Increase the depth after "do" even when END
+ is right after it.
+ (ruby-parse-partial): When END is in the middle of a percent
+ literal, increase the depth if the delimiter chars belong to the
+ paren syntax class.
+
2013-02-13 Kirill A. Korinskiy <catap@catap.ru>
* play/fortune.el (fortune-compile): Also make the compiled file
(concat "[^\\]\\(\\\\\\\\\\)*" w))
end t)))
(setq in-string (point))
+ (when (eq (char-syntax (string-to-char w)) ?\()
+ ;; The rest of the literal, when parsed separately, will
+ ;; have the depth of -1. So in the rare case when this
+ ;; number is used despite the in-string status, the
+ ;; depths will balance.
+ (setq depth (1+ depth)))
(goto-char end)))
(t
(goto-char pnt))))
(not (or (eq ?_ w)
(eq ?. w)))))
(goto-char pnt)
- (setq w (char-after (point)))
- (not (eq ?! w))
+ (not (eq ?! (char-after (point))))
(skip-chars-forward " \t")
(goto-char (match-beginning 0))
(or (not (looking-at ruby-modifier-re))
(defun ruby-move-to-block (n)
"Move to the beginning (N < 0) or the end (N > 0) of the
current block, a sibling block, or an outer block. Do that (abs N) times."
- (let ((orig (point))
- (start (ruby-calculate-indent))
- (signum (if (> n 0) 1 -1))
+ (let ((signum (if (> n 0) 1 -1))
(backward (< n 0))
- down pos done)
+ (depth (or (nth 2 (ruby-parse-region (line-beginning-position)
+ (line-end-position)))
+ 0))
+ down done)
+ (when (< (* depth signum) 0)
+ ;; Moving end -> end or beginning -> beginning.
+ (setq depth 0))
(dotimes (_ (abs n))
(setq done nil)
(setq down (save-excursion
((and backward (looking-at "^=end\\>"))
(re-search-backward "^=begin\\>"))
(t
- (setq pos (ruby-calculate-indent))
+ (incf depth (or (nth 2 (ruby-parse-region (point)
+ (line-end-position)))
+ 0))
(cond
;; Deeper indentation, we found a block.
;; FIXME: We can't recognize empty blocks this way.
- ((< start pos)
+ ((> (* signum depth) 0)
(setq down t))
;; Block found, and same indentation as when started, stop.
- ((and down (= pos start))
+ ((and down (zerop depth))
(setq done t))
;; Shallower indentation, means outer block, can stop now.
- ((> start pos)
+ ((< (* signum depth) 0)
(setq done t)))))
(if done
(save-excursion
(ruby-move-to-block -2)
(should (= 2 (line-number-at-pos))))
+(ert-deftest ruby-move-to-block-skips-percent-literal ()
+ (dolist (s (list (ruby-test-string
+ "foo do
+ | a = %%w(
+ | )
+ |end")
+ (ruby-test-string
+ "foo do
+ | a = %%w|
+ | |
+ |end")))
+ (ruby-with-temp-buffer s
+ (goto-line 1)
+ (ruby-end-of-block)
+ (should (= 4 (line-number-at-pos)))
+ (ruby-beginning-of-block)
+ (should (= 1 (line-number-at-pos))))))
+
(provide 'ruby-mode-tests)
;;; ruby-mode-tests.el ends here