* lisp/progmodes/ruby-mode.el (ruby-syntax-propertize-function):
Extract `ruby-syntax-propertize-expansions'. (ruby-syntax-propertize-expansions): Only change syntax on certain string delimiters, to punctuation. This way the common functions like forward-word and thing-at-point still work. (ruby-match-expression-expansion): Improve readability. (ruby-block-contains-point): New function. (ruby-add-log-current-method): Handle several edge cases. * test/automated/ruby-mode-tests.el Rename one interpolation test; add three more. (ruby-with-temp-buffer): New macro, use it where appropriate. (ruby-add-log-current-method-examples): Use "_" for target point. Add four tests for ruby-add-log-current-method.
This commit is contained in:
parent
dbb530d988
commit
bb808526ae
4 changed files with 122 additions and 66 deletions
|
@ -6,6 +6,8 @@
|
|||
certain string delimiters, to punctuation. This way the common
|
||||
functions like forward-word and thing-at-point still work.
|
||||
(ruby-match-expression-expansion): Improve readability.
|
||||
(ruby-block-contains-point): New function.
|
||||
(ruby-add-log-current-method): Handle several edge cases.
|
||||
|
||||
2012-12-13 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
|
|
|
@ -102,6 +102,10 @@
|
|||
'"\\(def\\|class\\|module\\)"
|
||||
"Regexp to match the beginning of a defun, in the general sense.")
|
||||
|
||||
(defconst ruby-singleton-class-re
|
||||
"class\\s *<<"
|
||||
"Regexp to match the beginning of a singleton class context.")
|
||||
|
||||
(eval-and-compile
|
||||
(defconst ruby-here-doc-beg-re
|
||||
"\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
|
||||
|
@ -384,7 +388,7 @@ and `\\' when preceded by `?'."
|
|||
(when pos (goto-char pos))
|
||||
(forward-word -1)
|
||||
(and (or (bolp) (not (eq (char-before (point)) ?_)))
|
||||
(looking-at "class\\s *<<"))))
|
||||
(looking-at ruby-singleton-class-re))))
|
||||
|
||||
(defun ruby-expr-beg (&optional option)
|
||||
"Check if point is possibly at the beginning of an expression.
|
||||
|
@ -1057,35 +1061,32 @@ For example:
|
|||
See `add-log-current-defun-function'."
|
||||
(condition-case nil
|
||||
(save-excursion
|
||||
(let (mname mlist (indent 0))
|
||||
(let ((indent 0) mname mlist
|
||||
(start (point))
|
||||
(definition-re
|
||||
(concat "^[ \t]*" ruby-defun-beg-re "[ \t]+"
|
||||
"\\("
|
||||
;; \\. and :: for class methods
|
||||
"\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
|
||||
"+\\)")))
|
||||
;; Get the current method definition (or class/module).
|
||||
(if (re-search-backward
|
||||
(concat "^[ \t]*" ruby-defun-beg-re "[ \t]+"
|
||||
"\\("
|
||||
;; \\. and :: for class methods
|
||||
"\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
|
||||
"+\\)")
|
||||
nil t)
|
||||
(progn
|
||||
(setq mname (match-string 2))
|
||||
(unless (string-equal "def" (match-string 1))
|
||||
(setq mlist (list mname) mname nil))
|
||||
(goto-char (match-beginning 1))
|
||||
(setq indent (current-column))
|
||||
(beginning-of-line)))
|
||||
(when (re-search-backward definition-re nil t)
|
||||
(goto-char (match-beginning 1))
|
||||
(when (ruby-block-contains-point start)
|
||||
;; We're inside the method, class or module.
|
||||
(setq mname (match-string 2))
|
||||
(unless (string-equal "def" (match-string 1))
|
||||
(setq mlist (list mname) mname nil)))
|
||||
(setq indent (current-column))
|
||||
(beginning-of-line))
|
||||
;; Walk up the class/module nesting.
|
||||
(while (and (> indent 0)
|
||||
(re-search-backward
|
||||
(concat
|
||||
"^[ \t]*\\(class\\|module\\)[ \t]+"
|
||||
"\\([A-Z]" ruby-symbol-re "*\\)")
|
||||
nil t))
|
||||
(re-search-backward definition-re nil t))
|
||||
(goto-char (match-beginning 1))
|
||||
(if (< (current-column) indent)
|
||||
(progn
|
||||
(setq mlist (cons (match-string 2) mlist))
|
||||
(setq indent (current-column))
|
||||
(beginning-of-line))))
|
||||
(when (ruby-block-contains-point start)
|
||||
(setq mlist (cons (match-string 2) mlist))
|
||||
(setq indent (current-column))
|
||||
(beginning-of-line)))
|
||||
;; Process the method name.
|
||||
(when mname
|
||||
(let ((mn (split-string mname "\\.\\|::")))
|
||||
|
@ -1104,7 +1105,14 @@ See `add-log-current-defun-function'."
|
|||
(setcdr (last mlist) (butlast mn))
|
||||
(setq mlist (butlast mn))))
|
||||
(setq mname (concat "." (car (last mn)))))
|
||||
(setq mname (concat "#" mname)))))
|
||||
;; See if the method is in singleton class context.
|
||||
(let ((in-singleton-class
|
||||
(when (re-search-forward ruby-singleton-class-re start t)
|
||||
(goto-char (match-beginning 0))
|
||||
(ruby-block-contains-point start))))
|
||||
(setq mname (concat
|
||||
(if in-singleton-class "." "#")
|
||||
mname))))))
|
||||
;; Generate the string.
|
||||
(if (consp mlist)
|
||||
(setq mlist (mapconcat (function identity) mlist "::")))
|
||||
|
@ -1112,6 +1120,12 @@ See `add-log-current-defun-function'."
|
|||
(if mlist (concat mlist mname) mname)
|
||||
mlist)))))
|
||||
|
||||
(defun ruby-block-contains-point (pt)
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(ruby-forward-sexp)
|
||||
(> (point) pt))))
|
||||
|
||||
(defun ruby-brace-to-do-end (orig end)
|
||||
(let (beg-marker end-marker)
|
||||
(goto-char end)
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
* automated/ruby-mode-tests.el
|
||||
Rename one interpolation test; add three more.
|
||||
(ruby-with-temp-buffer): New macro, use it where appropriate.
|
||||
(ruby-add-log-current-method-examples): Use "_" for target point.
|
||||
Add four new tests for ruby-add-log-current-method.
|
||||
|
||||
2012-12-11 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
(defun ruby-should-indent (content column)
|
||||
"Assert indentation COLUMN on the last line of CONTENT."
|
||||
(with-temp-buffer
|
||||
(insert content)
|
||||
(ruby-mode)
|
||||
(ruby-with-temp-buffer content
|
||||
(ruby-indent-line)
|
||||
(should (= (current-indentation) column))))
|
||||
|
||||
|
@ -35,12 +33,17 @@
|
|||
"Assert that CONTENT turns into EXPECTED after the buffer is re-indented.
|
||||
|
||||
The whitespace before and including \"|\" on each line is removed."
|
||||
(with-temp-buffer
|
||||
(insert (ruby-test-string content))
|
||||
(ruby-mode)
|
||||
(ruby-with-temp-buffer (ruby-test-string content)
|
||||
(indent-region (point-min) (point-max))
|
||||
(should (string= (ruby-test-string expected) (buffer-string)))))
|
||||
|
||||
(defmacro ruby-with-temp-buffer (contents &rest body)
|
||||
(declare (indent 1) (debug t))
|
||||
`(with-temp-buffer
|
||||
(insert ,contents)
|
||||
(ruby-mode)
|
||||
,@body))
|
||||
|
||||
(defun ruby-test-string (s &rest args)
|
||||
(apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args))
|
||||
|
||||
|
@ -48,9 +51,7 @@ The whitespace before and including \"|\" on each line is removed."
|
|||
"Assert syntax state values at the end of CONTENT.
|
||||
|
||||
VALUES-PLIST is a list with alternating index and value elements."
|
||||
(with-temp-buffer
|
||||
(insert content)
|
||||
(ruby-mode)
|
||||
(ruby-with-temp-buffer content
|
||||
(syntax-propertize (point))
|
||||
(while values-plist
|
||||
(should (eq (nth (car values-plist)
|
||||
|
@ -59,9 +60,7 @@ VALUES-PLIST is a list with alternating index and value elements."
|
|||
(setq values-plist (cddr values-plist)))))
|
||||
|
||||
(defun ruby-assert-face (content pos face)
|
||||
(with-temp-buffer
|
||||
(insert content)
|
||||
(ruby-mode)
|
||||
(ruby-with-temp-buffer content
|
||||
(font-lock-fontify-buffer)
|
||||
(should (eq face (get-text-property pos 'face)))))
|
||||
|
||||
|
@ -226,17 +225,13 @@ VALUES-PLIST is a list with alternating index and value elements."
|
|||
|"))
|
||||
|
||||
(ert-deftest ruby-move-to-block-stops-at-indentation ()
|
||||
(with-temp-buffer
|
||||
(insert "def f\nend")
|
||||
(ruby-with-temp-buffer "def f\nend"
|
||||
(beginning-of-line)
|
||||
(ruby-mode)
|
||||
(ruby-move-to-block -1)
|
||||
(should (looking-at "^def"))))
|
||||
|
||||
(ert-deftest ruby-toggle-block-to-do-end ()
|
||||
(with-temp-buffer
|
||||
(insert "foo {|b|\n}")
|
||||
(ruby-mode)
|
||||
(ruby-with-temp-buffer "foo {|b|\n}"
|
||||
(beginning-of-line)
|
||||
(ruby-toggle-block)
|
||||
(should (string= "foo do |b|\nend" (buffer-string)))))
|
||||
|
@ -254,9 +249,7 @@ VALUES-PLIST is a list with alternating index and value elements."
|
|||
(should (string= (cdr pair) (buffer-string))))))))
|
||||
|
||||
(ert-deftest ruby-toggle-block-to-multiline ()
|
||||
(with-temp-buffer
|
||||
(insert "foo {|b| b + 1}")
|
||||
(ruby-mode)
|
||||
(ruby-with-temp-buffer "foo {|b| b + 1}"
|
||||
(beginning-of-line)
|
||||
(ruby-toggle-block)
|
||||
(should (string= "foo do |b|\n b + 1\nend" (buffer-string)))))
|
||||
|
@ -295,9 +288,8 @@ VALUES-PLIST is a list with alternating index and value elements."
|
|||
|
||||
(ert-deftest ruby-interpolation-keeps-non-quote-syntax ()
|
||||
(let ((s "\"foo#{baz.tee}bar\""))
|
||||
(with-temp-buffer
|
||||
(save-excursion
|
||||
(insert s))
|
||||
(ruby-with-temp-buffer s
|
||||
(goto-char (point-min))
|
||||
(ruby-mode)
|
||||
(font-lock-fontify-buffer)
|
||||
(search-forward "tee")
|
||||
|
@ -318,21 +310,66 @@ VALUES-PLIST is a list with alternating index and value elements."
|
|||
("self.foo" . ".foo"))))
|
||||
(dolist (pair pairs)
|
||||
(let ((name (car pair))
|
||||
(value (cdr pair)))
|
||||
(with-temp-buffer
|
||||
(insert (ruby-test-string
|
||||
"module M
|
||||
| class C
|
||||
| def %s
|
||||
| end
|
||||
| end
|
||||
|end"
|
||||
name))
|
||||
(ruby-mode)
|
||||
(search-backward "def")
|
||||
(forward-line)
|
||||
(should (string= (ruby-add-log-current-method)
|
||||
(format "M::C%s" value))))))))
|
||||
(value (cdr pair)))
|
||||
(ruby-with-temp-buffer (ruby-test-string
|
||||
"module M
|
||||
| class C
|
||||
| def %s
|
||||
| _
|
||||
| end
|
||||
| end
|
||||
|end"
|
||||
name)
|
||||
(search-backward "_")
|
||||
(forward-line)
|
||||
(should (string= (ruby-add-log-current-method)
|
||||
(format "M::C%s" value))))))))
|
||||
|
||||
(ert-deftest ruby-add-log-current-method-outside-of-method ()
|
||||
(ruby-with-temp-buffer (ruby-test-string
|
||||
"module M
|
||||
| class C
|
||||
| def foo
|
||||
| end
|
||||
| _
|
||||
| end
|
||||
|end")
|
||||
(search-backward "_")
|
||||
(should (string= (ruby-add-log-current-method)"M::C"))))
|
||||
|
||||
(ert-deftest ruby-add-log-current-method-in-singleton-class ()
|
||||
(ruby-with-temp-buffer (ruby-test-string
|
||||
"class C
|
||||
| class << self
|
||||
| def foo
|
||||
| _
|
||||
| end
|
||||
| end
|
||||
|end")
|
||||
(search-backward "_")
|
||||
(should (string= (ruby-add-log-current-method) "C.foo"))))
|
||||
|
||||
(ert-deftest ruby-add-log-current-method-namespace-shorthand ()
|
||||
(ruby-with-temp-buffer (ruby-test-string
|
||||
"class C::D
|
||||
| def foo
|
||||
| _
|
||||
| end
|
||||
|end")
|
||||
(search-backward "_")
|
||||
(should (string= (ruby-add-log-current-method) "C::D#foo"))))
|
||||
|
||||
(ert-deftest ruby-add-log-current-method-after-inner-class ()
|
||||
(ruby-with-temp-buffer (ruby-test-string
|
||||
"module M
|
||||
| class C
|
||||
| class D
|
||||
| end
|
||||
| _
|
||||
| end
|
||||
|end")
|
||||
(search-backward "_")
|
||||
(should (string= (ruby-add-log-current-method) "M::C"))))
|
||||
|
||||
(defvar ruby-block-test-example
|
||||
(ruby-test-string
|
||||
|
|
Loading…
Add table
Reference in a new issue