X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/3c4ca7155293ffc2d04708007131bcbc882d8913..6ccb9cab43613632ece4f62d9ee28d694bc1d666:/lisp/progmodes/js.el diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 33ef760767..28ee859f9d 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -1,6 +1,6 @@ ;;; js.el --- Major mode for editing JavaScript -*- lexical-binding: t -*- -;; Copyright (C) 2008-2012 Free Software Foundation, Inc. +;; Copyright (C) 2008-2013 Free Software Foundation, Inc. ;; Author: Karl Landstrom ;; Daniel Colascione @@ -55,7 +55,6 @@ (eval-when-compile (require 'cl-lib) - (require 'comint) (require 'ido)) (defvar inferior-moz-buffer) @@ -1680,12 +1679,15 @@ This performs fontification according to `js--class-styles'." "each")) "Regexp matching keywords optionally followed by an opening brace.") +(defconst js--declaration-keyword-re + (regexp-opt '("var" "let" "const") 'words) + "Regular expression matching variable declaration keywords.") + (defconst js--indent-operator-re (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|" (js--regexp-opt-symbol '("in" "instanceof"))) "Regexp matching operators that affect indentation of continued expressions.") - (defun js--looking-at-operator-p () "Return non-nil if point is on a JavaScript operator, other than a comma." (save-match-data @@ -1764,6 +1766,37 @@ nil." (list (cons 'c js-comment-lineup-func)))) (c-get-syntactic-indentation (list (cons symbol anchor))))) +(defun js--multi-line-declaration-indentation () + "Helper function for `js--proper-indentation'. +Return the proper indentation of the current line if it belongs to a declaration +statement spanning multiple lines; otherwise, return nil." + (let (at-opening-bracket) + (save-excursion + (back-to-indentation) + (when (not (looking-at js--declaration-keyword-re)) + (when (looking-at js--indent-operator-re) + (goto-char (match-end 0))) + (while (and (not at-opening-bracket) + (not (bobp)) + (let ((pos (point))) + (save-excursion + (js--backward-syntactic-ws) + (or (eq (char-before) ?,) + (and (not (eq (char-before) ?\;)) + (prog2 + (skip-syntax-backward ".") + (looking-at js--indent-operator-re) + (js--backward-syntactic-ws)) + (not (eq (char-before) ?\;))) + (and (>= pos (point-at-bol)) + (<= pos (point-at-eol))))))) + (condition-case nil + (backward-sexp) + (scan-error (setq at-opening-bracket t)))) + (when (looking-at js--declaration-keyword-re) + (goto-char (match-end 0)) + (1+ (current-column))))))) + (defun js--proper-indentation (parse-status) "Return the proper indentation for the current line." (save-excursion @@ -1772,6 +1805,7 @@ nil." (js--get-c-offset 'c (nth 8 parse-status))) ((nth 8 parse-status) 0) ; inside string ((js--ctrl-statement-indentation)) + ((js--multi-line-declaration-indentation)) ((eq (char-after) ?#) 0) ((save-excursion (js--beginning-of-macro)) 4) ((nth 1 parse-status) @@ -2182,6 +2216,9 @@ marker." (defvar find-tag-marker-ring) ; etags +;; etags loads ring. +(declare-function ring-insert "ring" (ring item)) + (defun js-find-symbol (&optional arg) "Read a JavaScript symbol and jump to it. With a prefix argument, restrict symbols to those from the @@ -2604,6 +2641,11 @@ with `js--js-encode-value'." ;; order to catch a prompt that's only partially arrived (save-excursion (forward-line 0) (point)))) +;; Presumably "inferior-moz-process" loads comint. +(declare-function comint-send-string "comint" (process string)) +(declare-function comint-send-input "comint" + (&optional no-newline artificial)) + (defun js--js-enter-repl () (inferior-moz-process) ; called for side-effect (with-current-buffer inferior-moz-buffer @@ -2662,6 +2704,10 @@ with `js--js-encode-value'." (defsubst js--js-true (value) (not (js--js-not value))) +;; The somewhat complex code layout confuses the byte-compiler into +;; thinking this function "might not be defined at runtime". +(declare-function js--optimize-arglist "js" (arglist)) + (eval-and-compile (defun js--optimize-arglist (arglist) "Convert immediate js< and js! references to deferred ones." @@ -2789,6 +2835,8 @@ If nil, the whole Array is treated as a JS symbol.") (`error (signal 'js-js-error (list (cl-second result)))) (x (error "Unmatched case in js--js-decode-retval: %S" x)))) +(defvar comint-last-input-end) + (defun js--js-funcall (function &rest arguments) "Call the Mozilla function FUNCTION with arguments ARGUMENTS. If function is a string, look it up as a property on the global @@ -2961,6 +3009,8 @@ left-to-right." (defvar js-read-tab-history nil) +(declare-function ido-chop "ido" (items elem)) + (defun js--read-tab (prompt) "Read a Mozilla tab with prompt PROMPT. Return a cons of (TYPE . OBJECT). TYPE is either 'window or @@ -3306,29 +3356,21 @@ If one hasn't been set, or if it's stale, prompt for a new one." (define-derived-mode js-mode prog-mode "Javascript" "Major mode for editing JavaScript." :group 'js + (setq-local indent-line-function 'js-indent-line) + (setq-local beginning-of-defun-function 'js-beginning-of-defun) + (setq-local end-of-defun-function 'js-end-of-defun) + (setq-local open-paren-in-column-0-is-defun-start nil) + (setq-local font-lock-defaults (list js--font-lock-keywords)) + (setq-local syntax-propertize-function #'js-syntax-propertize) - (set (make-local-variable 'indent-line-function) 'js-indent-line) - (set (make-local-variable 'beginning-of-defun-function) - 'js-beginning-of-defun) - (set (make-local-variable 'end-of-defun-function) - 'js-end-of-defun) - - (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) - (set (make-local-variable 'font-lock-defaults) - (list js--font-lock-keywords)) - (set (make-local-variable 'syntax-propertize-function) - #'js-syntax-propertize) - - (set (make-local-variable 'parse-sexp-ignore-comments) t) - (set (make-local-variable 'parse-sexp-lookup-properties) t) - (set (make-local-variable 'which-func-imenu-joiner-function) - #'js--which-func-joiner) + (setq-local parse-sexp-ignore-comments t) + (setq-local parse-sexp-lookup-properties t) + (setq-local which-func-imenu-joiner-function #'js--which-func-joiner) ;; Comments - (set (make-local-variable 'comment-start) "// ") - (set (make-local-variable 'comment-end) "") - (set (make-local-variable 'fill-paragraph-function) - 'js-c-fill-paragraph) + (setq-local comment-start "// ") + (setq-local comment-end "") + (setq-local fill-paragraph-function 'js-c-fill-paragraph) ;; Parse cache (add-hook 'before-change-functions #'js--flush-caches t t) @@ -3338,8 +3380,7 @@ If one hasn't been set, or if it's stale, prompt for a new one." ;; Imenu (setq imenu-case-fold-search nil) - (set (make-local-variable 'imenu-create-index-function) - #'js--imenu-create-index) + (setq imenu-create-index-function #'js--imenu-create-index) ;; for filling, pretend we're cc-mode (setq c-comment-prefix-regexp "//+\\|\\**" @@ -3350,10 +3391,10 @@ 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)) ;FIXME: js2-mode adds "[]*". - (set (make-local-variable 'electric-layout-rules) - '((?\; . after) (?\{ . after) (?\} . before))) + (setq-local electric-indent-chars + (append "{}():;," electric-indent-chars)) ;FIXME: js2-mode adds "[]*". + (setq-local electric-layout-rules + '((?\; . after) (?\{ . after) (?\} . before))) (let ((c-buffer-is-cc-mode t)) ;; FIXME: These are normally set by `c-basic-common-init'. Should @@ -3365,8 +3406,7 @@ If one hasn't been set, or if it's stale, prompt for a new one." (make-local-variable 'adaptive-fill-regexp) (c-setup-paragraph-variables)) - (set (make-local-variable 'syntax-begin-function) - #'js--syntax-begin-function) + (setq-local syntax-begin-function #'js--syntax-begin-function) ;; Important to fontify the whole buffer syntactically! If we don't, ;; then we might have regular expression literals that aren't marked @@ -3380,8 +3420,7 @@ If one hasn't been set, or if it's stale, prompt for a new one." ;; calls to syntax-propertize wherever it's really needed. (syntax-propertize (point-max))) -;;;###autoload -(defalias 'javascript-mode 'js-mode) +;;;###autoload (defalias 'javascript-mode 'js-mode) (eval-after-load 'folding '(when (fboundp 'folding-add-to-marks-list)