]> git.eshelyaron.com Git - emacs.git/commitdiff
dabbrev: limit work, not results
authorEshel Yaron <me@eshelyaron.com>
Thu, 6 Mar 2025 09:55:50 +0000 (10:55 +0100)
committerEshel Yaron <me@eshelyaron.com>
Thu, 6 Mar 2025 09:55:50 +0000 (10:55 +0100)
lisp/dabbrev.el

index 10b406cce961cb0d91977e476f7133161784767f..bfba153f0240716f373d46b62ed8b1c8edef0098 100644 (file)
@@ -25,6 +25,9 @@
 (defvar dabbrev-maximum-expansions 16
   "Maximum number of dynamic abbreviation expansions to suggest.")
 
+(defvar dabbrev-maximum-characters 65536
+  "Maximum number of character to scan from dynamic expansions.")
+
 (defvar dabbrev-buffer-search-condition
   '(not (or (derived-mode . special-mode) "^ "))
   "Condition for searching a buffer for dynamic abbreviation expansions.
@@ -36,25 +39,27 @@ addition to the current buffer and the visible buffers.")
   "Return dynamic expansions for ABBREV sorted by proximity to ANCHOR."
   (let* ((abbrev (or abbrev (thing-at-point 'symbol)))
          (anchor (or anchor (car (bounds-of-thing-at-point 'symbol))))
-         (found 0) expansions more
+         (scanned 0) pos expansions more
          (search
           (lambda (buffer)
-            (when (< found dabbrev-maximum-expansions)
+            (when (< scanned dabbrev-maximum-characters)
               (with-current-buffer buffer
                 (save-excursion
                   (goto-char (point-min))
-                  (while (and (< found dabbrev-maximum-expansions)
+                  (setq pos (point))
+                  (while (and (< scanned dabbrev-maximum-characters)
                               (re-search-forward
                                (rx symbol-start
                                    (literal abbrev)
                                    (one-or-more (or (syntax word) (syntax symbol))))
                                nil t))
+                    (setq scanned (+ (- (point) pos))
+                          pos (point))
                     (let ((match (match-string-no-properties 0)))
                       (unless (or (equal match abbrev)
                                   (member match more)
                                   (member match expansions))
-                        (push match more)
-                        (setq found (1+ found)))))))))))
+                        (push match more))))))))))
     (when (and abbrev anchor)
       ;; Search the current buffer.
       (save-excursion
@@ -71,13 +76,13 @@ addition to the current buffer and the visible buffers.")
       (setq expansions (take dabbrev-maximum-expansions
                              (delete-consecutive-dups
                               (mapcar #'cdr (sort expansions :in-place t))))
-            found (length expansions))
+            scanned (- (point-max) (point-min)))
       ;; Then all visible buffers.
-      (when (< found dabbrev-maximum-expansions)
+      (when (< scanned dabbrev-maximum-characters)
         (walk-windows (compf [search] window-buffer) nil 'visible)
         (setq expansions (nconc expansions more) more nil))
       ;; Then try other buffers.
-      (when (< found dabbrev-maximum-expansions)
+      (when (< scanned dabbrev-maximum-characters)
         (mapc search (match-buffers dabbrev-buffer-search-condition))
         (setq expansions (nconc expansions more)))
       expansions)))
@@ -88,7 +93,7 @@ addition to the current buffer and the visible buffers.")
   (when-let ((bounds (bounds-of-thing-at-point 'symbol)))
     (list (car bounds) (cdr bounds)
           (completion-table-with-metadata
-           (completion-table-dynamic #'dabbrev-expansions)
+           (completion-table-with-cache #'dabbrev-expansions)
            '((sort-function . identity) (category . dabbrev)))
           :exclusive 'no)))