Add extra text property to fix issue with js2-mode integration

* lisp/progmodes/js.el (js-jsx--put-syntax-table): New function for
consistently ensuring smooth js2-mode integration.  js2-mode sets
syntax-table temporarily while parsing buffers—seemingly to recover
from parsing interruptions—and then it later clears syntax-table
blindly.  When integrating with js-mode, this means that unterminated
string quotes are re-broken in JSX (i.e., they become strings again,
often stringifying large regions of the buffer which should not be
strings).  We try to treat quotes in JSXText as non-strings by setting
syntax-table to a non-“string quote” syntax class, but that stops
working if we lose the property.  On the js2-mode end, by scanning for
this second js-jsx-syntax-table property, we can recover the
syntax-table property there.
(js-jsx--text-range, js-jsx--syntax-propertize-tag): Use
js-jsx--put-syntax-table for above reason.
(js-jsx--text-properties): Clear the js-jsx-syntax-table property too.
parent 9994bf17
Pipeline #1244 failed with stage
in 49 minutes and 34 seconds
......@@ -2140,6 +2140,14 @@ JSXElement or a JSXOpeningElement/JSXClosingElement pair."
;; `syntax-propertize-rules' loop so the next JSXBoundaryElement can
;; be parsed, if any, be it an opening or closing one.
(defun js-jsx--put-syntax-table (start end value)
"Set syntax-table text property from START to END as VALUE.
Redundantly set the value to two properties, syntax-table and
js-jsx-syntax-table. Derivative modes that remove syntax-table
text properties may recover the value from the second property." ; i.e. js2-mode
(add-text-properties start end (list 'syntax-table value
'js-jsx-syntax-table value)))
(defun js-jsx--text-range (beg end)
"Identify JSXText within a “>/{/}/<” pair."
(when (> (- end beg) 0)
......@@ -2151,7 +2159,7 @@ JSXElement or a JSXOpeningElement/JSXClosingElement pair."
;; negate those roles.
(when (or (= (char-after) ?/) ; comment
(= (syntax-class (syntax-after (point))) 7)) ; string quote
(put-text-property (point) (1+ (point)) 'syntax-table '(1)))
(js-jsx--put-syntax-table (point) (1+ (point)) '(1)))
(forward-char)))
;; Mark JSXText so it can be font-locked as non-keywords.
(put-text-property beg (1+ beg) 'js-jsx-text (list beg end (current-buffer)))
......@@ -2220,7 +2228,7 @@ testing for syntax only valid as JSX."
(cond
((= (char-after) ?>)
;; Make the closing “>” a close parenthesis.
(put-text-property (point) (1+ (point)) 'syntax-table '(5))
(js-jsx--put-syntax-table (point) (1+ (point)) '(5))
(forward-char)
(setq unambiguous t)
(throw 'stop nil))
......@@ -2306,7 +2314,7 @@ testing for syntax only valid as JSX."
;; Save JSXBoundaryElement’s name’s match data for font-locking.
(if name-beg (put-text-property name-beg (1+ name-beg) 'js-jsx-tag-name name-match-data))
;; Make the opening “<” an open parenthesis.
(put-text-property tag-beg (1+ tag-beg) 'syntax-table '(4))
(js-jsx--put-syntax-table tag-beg (1+ tag-beg) '(4))
;; Prevent “out of range” errors when typing at the end of a buffer.
(setq tag-end (if (eobp) (1- (point)) (point)))
;; Mark beginning and end of tag for font-locking.
......@@ -2325,7 +2333,8 @@ testing for syntax only valid as JSX."
(list
'js-jsx-tag-beg nil 'js-jsx-tag-end nil 'js-jsx-close-tag-pos nil
'js-jsx-tag-name nil 'js-jsx-attribute-name nil 'js-jsx-string nil
'js-jsx-text nil 'js-jsx-expr nil 'js-jsx-expr-attribute nil)
'js-jsx-text nil 'js-jsx-expr nil 'js-jsx-expr-attribute nil
'js-jsx-syntax-table nil)
"Plist of text properties added by `js-syntax-propertize'.")
(defun js-syntax-propertize (start end)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment