emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Overlay count for isearch


From: Augusto Stoffel
Subject: Re: Overlay count for isearch
Date: Wed, 16 Mar 2022 13:00:02 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.91 (gnu/linux)

Hi Jay,

when the patch proposed for bug#53126 is merged, a new
`lazy-count-update-hook' will be available.  I think you can probably
simplify your implementation by using it.

On Wed, 16 Mar 2022 at 21:37, Jai Flack <jflack@disroot.org> wrote:

> From d3a741f1b782b31f0ba62b5b173b84fbfddf677c Mon Sep 17 00:00:00 2001
> From: Jai Flack <jflack@disroot.org>
> Date: Wed, 16 Mar 2022 20:38:05 +1000
> Subject: [PATCH] New setting for an in-buffer display of isearch match numbers
>
> Exposes this behaviour through 'isearch-lazy-count-at-match' and
> 'isearch-lazy-count-at-match-format'. It relies on
> 'isearch-lazy-count' and 'isearch-lazy-highlight' behaviour for
> counting.
>
> * lisp/isearch.el (isearch-lazy-count-at-match): New variable
> (lazy-count-at-match): New face
> (isearch-show-lazy-count-at-match-format): New variable
> (isearch-done): Call 'isearch-show-lazy-count-at-match-cleanup' when
> appropriate
> (isearch-message): Call 'isearch-show-lazy-count-at-match' when
> appropriate
> (isearch-message-prefix): Update call to 'isearch-lazy-count-format'
> (isearch-message-suffix): Update call to 'isearch-lazy-count-format'
> (isearch-lazy-count-format): Now accepts format strings instead of
> SUFFIX-P
> (isearch-lazy-count-at-match-overlay): New variable
> (isearch-show-lazy-count-at-match): New function
> (isearch-show-lazy-count-at-match-cleanup): New function
> * doc/emacs/search.texi (Search Customizations): Document the
> behaviour
> ---
>  doc/emacs/search.texi |  10 +++
>  etc/NEWS              |   7 +++
>  lisp/isearch.el       | 138 +++++++++++++++++++++++++++++++-----------
>  3 files changed, 119 insertions(+), 36 deletions(-)
>
> diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
> index f2d82324e9..9994e45535 100644
> --- a/doc/emacs/search.texi
> +++ b/doc/emacs/search.texi
> @@ -2128,6 +2128,16 @@ Search Customizations
>  @vindex lazy-count-suffix-format
>  These two variables determine the format of showing the current and
>  the total number of matches for @code{isearch-lazy-count}.
> +
> +@item isearch-lazy-count-at-match
> +@vindex isearch-lazy-count-at-match
> +Show the current match number and total number of matches just after
> +the currently matched line.
> +
> +@item lazy-count-at-match-format
> +@vindex lazy-count-at-match-format
> +Determines the format for showing the current and the total number of
> +matches for @code{isearch-lazy-count-at-match}.
>  @end table
>  
>  @vindex search-nonincremental-instead
> diff --git a/etc/NEWS b/etc/NEWS
> index f4d8756950..292526d272 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -579,6 +579,13 @@ command accepts the Unicode name of an Emoji (for 
> example, "smiling
>  face" or "heart with arrow"), like 'C-x 8 e e', with minibuffer
>  completion, and adds the Emoji into the search string.
>  
> ++++
> +*** New user options 'isearch-lazy-count-at-match'
> +When non-nil, shows the current match numbers just after the current
> +matches line. Format can be controlled with
> +'isearch-lazy-count-at-match-format'. Requires 'isearch-lazy-count'
> +and 'isearch-lazy-highlight' to be non-nil in order to work.
> +
>  ** New minor mode 'glyphless-display-mode'.
>  This allows an easy way to toggle seeing all glyphless characters in
>  the current buffer.
> diff --git a/lisp/isearch.el b/lisp/isearch.el
> index 8970216398..8abbc56275 100644
> --- a/lisp/isearch.el
> +++ b/lisp/isearch.el
> @@ -362,6 +362,16 @@ isearch-lazy-count
>    :group 'isearch
>    :version "27.1")
>  
> +(defcustom isearch-lazy-count-at-match nil
> +  "Show match numbers near the current matched search.
> +When this option, `isearch-lazy-count' and
> +`isearch-lazy-highlight' are non-nil, show the match numbers (see
> +`isearch-lazy-count') at the end of the current matches line."
> +  :type 'boolean
> +  :group 'lazy-count
> +  :group 'isearch
> +  :version "29.1")
> +
>  ;;; Lazy highlight customization.
>  
>  (defgroup lazy-highlight nil
> @@ -465,6 +475,23 @@ lazy-count-suffix-format
>    :group 'lazy-count
>    :version "27.1")
>  
> +;;; Lazy count at match customization.
> +
> +(defface lazy-count-at-match
> +  '((t (:inherit isearch)))
> +  "Face for the lazy count shown at current match."
> +  :group 'lazy-count)
> +
> +(defcustom isearch-lazy-count-at-match-format " %s/%s"
> +  "Format of the current/total number of matches for the in-buffer
> +display.
> +
> +See `isearch-lazy-count-at-match'."
> +  :type 'boolean
> +  :group 'lazy-count
> +  :group 'isearch
> +  :version "29.1")
> +
>  
>  ;; Define isearch help map.
>  
> @@ -1431,6 +1458,8 @@ isearch-done
>    (setq minibuffer-message-timeout 
> isearch-original-minibuffer-message-timeout)
>    (isearch-dehighlight)
>    (lazy-highlight-cleanup lazy-highlight-cleanup)
> +  (when isearch-lazy-count-at-match
> +    (isearch-show-lazy-count-at-match-cleanup))
>    (setq isearch-lazy-highlight-last-string nil)
>    (let ((found-start (window-group-start))
>       (found-point (point)))
> @@ -3386,7 +3415,10 @@ isearch-message
>            (isearch-message-prefix ellipsis isearch-nonincremental)
>            m
>            (isearch-message-suffix c-q-hack)))
> -    (if c-q-hack m (let ((message-log-max nil)) (message "%s" m)))))
> +    (if c-q-hack m (let ((message-log-max nil)) (message "%s" m))))
> +  ;; Update the in-buffer count too
> +  (when isearch-lazy-count-at-match
> +    (isearch-show-lazy-count-at-match)))
>  
>  (defun isearch--describe-regexp-mode (regexp-function &optional space-before)
>    "Make a string for describing REGEXP-FUNCTION.
> @@ -3477,41 +3509,39 @@ isearch-message-prefix
>                       (concat " [" current-input-method-title "]: "))
>                    ": ")
>                  )))
> -    (apply #'propertize (concat (isearch-lazy-count-format)
> +    (apply #'propertize (concat (isearch-lazy-count-format 
> lazy-count-prefix-format)
>                          (upcase (substring m 0 1)) (substring m 1))
>          isearch-message-properties)))
>  
>  (defun isearch-message-suffix (&optional c-q-hack)
>    (apply #'propertize (concat (if c-q-hack "^Q" "")
> -                   (isearch-lazy-count-format 'suffix)
> +                           (isearch-lazy-count-format 
> lazy-count-suffix-format)
>                     (if isearch-error
>                         (concat " [" isearch-error "]")
>                       "")
>                     (or isearch-message-suffix-add ""))
>        isearch-message-properties))
>  
> -(defun isearch-lazy-count-format (&optional suffix-p)
> -  "Format the current match number and the total number of matches.
> -When SUFFIX-P is non-nil, the returned string is intended for
> -isearch-message-suffix prompt.  Otherwise, for isearch-message-prefix."
> -  (let ((format-string (if suffix-p
> -                           lazy-count-suffix-format
> -                         lazy-count-prefix-format)))
> -    (if (and format-string
> -             isearch-lazy-count
> -             isearch-lazy-count-current
> -             (not isearch-error)
> -             (not isearch-suspended))
> -        (format format-string
> -                (if isearch-lazy-highlight-forward
> -                    isearch-lazy-count-current
> -                  (if (eq isearch-lazy-count-current 0)
> -                      0
> -                    (- isearch-lazy-count-total
> -                       isearch-lazy-count-current
> -                       -1)))
> -                (or isearch-lazy-count-total "?"))
> -      "")))
> +(defun isearch-lazy-count-format (format-string)
> +  "Format the current match number and the total number of matches
> +using FORMAT-STRING. It is given two integer substitutions, the
> +first is the current match number and second the total number of
> +matches."
> +  (if (and format-string
> +           isearch-lazy-count
> +           isearch-lazy-count-current
> +           (not isearch-error)
> +           (not isearch-suspended))
> +      (format format-string
> +              (if isearch-lazy-highlight-forward
> +                  isearch-lazy-count-current
> +                (if (eq isearch-lazy-count-current 0)
> +                    0
> +                  (- isearch-lazy-count-total
> +                     isearch-lazy-count-current
> +                     -1)))
> +              (or isearch-lazy-count-total "?"))
> +    ""))
>  
>  
>  ;; Searching
> @@ -3990,6 +4020,7 @@ isearch-lazy-highlight-error
>  (defvar isearch-lazy-count-current nil)
>  (defvar isearch-lazy-count-total nil)
>  (defvar isearch-lazy-count-hash (make-hash-table))
> +(defvar isearch-lazy-count-at-match-overlay nil)
>  
>  (defun lazy-highlight-cleanup (&optional force procrastinate)
>    "Stop lazy highlighting and remove extra highlighting from current buffer.
> @@ -4325,17 +4356,52 @@ isearch-lazy-highlight-buffer-update
>               ;; not found or zero-length match at the search bound
>               (if (not found)
>                   (setq looping nil
> -                       nomore  t))))
> -         (if nomore
> -             (when (and isearch-lazy-count isearch-mode (null 
> isearch-message-function))
> -               (unless isearch-lazy-count-total
> -                 (setq isearch-lazy-count-total 0))
> -               (setq isearch-lazy-count-current
> -                     (gethash opoint isearch-lazy-count-hash 0))
> -               (isearch-message))
> -           (setq isearch-lazy-highlight-timer
> -                 (run-at-time lazy-highlight-interval nil
> -                              'isearch-lazy-highlight-buffer-update)))))))))
> +                       nomore  t))))))
> +     (if nomore
> +         (when (and isearch-lazy-count isearch-mode (null 
> isearch-message-function))
> +           (unless isearch-lazy-count-total
> +             (setq isearch-lazy-count-total 0))
> +           (setq isearch-lazy-count-current
> +                 (gethash opoint isearch-lazy-count-hash 0))
> +           (isearch-message))
> +       (setq isearch-lazy-highlight-timer
> +             (run-at-time lazy-highlight-interval nil
> +                          'isearch-lazy-highlight-buffer-update)))))))
> +
> +(defun isearch-show-lazy-count-at-match ()
> +  "Show the match count just after the end of the currently matched
> +line."
> +  ;; We try to reuse the overlay as much as possible to remove
> +  ;; flickering
> +  (unless isearch-lazy-count-at-match-overlay
> +    (let ((ov (make-overlay 0 0)))
> +      (setq isearch-lazy-count-at-match-overlay ov)
> +      ;; see isearch-lazy-highlight-match
> +      (overlay-put ov 'priority 1001)
> +      (overlay-put ov 'face 'lazy-count-at-match)
> +      (unless isearch-lazy-highlight-buffer
> +        (overlay-put ov 'window (selected-window)))))
> +
> +  (let ((ov isearch-lazy-count-at-match-overlay)
> +        (pae (point-at-eol))
> +        (count (propertize (isearch-lazy-count-format
> +                            isearch-lazy-count-at-match-format)
> +                           'cursor t)))
> +    (unless (and (= (overlay-end ov)
> +                    pae)
> +                 (eq (overlay-buffer ov)
> +                     (current-buffer)))
> +      (move-overlay ov pae pae (current-buffer)))
> +    (unless (string= (overlay-get ov 'after-string)
> +                     count)
> +      (overlay-put ov 'after-string count))))
> +
> +(defun isearch-show-lazy-count-at-match-cleanup ()
> +  "Remove the search count used by
> +\\[isearch-show-lazy-count-at-match]."
> +  (when isearch-lazy-count-at-match-overlay
> +    (delete-overlay isearch-lazy-count-at-match-overlay)
> +    (setq isearch-lazy-count-at-match-overlay nil)))
>  
>  (defun isearch-resume (string regexp word forward message case-fold)
>    "Resume an incremental search.
> -- 
> 2.30.2
>
>
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> If it's not for everyone, then it should arguably be provided under the
>> control of the config var, but that doesn't mean it should be in
>> a separate package or relegated to some ELisp snippets for people to
>> copy&paste into their init file.
>>
>> Whether it better belongs alongside `isearch` or `isearch-mb` will
>> probably depend on details of how it's implemented.
>
> Here's a patch providing just that for isearch. It could be added to
> isearch-mb almost just as easily though it has nothing to do with search
> entry.
>
> With regards to an isearch-mb wiki "trick": the same result could be
> achieved using `isearch-mode-end-hook` and :after advice on
> `isearch-message`.
>
> Whether it becomes a part of isearch or not some feedback would be
> appreciated (;
>
> 1. Is it right to modify `isearch-lazy-count-format` in this way to
> reduce code in `isearch-show-lazy-count-at-match`?
>
> 2. Is it right to add a new face for this and if so does this need to be
> included in NEWS or other documentation?
>
> 3. Should it be extended to allow for custom positioning of the overlay?
> Perhaps with a variable like `isearch-lazy-count-at-match-pos-function`?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]