mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-19 18:13:55 +00:00
* lisp/progmodes/ruby-mode.el (ruby-syntax-expansion-allowed-p): New
function, checks if expression expansion is allowed in given parse state. (ruby-syntax-propertize-expansion): Use it. (ruby-syntax-propertize-function): Bind `case-fold-search' to nil around the body. * test/automated/ruby-mode-tests.el: New tests, for percent literals and expression expansion.
This commit is contained in:
parent
fc186a96df
commit
19bb8e6293
@ -1,3 +1,12 @@
|
||||
2013-05-31 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* progmodes/ruby-mode.el (ruby-syntax-expansion-allowed-p): New
|
||||
function, checks if point is inside a literal that allows
|
||||
expression expansion.
|
||||
(ruby-syntax-propertize-expansion): Use it.
|
||||
(ruby-syntax-propertize-function): Bind `case-fold-search' to nil
|
||||
around the body.
|
||||
|
||||
2013-05-30 Juri Linkov <juri@jurta.org>
|
||||
|
||||
* isearch.el (isearch-mode-map): Bind `isearch-toggle-invisible'
|
||||
|
@ -1349,6 +1349,7 @@ If the result is do-end block, it will always be multiline."
|
||||
(declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit))
|
||||
;; Unusual code layout confuses the byte-compiler.
|
||||
(declare-function ruby-syntax-propertize-expansion "ruby-mode" ())
|
||||
(declare-function ruby-syntax-expansion-allowed-p "ruby-mode" (parse-state))
|
||||
|
||||
(if (eval-when-compile (fboundp #'syntax-propertize-rules))
|
||||
;; New code that works independently from font-lock.
|
||||
@ -1380,51 +1381,52 @@ It will be properly highlighted even when the call omits parens.")
|
||||
|
||||
(defun ruby-syntax-propertize-function (start end)
|
||||
"Syntactic keywords for Ruby mode. See `syntax-propertize-function'."
|
||||
(goto-char start)
|
||||
(remove-text-properties start end '(ruby-expansion-match-data))
|
||||
(ruby-syntax-propertize-heredoc end)
|
||||
(ruby-syntax-enclosing-percent-literal end)
|
||||
(funcall
|
||||
(syntax-propertize-rules
|
||||
;; $' $" $` .... are variables.
|
||||
;; ?' ?" ?` are ascii codes.
|
||||
("\\([?$]\\)[#\"'`]"
|
||||
(1 (unless (save-excursion
|
||||
;; Not within a string.
|
||||
(nth 3 (syntax-ppss (match-beginning 0))))
|
||||
(string-to-syntax "\\"))))
|
||||
;; Regular expressions. Start with matching unescaped slash.
|
||||
("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
|
||||
(1 (let ((state (save-excursion (syntax-ppss (match-beginning 1)))))
|
||||
(when (or
|
||||
;; Beginning of a regexp.
|
||||
(and (null (nth 8 state))
|
||||
(save-excursion
|
||||
(forward-char -1)
|
||||
(looking-back ruby-syntax-before-regexp-re
|
||||
(point-at-bol))))
|
||||
;; End of regexp. We don't match the whole
|
||||
;; regexp at once because it can have
|
||||
;; string interpolation inside, or span
|
||||
;; several lines.
|
||||
(eq ?/ (nth 3 state)))
|
||||
(string-to-syntax "\"/")))))
|
||||
;; Expression expansions in strings. We're handling them
|
||||
;; here, so that the regexp rule never matches inside them.
|
||||
(ruby-expression-expansion-re
|
||||
(0 (ignore (ruby-syntax-propertize-expansion))))
|
||||
("^=en\\(d\\)\\_>" (1 "!"))
|
||||
("^\\(=\\)begin\\_>" (1 "!"))
|
||||
;; Handle here documents.
|
||||
((concat ruby-here-doc-beg-re ".*\\(\n\\)")
|
||||
(7 (unless (ruby-singleton-class-p (match-beginning 0))
|
||||
(put-text-property (match-beginning 7) (match-end 7)
|
||||
'syntax-table (string-to-syntax "\""))
|
||||
(ruby-syntax-propertize-heredoc end))))
|
||||
;; Handle percent literals: %w(), %q{}, etc.
|
||||
((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
|
||||
(1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
|
||||
(point) end))
|
||||
(let (case-fold-search)
|
||||
(goto-char start)
|
||||
(remove-text-properties start end '(ruby-expansion-match-data))
|
||||
(ruby-syntax-propertize-heredoc end)
|
||||
(ruby-syntax-enclosing-percent-literal end)
|
||||
(funcall
|
||||
(syntax-propertize-rules
|
||||
;; $' $" $` .... are variables.
|
||||
;; ?' ?" ?` are ascii codes.
|
||||
("\\([?$]\\)[#\"'`]"
|
||||
(1 (unless (save-excursion
|
||||
;; Not within a string.
|
||||
(nth 3 (syntax-ppss (match-beginning 0))))
|
||||
(string-to-syntax "\\"))))
|
||||
;; Regular expressions. Start with matching unescaped slash.
|
||||
("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
|
||||
(1 (let ((state (save-excursion (syntax-ppss (match-beginning 1)))))
|
||||
(when (or
|
||||
;; Beginning of a regexp.
|
||||
(and (null (nth 8 state))
|
||||
(save-excursion
|
||||
(forward-char -1)
|
||||
(looking-back ruby-syntax-before-regexp-re
|
||||
(point-at-bol))))
|
||||
;; End of regexp. We don't match the whole
|
||||
;; regexp at once because it can have
|
||||
;; string interpolation inside, or span
|
||||
;; several lines.
|
||||
(eq ?/ (nth 3 state)))
|
||||
(string-to-syntax "\"/")))))
|
||||
;; Expression expansions in strings. We're handling them
|
||||
;; here, so that the regexp rule never matches inside them.
|
||||
(ruby-expression-expansion-re
|
||||
(0 (ignore (ruby-syntax-propertize-expansion))))
|
||||
("^=en\\(d\\)\\_>" (1 "!"))
|
||||
("^\\(=\\)begin\\_>" (1 "!"))
|
||||
;; Handle here documents.
|
||||
((concat ruby-here-doc-beg-re ".*\\(\n\\)")
|
||||
(7 (unless (ruby-singleton-class-p (match-beginning 0))
|
||||
(put-text-property (match-beginning 7) (match-end 7)
|
||||
'syntax-table (string-to-syntax "\""))
|
||||
(ruby-syntax-propertize-heredoc end))))
|
||||
;; Handle percent literals: %w(), %q{}, etc.
|
||||
((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
|
||||
(1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
|
||||
(point) end)))
|
||||
|
||||
(defun ruby-syntax-propertize-heredoc (limit)
|
||||
(let ((ppss (syntax-ppss))
|
||||
@ -1496,9 +1498,10 @@ It will be properly highlighted even when the call omits parens.")
|
||||
(defun ruby-syntax-propertize-expansion ()
|
||||
;; Save the match data to a text property, for font-locking later.
|
||||
;; Set the syntax of all double quotes and backticks to punctuation.
|
||||
(let ((beg (match-beginning 2))
|
||||
(end (match-end 2)))
|
||||
(when (and beg (save-excursion (nth 3 (syntax-ppss beg))))
|
||||
(let* ((beg (match-beginning 2))
|
||||
(end (match-end 2))
|
||||
(state (and beg (save-excursion (syntax-ppss beg)))))
|
||||
(when (ruby-syntax-expansion-allowed-p state)
|
||||
(put-text-property beg (1+ beg) 'ruby-expansion-match-data
|
||||
(match-data))
|
||||
(goto-char beg)
|
||||
@ -1506,6 +1509,17 @@ It will be properly highlighted even when the call omits parens.")
|
||||
(put-text-property (match-beginning 0) (match-end 0)
|
||||
'syntax-table (string-to-syntax "."))))))
|
||||
|
||||
(defun ruby-syntax-expansion-allowed-p (parse-state)
|
||||
"Return non-nil if expression expansion is allowed."
|
||||
(let ((term (nth 3 parse-state)))
|
||||
(cond
|
||||
((memq term '(?\" ?` ?\n)))
|
||||
((eq term t)
|
||||
(save-match-data
|
||||
(save-excursion
|
||||
(goto-char (nth 8 parse-state))
|
||||
(looking-at "%\\(?:[QWrx]\\|\\W\\)")))))))
|
||||
|
||||
(defun ruby-syntax-propertize-expansions (start end)
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
|
@ -1,3 +1,8 @@
|
||||
2013-05-31 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* automated/ruby-mode-tests.el: New tests, for percent literals
|
||||
and expression expansion.
|
||||
|
||||
2013-05-29 Leo Liu <sdl.web@gmail.com>
|
||||
|
||||
* indent/octave.m: Tweak.
|
||||
|
@ -353,6 +353,23 @@ VALUES-PLIST is a list with alternating index and value elements."
|
||||
;; It's confused by the closing paren in the middle.
|
||||
(ruby-assert-state s 8 nil)))
|
||||
|
||||
(ert-deftest ruby-interpolation-inside-double-quoted-percent-literals ()
|
||||
(ruby-assert-face "%Q{foo #@bar}" 8 font-lock-variable-name-face)
|
||||
(ruby-assert-face "%W{foo #@bar}" 8 font-lock-variable-name-face)
|
||||
(ruby-assert-face "%r{foo #@bar}" 8 font-lock-variable-name-face)
|
||||
(ruby-assert-face "%x{foo #@bar}" 8 font-lock-variable-name-face))
|
||||
|
||||
(ert-deftest ruby-no-interpolation-in-single-quoted-literals ()
|
||||
(ruby-assert-face "'foo #@bar'" 7 font-lock-string-face)
|
||||
(ruby-assert-face "%q{foo #@bar}" 8 font-lock-string-face)
|
||||
(ruby-assert-face "%w{foo #@bar}" 8 font-lock-string-face)
|
||||
(ruby-assert-face "%s{foo #@bar}" 8 font-lock-string-face))
|
||||
|
||||
(ert-deftest ruby-no-unknown-percent-literals ()
|
||||
;; No folding of case.
|
||||
(ruby-assert-face "%S{foo}" 4 nil)
|
||||
(ruby-assert-face "%R{foo}" 4 nil))
|
||||
|
||||
(ert-deftest ruby-add-log-current-method-examples ()
|
||||
(let ((pairs '(("foo" . "#foo")
|
||||
("C.foo" . ".foo")
|
||||
|
Loading…
Reference in New Issue
Block a user