Subject: bug#25243: 26.0.50; ffap-guesser very slow w/ region active in large diff files

From: Tino Calancha <[email-masked]>
Date: Thu, 22 Dec 2016 00:35:59 +0900

The slowness is apparent for diff files with > 2 klines.

emacs -Q -l ffap
;; From emacs git rep. extract a diff w/ 10 klines.
M-! git diff HEAD~200 | head -10000 > /tmp/test-Bug25243
M-: (find-file "/tmp/test-Bug25243")
C-x h
M-: (ffap-guesser)
;; It took > 2 min in my box.

In this example `ffap-guesser' is spending long time testing the
whole buffer content as a file name candidate.  It might has
sense to introduce a maximum limit in the length for file names
in `ffap-file-at-point'.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>From 9e919ba3c86a912bc42cb8e439ad7b8b3660dc37 Mon Sep 17 00:00:00 2001
From: Tino Calancha <[email-masked]>
Date: Thu, 22 Dec 2016 00:27:50 +0900
Subject: [PATCH] ffap-file-at-point: Limit length of file names

Do not spend time checking large strings which are
likely not actual file names (Bug#25243).
* lisp/ffap.el (ffap-file-name-max-length): New option.
(ffap-file-at-point): Use it.
; etc/NEWS: Add entry for the new option.
---
 etc/NEWS     |  4 ++++
 lisp/ffap.el | 12 +++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index 7338c0c6a7..fd89568c6e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -312,6 +312,10 @@ the file's actual content before prompting the user.
 
 * Changes in Specialized Modes and Packages in Emacs 26.1
 
+** ffap
+
+*** A new user option 'ffap-file-name-max-length'.
+
 ** Electric-Buffer-menu
 
 +++
diff --git a/lisp/ffap.el b/lisp/ffap.el
index 3d7cebadcf..1df30e4516 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -292,6 +292,13 @@ dired-at-point-require-prefix
   :group 'ffap
   :version "20.3")
 
+(defcustom ffap-file-name-max-length 1024
+  "Maximum length allowed for file names in `ffap-file-at-point'."
+  :type '(choice (const :tag "Unlimited" nil)
+                 (integer :tag "File Name Max Length" 1024))
+  :group 'ffap
+  :version "26.1")
+
 
 ;;; Compatibility:
 ;;
@@ -1244,6 +1251,9 @@ ffap-file-at-point
 	 (abs (file-name-absolute-p name))
 	 (default-directory default-directory)
          (oname name))
+    ;; When oname is very large is likely not a file name.
+    (when (or (null ffap-file-name-max-length)
+              (< (length oname) ffap-file-name-max-length))
     (unwind-protect
 	(cond
 	 ;; Immediate rejects (/ and // and /* are too common in C/C++):
@@ -1334,7 +1344,7 @@ ffap-file-at-point
             (and (not (string= dir "/"))
 		 (ffap-file-exists-string dir))))
 	 )
-      (set-match-data data))))
+      (set-match-data data)))))
 
 ;;; Prompting (`ffap-read-file-or-url'):
 ;;
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.4)
 of 2016-12-21
Repository revision: 8661313efd5fd5b0a27fe82f276a1ff862646424