+(defun js2-minor-mode-enter ()
+ "Initialization for `js2-minor-mode'."
+ (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-gears-externs js2-gears-externs)
+ (if js2-include-rhino-externs js2-rhino-externs)))
+ ;; Experiment: make reparse-delay longer for longer files.
+ (if (plusp js2-dynamic-idle-timer-adjust)
+ (setq js2-idle-timer-delay
+ (* js2-idle-timer-delay
+ (/ (point-max) js2-dynamic-idle-timer-adjust))))
+ (setq js2-mode-buffer-dirty-p t
+ js2-mode-parsing nil)
+ (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)
+ (js2-reparse))
+
+(defun js2-minor-mode-exit ()
+ "Turn off `js2-minor-mode'."
+ (setq next-error-function nil)
+ (remove-hook 'after-change-functions #'js2-mode-edit t)
+ (remove-hook 'change-major-mode-hook #'js2-minor-mode-exit t)
+ (when js2-mode-node-overlay
+ (delete-overlay js2-mode-node-overlay)
+ (setq js2-mode-node-overlay nil))
+ (js2-remove-overlays)
+ (setq js2-mode-ast nil))
+
+(defvar js2-source-buffer nil "Linked source buffer for diagnostics view")
+(make-variable-buffer-local 'js2-source-buffer)
+
+(defun* js2-display-error-list ()
+ "Display a navigable buffer listing parse errors/warnings."
+ (interactive)
+ (unless (js2-have-errors-p)
+ (message "No errors")
+ (return-from js2-display-error-list))
+ (labels ((annotate-list
+ (lst type)
+ "Add diagnostic TYPE and line number to errs list"
+ (mapcar (lambda (err)
+ (list err type (line-number-at-pos (nth 1 err))))
+ lst)))
+ (let* ((srcbuf (current-buffer))
+ (errbuf (get-buffer-create "*js-lint*"))
+ (errors (annotate-list
+ (when js2-mode-ast (js2-ast-root-errors js2-mode-ast))
+ 'js2-error)) ; must be a valid face name
+ (warnings (annotate-list
+ (when js2-mode-ast (js2-ast-root-warnings js2-mode-ast))
+ 'js2-warning)) ; must be a valid face name
+ (all-errs (sort (append errors warnings)
+ (lambda (e1 e2) (< (cadar e1) (cadar e2))))))
+ (with-current-buffer errbuf
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (dolist (err all-errs)
+ (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
+ 'follow-link "\C-m"
+ 'action 'js2-error-buffer-jump
+ 'js2-msg (js2-get-msg msg-key)
+ 'js2-pos beg)
+ (insert "\n"))))
+ (js2-error-buffer-mode)
+ (setq js2-source-buffer srcbuf)
+ (pop-to-buffer errbuf)
+ (goto-char (point-min))
+ (unless (eobp)
+ (js2-error-buffer-view))))))
+
+(defvar js2-error-buffer-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "n" #'js2-error-buffer-next)
+ (define-key map "p" #'js2-error-buffer-prev)
+ (define-key map (kbd "RET") #'js2-error-buffer-jump)
+ (define-key map "o" #'js2-error-buffer-view)
+ (define-key map "q" #'js2-error-buffer-quit)
+ map)
+ "Keymap used for js2 diagnostics buffers.")
+
+(defun js2-error-buffer-mode ()
+ "Major mode for js2 diagnostics buffers.
+Selecting an error will jump it to the corresponding source-buffer error.
+\\{js2-error-buffer-mode-map}"
+ (interactive)
+ (setq major-mode 'js2-error-buffer-mode
+ mode-name "JS Lint Diagnostics")
+ (use-local-map js2-error-buffer-mode-map)
+ (setq truncate-lines t)
+ (set-buffer-modified-p nil)
+ (setq buffer-read-only t)
+ (run-hooks 'js2-error-buffer-mode-hook))
+
+(defun js2-error-buffer-next ()
+ "Move to next error and view it."
+ (interactive)
+ (when (zerop (forward-line 1))
+ (js2-error-buffer-view)))
+
+(defun js2-error-buffer-prev ()
+ "Move to previous error and view it."
+ (interactive)
+ (when (zerop (forward-line -1))
+ (js2-error-buffer-view)))
+
+(defun js2-error-buffer-quit ()
+ "Kill the current buffer."