unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: "Štěpán Němec" <stepnem@gmail.com>
Cc: 9183@debbugs.gnu.org
Subject: bug#9183: js-mode highlights quotes inside regexp character sets as string
Date: Fri, 12 Aug 2011 11:48:11 -0400	[thread overview]
Message-ID: <jwvei0q7iis.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <87vcua3hae.fsf@gmail.com> ("Štěpán Němec"'s message of "Sat, 06 Aug 2011 13:34:17 +0200")

> Thanks, but it doesn't seem to fix anything, just mess things up in a
> somewhat different way.

It did fix the problem to some extent, but indeed it suffered from
a "multiline" problem (partly inherited from the previous code).

I've installed the patch below which should fix the problem, tho it may
introduce others.  Please try it out.

> (Just in case, I downloaded the fixed js.el and loaded that with my
> oldish Emacs 24 (started as emacs -Q), but I don't think that should
> matter, right?)

That should work OK, yes.  It won't work with Emacs-23 not with an ancient
Emacs-24, but oldish should be fine ;-)

>> But I don't know how to solve it completely because I don't know
>> Javascript enough to be sure exactly how to distinguish a /-division
>> from a /-regexp from a /-comment-starter in all cases:
>> - is something like
>> x = 1 + /a/.test("foo");
>> valid?
> Yes, it's valid, although I suspect it would be considered bad style.

Hmm, that makes it more interesting.
Especially if you ignore semantics and focus on syntax where it would
seem that "x = /foo/ / /bar/;" would then be valid, tho meaningless).

> (BTW, in Debian there is a spidermonkey-bin package, which has minimal
> dependencies and provides a `js' command, giving you a REPL.)

Thanks.

>> If so, is there a list of infix operators somewhere?
> I'd have to search for it just as you might have... There's this, for
> instance:
> https://developer.mozilla.org/en/JavaScript/Reference/Operators

Thanks, I'll keep it for next time I'm bored.


        Stefan


=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2011-08-12 13:49:45 +0000
+++ lisp/ChangeLog	2011-08-12 15:30:59 +0000
@@ -1,5 +1,13 @@
 2011-08-12  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+	* progmodes/js.el (js-syntax-propertize, js-syntax-propertize-regexp):
+	New function.
+	(js--regexp-literal, js-syntax-propertize-function): Remove.
+	(js-mode): Use js-syntax-propertize to handle multilines (bug#9183).
+	(js-mode-map): Don't rebind electric keys.
+	(js-insert-and-indent): Remove.
+	(js-mode): Setup electric-layout and electric-indent instead.
+
 	* epa-file.el (epa-file-select-keys): Revert to nil default (bug#9280).
 
 2011-08-12  Daiki Ueno  <ueno@unixuser.org>

=== modified file 'lisp/progmodes/js.el'
--- lisp/progmodes/js.el	2011-08-05 19:53:46 +0000
+++ lisp/progmodes/js.el	2011-08-12 15:29:28 +0000
@@ -1653,25 +1636,35 @@
                                    js--font-lock-keywords-3)
   "Font lock keywords for `js-mode'.  See `font-lock-keywords'.")
 
-;; XXX: Javascript can continue a regexp literal across lines so long
-;; as the newline is escaped with \. Account for that in the regexp
-;; below.
-(eval-and-compile
-  (defconst js--regexp-literal
-    (concat
-     ;; We want to match regular expressions only at the beginning of
-     ;; expressions.
-     ;; FIXME: Should we also allow /regexp/ after infix operators such as +,
-     ;; /, -, *, >, ...?
-     "\\(?:\\`\\|[=([{,:;]\\)\\(?:\\s-\\|\n\\)*"
-     "\\(/\\)\\(?:\\\\.\\|[^/*\\]\\)\\(?:\\\\.\\|[^/\\]\\)*\\(/\\)")
-  "Regexp matching a JavaScript regular expression literal.
-Match groups 1 and 2 are the characters forming the beginning and
-end of the literal."))
-
-(defconst js-syntax-propertize-function
+(defun js-syntax-propertize-regexp (end)
+  (when (eq (nth 3 (syntax-ppss)) ?/)
+    ;; A /.../ regexp.
+    (when (re-search-forward "\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*/" end 'move)
+      (put-text-property (1- (point)) (point)
+                         'syntax-table (string-to-syntax "\"/")))))
+
+(defun js-syntax-propertize (start end)
+  ;; Javascript allows immediate regular expression objects, written /.../.
+  (goto-char start)
+  (js-syntax-propertize-regexp end)
+  (funcall
   (syntax-propertize-rules
-   (js--regexp-literal (1 "\"") (2 "\""))))
+    ;; Distinguish /-division from /-regexp chars (and from /-comment-starter).
+    ("\\(?:^\\|[=([{,:;]\\)\\(?:[ \t]\\)*\\(/\\)[^/*]"
+     (1 (ignore
+	 (forward-char -1)
+         (when (or (not (memq (char-after (match-beginning 0)) '(?\s ?\t)))
+                   ;; If the / is at the beginning of line, we have to check
+                   ;; the end of the previous text.
+                   (save-excursion
+                     (goto-char (match-beginning 0))
+                     (forward-comment (- (point)))
+                     (memq (char-before)
+                           (eval-when-compile (append "=({[,:;" '(nil))))))
+           (put-text-property (match-beginning 1) (match-end 1)
+                              'syntax-table (string-to-syntax "\"/"))
+           (js-syntax-propertize-regexp end))))))
+   (point) end))
 
 ;;; Indentation
 
@@ -3302,7 +3295,7 @@
   (set (make-local-variable 'font-lock-defaults)
        (list js--font-lock-keywords))
   (set (make-local-variable 'syntax-propertize-function)
-       js-syntax-propertize-function)
+       #'js-syntax-propertize)
 
   (set (make-local-variable 'parse-sexp-ignore-comments) t)
   (set (make-local-variable 'parse-sexp-lookup-properties) t)





  reply	other threads:[~2011-08-12 15:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-27 19:27 bug#9183: js-mode highlights quotes inside regexp character sets as string Štěpán Němec
2011-08-05 16:54 ` Stefan Monnier
2011-08-06 11:34   ` Štěpán Němec
2011-08-12 15:48     ` Stefan Monnier [this message]
2011-08-12 16:47       ` Daniel Colascione
2011-08-12 17:25       ` Štěpán Němec

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvei0q7iis.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=9183@debbugs.gnu.org \
    --cc=stepnem@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).