From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Jai Flack Newsgroups: gmane.emacs.devel Subject: Overlay count for isearch (Was: [NonGNU] New package: ctrlf and Questions) Date: Wed, 16 Mar 2022 21:37:03 +1000 Message-ID: <87czim3z8g.fsf_-_@disroot.org> References: <9631587bddf2ab3b07b60bd4195cc3e1@disroot.org> <87r17tmnzc.fsf@gmail.com> <8735k9jrr2.fsf@posteo.net> <87mtihmh8t.fsf@gmail.com> <87tucoblfh.fsf@disroot.org> <878rtxdh6a.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="17697"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Augusto Stoffel , Philip Kaludercic , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Mar 16 13:10:49 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nUSUK-0004Q8-Qt for ged-emacs-devel@m.gmane-mx.org; Wed, 16 Mar 2022 13:10:48 +0100 Original-Received: from localhost ([::1]:59862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nUSUJ-00058W-Mk for ged-emacs-devel@m.gmane-mx.org; Wed, 16 Mar 2022 08:10:47 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:40878) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nURxs-0002kn-AA for emacs-devel@gnu.org; Wed, 16 Mar 2022 07:37:16 -0400 Original-Received: from knopi.disroot.org ([178.21.23.139]:54688) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nURxp-0000o7-B5 for emacs-devel@gnu.org; Wed, 16 Mar 2022 07:37:15 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by disroot.org (Postfix) with ESMTP id 6F3284006D; Wed, 16 Mar 2022 12:37:10 +0100 (CET) X-Virus-Scanned: SPAM Filter at disroot.org Original-Received: from knopi.disroot.org ([127.0.0.1]) by localhost (disroot.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FZP3KqAqQgZn; Wed, 16 Mar 2022 12:37:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1647430628; bh=2iBakQ4KTCs9bKfIzoFPVt/UUkr77XV0CugKoalFDBk=; h=From:To:Cc:Subject:References:Date:In-Reply-To; b=Gt5K5bX3V+MZPXvF7pb9+Z8soM42R+T95aj3eZtF8g0kE9CDGy5YeeZR5ZUY78m/C g30fwnk5g7vY4EubPzi65xMuCDF4vBsIfPl92PTnLwSn7zAeV9RrFgDnUrEcRmMhxM UDdBNTP08juWstDlpq8bi+oQPsADMi6Hner+qRO5+RNPxSd6NQ1djBFJu9NLE0/nXd HnfSHDe7bqhrnrmB1LvcAHxcbJ0sMukKzZBf2ceXvNDIZLkFSV9zDoxpv0dDzSIkXC KCrKSbPjvhl7Ll9WiBc6BtAn8Z0shgsaLjgASKEHwp1u7BRmu6VGcTChTownNH13IB wUgcwy9ZLkP8Q== In-Reply-To: (Stefan Monnier's message of "Sat, 26 Feb 2022 23:02:02 -0500") Received-SPF: pass client-ip=178.21.23.139; envelope-from=jflack@disroot.org; helo=knopi.disroot.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 16 Mar 2022 08:07:33 -0400 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:287217 Archived-At: --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-New-setting-for-an-in-buffer-display-of-isearch-matc.patch >From d3a741f1b782b31f0ba62b5b173b84fbfddf677c Mon Sep 17 00:00:00 2001 From: Jai Flack 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 --=-=-= Content-Type: text/plain Stefan Monnier 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`? -- Thanks, Jai --=-=-=--