diff options
author | Dmitry Gutov <dgutov@yandex.ru> | 2012-11-14 16:17:21 +0400 |
---|---|---|
committer | Dmitry Gutov <dgutov@yandex.ru> | 2012-11-14 16:17:21 +0400 |
commit | c62792e7dfa403db8c36cb92f32fb69258a199ef (patch) | |
tree | b66f89060cd2f882a04b508896cbbbd424b08412 /lisp/progmodes/ruby-mode.el | |
parent | 710f581278f6eaea5dbc5c0bcc7c206be9690746 (diff) | |
download | emacs-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.el | 32 |
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" |