summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Ray Hamilton <jackson@jacksonrayhamilton.com>2019-04-10 22:53:34 -0700
committerJackson Ray Hamilton <jackson@jacksonrayhamilton.com>2019-04-10 22:53:34 -0700
commit382a508ed21e4f12ace9f8871818e25235e8f05e (patch)
tree700e5ef6533d11eff67e274811b11aebd5dcb88a
parent9994bf17cf532f2e1d4310341da7180342202191 (diff)
downloademacs-382a508ed21e4f12ace9f8871818e25235e8f05e.tar.gz
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.
-rw-r--r--lisp/progmodes/js.el17
1 files changed, 13 insertions, 4 deletions
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index afdc28e53b9..a0adaa84eeb 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -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)