diff options
Diffstat (limited to 'lisp/imenu.el')
-rw-r--r-- | lisp/imenu.el | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/lisp/imenu.el b/lisp/imenu.el index 2024bb1e066..22412d5f88b 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -85,7 +85,8 @@ This might not yet be honored by all index-building functions." :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") @@ -153,6 +154,11 @@ uses `imenu--generic-function')." :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. @@ -520,10 +526,13 @@ The alternate method, which is the one most often used, is to call (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)) @@ -576,6 +585,7 @@ depending on PATTERNS." (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)) @@ -618,7 +628,13 @@ depending on PATTERNS." (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. @@ -813,8 +829,7 @@ A trivial interface to `imenu-add-to-menubar' suitable for use in a hook." (defvar imenu-buffer-menubar nil) (defvar-local imenu-menubar-modified-tick 0 - "The value of (buffer-chars-modified-tick) as of the last call -to `imenu-update-menubar'.") + "Value of (buffer-chars-modified-tick) when `imenu-update-menubar' was called.") (defun imenu-update-menubar () (when (and (current-local-map) |