From a7254bbf99d9c9a55c93aae840c9d97598d4ce73 Mon Sep 17 00:00:00 2001 From: Agustin Martin Domingo Date: Thu, 12 Feb 2015 18:38:11 +0100 Subject: [PATCH] Improve string search in `flyspell-word-search-*`. (Bug#16800) * flyspell.el (flyspell-duplicate-distance): Limit default search distance for duplicated words to 40000. (flyspell-word-search-backward, flyspell-word-search-forward): Search as full word with defined casechars, not as substring. Fixes: debbugs:16800 --- lisp/ChangeLog | 9 +++++ lisp/textmodes/flyspell.el | 70 +++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ea428b1de15..6fb752a48a9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,12 @@ +2015-02-12 Agustín Martín Domingo + + Improve string search in `flyspell-word-search-*`. (Bug#16800) + + * flyspell.el (flyspell-duplicate-distance): Limit default search + distance for duplicated words to 40000. + (flyspell-word-search-backward, flyspell-word-search-forward): + Search as full word with defined casechars, not as substring. + 2015-02-10 Juri Linkov Better support for the case of typing RET on the prompt in comint. diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index 66243b42102..cd64a806778 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -92,7 +92,7 @@ downcased before comparing with these exceptions." :version "21.1" :type 'boolean) -(defcustom flyspell-duplicate-distance -1 +(defcustom flyspell-duplicate-distance 400000 "The maximum distance for finding duplicates of unrecognized words. This applies to the feature that when a word is not found in the dictionary, if the same spelling occurs elsewhere in the buffer, @@ -1010,17 +1010,33 @@ Mostly we check word delimiters." ;;*---------------------------------------------------------------------*/ (defun flyspell-word-search-backward (word bound &optional ignore-case) (save-excursion - (let ((r '()) - (inhibit-point-motion-hooks t) - p) - (while (and (not r) (setq p (search-backward word bound t))) - (let ((lw (flyspell-get-word))) - (if (and (consp lw) - (if ignore-case - (string-equal (downcase (car lw)) (downcase word)) - (string-equal (car lw) word))) - (setq r p) - (goto-char p)))) + (let* ((r '()) + (inhibit-point-motion-hooks t) + (flyspell-not-casechars (flyspell-get-not-casechars)) + (bound (if (and bound + (> bound (point-min))) + (- bound 1))) + (word-re (concat + "\\(?:" flyspell-not-casechars "\\|\\`\\)" + (regexp-quote word) + flyspell-not-casechars)) + p) + (while + (and (not r) + (setq p + (and + (re-search-backward word-re bound t) + (if (bobp) + (point) + (forward-char) + (point))))) + (let ((lw (flyspell-get-word))) + (if (and (consp lw) + (if ignore-case + (string-equal (downcase (car lw)) (downcase word)) + (string-equal (car lw) word))) + (setq r p) + (goto-char p)))) r))) ;;*---------------------------------------------------------------------*/ @@ -1028,14 +1044,28 @@ Mostly we check word delimiters." ;;*---------------------------------------------------------------------*/ (defun flyspell-word-search-forward (word bound) (save-excursion - (let ((r '()) - (inhibit-point-motion-hooks t) - p) - (while (and (not r) (setq p (search-forward word bound t))) - (let ((lw (flyspell-get-word))) - (if (and (consp lw) (string-equal (car lw) word)) - (setq r p) - (goto-char (1+ p))))) + (let* ((r '()) + (inhibit-point-motion-hooks t) + (flyspell-not-casechars (flyspell-get-not-casechars)) + (bound (if (and bound + (< bound (point-max))) + (+ bound 1))) + (word-re (concat flyspell-not-casechars + (regexp-quote word) + "\\(?:" flyspell-not-casechars "\\|\\'\\)")) + p) + (while + (and (not r) + (setq p (and + (re-search-forward word-re bound t) + (if (eobp) + (point) + (backward-char) + (point))))) + (let ((lw (flyspell-get-word))) + (if (and (consp lw) (string-equal (car lw) word)) + (setq r p) + (goto-char (1+ p))))) r))) ;;*---------------------------------------------------------------------*/ -- 2.39.2