aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2012-09-07 08:15:56 +0400
committerDmitry Gutov2012-09-07 08:15:56 +0400
commit0ba2d4b6465b0b66d34e6ef47c151bd5920fbe54 (patch)
treeadb7447fb81dd81374d12a3765716b8d60e01fe6
parent1d43a35f49f7403f7f50f36dddf88167a7c81f11 (diff)
downloademacs-0ba2d4b6465b0b66d34e6ef47c151bd5920fbe54.tar.gz
emacs-0ba2d4b6465b0b66d34e6ef47c151bd5920fbe54.zip
* lisp/progmodes/ruby-mode.el (ruby-indent-beg-re): Add pieces from
ruby-beginning-of-indent, simplify, allow all keywords to have indentation before them. (ruby-beginning-of-indent): Adjust for above. Search until the found point is not inside a string or comment. (ruby-font-lock-keywords): Allow symbols to start with "@" character, give them higher priority than variables. (ruby-syntax-propertize-function) (ruby-font-lock-syntactic-keywords): Remove the "not comments" matchers. Expression expansions are not comments when inside a string, and there comment syntax status is irrelevant. (ruby-match-expression-expansion): New function. Check that expression expansion is inside a string, and it's not escaped. (ruby-font-lock-keywords): Use it. * test/automated/ruby-mode-tests.el: New tests (Bug#11613).
-rw-r--r--lisp/ChangeLog17
-rw-r--r--lisp/progmodes/ruby-mode.el38
-rw-r--r--test/ChangeLog4
-rw-r--r--test/automated/ruby-mode-tests.el25
4 files changed, 65 insertions, 19 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 37064b6680b..2f7dac68467 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -51,6 +51,23 @@
51 Let-bind `isearch-word' to the argument `delimited-flag'. 51 Let-bind `isearch-word' to the argument `delimited-flag'.
52 (Bug#10885, bug#10887) 52 (Bug#10885, bug#10887)
53 53
542012-09-07 Dmitry Gutov <dgutov@yandex.ru>
55
56 * progmodes/ruby-mode.el (ruby-indent-beg-re): Add pieces from
57 ruby-beginning-of-indent, simplify, allow all keywords to have
58 indentation before them.
59 (ruby-beginning-of-indent): Adjust for above. Search until the
60 found point is not inside a string or comment.
61 (ruby-font-lock-keywords): Allow symbols to start with "@"
62 character, give them higher priority than variables.
63 (ruby-syntax-propertize-function)
64 (ruby-font-lock-syntactic-keywords): Remove the "not comments"
65 matchers. Expression expansions are not comments when inside a
66 string, and there comment syntax status is irrelevant.
67 (ruby-match-expression-expansion): New function. Check that
68 expression expansion is inside a string, and it's not escaped.
69 (ruby-font-lock-keywords): Use it.
70
542012-09-05 Martin Rudalics <rudalics@gmx.at> 712012-09-05 Martin Rudalics <rudalics@gmx.at>
55 72
56 * help.el (temp-buffer-max-height): New default value. 73 * help.el (temp-buffer-max-height): New default value.
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 3f93ffa84ba..bcebada5e86 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -64,8 +64,8 @@
64 "Regexp to match keywords that nest without blocks.") 64 "Regexp to match keywords that nest without blocks.")
65 65
66(defconst ruby-indent-beg-re 66(defconst ruby-indent-beg-re
67 (concat "\\(\\s *" (regexp-opt '("class" "module" "def") t) "\\)\\|" 67 (concat "^\\s *" (regexp-opt '("class" "module" "def" "if" "unless" "case"
68 (regexp-opt '("if" "unless" "case" "while" "until" "for" "begin"))) 68 "while" "until" "for" "begin")) "\\_>")
69 "Regexp to match where the indentation gets deeper.") 69 "Regexp to match where the indentation gets deeper.")
70 70
71(defconst ruby-modifier-beg-keywords 71(defconst ruby-modifier-beg-keywords
@@ -848,19 +848,18 @@ move forward."
848With ARG, move forward multiple defuns. Negative ARG means 848With ARG, move forward multiple defuns. Negative ARG means
849move backward." 849move backward."
850 (interactive "p") 850 (interactive "p")
851 (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\($\\|\\b[^_]\\)") 851 (and (re-search-forward ruby-indent-beg-re nil 'move (or arg 1))
852 nil 'move (or arg 1))
853 (beginning-of-line)) 852 (beginning-of-line))
854 (forward-line 1)) 853 (forward-line 1))
855 854
856(defun ruby-beginning-of-indent () 855(defun ruby-beginning-of-indent ()
857 "TODO: document" 856 "Backtrack to a line which can be used as a reference for
858 ;; I don't understand this function. 857calculating indentation on the lines after it."
859 ;; It seems like it should move to the line where indentation should deepen, 858 (while (and (re-search-backward ruby-indent-beg-re nil 'move)
860 ;; but ruby-indent-beg-re only accounts for whitespace before class, module and def, 859 (if (ruby-in-ppss-context-p 'anything)
861 ;; so this will only match other block beginners at the beginning of the line. 860 t
862 (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\_>") nil 'move) 861 ;; We can stop, then.
863 (beginning-of-line))) 862 (beginning-of-line)))))
864 863
865(defun ruby-move-to-block (n) 864(defun ruby-move-to-block (n)
866 "Move to the beginning (N < 0) or the end (N > 0) of the current block 865 "Move to the beginning (N < 0) or the end (N > 0) of the current block
@@ -1171,8 +1170,6 @@ It will be properly highlighted even when the call omits parens."))
1171 (ruby-syntax-enclosing-percent-literal end) 1170 (ruby-syntax-enclosing-percent-literal end)
1172 (funcall 1171 (funcall
1173 (syntax-propertize-rules 1172 (syntax-propertize-rules
1174 ;; #{ }, #$hoge, #@foo are not comments.
1175 ("\\(#\\)[{$@]" (1 "."))
1176 ;; $' $" $` .... are variables. 1173 ;; $' $" $` .... are variables.
1177 ;; ?' ?" ?` are ascii codes. 1174 ;; ?' ?" ?` are ascii codes.
1178 ("\\([?$]\\)[#\"'`]" 1175 ("\\([?$]\\)[#\"'`]"
@@ -1304,8 +1301,7 @@ This should only be called after matching against `ruby-here-doc-end-re'."
1304 (concat "-?\\([\"']\\|\\)" contents "\\1")))))) 1301 (concat "-?\\([\"']\\|\\)" contents "\\1"))))))
1305 1302
1306 (defconst ruby-font-lock-syntactic-keywords 1303 (defconst ruby-font-lock-syntactic-keywords
1307 `( ;; #{ }, #$hoge, #@foo are not comments 1304 `(
1308 ("\\(#\\)[{$@]" 1 (1 . nil))
1309 ;; the last $', $", $` in the respective string is not variable 1305 ;; the last $', $", $` in the respective string is not variable
1310 ;; the last ?', ?", ?` in the respective string is not ascii code 1306 ;; the last ?', ?", ?` in the respective string is not ascii code
1311 ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)" 1307 ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)"
@@ -1527,6 +1523,9 @@ See `font-lock-syntax-table'.")
1527 ;; variables 1523 ;; variables
1528 '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>" 1524 '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>"
1529 2 font-lock-variable-name-face) 1525 2 font-lock-variable-name-face)
1526 ;; symbols
1527 '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
1528 2 font-lock-reference-face)
1530 ;; variables 1529 ;; variables
1531 '("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W" 1530 '("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
1532 1 font-lock-variable-name-face) 1531 1 font-lock-variable-name-face)
@@ -1535,12 +1534,9 @@ See `font-lock-syntax-table'.")
1535 ;; constants 1534 ;; constants
1536 '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)" 1535 '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
1537 2 font-lock-type-face) 1536 2 font-lock-type-face)
1538 ;; symbols
1539 '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
1540 2 font-lock-reference-face)
1541 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-reference-face) 1537 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-reference-face)
1542 ;; expression expansion 1538 ;; expression expansion
1543 '("#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)" 1539 '(ruby-match-expression-expansion
1544 0 font-lock-variable-name-face t) 1540 0 font-lock-variable-name-face t)
1545 ;; warn lower camel case 1541 ;; warn lower camel case
1546 ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)" 1542 ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
@@ -1548,6 +1544,10 @@ See `font-lock-syntax-table'.")
1548 ) 1544 )
1549 "Additional expressions to highlight in Ruby mode.") 1545 "Additional expressions to highlight in Ruby mode.")
1550 1546
1547(defun ruby-match-expression-expansion (limit)
1548 (when (re-search-forward "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)" limit 'move)
1549 (ruby-in-ppss-context-p 'string)))
1550
1551;;;###autoload 1551;;;###autoload
1552(define-derived-mode ruby-mode prog-mode "Ruby" 1552(define-derived-mode ruby-mode prog-mode "Ruby"
1553 "Major mode for editing Ruby scripts. 1553 "Major mode for editing Ruby scripts.
diff --git a/test/ChangeLog b/test/ChangeLog
index f523f6f59a9..541937ec4e7 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
12012-09-07 Dmitry Gutov <dgutov@yandex.ru>
2
3 * automated/ruby-mode-tests.el: New tests (Bug#11613).
4
12012-08-28 Chong Yidong <cyd@gnu.org> 52012-08-28 Chong Yidong <cyd@gnu.org>
2 6
3 * automated/files.el: Test every combination of values for 7 * automated/files.el: Test every combination of values for
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index df51aa0d15a..1adc4acdfa0 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -57,6 +57,13 @@ VALUES-PLIST is a list with alternating index and value elements."
57 (cadr values-plist))) 57 (cadr values-plist)))
58 (setq values-plist (cddr values-plist))))) 58 (setq values-plist (cddr values-plist)))))
59 59
60(defun ruby-assert-face (content pos face)
61 (with-temp-buffer
62 (insert content)
63 (ruby-mode)
64 (font-lock-fontify-buffer)
65 (should (eq face (get-text-property pos 'face)))))
66
60(ert-deftest ruby-indent-after-symbol-made-from-string-interpolation () 67(ert-deftest ruby-indent-after-symbol-made-from-string-interpolation ()
61 "It can indent the line after symbol made using string interpolation." 68 "It can indent the line after symbol made using string interpolation."
62 (ruby-should-indent "def foo(suffix)\n :\"bar#{suffix}\"\n" 69 (ruby-should-indent "def foo(suffix)\n :\"bar#{suffix}\"\n"
@@ -84,6 +91,11 @@ VALUES-PLIST is a list with alternating index and value elements."
84 (ruby-should-indent "foo = {\na: b" ruby-indent-level) 91 (ruby-should-indent "foo = {\na: b" ruby-indent-level)
85 (ruby-should-indent "foo(\na" ruby-indent-level))) 92 (ruby-should-indent "foo(\na" ruby-indent-level)))
86 93
94(ert-deftest ruby-indent-after-keyword-in-a-string ()
95 (ruby-should-indent "a = \"abc\nif\"\n " 0)
96 (ruby-should-indent "a = %w[abc\n def]\n " 0)
97 (ruby-should-indent "a = \"abc\n def\"\n " 0))
98
87(ert-deftest ruby-indent-simple () 99(ert-deftest ruby-indent-simple ()
88 (ruby-should-indent-buffer 100 (ruby-should-indent-buffer
89 "if foo 101 "if foo
@@ -217,6 +229,19 @@ VALUES-PLIST is a list with alternating index and value elements."
217 (should (string= "foo {|b|\n}\n" (buffer-substring-no-properties 229 (should (string= "foo {|b|\n}\n" (buffer-substring-no-properties
218 (point-min) (point-max)))))) 230 (point-min) (point-max))))))
219 231
232(ert-deftest ruby-recognize-symbols-starting-with-at-character ()
233 (ruby-assert-face ":@abc" 3 'font-lock-constant-face))
234
235(ert-deftest ruby-hash-character-not-interpolation ()
236 (ruby-assert-face "\"This is #{interpolation}\"" 15
237 'font-lock-variable-name-face)
238 (ruby-assert-face "\"This is \\#{no interpolation} despite the #\""
239 15 'font-lock-string-face)
240 (ruby-assert-face "#@comment, not ruby code" 3 'font-lock-comment-face)
241 (ruby-assert-state "#@comment, not ruby code" 4 t)
242 (ruby-assert-face "# A comment cannot have #{an interpolation} in it"
243 30 'font-lock-comment-face))
244
220(provide 'ruby-mode-tests) 245(provide 'ruby-mode-tests)
221 246
222;;; ruby-mode-tests.el ends here 247;;; ruby-mode-tests.el ends here