X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/db4613576d3115aa320f0293d081ce98baa06acd..9fcd66daf819294168e86ea5eb50c241b1d9fa11:/lisp/progmodes/js.el diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index de6a33988a..f06c5c75b1 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -248,7 +248,7 @@ name as matched contains (defconst js--function-heading-1-re (concat - "^\\s-*function\\s-+\\(" js--name-re "\\)") + "^\\s-*function\\(?:\\s-\\|\\*\\)+\\(" js--name-re "\\)") "Regexp matching the start of a JavaScript function header. Match group 1 is the name of the function.") @@ -509,6 +509,48 @@ getting timeout messages." :type 'integer :group 'js) +(defcustom js-indent-first-init nil + "Non-nil means specially indent the first variable declaration's initializer. +Normally, the first declaration's initializer is unindented, and +subsequent declarations have their identifiers aligned with it: + + var o = { + foo: 3 + }; + + var o = { + foo: 3 + }, + bar = 2; + +If this option has the value t, indent the first declaration's +initializer by an additional level: + + var o = { + foo: 3 + }; + + var o = { + foo: 3 + }, + bar = 2; + +If this option has the value `dynamic', if there is only one declaration, +don't indent the first one's initializer; otherwise, indent it. + + var o = { + foo: 3 + }; + + var o = { + foo: 3 + }, + bar = 2;" + :version "25.1" + :type '(choice (const nil) (const t) (const dynamic)) + :safe 'symbolp + :group 'js) + ;;; KeyMap (defvar js-mode-map @@ -534,6 +576,7 @@ getting timeout messages." (let ((table (make-syntax-table))) (c-populate-syntax-table table) (modify-syntax-entry ?$ "_" table) + (modify-syntax-entry ?` "\"" table) table) "Syntax table for `js-mode'.") @@ -796,6 +839,9 @@ determined. Otherwise, return nil." (let ((name t)) (forward-word) (forward-comment most-positive-fixnum) + (when (eq (char-after) ?*) + (forward-char) + (forward-comment most-positive-fixnum)) (when (looking-at js--name-re) (setq name (match-string-no-properties 0)) (goto-char (match-end 0))) @@ -1854,6 +1900,36 @@ In particular, return the buffer position of the first `for' kwd." (goto-char for-kwd) (current-column)))) +(defun js--maybe-goto-declaration-keyword-end (parse-status) + "Helper function for `js--proper-indentation'. +Depending on the value of `js-indent-first-init', move +point to the end of a variable declaration keyword so that +indentation is aligned to that column." + (cond + ((eq js-indent-first-init t) + (when (looking-at js--declaration-keyword-re) + (goto-char (1+ (match-end 0))))) + ((eq js-indent-first-init 'dynamic) + (let ((bracket (nth 1 parse-status)) + declaration-keyword-end + at-closing-bracket-p + comma-p) + (when (looking-at js--declaration-keyword-re) + (setq declaration-keyword-end (match-end 0)) + (save-excursion + (goto-char bracket) + (setq at-closing-bracket-p + (condition-case nil + (progn + (forward-sexp) + t) + (error nil))) + (when at-closing-bracket-p + (while (forward-comment 1)) + (setq comma-p (looking-at-p ",")))) + (when comma-p + (goto-char (1+ declaration-keyword-end)))))))) + (defun js--proper-indentation (parse-status) "Return the proper indentation for the current line." (save-excursion @@ -1887,6 +1963,7 @@ In particular, return the buffer position of the first `for' kwd." (skip-syntax-backward " ") (when (eq (char-before) ?\)) (backward-list)) (back-to-indentation) + (js--maybe-goto-declaration-keyword-end parse-status) (let* ((in-switch-p (unless same-indent-p (looking-at "\\_"))) (same-indent-p (or same-indent-p @@ -1925,8 +2002,9 @@ In particular, return the buffer position of the first `for' kwd." (let* ((parse-status (save-excursion (syntax-ppss (point-at-bol)))) (offset (- (point) (save-excursion (back-to-indentation) (point))))) - (indent-line-to (js--proper-indentation parse-status)) - (when (> offset 0) (forward-char offset)))) + (unless (nth 3 parse-status) + (indent-line-to (js--proper-indentation parse-status)) + (when (> offset 0) (forward-char offset))))) ;;; Filling @@ -2774,10 +2852,6 @@ 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."