summaryrefslogtreecommitdiff
path: root/lisp/progmodes/ruby-mode.el
diff options
context:
space:
mode:
authorDmitry Gutov <dgutov@yandex.ru>2012-11-14 16:17:21 +0400
committerDmitry Gutov <dgutov@yandex.ru>2012-11-14 16:17:21 +0400
commitc62792e7dfa403db8c36cb92f32fb69258a199ef (patch)
treeb66f89060cd2f882a04b508896cbbbd424b08412 /lisp/progmodes/ruby-mode.el
parent710f581278f6eaea5dbc5c0bcc7c206be9690746 (diff)
downloademacs-c62792e7dfa403db8c36cb92f32fb69258a199ef.tar.gz
emacs-c62792e7dfa403db8c36cb92f32fb69258a199ef.tar.bz2
emacs-c62792e7dfa403db8c36cb92f32fb69258a199ef.zip
* lisp/progmodes/ruby-mode.el
(ruby-syntax-propertize-function): After everything else, search for expansions in string literals, mark their insides as whitespace syntax and save match data for font-lock. (ruby-font-lock-keywords): Highlight just the 2nd group from expression expansion matches. (ruby-match-expression-expansion): Use the match data saved to the text property in ruby-syntax-propertize-function. * test/automated/ruby-mode-tests.el Change direct font-lock face references to var references. (ruby-interpolation-suppresses-syntax-inside): New test. (ruby-interpolation-inside-percent-literal-with-paren): New failing test.
Diffstat (limited to 'lisp/progmodes/ruby-mode.el')
-rw-r--r--lisp/progmodes/ruby-mode.el32
1 files changed, 26 insertions, 6 deletions
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 686bec89a95..9d78b20ba4c 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -105,7 +105,10 @@
(eval-and-compile
(defconst ruby-here-doc-beg-re
"\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
- "Regexp to match the beginning of a heredoc."))
+ "Regexp to match the beginning of a heredoc.")
+
+ (defconst ruby-expression-expansion-re
+ "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)"))
(defun ruby-here-doc-end-match ()
"Return a regexp to find the end of a heredoc.
@@ -1249,7 +1252,19 @@ It will be properly highlighted even when the call omits parens."))
;; Handle percent literals: %w(), %q{}, etc.
((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
(1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
- (point) end))
+ (point) end)
+ (remove-text-properties start end '(ruby-expansion-match-data))
+ (goto-char start)
+ ;; Find all expression expansions and
+ ;; - set the syntax of all text inside to whitespace,
+ ;; - save the match data to a text property, for font-locking later.
+ (while (re-search-forward ruby-expression-expansion-re end 'move)
+ (when (ruby-in-ppss-context-p 'string)
+ (put-text-property (match-beginning 2) (match-end 2)
+ 'syntax-table (string-to-syntax "-"))
+ (put-text-property (match-beginning 2) (1+ (match-beginning 2))
+ 'ruby-expansion-match-data
+ (match-data)))))
(defun ruby-syntax-propertize-heredoc (limit)
(let ((ppss (syntax-ppss))
@@ -1582,7 +1597,7 @@ See `font-lock-syntax-table'.")
'("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face)
;; expression expansion
'(ruby-match-expression-expansion
- 0 font-lock-variable-name-face t)
+ 2 font-lock-variable-name-face t)
;; warn lower camel case
;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
; 0 font-lock-warning-face)
@@ -1590,9 +1605,14 @@ See `font-lock-syntax-table'.")
"Additional expressions to highlight in Ruby mode.")
(defun ruby-match-expression-expansion (limit)
- (when (re-search-forward "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)" limit 'move)
- (or (ruby-in-ppss-context-p 'string)
- (ruby-match-expression-expansion limit))))
+ (let ((prop 'ruby-expansion-match-data) pos value)
+ (when (and (setq pos (next-single-char-property-change (point) prop
+ nil limit))
+ (> pos (point)))
+ (goto-char pos)
+ (or (and (setq value (get-text-property pos prop))
+ (progn (set-match-data value) t))
+ (ruby-match-expression-expansion limit)))))
;;;###autoload
(define-derived-mode ruby-mode prog-mode "Ruby"