1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-30 08:09:04 +00:00

* lisp/progmodes/ruby-mode.el (ruby-move-to-block): Looks for a block

start/end keyword a bit harder.  Works with different values of N.
Add more comments.
(ruby-end-of-block): Update accordingly.

* test/automated/ruby-mode-tests.el (ruby-heredoc-font-lock)
(ruby-singleton-class-no-heredoc-font-lock)
(ruby-add-log-current-method-examples): New tests.
(ruby-test-string): Extract from ruby-should-indent-buffer.
(ruby-deftest-move-to-block): New macro.
Add several move-to-block tests.
This commit is contained in:
Dmitry Gutov 2012-11-13 22:57:26 +04:00
parent a77b8d5eb0
commit 5e9419e849
4 changed files with 103 additions and 32 deletions

View File

@ -1,3 +1,10 @@
2012-11-13 Dmitry Gutov <dgutov@yandex.ru>
* progmodes/ruby-mode.el (ruby-move-to-block): Looks for a block
start/end keyword a bit harder. Works with different values of N.
Add more comments.
(ruby-end-of-block): Update accordingly.
2012-11-13 Stefan Monnier <monnier@iro.umontreal.ca> 2012-11-13 Stefan Monnier <monnier@iro.umontreal.ca>
* woman.el (woman-file-name): Don't mess with unread-command-events * woman.el (woman-file-name): Don't mess with unread-command-events

View File

@ -865,39 +865,54 @@ calculating indentation on the lines after it."
(beginning-of-line))))) (beginning-of-line)))))
(defun ruby-move-to-block (n) (defun ruby-move-to-block (n)
"Move to the beginning (N < 0) or the end (N > 0) of the current block "Move to the beginning (N < 0) or the end (N > 0) of the
or blocks containing the current block." current block, a sibling block, or an outer block. Do that (abs N) times."
;; TODO: Make this work for n > 1,
;; make it not loop for n = 0,
;; document body
(let ((orig (point)) (let ((orig (point))
(start (ruby-calculate-indent)) (start (ruby-calculate-indent))
(down (looking-at (if (< n 0) ruby-block-end-re (signum (if (> n 0) 1 -1))
(concat "\\<\\(" ruby-block-beg-re "\\)\\>")))) (backward (< n 0))
pos done) down pos done)
(while (and (not done) (not (if (< n 0) (bobp) (eobp)))) (dotimes (_ (abs n))
(forward-line n) (setq done nil)
(cond (setq down (save-excursion
((looking-at "^\\s *$")) (back-to-indentation)
((looking-at "^\\s *#")) ;; There is a block start or block end keyword on this
((and (> n 0) (looking-at "^=begin\\>")) ;; line, don't need to look for another block.
(re-search-forward "^=end\\>")) (and (re-search-forward
((and (< n 0) (looking-at "^=end\\>")) (if backward ruby-block-end-re
(re-search-backward "^=begin\\>")) (concat "\\_<\\(" ruby-block-beg-re "\\)\\_>"))
(t (line-end-position) t)
(setq pos (current-indentation)) (not (nth 8 (syntax-ppss))))))
(while (and (not done) (not (if backward (bobp) (eobp))))
(forward-line signum)
(cond (cond
((< start pos) ;; Skip empty and commented out lines.
(setq down t)) ((looking-at "^\\s *$"))
((and down (= pos start)) ((looking-at "^\\s *#"))
(setq done t)) ;; Skip block comments;
((> start pos) ((and (not backward) (looking-at "^=begin\\>"))
(setq done t))))) (re-search-forward "^=end\\>"))
(if done ((and backward (looking-at "^=end\\>"))
(save-excursion (re-search-backward "^=begin\\>"))
(back-to-indentation) (t
(if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>")) (setq pos (current-indentation))
(setq done nil))))) (cond
;; Deeper intendation, we found a block.
;; FIXME: We can't recognize empty blocks this way.
((< start pos)
(setq down t))
;; Block found, and same indentation as when started, stop.
((and down (= pos start))
(setq done t))
;; Shallower indentation, means outer block, can stop now.
((> start pos)
(setq done t)))))
(if done
(save-excursion
(back-to-indentation)
;; Not really at the first or last line of the block, move on.
(if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>"))
(setq done nil))))))
(back-to-indentation))) (back-to-indentation)))
(defun ruby-beginning-of-block (&optional arg) (defun ruby-beginning-of-block (&optional arg)
@ -909,8 +924,7 @@ With ARG, move up multiple blocks."
(defun ruby-end-of-block (&optional arg) (defun ruby-end-of-block (&optional arg)
"Move forward to the end of the current block. "Move forward to the end of the current block.
With ARG, move out of multiple blocks." With ARG, move out of multiple blocks."
;; Passing a value > 1 to ruby-move-to-block currently doesn't work. (interactive "p")
(interactive)
(ruby-move-to-block (or arg 1))) (ruby-move-to-block (or arg 1)))
(defun ruby-forward-sexp (&optional arg) (defun ruby-forward-sexp (&optional arg)

View File

@ -4,6 +4,8 @@
(ruby-singleton-class-no-heredoc-font-lock) (ruby-singleton-class-no-heredoc-font-lock)
(ruby-add-log-current-method-examples): New tests. (ruby-add-log-current-method-examples): New tests.
(ruby-test-string): Extract from ruby-should-indent-buffer. (ruby-test-string): Extract from ruby-should-indent-buffer.
(ruby-deftest-move-to-block): New macro.
Add several move-to-block tests.
2012-11-12 Stefan Monnier <monnier@iro.umontreal.ca> 2012-11-12 Stefan Monnier <monnier@iro.umontreal.ca>

View File

@ -283,6 +283,54 @@ VALUES-PLIST is a list with alternating index and value elements."
(should (string= (ruby-add-log-current-method) (should (string= (ruby-add-log-current-method)
(format "M::C%s" value))))))) (format "M::C%s" value)))))))
(defvar ruby-block-test-example
(ruby-test-string
"class C
| def foo
| 1
| end
|
| def bar
| 2
| end
|
| def baz
| some do
| end
| end
|end"))
(defmacro ruby-deftest-move-to-block (name &rest body)
`(ert-deftest ,(intern (format "ruby-move-to-block-%s" name)) ()
(with-temp-buffer
(insert ruby-block-test-example)
(ruby-mode)
,@body)))
(put 'ruby-deftest-move-to-block 'lisp-indent-function 'defun)
(ruby-deftest-move-to-block works-on-do
(goto-line 11)
(ruby-end-of-block)
(should (= 12 (line-number-at-pos)))
(ruby-beginning-of-block)
(should (= 11 (line-number-at-pos))))
(ruby-deftest-move-to-block zero-is-noop
(goto-line 5)
(ruby-move-to-block 0)
(should (= 5 (line-number-at-pos))))
(ruby-deftest-move-to-block ok-with-three
(goto-line 2)
(ruby-move-to-block 3)
(should (= 13 (line-number-at-pos))))
(ruby-deftest-move-to-block ok-with-minus-two
(goto-line 10)
(ruby-move-to-block -2)
(should (= 2 (line-number-at-pos))))
(provide 'ruby-mode-tests) (provide 'ruby-mode-tests)
;;; ruby-mode-tests.el ends here ;;; ruby-mode-tests.el ends here