Guard against nested percent literals
* lisp/progmodes/ruby-mode.el (ruby-syntax-propertize-percent-literal): Don't check the syntax status. (ruby-syntax-propertize): Check it here. And also guard against being in a larger percent literal. * test/automated/ruby-mode-tests.el (ruby-no-nested-percent-literals): New test.
This commit is contained in:
parent
066f3bc3f3
commit
6e63b3e997
2 changed files with 39 additions and 30 deletions
|
@ -1901,7 +1901,10 @@ It will be properly highlighted even when the call omits parens.")
|
||||||
(ruby-syntax-propertize-heredoc end))))
|
(ruby-syntax-propertize-heredoc end))))
|
||||||
;; Handle percent literals: %w(), %q{}, etc.
|
;; Handle percent literals: %w(), %q{}, etc.
|
||||||
((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
|
((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
|
||||||
(1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
|
(1 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 1))))
|
||||||
|
;; Not inside a string, a comment, or a percent literal.
|
||||||
|
(ruby-syntax-propertize-percent-literal end)
|
||||||
|
(string-to-syntax "|")))))
|
||||||
(point) end)))
|
(point) end)))
|
||||||
|
|
||||||
(define-obsolete-function-alias
|
(define-obsolete-function-alias
|
||||||
|
@ -1944,35 +1947,33 @@ It will be properly highlighted even when the call omits parens.")
|
||||||
|
|
||||||
(defun ruby-syntax-propertize-percent-literal (limit)
|
(defun ruby-syntax-propertize-percent-literal (limit)
|
||||||
(goto-char (match-beginning 2))
|
(goto-char (match-beginning 2))
|
||||||
;; Not inside a simple string or comment.
|
(let* ((op (char-after))
|
||||||
(when (eq t (nth 3 (syntax-ppss)))
|
(ops (char-to-string op))
|
||||||
(let* ((op (char-after))
|
(cl (or (cdr (aref (syntax-table) op))
|
||||||
(ops (char-to-string op))
|
(cdr (assoc op '((?< . ?>))))))
|
||||||
(cl (or (cdr (aref (syntax-table) op))
|
parse-sexp-lookup-properties)
|
||||||
(cdr (assoc op '((?< . ?>))))))
|
(save-excursion
|
||||||
parse-sexp-lookup-properties)
|
(condition-case nil
|
||||||
(save-excursion
|
(progn
|
||||||
(condition-case nil
|
(if cl ; Paired delimiters.
|
||||||
(progn
|
;; Delimiter pairs of the same kind can be nested
|
||||||
(if cl ; Paired delimiters.
|
;; inside the literal, as long as they are balanced.
|
||||||
;; Delimiter pairs of the same kind can be nested
|
;; Create syntax table that ignores other characters.
|
||||||
;; inside the literal, as long as they are balanced.
|
(with-syntax-table (make-char-table 'syntax-table nil)
|
||||||
;; Create syntax table that ignores other characters.
|
(modify-syntax-entry op (concat "(" (char-to-string cl)))
|
||||||
(with-syntax-table (make-char-table 'syntax-table nil)
|
(modify-syntax-entry cl (concat ")" ops))
|
||||||
(modify-syntax-entry op (concat "(" (char-to-string cl)))
|
(modify-syntax-entry ?\\ "\\")
|
||||||
(modify-syntax-entry cl (concat ")" ops))
|
(save-restriction
|
||||||
(modify-syntax-entry ?\\ "\\")
|
(narrow-to-region (point) limit)
|
||||||
(save-restriction
|
(forward-list))) ; skip to the paired character
|
||||||
(narrow-to-region (point) limit)
|
;; Single character delimiter.
|
||||||
(forward-list))) ; skip to the paired character
|
(re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
|
||||||
;; Single character delimiter.
|
(regexp-quote ops)) limit nil))
|
||||||
(re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
|
;; Found the closing delimiter.
|
||||||
(regexp-quote ops)) limit nil))
|
(put-text-property (1- (point)) (point) 'syntax-table
|
||||||
;; Found the closing delimiter.
|
(string-to-syntax "|")))
|
||||||
(put-text-property (1- (point)) (point) 'syntax-table
|
;; Unclosed literal, do nothing.
|
||||||
(string-to-syntax "|")))
|
((scan-error search-failed))))))
|
||||||
;; Unclosed literal, do nothing.
|
|
||||||
((scan-error search-failed)))))))
|
|
||||||
|
|
||||||
(defun ruby-syntax-propertize-expansion ()
|
(defun ruby-syntax-propertize-expansion ()
|
||||||
;; Save the match data to a text property, for font-locking later.
|
;; Save the match data to a text property, for font-locking later.
|
||||||
|
|
|
@ -461,6 +461,14 @@ VALUES-PLIST is a list with alternating index and value elements."
|
||||||
(ruby-assert-face "%S{foo}" 4 nil)
|
(ruby-assert-face "%S{foo}" 4 nil)
|
||||||
(ruby-assert-face "%R{foo}" 4 nil))
|
(ruby-assert-face "%R{foo}" 4 nil))
|
||||||
|
|
||||||
|
(ert-deftest ruby-no-nested-percent-literals ()
|
||||||
|
(ruby-with-temp-buffer "a = %w[b %()]"
|
||||||
|
(syntax-propertize (point))
|
||||||
|
(should (null (nth 8 (syntax-ppss))))
|
||||||
|
(should (eq t (nth 3 (syntax-ppss (1- (point-max))))))
|
||||||
|
(search-backward "[")
|
||||||
|
(should (eq t (nth 3 (syntax-ppss))))))
|
||||||
|
|
||||||
(ert-deftest ruby-add-log-current-method-examples ()
|
(ert-deftest ruby-add-log-current-method-examples ()
|
||||||
(let ((pairs '(("foo" . "#foo")
|
(let ((pairs '(("foo" . "#foo")
|
||||||
("C.foo" . ".foo")
|
("C.foo" . ".foo")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue