;; Dmitry Gutov <dgutov@yandex.ru>
;; URL: https://github.com/mooz/js2-mode/
;; http://code.google.com/p/js2-mode/
-;; Version: 20130219
+;; Version: 20130619
;; Keywords: languages, javascript
;; Package-Requires: ((emacs "24.1"))
;; (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
-;; Alternately, to install it as a minor mode just for JavaScript linting,
+;; Alternatively, to install it as a minor mode just for JavaScript linting,
;; you must add it to the appropriate major-mode hook. Normally this would be:
;; (add-hook 'js-mode-hook 'js2-minor-mode)
+;; You may also want to hook it in for shell scripts running via node.js:
+
+;; (add-to-list 'interpreter-mode-alist '("node" . js2-mode))
+
;; To customize how it works:
;; M-x customize-group RET js2-mode RET
;; files, and not for editing JavaScript within <script> tags or templates.
;; The project page on GitHub is used for development and issue tracking.
-;; The original homepage at Google Code is mentioned here for posterity, it has
-;; outdated information and is mostly unmaintained.
+;; The original homepage at Google Code has outdated information and is mostly
+;; unmaintained.
;;; Code:
DocumentRange Range RangeException
;; W3C XML
- XPathResult XMLHttpRequest))
+ XPathResult XMLHttpRequest
+
+ ;; console object. Provided by at least Chrome and Firefox.
+ console))
"Browser externs.
You can cause these to be included or excluded with the custom
variable `js2-include-browser-externs'.")
"Node.js externs.
Set `js2-include-node-externs' to t to include them.")
+(defvar js2-typed-array-externs
+ (mapcar 'symbol-name
+ '(ArrayBuffer Uint8ClampedArray DataView
+ Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array
+ Float32Array Float64Array))
+ "Khronos typed array externs. Available in most modern browsers and
+in node.js >= 0.6. If `js2-include-node-externs' or `js2-include-browser-externs'
+are enabled, these will also be included.")
+
;;; Variables
(defun js2-mark-safe-local (name pred)
:group 'js2-mode)
(defcustom js2-concat-multiline-strings t
- "Non-nil to automatically turn a newline in mid-string into a
-string concatenation. When `eol', the '+' will be inserted at the
+ "When non-nil, `js2-line-break' in mid-string will make it a
+string concatenation. When `eol', the '+' will be inserted at the
end of the line, otherwise, at the beginning of the next line."
:type '(choice (const t) (const eol) (const nil))
:group 'js2-mode)
You should probably do this by adding them to `js2-global-externs', which
is a global list used for all js2-mode files.
-Next, you can add a function to `js2-mode-hook' that adds additional
+Next, you can add a function to `js2-init-hook' that adds additional
externs appropriate for the specific file, perhaps based on its path.
These should go in `js2-additional-externs', which is buffer-local.
+Third, you can use JSLint's global declaration, as long as
+`js2-include-jslint-globals' is non-nil, which see.
+
Finally, you can add a function to `js2-post-parse-callbacks',
which is called after parsing completes, and `js2-mode-ast' is bound to
the root of the parse tree. At this stage you can set up an AST
'((t :foreground "orange"))
"Face used to highlight undeclared variable identifiers.")
+(defcustom js2-init-hook nil
+ "List of functions to be called after `js2-mode' or
+`js2-minor-mode' has initialized all variables, before parsing
+the buffer for the first time."
+ :type 'hook
+ :group 'js2-mode
+ :version "20130608")
+
(defcustom js2-post-parse-callbacks nil
- "A list of callback functions invoked after parsing finishes.
+ "List of callback functions invoked after parsing finishes.
Currently, the main use for this function is to add synthetic
declarations to `js2-recorded-identifiers', which see."
- :type 'list
+ :type 'hook
:group 'js2-mode)
(defcustom js2-highlight-external-variables t
:type 'boolean
:group 'js2-mode)
-(defcustom js2-auto-insert-catch-block t
- "Non-nil to insert matching catch block on open-curly after `try'."
+(defcustom js2-include-jslint-globals t
+ "Non-nil to include the identifiers from JSLint global
+declaration (see http://www.jslint.com/lint.html#global) in the
+buffer-local externs list. See `js2-additional-externs' for more
+information."
:type 'boolean
:group 'js2-mode)
(defvar js2-mode-map
- (let ((map (make-sparse-keymap))
- keys)
+ (let ((map (make-sparse-keymap)))
(define-key map [mouse-1] #'js2-mode-show-node)
(define-key map (kbd "M-j") #'js2-line-break)
(define-key map (kbd "C-c C-e") #'js2-mode-hide-element)
map)
"Keymap used in `js2-mode' buffers.")
-(defconst js2-mode-identifier-re "[a-zA-Z_$][a-zA-Z0-9_$]*")
+(defconst js2-mode-identifier-re "[[:alpha:]_$][[:alnum:]_$]*")
(defvar js2-mode-//-comment-re "^\\(\\s-*\\)//.+"
"Matches a //-comment line. Must be first non-whitespace on line.
(js2-deflocal js2-imenu-function-map nil "Private variable")
(defvar js2-paragraph-start
- "\\(@[a-zA-Z]+\\>\\|$\\)")
+ "\\(@[[:alpha:]]+\\>\\|$\\)")
;; Note that we also set a 'c-in-sws text property in html comments,
;; so that `c-forward-sws' and `c-backward-sws' work properly.
(and (>= pos (point-at-bol))
(<= pos (point-at-eol))))
-(defun js2-same-line-2 (p1 p2)
- "Return t if P1 is on the same line as P2."
- (save-excursion
- (goto-char p1)
- (js2-same-line p2)))
-
(defun js2-code-bug ()
"Signal an error when we encounter an unexpected code path."
(error "failed assertion"))
(put 'cl-struct-js2-scope 'js2-visitor 'js2-visit-block)
(put 'cl-struct-js2-scope 'js2-printer 'js2-print-none)
-(defun js2-scope-set-parent-scope (scope parent)
- (setf (js2-scope-parent-scope scope) parent
- (js2-scope-top scope) (if (null parent)
- scope
- (js2-scope-top parent))))
-
(defun js2-node-get-enclosing-scope (node)
"Return the innermost `js2-scope' node surrounding NODE.
Returns nil if there is no enclosing scope node."
(:constructor make-js2-script-node (&key (type js2-SCRIPT)
(pos js2-token-beg)
len
+ ;; FIXME: What are those?
var-decls
fun-decls)))
functions ; Lisp list of nested functions
(insert "each "))
(insert "(")
(js2-print-ast (js2-for-in-node-iterator n) 0)
- (if forof
- (insert " of ")
- (insert " in "))
+ (insert (if forof " of " " in "))
(js2-print-ast (js2-for-in-node-object n) 0)
(insert ") {\n")
(js2-print-body (js2-for-in-node-body n) (1+ i))
(js2-visit-ast (js2-array-comp-loop-node-iterator n) v)
(js2-visit-ast (js2-array-comp-loop-node-object n) v))
-(defun js2-print-array-comp-loop (n i)
+(defun js2-print-array-comp-loop (n _i)
(insert "for ")
(when (js2-array-comp-loop-node-foreach-p n) (insert "each "))
(insert "(")
(js2-print-ast (js2-array-comp-loop-node-iterator n) 0)
- (if (js2-array-comp-loop-node-forof-p n)
- (insert " of ")
- (insert " in "))
+ (insert (if (js2-array-comp-loop-node-forof-p n)
+ " of " " in "))
(js2-print-ast (js2-array-comp-loop-node-object n) 0)
(insert ")"))
(js2-node-root parent)
n)))
-(defun js2-node-position-in-parent (node &optional parent)
- "Return the position of NODE in parent's block-kids list.
-PARENT can be supplied if known. Positioned returned is zero-indexed.
-Returns 0 if NODE is not a child of a block statement, or if NODE
-is not a statement node."
- (let ((p (or parent (js2-node-parent node)))
- (i 0))
- (if (not (js2-block-node-p p))
- i
- (or (js2-position node (js2-block-node-kids p))
- 0))))
-
(defsubst js2-node-short-name (n)
"Return the short name of node N as a string, e.g. `js2-if-node'."
(substring (symbol-name (aref n 0))
((js2-call-node-p node)
(js2-call-node-lp node))
((js2-paren-node-p node)
- (js2-node-pos node))
+ 0)
((js2-switch-node-p node)
(js2-switch-node-lp node))
((js2-catch-node-p node)
((js2-call-node-p node)
(js2-call-node-rp node))
((js2-paren-node-p node)
- (+ (js2-node-pos node) (js2-node-len node)))
+ (1- (js2-node-len node)))
((js2-switch-node-p node)
(js2-switch-node-rp node))
((js2-catch-node-p node)
(let ((kids (if (js2-function-node-p parent)
(js2-block-node-kids (js2-function-node-body parent))
(js2-node-child-list parent)))
- (beg (if (js2-function-node-p parent)
- (js2-node-abs-pos (js2-function-node-body parent))
- (js2-node-abs-pos parent)))
+ (beg (js2-node-abs-pos (if (js2-function-node-p parent)
+ (js2-function-node-body parent)
+ parent)))
kid result fn
(continue t))
(setq fn (if after '>= '<))
(setq kid (car kids))
(if (funcall fn (+ beg (js2-node-pos kid)) pos)
(setq result kid
- continue (if after nil t))
- (setq continue (if after t nil)))
+ continue (not after))
+ (setq continue after))
(setq kids (cdr kids)))
result))
(setq node (js2-node-parent node)))
node))
-(defun js2-nested-function-p (node)
- "Return t if NODE is a nested function, or is inside a nested function."
- (unless (js2-ast-root-p node)
- (js2-function-node-p (if (js2-function-node-p node)
- (js2-node-parent-script-or-fn node)
- (js2-node-parent-script-or-fn
- (js2-node-parent-script-or-fn node))))))
-
-(defun js2-mode-shift-kids (kids start offset)
- (dolist (kid kids)
- (if (> (js2-node-pos kid) start)
- (incf (js2-node-pos kid) offset))))
-
-(defun js2-mode-shift-children (parent start offset)
- "Update start-positions of all children of PARENT beyond START."
- (let ((root (js2-node-root parent)))
- (js2-mode-shift-kids (js2-node-child-list parent) start offset)
- (js2-mode-shift-kids (js2-ast-root-comments root) start offset)))
-
(defun js2-node-is-descendant (node ancestor)
"Return t if NODE is a descendant of ANCESTOR."
(while (and node
;;; visitor infrastructure
-(defun js2-visit-none (node callback)
+(defun js2-visit-none (_node _callback)
"Visitor for AST node that have no node children."
nil)
-(defun js2-print-none (node indent)
+(defun js2-print-none (_node _indent)
"Visitor for AST node with no printed representation.")
(defun js2-print-body (node indent)
Requires `js2-ast-parent-nodes' to be non-nil.
You should use `js2-print-tree' instead of this function."
(let ((printer (get (aref node 0) 'js2-printer))
- (i (or indent 0))
- (pos (js2-node-abs-pos node)))
+ (i (or indent 0)))
;; TODO: wedge comments in here somewhere
(if printer
(funcall printer node i))))
(let ((expr (js2-expr-stmt-node-expr node)))
(or (js2-node-has-side-effects expr)
(when (js2-string-node-p expr)
- (string= "use strict" (js2-string-node-value expr))))))
+ (member (js2-string-node-value expr) '("use strict" "use asm"))))))
((= tt js2-COMMA)
(js2-node-has-side-effects (js2-infix-node-right node)))
((or (= tt js2-AND)
(t
(aref js2-side-effecting-tokens tt))))))
-(defun js2-member-expr-leftmost-name (node)
- "For an expr such as foo.bar.baz, return leftmost node foo.
-NODE is any `js2-node' object. If it represents a member expression,
-which is any sequence of property gets, element-gets, function calls,
-or xml descendants/filter operators, then we look at the lexically
-leftmost (first) node in the chain. If it is a name-node we return it.
-Note that NODE can be a raw name-node and it will be returned as well.
-If NODE is not a name-node or member expression, or if it is a member
-expression whose leftmost target is not a name node, returns nil."
- (let ((continue t)
- result)
- (while (and continue (not result))
- (cond
- ((js2-name-node-p node)
- (setq result node))
- ((js2-prop-get-node-p node)
- (setq node (js2-prop-get-node-left node)))
- ;; TODO: handle call-nodes, xml-nodes, others?
- (t
- (setq continue nil))))
- result))
-
(defconst js2-stmt-node-types
(list js2-BLOCK
js2-BREAK
(defconst js2-token-names
(let* ((names (make-vector js2-num-tokens -1))
(case-fold-search nil) ; only match js2-UPPER_CASE
- (syms (apropos-internal "^js2-\\(?:[A-Z_]+\\)")))
+ (syms (apropos-internal "^js2-\\(?:[[:upper:]_]+\\)")))
(loop for sym in syms
for i from 0
do
(ignore-errors
(let ((s (buffer-substring-no-properties js2-ts-cursor
(+ 4 js2-ts-cursor))))
- (if (string-match "[a-zA-Z0-9]\\{4\\}" s)
+ (if (string-match "[[:alnum:]]\\{4\\}" s)
(read (concat "?\\u" s))))))
(defun js2-match-char (test)
(defun js2-skip-line ()
"Skip to end of line."
- (let (c)
- (while (not (memq (setq c (js2-get-char)) js2-eol-chars)))
- (js2-unget-char)
- (setq js2-token-end js2-ts-cursor)))
+ (while (not (memq (js2-get-char) js2-eol-chars)))
+ (js2-unget-char)
+ (setq js2-token-end js2-ts-cursor))
(defun js2-init-scanner (&optional buf line)
"Create token stream for BUF starting on LINE.
(defun js2-get-token ()
"Return next JavaScript token, an int such as js2-RETURN."
(let (c c1 identifier-start is-unicode-escape-start
- contains-escape escape-val escape-start str result base
+ contains-escape escape-val str result base
is-integer quote-char val look-for-slash continue)
(catch 'return
(while t
;; an error here.
(progn
(setq escape-val 0)
- (dotimes (i 4)
+ (dotimes (_ 4)
(setq c (js2-get-char)
escape-val (js2-x-digit-to-int c escape-val))
;; Next check takes care of c < 0 and bad escape
;; just copy the string in IDE-mode
(js2-add-to-string ?\\)
(js2-add-to-string ?u)
- (dotimes (i 3)
+ (dotimes (_ 3)
(js2-add-to-string (js2-get-char)))
(setq c (js2-get-char))) ; added at end of loop
;; flag it as an invalid escape
;; literal character sequence that follows.
(js2-add-to-string ?u)
(setq escape-val 0)
- (dotimes (i 4)
+ (dotimes (_ 4)
(setq c (js2-get-char)
escape-val (js2-x-digit-to-int c escape-val))
(if (minusp escape-val)
(setq c (js2-get-char)))))
(setq js2-ts-string (js2-get-string-from-buffer))
(throw 'return js2-STRING))
- (case c
+ (js2-ts-return
+ (case c
(?\;
(throw 'return js2-SEMI))
(?\[
(throw 'return js2-HOOK))
(?:
(if (js2-match-char ?:)
- (js2-ts-return js2-COLONCOLON)
+ js2-COLONCOLON
(throw 'return js2-COLON)))
(?.
(if (js2-match-char ?.)
(if (js2-match-char ?.)
- (js2-ts-return js2-TRIPLEDOT)
- (js2-ts-return js2-DOTDOT))
+ js2-TRIPLEDOT js2-DOTDOT)
(if (js2-match-char ?\()
- (js2-ts-return js2-DOTQUERY)
+ js2-DOTQUERY
(throw 'return js2-DOT))))
(?|
(if (js2-match-char ?|)
(throw 'return js2-OR)
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_BITOR)
+ js2-ASSIGN_BITOR
(throw 'return js2-BITOR))))
(?^
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_BITOR)
+ js2-ASSIGN_BITOR
(throw 'return js2-BITXOR)))
(?&
(if (js2-match-char ?&)
(throw 'return js2-AND)
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_BITAND)
+ js2-ASSIGN_BITAND
(throw 'return js2-BITAND))))
(?=
(if (js2-match-char ?=)
(if (js2-match-char ?=)
- (js2-ts-return js2-SHEQ)
+ js2-SHEQ
(throw 'return js2-EQ))
(throw 'return js2-ASSIGN)))
(?!
(if (js2-match-char ?=)
(if (js2-match-char ?=)
- (js2-ts-return js2-SHNE)
- (js2-ts-return js2-NE))
+ js2-SHNE
+ js2-NE)
(throw 'return js2-NOT)))
(?<
;; NB:treat HTML begin-comment as comment-till-eol
(js2-unget-char))
(if (js2-match-char ?<)
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_LSH)
- (js2-ts-return js2-LSH))
+ js2-ASSIGN_LSH
+ js2-LSH)
(if (js2-match-char ?=)
- (js2-ts-return js2-LE)
+ js2-LE
(throw 'return js2-LT))))
(?>
(if (js2-match-char ?>)
(if (js2-match-char ?>)
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_URSH)
- (js2-ts-return js2-URSH))
+ js2-ASSIGN_URSH
+ js2-URSH)
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_RSH)
- (js2-ts-return js2-RSH)))
+ js2-ASSIGN_RSH
+ js2-RSH))
(if (js2-match-char ?=)
- (js2-ts-return js2-GE)
+ js2-GE
(throw 'return js2-GT))))
(?*
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_MUL)
+ js2-ASSIGN_MUL
(throw 'return js2-MUL)))
(?/
;; is it a // comment?
(setq look-for-slash nil
js2-token-end js2-ts-cursor)))))
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_DIV)
+ js2-ASSIGN_DIV
(throw 'return js2-DIV)))
- (?#
+ (?#
(when js2-skip-preprocessor-directives
(js2-skip-line)
(setq js2-ts-comment-type 'preprocessor
(throw 'return js2-ERROR))
(?%
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_MOD)
+ js2-ASSIGN_MOD
(throw 'return js2-MOD)))
(?~
(throw 'return js2-BITNOT))
(?+
(if (js2-match-char ?=)
- (js2-ts-return js2-ASSIGN_ADD)
+ js2-ASSIGN_ADD
(if (js2-match-char ?+)
- (js2-ts-return js2-INC)
+ js2-INC
(throw 'return js2-ADD))))
(?-
(cond
(t
(setq c js2-SUB)))
(setq js2-ts-dirty-line t)
- (js2-ts-return c))
+ c)
(otherwise
- (js2-report-scan-error "msg.illegal.character")))))))
+ (js2-report-scan-error "msg.illegal.character"))))))))
(defun js2-read-regexp (start-token)
"Called by parser when it gets / or /= in literal context."
(js2-xml-discard-string)
nil)))
-(defun js2-scanner-get-line ()
- "Return the text of the current scan line."
- (buffer-substring (point-at-bol) (point-at-eol)))
-
;;; Highlighting
(defun js2-set-face (beg end face &optional record)
(push (list beg end face) js2-mode-fontifications)
(put-text-property beg end 'font-lock-face face))))
-(defun js2-set-kid-face (pos kid len face)
- "Set-face on a child node.
-POS is absolute buffer position of parent.
-KID is the child node.
-LEN is the length to fontify.
-FACE is the face to fontify with."
- (js2-set-face (+ pos (js2-node-pos kid))
- (+ pos (js2-node-pos kid) (js2-node-len kid))
- face))
-
-(defsubst js2-fontify-kwd (start length)
- (js2-set-face start (+ start length) 'font-lock-keyword-face))
-
(defsubst js2-clear-face (beg end)
(remove-text-properties beg end '(font-lock-face nil
help-echo nil
(js2-name-node-p target)
(js2-name-node-name target)))
(prop-name (if prop (js2-name-node-name prop)))
- (level1 (>= js2-highlight-level 1))
(level2 (>= js2-highlight-level 2))
- (level3 (>= js2-highlight-level 3))
- pos face)
+ (level3 (>= js2-highlight-level 3)))
(when level2
- (if call-p
- (cond
- ((and target prop)
- (cond
- ((and level3 (string-match js2-ecma-function-props prop-name))
- (setq face 'font-lock-builtin-face))
- ((and target-name prop)
- (cond
- ((string= target-name "Date")
- (if (string-match js2-ecma-date-props prop-name)
- (setq face 'font-lock-builtin-face)))
- ((string= target-name "Math")
- (if (string-match js2-ecma-math-funcs prop-name)
- (setq face 'font-lock-builtin-face)))))))
- (prop
- (if (string-match js2-ecma-global-funcs prop-name)
- (setq face 'font-lock-builtin-face))))
- (cond
- ((and target prop)
- (cond
- ((string= target-name "Number")
- (if (string-match js2-ecma-number-props prop-name)
- (setq face 'font-lock-constant-face)))
- ((string= target-name "Math")
- (if (string-match js2-ecma-math-props prop-name)
- (setq face 'font-lock-constant-face)))))
- (prop
- (if (string-match js2-ecma-object-props prop-name)
- (setq face 'font-lock-constant-face)))))
- (when face
- (js2-set-face (setq pos (+ (js2-node-pos parent) ; absolute
- (js2-node-pos prop))) ; relative
- (+ pos (js2-node-len prop))
- face 'record)))))
+ (let ((face
+ (if call-p
+ (cond
+ ((and target prop)
+ (cond
+ ((and level3 (string-match js2-ecma-function-props prop-name))
+ 'font-lock-builtin-face)
+ ((and target-name prop)
+ (cond
+ ((string= target-name "Date")
+ (if (string-match js2-ecma-date-props prop-name)
+ 'font-lock-builtin-face))
+ ((string= target-name "Math")
+ (if (string-match js2-ecma-math-funcs prop-name)
+ 'font-lock-builtin-face))))))
+ (prop
+ (if (string-match js2-ecma-global-funcs prop-name)
+ 'font-lock-builtin-face)))
+ (cond
+ ((and target prop)
+ (cond
+ ((string= target-name "Number")
+ (if (string-match js2-ecma-number-props prop-name)
+ 'font-lock-constant-face))
+ ((string= target-name "Math")
+ (if (string-match js2-ecma-math-props prop-name)
+ 'font-lock-constant-face))))
+ (prop
+ (if (string-match js2-ecma-object-props prop-name)
+ 'font-lock-constant-face))))))
+ (when face
+ (let ((pos (+ (js2-node-pos parent) ; absolute
+ (js2-node-pos prop)))) ; relative
+ (js2-set-face pos
+ (+ pos (js2-node-len prop))
+ face 'record)))))))
(defun js2-parse-highlight-member-expr-node (node)
"Perform syntax highlighting of EcmaScript built-in properties.
(setq target (js2-prop-get-node-left node)
prop (js2-prop-get-node-right node)))
(cond
- ((js2-name-node-p target)
- (if (js2-name-node-p prop)
- ;; case 2a: simple target, simple prop name, e.g. foo.bar
- (js2-parse-highlight-prop-get parent target prop call-p)
- ;; case 2b: simple target, complex name, e.g. foo.x[y]
- (js2-parse-highlight-prop-get parent target nil call-p)))
((js2-name-node-p prop)
- ;; case 2c: complex target, simple name, e.g. x[y].bar
- (js2-parse-highlight-prop-get parent target prop call-p)))))))
+ ;; case 2(a&c): simple or complex target, simple name, e.g. x[y].bar
+ (js2-parse-highlight-prop-get parent target prop call-p))
+ ((js2-name-node-p target)
+ ;; case 2b: simple target, complex name, e.g. foo.x[y]
+ (js2-parse-highlight-prop-get parent target nil call-p)))))))
(defun js2-parse-highlight-member-expr-fn-name (expr)
"Highlight the `baz' in function foo.bar.baz(args) {...}.
"\\(?:param\\|argument\\)"
"\\)"
"\\s-*\\({[^}]+}\\)?" ; optional type
- "\\s-*\\[?\\([a-zA-Z0-9_$\.]+\\)?\\]?" ; name
+ "\\s-*\\[?\\([[:alnum:]_$\.]+\\)?\\]?" ; name
"\\>")
"Matches jsdoc tags with optional type and optional param name.")
"Matches a jsdoc @see tag.")
(defconst js2-jsdoc-html-tag-regexp
- "\\(</?\\)\\([a-zA-Z]+\\)\\s-*\\(/?>\\)"
+ "\\(</?\\)\\([[:alpha:]]+\\)\\s-*\\(/?>\\)"
"Matches a simple (no attributes) html start- or end-tag.")
(defun js2-jsdoc-highlight-helper ()
(match-end 3)
'js2-jsdoc-html-tag-delimiter))))))))
-(defun js2-highlight-assign-targets (node left right)
+(defun js2-highlight-assign-targets (_node left right)
"Highlight function properties and external variables."
- (let (leftpos end name)
+ (let (leftpos name)
;; highlight vars and props assigned function values
(when (js2-function-node-p right)
(cond
(defun js2-record-name-node (node)
"Saves NODE to `js2-recorded-identifiers' to check for undeclared variables
later. NODE must be a name node."
- (let (leftpos end)
+ (let ((leftpos (js2-node-abs-pos node)))
(push (list node js2-current-scope
- (setq leftpos (js2-node-abs-pos node))
- (setq end (+ leftpos (js2-node-len node))))
+ leftpos
+ (+ leftpos (js2-node-len node)))
js2-recorded-identifiers)))
(defun js2-highlight-undeclared-vars ()
'js2-external-variable))))
(setq js2-recorded-identifiers nil)))
+(defun js2-set-default-externs ()
+ "Set the value of `js2-default-externs' based on the various
+`js2-include-?-externs' variables."
+ (setq js2-default-externs
+ (append js2-ecma-262-externs
+ (if js2-include-browser-externs js2-browser-externs)
+ (if js2-include-rhino-externs js2-rhino-externs)
+ (if js2-include-node-externs js2-node-externs)
+ (if (or js2-include-browser-externs js2-include-node-externs)
+ js2-typed-array-externs))))
+
+(defun js2-apply-jslint-globals ()
+ (setq js2-additional-externs
+ (nconc (js2-get-jslint-globals)
+ js2-additional-externs)))
+
+(defun js2-get-jslint-globals ()
+ (loop for node in (js2-ast-root-comments js2-mode-ast)
+ when (and (eq 'block (js2-comment-node-format node))
+ (save-excursion
+ (goto-char (js2-node-abs-pos node))
+ (looking-at "/\\*global ")))
+ append (js2-get-jslint-globals-in
+ (match-end 0)
+ (js2-node-abs-end node))))
+
+(defun js2-get-jslint-globals-in (beg end)
+ (let (res)
+ (save-excursion
+ (goto-char beg)
+ (while (re-search-forward js2-mode-identifier-re end t)
+ (let ((match (match-string 0)))
+ (unless (member match '("true" "false"))
+ (push match res)))))
+ (nreverse res)))
+
;;; IMenu support
;; We currently only support imenu, but eventually should support speedbar and
When passed arguments of wrong type, does nothing."
(when js2-parse-ide-mode
(let ((fun-p (js2-function-node-p node))
- qname left fname-node pos)
+ qname fname-node)
(cond
;; non-anonymous function declaration?
((and fun-p
POS is the absolute position of the node.
We do a depth-first traversal of NODE. For any functions we find,
we append the property name to QNAME, then call `js2-record-imenu-entry'."
- (let (left right prop-qname)
+ (let (right)
(dolist (e (js2-object-node-elems node)) ; e is a `js2-object-prop-node'
(let ((left (js2-infix-node-left e))
;; Element positions are relative to the parent position.
"Modify function-declaration name chains after parsing finishes.
Some of the information is only available after the parse tree is complete.
For instance, processing a nested scope requires a parent function node."
- (let (result head fn current-fn parent-qname qname p elem)
+ (let (result fn parent-qname p elem)
(dolist (entry entries)
;; function node goes first
(destructuring-bind (current-fn &rest (&whole chain head &rest)) entry
(if (js2-function-node-p js2-current-script-or-fn)
(setf (js2-function-node-needs-activation js2-current-script-or-fn) t)))
-(defun js2-check-activation-name (name token)
+(defun js2-check-activation-name (name _token)
(when (js2-inside-function)
;; skip language-version 1.2 check from Rhino
(if (or (string= "arguments" name)
;; Give extensions a chance to muck with things before highlighting starts.
(let ((js2-additional-externs js2-additional-externs))
(save-excursion
- (dolist (callback js2-post-parse-callbacks)
- (funcall callback)))
+ (run-hooks 'js2-post-parse-callbacks))
(js2-highlight-undeclared-vars))
root))
(defun js2-parse-function-params (fn-node pos)
(if (js2-match-token js2-RP)
(setf (js2-function-node-rp fn-node) (- js2-token-beg pos))
- (let (params len param default-found rest-param-at)
+ (let (params param default-found rest-param-at)
(loop for tt = (js2-peek-token)
do
(cond
pn))
(defun js2-parse-statement ()
- (let (tt pn beg end)
+ (let (pn beg end)
;; coarse-grained user-interrupt check - needs work
(and js2-parse-interruptable-p
(zerop (% (incf js2-parse-stmt-count)
(defun js2-statement-helper ()
(let* ((tt (js2-peek-token))
(first-tt tt)
- (beg js2-token-beg)
(parser (if (= tt js2-ERROR)
#'js2-parse-semi
(aref js2-parsers tt)))
- pn
- tt-flagged)
+ pn)
;; If the statement is set, then it's been told its label by now.
(and js2-labeled-stmt
(js2-labeled-stmt-node-stmt js2-labeled-stmt)
"Parser for if-statement. Last matched token must be js2-SWITCH."
(let ((pos js2-token-beg)
tt pn discriminant has-default case-expr case-node
- case-pos cases stmt lp rp)
+ case-pos cases stmt lp)
(js2-consume-token)
(if (js2-must-match js2-LP "msg.no.paren.switch")
(setq lp js2-token-beg))
(defun js2-parse-default-xml-namespace ()
"Parse a `default xml namespace = <expr>' e4x statement."
(let ((pos js2-token-beg)
- end len expr unary es)
+ end len expr unary)
(js2-consume-token)
(js2-must-have-xml)
(js2-set-requires-activation)
`js2-labeled-stmt-node' bundle and return that. Otherwise we parse an
expression and return it wrapped in a `js2-expr-stmt-node'."
(let ((pos js2-token-beg)
- (end js2-token-end)
expr stmt pn bundle
(continue t))
;; set check for label and call down to `js2-parse-primary-expr'
(setq expr (js2-parse-expr))
(if (/= (js2-node-type expr) js2-LABEL)
;; Parsed non-label expression - wrap with expression stmt.
- (setq pn (js2-wrap-with-expr-stmt pos expr t))
+ (setq pn (js2-wrap-with-expr-stmt pos expr t)) ;FIXME: `pn' is unused!
;; else parsed a label
(setq bundle (make-js2-labeled-stmt-node :pos pos))
(js2-record-label expr bundle)
(defun js2-parse-member-expr (&optional allow-call-syntax)
(let ((tt (js2-peek-token))
- pn pos target args beg end init tail)
+ pn pos target args beg end init)
(if (/= tt js2-NEW)
(setq pn (js2-parse-primary-expr))
;; parse a 'new' expression
Includes parsing for E4X operators like `..' and `.@'.
If ALLOW-CALL-SYNTAX is nil, stops when we encounter a left-paren.
Returns an expression tree that includes PN, the parent node."
- (let ((beg (js2-node-pos pn))
- tt
+ (let (tt
(continue t))
(while continue
(setq tt (js2-peek-token))
(js2-save-name-token-data js2-token-beg "")
(js2-parse-property-name js2-token-beg "" 0)))))
-(defun js2-parse-property-name (at-pos s member-type-flags)
+(defun js2-parse-property-name (at-pos _s member-type-flags)
"Check if :: follows name in which case it becomes qualified name.
AT-POS is a natural number if we just read an '@' token, else nil.
(let ((pos (or at-pos js2-token-beg))
colon-pos
(name (js2-create-name-node t js2-current-token))
- ns tt ref pn)
+ ns tt pn)
(catch 'return
(when (js2-match-token js2-COLONCOLON)
(setq ns name
(js2-report-error "msg.syntax")
(make-js2-error-node)))))
-(defun js2-parse-name (tt-flagged tt)
+(defun js2-parse-name (tt-flagged _tt)
(let ((name js2-ts-string)
(name-pos js2-token-beg)
node)
(defun js2-parse-array-literal ()
(let ((pos js2-token-beg)
- (end js2-token-end)
(after-lb-or-comma t)
after-comma tt elems pn
(continue t))
(js2-report-error "msg.no.bracket.arg" nil pos)
(js2-consume-token))
(setq continue nil
- end js2-token-end
pn (make-js2-array-node :pos pos
:len (- js2-ts-cursor pos)
:elems (nreverse elems)))
EXPR is the first expression after the opening left-bracket.
POS is the beginning of the LB token preceding EXPR.
We should have just parsed the 'for' keyword before calling this function."
- (let (loops loop first prev filter if-pos result)
+ (let (loops loop first filter if-pos result)
(while (= (js2-peek-token) js2-FOR)
(let ((prev (car loops))) ; rearrange scope chain
(push (setq loop (js2-parse-array-comp-loop)) loops)
"Search forward but ignore strings and comments.
Invokes `re-search-forward' but treats the buffer as if strings
and comments have been removed."
- (let ((saved-point (point))
- (search-expr
- (cond ((null count)
- '(js2-re-search-forward-inner regexp bound 1))
- ((< count 0)
- '(js2-re-search-backward-inner regexp bound (- count)))
- ((> count 0)
- '(js2-re-search-forward-inner regexp bound count)))))
+ (let ((saved-point (point)))
(condition-case err
- (eval search-expr)
+ (cond ((null count)
+ (js2-re-search-forward-inner regexp bound 1))
+ ((< count 0)
+ (js2-re-search-backward-inner regexp bound (- count)))
+ ((> count 0)
+ (js2-re-search-forward-inner regexp bound count)))
(search-failed
(goto-char saved-point)
(unless noerror
"Search backward but ignore strings and comments.
Invokes `re-search-backward' but treats the buffer as if strings
and comments have been removed."
- (let ((saved-point (point))
- (search-expr
- (cond ((null count)
- '(js2-re-search-backward-inner regexp bound 1))
- ((< count 0)
- '(js2-re-search-forward-inner regexp bound (- count)))
- ((> count 0)
- '(js2-re-search-backward-inner regexp bound count)))))
+ (let ((saved-point (point)))
(condition-case err
- (eval search-expr)
+ (cond ((null count)
+ (js2-re-search-backward-inner regexp bound 1))
+ ((< count 0)
+ (js2-re-search-forward-inner regexp bound (- count)))
+ ((> count 0)
+ (js2-re-search-backward-inner regexp bound count)))
(search-failed
(goto-char saved-point)
(unless noerror
(js2-backward-sws)
(or (eq (char-before) ?,)
(and (not (eq (char-before) ?\;))
- (and
- (prog2 (skip-chars-backward "[[:punct:]]")
- (looking-at js2-indent-operator-re)
- (js2-backward-sws))
- (not (eq (char-before) ?\;))))
+ (prog2 (skip-syntax-backward ".")
+ (looking-at js2-indent-operator-re)
+ (js2-backward-sws))
+ (not (eq (char-before) ?\;)))
(js2-same-line pos)))))
- (condition-case err
+ (condition-case _
(backward-sexp)
(scan-error (setq at-opening-bracket t))))
(when (looking-at js2-declaration-keyword-re)
(skip-chars-forward " \t")
(looking-at "case\\s-.+:")))
-(defun js2-syntax-bol ()
- "Return the point at the first non-whitespace char on the line.
-Returns `point-at-bol' if the line is empty."
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (point)))
-
(defun js2-bounce-indent (normal-col parse-status &optional backwards)
"Cycle among alternate computed indentation positions.
PARSE-STATUS is the result of `parse-partial-sexp' from the beginning
(forward-line 0) ; move to bol
(1+ (count-lines (point-min) (point)))))
positions pos main-pos anchor arglist-cont same-indent
- prev-line-col basic-offset computed-pos)
+ basic-offset computed-pos)
;; temporarily don't record undo info, if user requested this
(when js2-mode-indent-inhibit-undo
(setq buffer-undo-list t))
(back-to-indentation)
(js2-backward-sws)
(back-to-indentation)
- (setq prev-line-col (current-column)))
+ (current-column))
js2-basic-offset))
positions)
(back-to-indentation)
(js2-backward-sws)
(back-to-indentation)
- (setq prev-line-col (current-column)))
+ (current-column))
(* 2 js2-basic-offset)))
positions)
(defun js2-indent-line (&optional bounce-backwards)
"Indent the current line as JavaScript source text."
(interactive)
- (let (parse-status current-indent offset indent-col moved
+ (let (parse-status offset indent-col
;; Don't whine about errors/warnings when we're indenting.
;; This has to be set before calling parse-partial-sexp below.
(inhibit-point-motion-hooks t))
(set (make-local-variable 'max-lisp-eval-depth)
(max max-lisp-eval-depth 3000))
(setq next-error-function #'js2-next-error)
- (setq js2-default-externs
- (append js2-ecma-262-externs
- (if js2-include-browser-externs js2-browser-externs)
- (if js2-include-rhino-externs js2-rhino-externs)
- (if js2-include-node-externs js2-node-externs)))
+ (js2-set-default-externs)
;; Experiment: make reparse-delay longer for longer files.
(if (plusp js2-dynamic-idle-timer-adjust)
(setq js2-idle-timer-delay
(set (make-local-variable 'js2-highlight-level) 0) ; no syntax highlighting
(add-hook 'after-change-functions #'js2-minor-mode-edit nil t)
(add-hook 'change-major-mode-hook #'js2-minor-mode-exit nil t)
+ (when js2-include-jslint-globals
+ (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
+ (run-hooks 'js2-init-hook)
(js2-reparse))
(defun js2-minor-mode-exit ()
(delete-overlay js2-mode-node-overlay)
(setq js2-mode-node-overlay nil))
(js2-remove-overlays)
+ (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals t)
(setq js2-mode-ast nil))
(defvar js2-source-buffer nil "Linked source buffer for diagnostics view")
(let ((inhibit-read-only t))
(erase-buffer)
(dolist (err all-errs)
- (destructuring-bind ((msg-key beg end &rest) type line) err
+ (destructuring-bind ((msg-key beg _end &rest) type line) err
(insert-text-button
(format "line %d: %s" line (js2-get-msg msg-key))
'face type
(define-derived-mode js2-mode prog-mode "Javascript-IDE"
;; FIXME: Should derive from js-mode.
"Major mode for editing JavaScript code."
- (setq comment-start "//" ; used by comment-region; don't change it
- comment-end "")
+ ;; Used by comment-region; don't change it.
+ (set (make-local-variable 'comment-start) "//")
+ (set (make-local-variable 'comment-end) "")
+ (set (make-local-variable 'comment-start-skip) js2-comment-start-skip)
(set (make-local-variable 'max-lisp-eval-depth)
(max max-lisp-eval-depth 3000))
(set (make-local-variable 'indent-line-function) #'js2-indent-line)
c-line-comment-starter "//"
c-paragraph-start js2-paragraph-start
c-paragraph-separate "$"
- comment-start-skip js2-comment-start-skip
c-syntactic-ws-start js2-syntactic-ws-start
c-syntactic-ws-end js2-syntactic-ws-end
c-syntactic-eol js2-syntactic-eol)
(make-local-variable 'adaptive-fill-regexp)
(c-setup-paragraph-variables))
- (setq js2-default-externs
- (append js2-ecma-262-externs
- (if js2-include-browser-externs js2-browser-externs)
- (if js2-include-rhino-externs js2-rhino-externs)
- (if js2-include-node-externs js2-node-externs)))
-
(setq font-lock-defaults '(nil t))
;; Experiment: make reparse-delay longer for longer files.
js2-mode-comments-hidden nil
js2-mode-buffer-dirty-p t
js2-mode-parsing nil)
+
+ (js2-set-default-externs)
+
+ (when js2-include-jslint-globals
+ (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
+
+ (run-hooks 'js2-init-hook)
+
(js2-reparse))
(defun js2-mode-exit ()
t)
(js2-reparse))
-(defun js2-mode-edit (beg end len)
+(defun js2-mode-edit (_beg _end _len)
"Schedule a new parse after buffer is edited.
Buffer edit spans from BEG to END and is of length LEN."
(setq js2-mode-buffer-dirty-p t)
(js2-mode-hide-overlay)
(js2-mode-reset-timer))
-(defun js2-minor-mode-edit (beg end len)
+(defun js2-minor-mode-edit (_beg _end _len)
"Callback for buffer edits in `js2-mode'.
Schedules a new parse after buffer is edited.
Buffer edit spans from BEG to END and is of length LEN."
(js2-node-short-name (js2-node-parent node))
"nil"))))))
-(defun js2-mode-hide-overlay (&optional p1 p2)
+(defun js2-mode-hide-overlay (&optional _p1 p2)
"Remove the debugging overlay when the point moves.
P1 and P2 are the old and new values of point, respectively."
(when js2-mode-node-overlay
(dolist (e (js2-ast-root-warnings js2-mode-ast))
(js2-mode-show-warn-or-err e 'js2-warning))))
-(defun js2-echo-error (old-point new-point)
+(defun js2-echo-error (_old-point new-point)
"Called by point-motion hooks."
(let ((msg (get-text-property new-point 'help-echo)))
- (when (and (stringp msg) (or (not (current-message))
- (string= (current-message) "Quit")))
+ (when (and (stringp msg)
+ (not (active-minibuffer-window))
+ (not (current-message)))
(message msg))))
-(defalias #'js2-echo-help #'js2-echo-error)
+(defalias 'js2-echo-help #'js2-echo-error)
-(defun js2-line-break (&optional soft)
+(defun js2-line-break (&optional _soft)
"Break line at point and indent, continuing comment if within one.
If inside a string, and `js2-concat-multiline-strings' is not
nil, turn it into concatenation."
(defun js2-mode-split-string (parse-status)
"Turn a newline in mid-string into a string concatenation.
PARSE-STATUS is as documented in `parse-partial-sexp'."
- (let* ((col (current-column))
- (quote-char (nth 3 parse-status))
- (string-beg (nth 8 parse-status))
+ (let* ((quote-char (nth 3 parse-status))
(at-eol (eq js2-concat-multiline-strings 'eol)))
(insert quote-char)
- (if at-eol
- (insert " +\n")
- (insert "\n"))
+ (insert (if at-eol " +\n" "\n"))
(unless at-eol
(insert "+ "))
(js2-indent-line)
"Toggle point between bol and first non-whitespace char in line.
Also moves past comment delimiters when inside comments."
(interactive)
- (let (node beg)
+ (let (node)
(cond
((bolp)
(back-to-indentation))
(skip-chars-backward " \t")
(goto-char (point-at-eol))))
-(defsubst js2-mode-inside-string ()
- "Return non-nil if inside a string.
-Actually returns the quote character that begins the string."
- (nth 3 (syntax-ppss)))
-
-(defun js2-mode-inside-comment-or-string ()
- "Return non-nil if inside a comment or string."
- (or
- (let ((comment-start
- (save-excursion
- (goto-char (point-at-bol))
- (if (re-search-forward "//" (point-at-eol) t)
- (match-beginning 0)))))
- (and comment-start
- (<= comment-start (point))))
- (let ((parse-state (syntax-ppss)))
- (or (nth 3 parse-state)
- (nth 4 parse-state)))))
-
-
-(defun js2-insert-catch-skel (try-pos)
- "Complete a try/catch block after inserting a { following a try keyword.
-Rationale is that a try always needs a catch or a finally, and the catch is
-the more likely of the two.
-
-TRY-POS is the buffer position of the try keyword. The open-curly should
-already have been inserted."
- (insert "{")
- (let ((try-col (save-excursion
- (goto-char try-pos)
- (current-column))))
- (insert "\n")
- (undo-boundary)
- (js2-indent-line) ;; indent the blank line where cursor will end up
- (save-excursion
- (insert "\n")
- (indent-to try-col)
- (insert "} catch (x) {\n\n")
- (indent-to try-col)
- (insert "}"))))
-
-
(defun js2-mode-wait-for-parse (callback)
"Invoke CALLBACK when parsing is finished.
If parsing is already finished, calls CALLBACK immediately."
;; Function to be set as an outline-isearch-open-invisible' property
;; to the overlay that makes the outline invisible (see
;; `js2-mode-flag-region').
-(defun js2-isearch-open-invisible (overlay)
+(defun js2-isearch-open-invisible (_overlay)
;; We rely on the fact that isearch places point on the matched text.
(js2-mode-show-element))
(message "Oops - parsing failed")
(setq js2-mode-comments-hidden t)
(dolist (n (js2-ast-root-comments js2-mode-ast))
- (let ((format (js2-comment-node-format n)))
- (when (js2-block-comment-p n)
- (js2-mode-hide-comment n))))
+ (when (js2-block-comment-p n)
+ (js2-mode-hide-comment n)))
(js2-mode-hide-//-comments)))
(defun js2-mode-extend-//-comment (direction)
(save-restriction
(widen) ;; `blink-matching-open' calls `narrow-to-region'
(js2-reparse))
- (let ((scan-msg "Containing expression ends prematurely")
+ (let (forward-sexp-function
node (start (point)) pos lp rp child)
(cond
;; backward-sexp
;; - infix exprs like (foo in bar) - maybe go to beginning
;; of infix expr if in the right-side expression?
((and arg (minusp arg))
- (dotimes (i (- arg))
+ (dotimes (_ (- arg))
(js2-backward-sws)
- (forward-char -1) ; enter the node we backed up to
+ (forward-char -1) ; Enter the node we backed up to.
(when (setq node (js2-node-at-point (point) t))
(setq pos (js2-node-abs-pos node))
(let ((parens (js2-mode-forward-sexp-parens node pos)))
(setq lp (car parens)
- rp (cdr parens))))
- (goto-char
- (or (when (and lp (> start lp))
- (if (and rp (<= start rp))
- (if (setq child (js2-node-closest-child node (point) lp t))
- (js2-node-abs-pos child)
- (goto-char start)
- (signal 'scan-error (list scan-msg lp lp)))
- lp))
- pos
- (point-min)))))
+ rp (cdr parens)))
+ (when (and lp (> start lp))
+ (if (and rp (<= start rp))
+ ;; Between parens, check if there's a child node we can jump.
+ (when (setq child (js2-node-closest-child node (point) lp t))
+ (setq pos (js2-node-abs-pos child)))
+ ;; Before both parens.
+ (setq pos lp)))
+ (let ((state (parse-partial-sexp start pos)))
+ (goto-char (if (not (zerop (car state)))
+ ;; Stumble at the unbalanced paren if < 0, or
+ ;; jump a bit further if > 0.
+ (scan-sexps start -1)
+ pos))))
+ (unless pos (goto-char (point-min)))))
(t
;; forward-sexp
- (js2-forward-sws)
- (dotimes (i arg)
+ (dotimes (_ arg)
(js2-forward-sws)
(when (setq node (js2-node-at-point (point) t))
(setq pos (js2-node-abs-pos node))
(let ((parens (js2-mode-forward-sexp-parens node pos)))
(setq lp (car parens)
- rp (cdr parens))))
- (goto-char
- (or (when (and rp (<= start rp))
- (if (> start lp)
- (if (setq child (js2-node-closest-child node (point) rp))
- (js2-node-abs-end child)
- (goto-char start)
- (signal 'scan-error (list scan-msg rp (1+ rp))))
- (1+ rp)))
- (and pos
- (+ pos
- (js2-node-len
+ rp (cdr parens)))
+ (or
+ (when (and rp (<= start rp))
+ (if (> start lp)
+ (when (setq child (js2-node-closest-child node (point) rp))
+ (setq pos (js2-node-abs-end child)))
+ (setq pos (1+ rp))))
+ ;; No parens or child nodes, looks for the end of the curren node.
+ (incf pos (js2-node-len
(if (js2-expr-stmt-node-p (js2-node-parent node))
- ;; stop after the semicolon
+ ;; Stop after the semicolon.
(js2-node-parent node)
node))))
- (point-max))))))))
+ (let ((state (save-excursion (parse-partial-sexp start pos))))
+ (goto-char (if (not (zerop (car state)))
+ (scan-sexps start 1)
+ pos))))
+ (unless pos (goto-char (point-max))))))))
(defun js2-mode-forward-sexp-parens (node abs-pos)
+ "Return a cons cell with positions of main parens in NODE."
(cond
((or (js2-array-node-p node)
(js2-object-node-p node)
(catch 'done
(js2-visit-ast
parent
- (lambda (node end-p)
+ (lambda (node _end-p)
(if (eq node parent)
t
(let ((pos (js2-node-pos node)) ;; Both relative values.
(if (zerop (decf count))
(setq continue nil)))
(setq errs (cdr errs)))
+ ;; Clear for `js2-echo-error'.
+ (message nil)
(if err
(goto-char (second err))
;; Wrap around to first error.
(let (beg end)
(js2-with-underscore-as-word-syntax
(save-excursion
- (if (and (not (looking-at "[A-Za-z0-9_$]"))
- (looking-back "[A-Za-z0-9_$]"))
+ (if (and (not (looking-at "[[:alnum:]_$]"))
+ (looking-back "[[:alnum:]_$]"))
(setq beg (progn (forward-word -1) (point))
end (progn (forward-word 1) (point)))
(setq beg (progn (forward-word 1) (point))
(js2-beginning-of-defun (1- arg))
t)))
(when (js2-end-of-defun)
- (if (>= arg -1)
- (js2-beginning-of-defun 1)
- (js2-beginning-of-defun (1+ arg))))))
+ (js2-beginning-of-defun (if (>= arg -1) 1 (1+ arg))))))
(defun js2-end-of-defun ()
"Go to the char after the last position of the current function
(let ((sib (save-excursion
(goto-char (mark))
(if (js2-mode-forward-sibling)
- (point))))
- node)
+ (point)))))
(if sib
(progn
(set-mark sib)