changes in the text.
@vindex imenu-auto-rescan-maxout
+@vindex imenu-max-index-time
@code{imenu-auto-rescan} will be disabled in buffers that are larger
-than @code{imenu-auto-rescan-maxout} in bytes.
+than @code{imenu-auto-rescan-maxout} in bytes, and scanning is
+stopped if it takes more than @code{imenu-max-index-time} seconds.
@vindex imenu-sort-function
You can customize the way the menus are sorted by setting the
but it now aligns with the first sibling (which is the preferred style
in Ruby).
+** Imenu
+
++++
+*** New user option 'imenu-max-index-time'.
+If creating the imenu index takes longer than specified by this
+variable (default 5 seconds), imenu indexing is stopped.
+
\f
* New Modes and Packages in Emacs 28.1
:type 'boolean)
(defcustom imenu-auto-rescan-maxout 600000
- "Imenu auto-rescan is disabled in buffers larger than this size (in bytes)."
+ "Imenu auto-rescan is disabled in buffers larger than this size (in bytes).
+Also see `imenu-max-index-time'."
:type 'integer
:version "26.2")
:type 'boolean
:version "24.4")
+(defcustom imenu-max-index-time 5
+ "Max time to use when creating imenu indices."
+ :type 'number
+ :version "28.1")
+
;;;###autoload
(defvar-local imenu-generic-expression nil
"List of definition matchers for creating an Imenu index.
(cond ((and imenu-prev-index-position-function
imenu-extract-index-name-function)
(let ((index-alist '()) (pos (point-max))
+ (start (float-time))
name)
(goto-char pos)
;; Search for the function
- (while (funcall imenu-prev-index-position-function)
+ (while (and (funcall imenu-prev-index-position-function)
+ ;; Don't use an excessive amount of time.
+ (< (- (float-time) start) imenu-max-index-time))
(unless (< (point) pos)
(error "Infinite loop at %s:%d: imenu-prev-index-position-function does not move point" (buffer-name) pos))
(setq pos (point))
(not (local-variable-p 'font-lock-defaults)))
imenu-case-fold-search
(nth 2 font-lock-defaults)))
+ (start-time (float-time))
(old-table (syntax-table))
(table (copy-syntax-table (syntax-table)))
(slist imenu-syntax-alist))
(not invis))))))
;; Exit the loop if we get an empty match,
;; because it means a bad regexp was specified.
- (not (= (match-beginning 0) (match-end 0))))
+ (not (= (match-beginning 0) (match-end 0)))
+ ;; Don't take an excessive amount of time.
+ (or (< (- (float-time) start-time)
+ imenu-max-index-time)
+ (progn
+ (message "`imenu-max-index-time' exceeded")
+ nil)))
(setq start (point))
;; Record the start of the line in which the match starts.
;; That's the official position of this definition.