]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/progmodes/js.el (js-syntax-propertize, js-syntax-propertize-regexp):
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 12 Aug 2011 15:32:39 +0000 (11:32 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 12 Aug 2011 15:32:39 +0000 (11:32 -0400)
New function.
(js--regexp-literal, js-syntax-propertize-function): Remove.
(js-mode): Use js-syntax-propertize to handle multilines.
(js-mode-map): Don't rebind electric keys.
(js-insert-and-indent): Remove.
(js-mode): Setup electric-layout and electric-indent instead.

Fixes: debbugs:9183
lisp/ChangeLog
lisp/progmodes/js.el

index a75c5330ed909d0b8b1c360154bd7c1fc7857bab..bde9d54cfa24b925e4fd67cae155e9f2b6ea20e3 100644 (file)
@@ -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>
index 4abbe3b895fd29f54dace2442b6e93fafeb7db88..5505e8e94b2837c7148c428b1ced4473e281c3cb 100644 (file)
@@ -61,6 +61,7 @@
 (defvar inferior-moz-buffer)
 (defvar moz-repl-name)
 (defvar ido-cur-list)
+(defvar electric-layout-rules)
 (declare-function ido-mode "ido")
 (declare-function inferior-moz-process "ext:mozrepl" ())
 
@@ -507,9 +508,6 @@ getting timeout messages."
 
 (defvar js-mode-map
   (let ((keymap (make-sparse-keymap)))
-    (mapc (lambda (key)
-           (define-key keymap key #'js-insert-and-indent))
-         '("{" "}" "(" ")" ":" ";" ","))
     (define-key keymap [(control ?c) (meta ?:)] #'js-eval)
     (define-key keymap [(control ?c) (control ?j)] #'js-set-js-context)
     (define-key keymap [(control meta ?x)] #'js-eval-defun)
@@ -525,21 +523,6 @@ getting timeout messages."
     keymap)
   "Keymap for `js-mode'.")
 
-(defun js-insert-and-indent (key)
-  "Run the command bound to KEY, and indent if necessary.
-Indentation does not take place if point is in a string or
-comment."
-  (interactive (list (this-command-keys)))
-  (call-interactively (lookup-key (current-global-map) key))
-  (let ((syntax (save-restriction (widen) (syntax-ppss))))
-    (when (or (and (not (nth 8 syntax))
-                   js-auto-indent-flag)
-              (and (nth 4 syntax)
-                   (eq (current-column)
-                       (1+ (current-indentation)))))
-      (indent-according-to-mode))))
-
-
 ;;; Syntax table and parsing
 
 (defvar js-mode-syntax-table
@@ -1653,25 +1636,35 @@ This performs fontification according to `js--class-styles'."
                                    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
-  (syntax-propertize-rules
-   (js--regexp-literal (1 "\"") (2 "\""))))
+(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
+    ;; 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 @@ If one hasn't been set, or if it's stale, prompt for a new one."
   (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)
@@ -3335,6 +3328,11 @@ If one hasn't been set, or if it's stale, prompt for a new one."
         c-comment-start-regexp "/[*/]\\|\\s!"
         comment-start-skip "\\(//+\\|/\\*+\\)\\s *")
 
+  (set (make-local-variable 'electric-indent-chars)
+       (append "{}():;," electric-indent-chars))
+  (set (make-local-variable 'electric-layout-rules)
+       '((?\; . after) (?\{ . after) (?\} . before)))
+
   (let ((c-buffer-is-cc-mode t))
     ;; FIXME: These are normally set by `c-basic-common-init'.  Should
     ;; we call it instead?  (Bug#6071)