From: Stefan Monnier Date: Fri, 12 Aug 2011 15:32:39 +0000 (-0400) Subject: * lisp/progmodes/js.el (js-syntax-propertize, js-syntax-propertize-regexp): X-Git-Tag: emacs-pretest-24.0.90~104^2~124^2~62^2~7 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6cd18349b892a5c432991e8231364e7a4d1ea33d;p=emacs.git * lisp/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. (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 --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a75c5330ed9..bde9d54cfa2 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,13 @@ 2011-08-12 Stefan Monnier + * 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 diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 4abbe3b895f..5505e8e94b2 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -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)