aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2012-12-14 10:58:15 +0400
committerDmitry Gutov2012-12-14 10:58:15 +0400
commitbb808526ae2847f1e9aa6559835da2a10545a273 (patch)
tree98fea65f31b2de5192163bea1d25beab29cb5044
parentdbb530d9887fd51de9f8e338b325537d9eac0a3a (diff)
downloademacs-bb808526ae2847f1e9aa6559835da2a10545a273.tar.gz
emacs-bb808526ae2847f1e9aa6559835da2a10545a273.zip
* 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.
-rw-r--r--lisp/ChangeLog2
-rw-r--r--lisp/progmodes/ruby-mode.el68
-rw-r--r--test/ChangeLog3
-rw-r--r--test/automated/ruby-mode-tests.el115
4 files changed, 122 insertions, 66 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 2d12a357cbf..8df55eaa108 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -6,6 +6,8 @@
6 certain string delimiters, to punctuation. This way the common 6 certain string delimiters, to punctuation. This way the common
7 functions like forward-word and thing-at-point still work. 7 functions like forward-word and thing-at-point still work.
8 (ruby-match-expression-expansion): Improve readability. 8 (ruby-match-expression-expansion): Improve readability.
9 (ruby-block-contains-point): New function.
10 (ruby-add-log-current-method): Handle several edge cases.
9 11
102012-12-13 Juanma Barranquero <lekktu@gmail.com> 122012-12-13 Juanma Barranquero <lekktu@gmail.com>
11 13
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 6b9e921be67..8ac2f659058 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -102,6 +102,10 @@
102 '"\\(def\\|class\\|module\\)" 102 '"\\(def\\|class\\|module\\)"
103 "Regexp to match the beginning of a defun, in the general sense.") 103 "Regexp to match the beginning of a defun, in the general sense.")
104 104
105(defconst ruby-singleton-class-re
106 "class\\s *<<"
107 "Regexp to match the beginning of a singleton class context.")
108
105(eval-and-compile 109(eval-and-compile
106 (defconst ruby-here-doc-beg-re 110 (defconst ruby-here-doc-beg-re
107 "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)" 111 "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
@@ -384,7 +388,7 @@ and `\\' when preceded by `?'."
384 (when pos (goto-char pos)) 388 (when pos (goto-char pos))
385 (forward-word -1) 389 (forward-word -1)
386 (and (or (bolp) (not (eq (char-before (point)) ?_))) 390 (and (or (bolp) (not (eq (char-before (point)) ?_)))
387 (looking-at "class\\s *<<")))) 391 (looking-at ruby-singleton-class-re))))
388 392
389(defun ruby-expr-beg (&optional option) 393(defun ruby-expr-beg (&optional option)
390 "Check if point is possibly at the beginning of an expression. 394 "Check if point is possibly at the beginning of an expression.
@@ -1057,35 +1061,32 @@ For example:
1057See `add-log-current-defun-function'." 1061See `add-log-current-defun-function'."
1058 (condition-case nil 1062 (condition-case nil
1059 (save-excursion 1063 (save-excursion
1060 (let (mname mlist (indent 0)) 1064 (let ((indent 0) mname mlist
1065 (start (point))
1066 (definition-re
1067 (concat "^[ \t]*" ruby-defun-beg-re "[ \t]+"
1068 "\\("
1069 ;; \\. and :: for class methods
1070 "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
1071 "+\\)")))
1061 ;; Get the current method definition (or class/module). 1072 ;; Get the current method definition (or class/module).
1062 (if (re-search-backward 1073 (when (re-search-backward definition-re nil t)
1063 (concat "^[ \t]*" ruby-defun-beg-re "[ \t]+" 1074 (goto-char (match-beginning 1))
1064 "\\(" 1075 (when (ruby-block-contains-point start)
1065 ;; \\. and :: for class methods 1076 ;; We're inside the method, class or module.
1066 "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)" 1077 (setq mname (match-string 2))
1067 "+\\)") 1078 (unless (string-equal "def" (match-string 1))
1068 nil t) 1079 (setq mlist (list mname) mname nil)))
1069 (progn 1080 (setq indent (current-column))
1070 (setq mname (match-string 2)) 1081 (beginning-of-line))
1071 (unless (string-equal "def" (match-string 1))
1072 (setq mlist (list mname) mname nil))
1073 (goto-char (match-beginning 1))
1074 (setq indent (current-column))
1075 (beginning-of-line)))
1076 ;; Walk up the class/module nesting. 1082 ;; Walk up the class/module nesting.
1077 (while (and (> indent 0) 1083 (while (and (> indent 0)
1078 (re-search-backward 1084 (re-search-backward definition-re nil t))
1079 (concat
1080 "^[ \t]*\\(class\\|module\\)[ \t]+"
1081 "\\([A-Z]" ruby-symbol-re "*\\)")
1082 nil t))
1083 (goto-char (match-beginning 1)) 1085 (goto-char (match-beginning 1))
1084 (if (< (current-column) indent) 1086 (when (ruby-block-contains-point start)
1085 (progn 1087 (setq mlist (cons (match-string 2) mlist))
1086 (setq mlist (cons (match-string 2) mlist)) 1088 (setq indent (current-column))
1087 (setq indent (current-column)) 1089 (beginning-of-line)))
1088 (beginning-of-line))))
1089 ;; Process the method name. 1090 ;; Process the method name.
1090 (when mname 1091 (when mname
1091 (let ((mn (split-string mname "\\.\\|::"))) 1092 (let ((mn (split-string mname "\\.\\|::")))
@@ -1104,7 +1105,14 @@ See `add-log-current-defun-function'."
1104 (setcdr (last mlist) (butlast mn)) 1105 (setcdr (last mlist) (butlast mn))
1105 (setq mlist (butlast mn)))) 1106 (setq mlist (butlast mn))))
1106 (setq mname (concat "." (car (last mn))))) 1107 (setq mname (concat "." (car (last mn)))))
1107 (setq mname (concat "#" mname))))) 1108 ;; See if the method is in singleton class context.
1109 (let ((in-singleton-class
1110 (when (re-search-forward ruby-singleton-class-re start t)
1111 (goto-char (match-beginning 0))
1112 (ruby-block-contains-point start))))
1113 (setq mname (concat
1114 (if in-singleton-class "." "#")
1115 mname))))))
1108 ;; Generate the string. 1116 ;; Generate the string.
1109 (if (consp mlist) 1117 (if (consp mlist)
1110 (setq mlist (mapconcat (function identity) mlist "::"))) 1118 (setq mlist (mapconcat (function identity) mlist "::")))
@@ -1112,6 +1120,12 @@ See `add-log-current-defun-function'."
1112 (if mlist (concat mlist mname) mname) 1120 (if mlist (concat mlist mname) mname)
1113 mlist))))) 1121 mlist)))))
1114 1122
1123(defun ruby-block-contains-point (pt)
1124 (save-excursion
1125 (save-match-data
1126 (ruby-forward-sexp)
1127 (> (point) pt))))
1128
1115(defun ruby-brace-to-do-end (orig end) 1129(defun ruby-brace-to-do-end (orig end)
1116 (let (beg-marker end-marker) 1130 (let (beg-marker end-marker)
1117 (goto-char end) 1131 (goto-char end)
diff --git a/test/ChangeLog b/test/ChangeLog
index ccebdda7411..e7e7c755d02 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -2,6 +2,9 @@
2 2
3 * automated/ruby-mode-tests.el 3 * automated/ruby-mode-tests.el
4 Rename one interpolation test; add three more. 4 Rename one interpolation test; add three more.
5 (ruby-with-temp-buffer): New macro, use it where appropriate.
6 (ruby-add-log-current-method-examples): Use "_" for target point.
7 Add four new tests for ruby-add-log-current-method.
5 8
62012-12-11 Glenn Morris <rgm@gnu.org> 92012-12-11 Glenn Morris <rgm@gnu.org>
7 10
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index 6ae23f94f1a..1f0c0ab6f9e 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -25,9 +25,7 @@
25 25
26(defun ruby-should-indent (content column) 26(defun ruby-should-indent (content column)
27 "Assert indentation COLUMN on the last line of CONTENT." 27 "Assert indentation COLUMN on the last line of CONTENT."
28 (with-temp-buffer 28 (ruby-with-temp-buffer content
29 (insert content)
30 (ruby-mode)
31 (ruby-indent-line) 29 (ruby-indent-line)
32 (should (= (current-indentation) column)))) 30 (should (= (current-indentation) column))))
33 31
@@ -35,12 +33,17 @@
35 "Assert that CONTENT turns into EXPECTED after the buffer is re-indented. 33 "Assert that CONTENT turns into EXPECTED after the buffer is re-indented.
36 34
37The whitespace before and including \"|\" on each line is removed." 35The whitespace before and including \"|\" on each line is removed."
38 (with-temp-buffer 36 (ruby-with-temp-buffer (ruby-test-string content)
39 (insert (ruby-test-string content))
40 (ruby-mode)
41 (indent-region (point-min) (point-max)) 37 (indent-region (point-min) (point-max))
42 (should (string= (ruby-test-string expected) (buffer-string))))) 38 (should (string= (ruby-test-string expected) (buffer-string)))))
43 39
40(defmacro ruby-with-temp-buffer (contents &rest body)
41 (declare (indent 1) (debug t))
42 `(with-temp-buffer
43 (insert ,contents)
44 (ruby-mode)
45 ,@body))
46
44(defun ruby-test-string (s &rest args) 47(defun ruby-test-string (s &rest args)
45 (apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args)) 48 (apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args))
46 49
@@ -48,9 +51,7 @@ The whitespace before and including \"|\" on each line is removed."
48 "Assert syntax state values at the end of CONTENT. 51 "Assert syntax state values at the end of CONTENT.
49 52
50VALUES-PLIST is a list with alternating index and value elements." 53VALUES-PLIST is a list with alternating index and value elements."
51 (with-temp-buffer 54 (ruby-with-temp-buffer content
52 (insert content)
53 (ruby-mode)
54 (syntax-propertize (point)) 55 (syntax-propertize (point))
55 (while values-plist 56 (while values-plist
56 (should (eq (nth (car values-plist) 57 (should (eq (nth (car values-plist)
@@ -59,9 +60,7 @@ VALUES-PLIST is a list with alternating index and value elements."
59 (setq values-plist (cddr values-plist))))) 60 (setq values-plist (cddr values-plist)))))
60 61
61(defun ruby-assert-face (content pos face) 62(defun ruby-assert-face (content pos face)
62 (with-temp-buffer 63 (ruby-with-temp-buffer content
63 (insert content)
64 (ruby-mode)
65 (font-lock-fontify-buffer) 64 (font-lock-fontify-buffer)
66 (should (eq face (get-text-property pos 'face))))) 65 (should (eq face (get-text-property pos 'face)))))
67 66
@@ -226,17 +225,13 @@ VALUES-PLIST is a list with alternating index and value elements."
226 |")) 225 |"))
227 226
228(ert-deftest ruby-move-to-block-stops-at-indentation () 227(ert-deftest ruby-move-to-block-stops-at-indentation ()
229 (with-temp-buffer 228 (ruby-with-temp-buffer "def f\nend"
230 (insert "def f\nend")
231 (beginning-of-line) 229 (beginning-of-line)
232 (ruby-mode)
233 (ruby-move-to-block -1) 230 (ruby-move-to-block -1)
234 (should (looking-at "^def")))) 231 (should (looking-at "^def"))))
235 232
236(ert-deftest ruby-toggle-block-to-do-end () 233(ert-deftest ruby-toggle-block-to-do-end ()
237 (with-temp-buffer 234 (ruby-with-temp-buffer "foo {|b|\n}"
238 (insert "foo {|b|\n}")
239 (ruby-mode)
240 (beginning-of-line) 235 (beginning-of-line)
241 (ruby-toggle-block) 236 (ruby-toggle-block)
242 (should (string= "foo do |b|\nend" (buffer-string))))) 237 (should (string= "foo do |b|\nend" (buffer-string)))))
@@ -254,9 +249,7 @@ VALUES-PLIST is a list with alternating index and value elements."
254 (should (string= (cdr pair) (buffer-string)))))))) 249 (should (string= (cdr pair) (buffer-string))))))))
255 250
256(ert-deftest ruby-toggle-block-to-multiline () 251(ert-deftest ruby-toggle-block-to-multiline ()
257 (with-temp-buffer 252 (ruby-with-temp-buffer "foo {|b| b + 1}"
258 (insert "foo {|b| b + 1}")
259 (ruby-mode)
260 (beginning-of-line) 253 (beginning-of-line)
261 (ruby-toggle-block) 254 (ruby-toggle-block)
262 (should (string= "foo do |b|\n b + 1\nend" (buffer-string))))) 255 (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."
295 288
296(ert-deftest ruby-interpolation-keeps-non-quote-syntax () 289(ert-deftest ruby-interpolation-keeps-non-quote-syntax ()
297 (let ((s "\"foo#{baz.tee}bar\"")) 290 (let ((s "\"foo#{baz.tee}bar\""))
298 (with-temp-buffer 291 (ruby-with-temp-buffer s
299 (save-excursion 292 (goto-char (point-min))
300 (insert s))
301 (ruby-mode) 293 (ruby-mode)
302 (font-lock-fontify-buffer) 294 (font-lock-fontify-buffer)
303 (search-forward "tee") 295 (search-forward "tee")
@@ -318,21 +310,66 @@ VALUES-PLIST is a list with alternating index and value elements."
318 ("self.foo" . ".foo")))) 310 ("self.foo" . ".foo"))))
319 (dolist (pair pairs) 311 (dolist (pair pairs)
320 (let ((name (car pair)) 312 (let ((name (car pair))
321 (value (cdr pair))) 313 (value (cdr pair)))
322 (with-temp-buffer 314 (ruby-with-temp-buffer (ruby-test-string
323 (insert (ruby-test-string 315 "module M
324 "module M 316 | class C
325 | class C 317 | def %s
326 | def %s 318 | _
327 | end 319 | end
328 | end 320 | end
329 |end" 321 |end"
330 name)) 322 name)
331 (ruby-mode) 323 (search-backward "_")
332 (search-backward "def") 324 (forward-line)
333 (forward-line) 325 (should (string= (ruby-add-log-current-method)
334 (should (string= (ruby-add-log-current-method) 326 (format "M::C%s" value))))))))
335 (format "M::C%s" value)))))))) 327
328(ert-deftest ruby-add-log-current-method-outside-of-method ()
329 (ruby-with-temp-buffer (ruby-test-string
330 "module M
331 | class C
332 | def foo
333 | end
334 | _
335 | end
336 |end")
337 (search-backward "_")
338 (should (string= (ruby-add-log-current-method)"M::C"))))
339
340(ert-deftest ruby-add-log-current-method-in-singleton-class ()
341 (ruby-with-temp-buffer (ruby-test-string
342 "class C
343 | class << self
344 | def foo
345 | _
346 | end
347 | end
348 |end")
349 (search-backward "_")
350 (should (string= (ruby-add-log-current-method) "C.foo"))))
351
352(ert-deftest ruby-add-log-current-method-namespace-shorthand ()
353 (ruby-with-temp-buffer (ruby-test-string
354 "class C::D
355 | def foo
356 | _
357 | end
358 |end")
359 (search-backward "_")
360 (should (string= (ruby-add-log-current-method) "C::D#foo"))))
361
362(ert-deftest ruby-add-log-current-method-after-inner-class ()
363 (ruby-with-temp-buffer (ruby-test-string
364 "module M
365 | class C
366 | class D
367 | end
368 | _
369 | end
370 |end")
371 (search-backward "_")
372 (should (string= (ruby-add-log-current-method) "M::C"))))
336 373
337(defvar ruby-block-test-example 374(defvar ruby-block-test-example
338 (ruby-test-string 375 (ruby-test-string