From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: Thierry Volpiatto <thievol@posteo.net>
Newsgroups: gmane.emacs.bugs
Subject: bug#66394: 29.1; Make register-read-with-preview more useful
Date: Mon, 20 Nov 2023 06:00:26 +0000
Message-ID: <877cmdx8ud.fsf@posteo.net>
References: <87il7ib6cu.fsf@posteo.net> <87sf67qqmp.fsf@web.de>
 <875y3386ep.fsf@posteo.net> <87a5sddh14.fsf@web.de>
 <8734y5vnj7.fsf@posteo.net> <87bkcslr18.fsf@web.de>
 <87y1fwtyrl.fsf@posteo.net> <87y1fut1wp.fsf@web.de>
 <87ttqgpjiz.fsf@posteo.net> <87wmvbibpr.fsf@web.de>
 <877cnb2n63.fsf@posteo.net> <8734xyc8z0.fsf@web.de>
 <87zg05rewi.fsf@posteo.net> <87ttqcg8gw.fsf@web.de>
 <87h6mcr8ol.fsf@posteo.net> <87r0l73029.fsf@web.de>
Mime-Version: 1.0
Content-Type: multipart/signed; boundary="==-=-=";
 micalg=pgp-sha512; protocol="application/pgp-signature"
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="38447"; mail-complaints-to="usenet@ciao.gmane.io"
Cc: stefankangas@gmail.com, monnier@iro.umontreal.ca, 66394@debbugs.gnu.org
To: Michael Heerdegen <michael_heerdegen@web.de>
Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Nov 20 07:01:11 2023
Return-path: <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>
Envelope-to: geb-bug-gnu-emacs@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 <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>)
	id 1r4xLL-0009pR-Jr
	for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 20 Nov 2023 07:01:11 +0100
Original-Received: from localhost ([::1] helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <bug-gnu-emacs-bounces@gnu.org>)
	id 1r4xLE-00043m-F0; Mon, 20 Nov 2023 01:01:04 -0500
Original-Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1r4xLA-000433-H8
 for bug-gnu-emacs@gnu.org; Mon, 20 Nov 2023 01:01:01 -0500
Original-Received: from debbugs.gnu.org ([2001:470:142:5::43])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1r4xLA-0007rZ-7n
 for bug-gnu-emacs@gnu.org; Mon, 20 Nov 2023 01:01:00 -0500
Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2)
 (envelope-from <Debian-debbugs@debbugs.gnu.org>) id 1r4xLB-0006lu-Ne
 for bug-gnu-emacs@gnu.org; Mon, 20 Nov 2023 01:01:01 -0500
X-Loop: help-debbugs@gnu.org
Resent-From: Thierry Volpiatto <thievol@posteo.net>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces@debbugs.gnu.org>
Resent-CC: bug-gnu-emacs@gnu.org
Resent-Date: Mon, 20 Nov 2023 06:01:01 +0000
Resent-Message-ID: <handler.66394.B66394.170046005326009@debbugs.gnu.org>
Resent-Sender: help-debbugs@gnu.org
X-GNU-PR-Message: followup 66394
X-GNU-PR-Package: emacs
Original-Received: via spool by 66394-submit@debbugs.gnu.org id=B66394.170046005326009
 (code B ref 66394); Mon, 20 Nov 2023 06:01:01 +0000
Original-Received: (at 66394) by debbugs.gnu.org; 20 Nov 2023 06:00:53 +0000
Original-Received: from localhost ([127.0.0.1]:52393 helo=debbugs.gnu.org)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <debbugs-submit-bounces@debbugs.gnu.org>)
 id 1r4xL2-0006lQ-Nb
 for submit@debbugs.gnu.org; Mon, 20 Nov 2023 01:00:53 -0500
Original-Received: from mout01.posteo.de ([185.67.36.65]:37477)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <thievol@posteo.net>) id 1r4xKx-0006l8-7c
 for 66394@debbugs.gnu.org; Mon, 20 Nov 2023 01:00:51 -0500
Original-Received: from submission (posteo.de [185.67.36.169]) 
 by mout01.posteo.de (Postfix) with ESMTPS id 61B6F240027
 for <66394@debbugs.gnu.org>; Mon, 20 Nov 2023 07:00:38 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017;
 t=1700460038; bh=aHA4aV0NNXeHz+aJhEM9SVCVz9p6l464DBekTcZ4gek=;
 h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Autocrypt:OpenPGP:
 From;
 b=bVKw+EiB4t2NUDLEvskTWyh2evHsQ3kmVV/+UHOEYAc3Je39B66ULVLTZIK3SP6jb
 0hralYiDv9W++1SPsSrBSE61xr2OSx3aLDy5wRhKzFvNiEkku6+cjyVMc7M+zCw/ZB
 qsEI8vzY/1HsESk2L/pVLWegeEs2WcXaWwKH6yTcjs/LR+jyATEwvnWGiEAX4EUNgc
 eQNTNrTK4N7FdubVnYFxV+wTK2RMEvCeLGppEjOSc31eiKxelPFILa0A23Vaffw14U
 q+zOyLeJL0C613YQzrB5+cVdQxyDw4Zat6JSg5lZrVRQutRjsfkMiuzqJXJbbGvEPJ
 GWU8Upa7mswbw==
Original-Received: from customer (localhost [127.0.0.1])
 by submission (posteo.de) with ESMTPSA id 4SYcLV6CR0z6tw6;
 Mon, 20 Nov 2023 07:00:34 +0100 (CET)
In-Reply-To: <87r0l73029.fsf@web.de> (Michael Heerdegen's message of "Fri, 03
 Nov 2023 05:58:22 +0100")
Autocrypt: addr=thievol@posteo.net; prefer-encrypt=mutual;
 keydata=xsDNBF8ylcIBDADG+hy+zR6L4/vbdDDZuSaMmSrU3A5QZJpeBCvxTr7MpzzruZbhLPW1K3R6N2MA
 edi8Y+C8o27FVRIjpdbaKMGu9je7JV/TbUQYo3SOwCK1vM4LUn4V6ZLzSYkuiEt4eyMoiDdyvN0p
 kcK6P9x9DCetcEVszXzQg+yzCVrQ2hXWDXWT4M18EC3wtO7RHPouMqGiwBFhBAYErCqFWFxQHkfb
 tG/4yGyJ58rglb65O3qijjMWvYwcWZun9/7qm8Z4/4mHopmo2zgU+OrptnLSZfkZGz3Y7Uf452xQ
 GVq0Fv75NPvQru7y+DYVhuVXXyAmGxt+vf4rIiixMBbhKEPjcxEPAa2LTzex2IsTZR+QVG9uDnqC
 WcgaOEQ58fzXNvNhtwwF/Rgio2XWAJVdmFWS59/k9W58CIUSNKBMZh2XeGdEmtHvDtCxW3z6FJha
 36RzOM3fMNNiAGdFZJA84gcdloJR+sHCDTTPT3784fjr+V8An7sI581NGFzkRQqPvEQCZbUAEQEA
 Ac0SdGhpZXZvbEBwb3N0ZW8ubmV0wsEOBBMBCgA4AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA
 FiEEI9twfRN7r3nig/xwDsVtFB0W75MFAmL3HCoACgkQDsVtFB0W75OVEAv/f6XxmtIFz08fUb8h
 Bp/zJP6IC4/rhhh+0GMRIRzLN8DK0jV8JCzYdFHiRJOy2lNIOpmrrCmjRRxferc2G42+ePFIsslx
 hU46VSz1Z83NwIG3mpdYNV5WUTUdgzxExHTNTFCd7NKv0nlHKQaA 
OpenPGP: url=https://posteo.de/keys/thievol@posteo.net.asc; preference=encrypt
X-BeenThere: debbugs-submit@debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
X-BeenThere: bug-gnu-emacs@gnu.org
List-Id: "Bug reports for GNU Emacs,
 the Swiss army knife of text editors" <bug-gnu-emacs.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/bug-gnu-emacs>
List-Post: <mailto:bug-gnu-emacs@gnu.org>
List-Help: <mailto:bug-gnu-emacs-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=subscribe>
Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org
Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org
Xref: news.gmane.io gmane.emacs.bugs:274649
Archived-At: <http://permalink.gmane.org/gmane.emacs.bugs/274649>

--==-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Type: text/plain


Here the full patch attached, the previous was not applying properly.

Ccing also Stefan monnier because for some reasons the patch when
applied doesn't compile (when compiling Emacs) unless we add on
top:

    (cl--generic-prefill-dispatchers 0 (eql 'x) integer)

following the advice of the compiler, but I am not sure it is the way to
do.

Compiling register.el manually without this works correctly.


--=-=-=
Content-Type: text/x-diff
Content-Disposition: attachment;
 filename=0001-Improve-register-preview-Fix-bug-66394.patch
Content-Transfer-Encoding: quoted-printable
Content-Description: register-preview

From=20c794d62a45b4c83131e506699f465e54b7dae7b5 Mon Sep 17 00:00:00 2001
From: Thierry Volpiatto <thievol@posteo.net>
Date: Sun, 19 Nov 2023 20:42:56 +0100
Subject: [PATCH] Improve register-preview (Fix bug#66394)

A minibuffer is used now instead of read-key.
Registers in preview buffer are now filtered according to type of
registers the current command requires.
Navigation with C-n/p or up/down is now provided and update
minibuffer.
Current register is highlighted in preview buffer.

* register.el:

* (register-preview-default-keys): new user var.
* (register-use-preview): Same.
* (register-preview-info): New structure to store various info for
  preview.
* (register-command-info): New generic.
* (register-preview-forward-line): New, provide navigation in preview
  buffer.
* (register-preview-next, register-preview-previous): New, navigation.
* (register-type): New, returns register type.
* (register--type): Generic fn, new, returns register type according
  to value.
* (register-of-type-alist): New, filter register-alist according to
  type.
* (register-preview): Signature changed, use TYPES now.
* (register-preview-get-defaults): New generic, compute defauts
  according to action.
* (register-read-with-preview): Now use read-from-minibuffer and
  minibuffer-setup-hook.
=2D--
 lisp/register.el | 296 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 259 insertions(+), 37 deletions(-)

diff --git a/lisp/register.el b/lisp/register.el
index ca6de450993..47f0dfa389c 100644
=2D-- a/lisp/register.el
+++ b/lisp/register.el
@@ -30,11 +30,14 @@
 ;; documented in the Emacs user's manual: (info "(emacs) Registers").
=20
 (eval-when-compile (require 'cl-lib))
+(cl--generic-prefill-dispatchers 0 (eql 'x) integer)
=20
 ;;; Code:
=20
 ;; FIXME: Clean up namespace usage!
=20
+(declare-function frameset-register-p "frameset")
+
 (cl-defstruct
   (registerv (:constructor nil)
 	     (:constructor registerv--make (&optional data print-func
@@ -91,6 +94,7 @@ of the marked text."
   :type '(choice (const :tag "None" nil)
 		 (character :tag "Use register" :value ?+)))
=20
+;; FIXME: This is no more needed, remove it.
 (defcustom register-preview-delay 1
   "If non-nil, time to wait in seconds before popping up register preview =
window.
 If nil, do not show register previews, unless `help-char' (or a member of
@@ -99,6 +103,14 @@ If nil, do not show register previews, unless `help-cha=
r' (or a member of
   :type '(choice number (const :tag "No preview unless requested" nil))
   :group 'register)
=20
+(defcustom register-preview-default-keys (mapcar #'string (number-sequence=
 ?a ?z))
+  "Default keys for setting a new register."
+  :type '(repeat string))
+
+(defcustom register-use-preview t
+  "Always show register preview when non nil."
+  :type 'boolean)
+
 (defun get-register (register)
   "Return contents of Emacs register named REGISTER, or nil if none."
   (alist-get register register-alist))
@@ -128,53 +140,263 @@ See the documentation of the variable `register-alis=
t' for possible VALUEs."
 Called with one argument, a cons (NAME . CONTENTS) as found in `register-a=
list'.
 The function should return a string, the description of the argument.")
=20
=2D(defun register-preview (buffer &optional show-empty)
+(cl-defstruct register-preview-info
+  "Store data for a specific register command.
+TYPES are the types of register supported.
+MSG is the minibuffer message to send when a register is selected.
+ACT is the type of action the command is doing on register.
+SMATCH accept a boolean value to say if command accept non matching regist=
er."
+  types msg act smatch)
+
+(cl-defgeneric register-command-info (command)
+  "Returns a `register-preview-info' object storing data for COMMAND."
+  (ignore command))
+(cl-defmethod register-command-info ((_command (eql insert-register)))
+  (make-register-preview-info
+   :types '(string number)
+   :msg "Insert register `%s'"
+   :act 'insert
+   :smatch t))
+(cl-defmethod register-command-info ((_command (eql jump-to-register)))
+  (make-register-preview-info
+   :types  '(window frame marker kmacro
+             file buffer file-query)
+   :msg "Jump to register `%s'"
+   :act 'jump
+   :smatch t))
+(cl-defmethod register-command-info ((_command (eql view-register)))
+  (make-register-preview-info
+   :types '(all)
+   :msg "View register `%s'"
+   :act 'view
+   :smatch t))
+(cl-defmethod register-command-info ((_command (eql append-to-register)))
+  (make-register-preview-info
+   :types '(string number)
+   :msg "Append to register `%s'"
+   :act 'modify
+   :smatch t))
+(cl-defmethod register-command-info ((_command (eql prepend-to-register)))
+  (make-register-preview-info
+   :types '(string number)
+   :msg "Prepend to register `%s'"
+   :act 'modify
+   :smatch t))
+(cl-defmethod register-command-info ((_command (eql increment-register)))
+  (make-register-preview-info
+   :types '(string number)
+   :msg "Increment register `%s'"
+   :act 'modify
+   :smatch t))
+
+(defun register-preview-forward-line (arg)
+  "Move to next or previous line in register preview buffer.
+If ARG is positive goto next line, if negative to previous.
+Do nothing when defining or executing kmacros."
+  ;; Ensure user enter manually key in minibuffer when recording a macro.
+  (unless (or defining-kbd-macro executing-kbd-macro
+              (not (get-buffer-window "*Register Preview*" 'visible)))
+    (let ((fn (if (> arg 0) #'eobp #'bobp))
+          (posfn (if (> arg 0)
+                     #'point-min
+                     (lambda () (1- (point-max)))))
+          str)
+      (with-current-buffer "*Register Preview*"
+        (let ((ovs (overlays-in (point-min) (point-max)))
+              pos)
+          (goto-char (if ovs
+                         (overlay-start (car ovs))
+                         (point-min)))
+          (setq pos (point))
+          (and ovs (forward-line arg))
+          (when (and (funcall fn)
+                     (or (> arg 0) (eql pos (point))))
+            (goto-char (funcall posfn)))
+          (setq str (buffer-substring-no-properties
+                     (pos-bol) (1+ (pos-bol))))
+          (remove-overlays)
+          (with-selected-window (minibuffer-window)
+            (delete-minibuffer-contents)
+            (insert str)))))))
+
+(defun register-preview-next ()
+  "Goto next line in register preview buffer."
+  (interactive)
+  (register-preview-forward-line 1))
+
+(defun register-preview-previous ()
+  "Goto previous line in register preview buffer."
+  (interactive)
+  (register-preview-forward-line -1))
+
+(defun register-type (register)
+  "Return REGISTER type.
+Current register types actually returned are one of:
+- string
+- number
+- marker
+- buffer
+- file
+- file-query
+- window
+- frame
+- kmacro
+
+One can add new types to a specific command by defining a new `cl-defmetho=
d'
+matching this command. Predicate for type in new `cl-defmethod' should
+satisfy `cl-typep' otherwise the new type should be defined with
+`cl-deftype'."
+  ;; Call register--type against the register value.
+  (register--type (if (consp (cdr register))
+                     (cadr register)
+                   (cdr register))))
+
+(cl-defgeneric register--type (regval)
+  "Returns type of register value REGVAL."
+  (ignore regval))
+
+(cl-defmethod register--type ((_regval string)) 'string)
+(cl-defmethod register--type ((_regval number)) 'number)
+(cl-defmethod register--type ((_regval marker)) 'marker)
+(cl-defmethod register--type ((_regval (eql 'buffer))) 'buffer)
+(cl-defmethod register--type ((_regval (eql 'file))) 'file)
+(cl-defmethod register--type ((_regval (eql 'file-query))) 'file-query)
+(cl-defmethod register--type ((_regval window-configuration)) 'window)
+(cl-deftype frame-register () '(satisfies frameset-register-p))
+(cl-defmethod register--type :extra "frame-register" (_regval) 'frame)
+(cl-deftype kmacro-register () '(satisfies kmacro-register-p))
+(cl-defmethod register--type :extra "kmacro-register" (_regval) 'kmacro)
+
+(defun register-of-type-alist (types)
+  "Filter `register-alist' according to TYPES."
+  (if (memq 'all types)
+      register-alist
+    (cl-loop for register in register-alist
+             when (memq (register-type register) types)
+             collect register)))
+
+(defun register-preview (buffer &optional show-empty types)
   "Pop up a window showing the registers preview in BUFFER.
 If SHOW-EMPTY is non-nil, show the window even if no registers.
+Argument TYPES (a list) specify the types of register to show, when nil sh=
ow all
+registers, see `register-type' for suitable types.
 Format of each entry is controlled by the variable `register-preview-funct=
ion'."
=2D  (when (or show-empty (consp register-alist))
=2D    (with-current-buffer-window
=2D     buffer
=2D     (cons 'display-buffer-below-selected
=2D	   '((window-height . fit-window-to-buffer)
=2D	     (preserve-size . (nil . t))))
=2D     nil
=2D     (with-current-buffer standard-output
=2D       (setq cursor-in-non-selected-windows nil)
=2D       (mapc (lambda (elem)
=2D               (when (get-register (car elem))
=2D                 (insert (funcall register-preview-function elem))))
=2D             register-alist)))))
+  (let ((registers (register-of-type-alist (or types '(all)))))
+    (when (or show-empty (consp registers))
+      (with-current-buffer-window
+        buffer
+        (cons 'display-buffer-below-selected
+	      '((window-height . fit-window-to-buffer)
+	        (preserve-size . (nil . t))))
+        nil
+        (with-current-buffer standard-output
+          (setq cursor-in-non-selected-windows nil)
+          (mapc (lambda (elem)
+                  (when (get-register (car elem))
+                    (insert (funcall register-preview-function elem))))
+                registers))))))
+
+(cl-defgeneric register-preview-get-defaults (action)
+  "Returns default registers according to ACTION."
+  (ignore action))
+(cl-defmethod register-preview-get-defaults ((_action (eql set)))
+  (cl-loop for s in register-preview-default-keys
+           unless (assoc (string-to-char s) register-alist)
+           collect s))
=20
 (defun register-read-with-preview (prompt)
   "Read and return a register name, possibly showing existing registers.
=2DPrompt with the string PROMPT.  If `register-alist' and
=2D`register-preview-delay' are both non-nil, display a window
=2Dlisting existing registers after `register-preview-delay' seconds.
+Prompt with the string PROMPT.
 If `help-char' (or a member of `help-event-list') is pressed,
 display such a window regardless."
   (let* ((buffer "*Register Preview*")
=2D	 (timer (when (numberp register-preview-delay)
=2D		  (run-with-timer register-preview-delay nil
=2D				  (lambda ()
=2D				    (unless (get-buffer-window buffer)
=2D				      (register-preview buffer))))))
=2D	 (help-chars (cl-loop for c in (cons help-char help-event-list)
=2D			      when (not (get-register c))
=2D			      collect c)))
+         (pat "")
+         (map (let ((m (make-sparse-keymap)))
+                (set-keymap-parent m minibuffer-local-map)
+                m))
+         (data (register-command-info this-command))
+         types msg result timer act win strs smatch)
+    (if data
+        (setq types  (register-preview-info-types data)
+              msg    (register-preview-info-msg   data)
+              act    (register-preview-info-act   data)
+              smatch (register-preview-info-smatch data))
+      (setq types '(all)
+            msg   "Overwrite register `%s'"
+            act   'set))
+    (setq strs (mapcar (lambda (x)
+                         (string (car x)))
+                       (register-of-type-alist types)))
+    (when (and (memq act '(insert jump view)) (null strs))
+      (error "No register suitable for `%s'" act))
+    (dolist (k (cons help-char help-event-list))
+      (define-key map
+          (vector k) (lambda ()
+                       (interactive)
+                       (unless (get-buffer-window buffer)
+                         (with-selected-window (minibuffer-selected-window)
+                           (register-preview buffer 'show-empty types))))))
+    (define-key map (kbd "<down>") 'register-preview-next)
+    (define-key map (kbd "<up>")   'register-preview-previous)
+    (define-key map (kbd "C-n")    'register-preview-next)
+    (define-key map (kbd "C-p")    'register-preview-previous)
+    (unless (or executing-kbd-macro (null register-use-preview))
+      (register-preview buffer nil types))
     (unwind-protect
=2D	(progn
=2D	  (while (memq (read-key (propertize prompt 'face 'minibuffer-prompt))
=2D		       help-chars)
=2D	    (unless (get-buffer-window buffer)
=2D	      (register-preview buffer 'show-empty)))
=2D          (when (or (eq ?\C-g last-input-event)
=2D                    (eq 'escape last-input-event)
=2D                    (eq ?\C-\[ last-input-event))
=2D            (keyboard-quit))
=2D	  (if (characterp last-input-event) last-input-event
=2D	    (error "Non-character input-event")))
=2D      (and (timerp timer) (cancel-timer timer))
+         (progn
+           (minibuffer-with-setup-hook
+               (lambda ()
+                 (setq timer
+                       (run-with-idle-timer
+                        0.01 'repeat
+                        (lambda ()
+                          (with-selected-window (minibuffer-window)
+                            (let ((input (minibuffer-contents)))
+                              (when (> (length input) 1)
+                                (let ((new (substring input 1))
+                                      (old (substring input 0 1)))
+                                  (setq input (if (or (null smatch)
+                                                      (member new strs))
+                                                  new old))
+                                  (delete-minibuffer-contents)
+                                  (insert input)))
+                              (when (and smatch (not (string=3D input ""))
+                                         (not (member input strs)))
+                                (setq input "")
+                                (delete-minibuffer-contents)
+                                (minibuffer-message "Not matching"))
+                              (when (not (string=3D input pat))
+                                (setq pat input))))
+                          (if (setq win (get-buffer-window buffer))
+                              (with-selected-window win
+                                (let ((ov (make-overlay (point-min) (point=
-min))))
+                                  (goto-char (point-min))
+                                  (remove-overlays)
+                                  (unless (string=3D pat "")
+                                    (if (re-search-forward (concat "^" pat=
) nil t)
+                                        (progn (move-overlay
+                                                ov
+                                                (match-beginning 0) (pos-e=
ol))
+                                               (overlay-put ov 'face 'matc=
h)
+                                               (when msg
+                                                 (with-selected-window (mi=
nibuffer-window)
+                                                   (minibuffer-message msg=
 pat))))
+                                      (with-selected-window (minibuffer-wi=
ndow)
+                                        (minibuffer-message
+                                         "Register `%s' is empty" pat))))))
+                            (unless (string=3D pat "")
+                              (if (member pat strs)
+                                  (with-selected-window (minibuffer-window)
+                                    (minibuffer-message msg pat))
+                                (with-selected-window (minibuffer-window)
+                                  (minibuffer-message
+                                   "Register `%s' is empty" pat)))))))))
+             (setq result (read-from-minibuffer
+                           prompt nil map nil nil (register-preview-get-de=
faults act))))
+           (cl-assert (and result (not (string=3D result "")))
+                      nil "No register specified")
+           (string-to-char result))
+      (when timer (cancel-timer timer))
       (let ((w (get-buffer-window buffer)))
         (and (window-live-p w) (delete-window w)))
       (and (get-buffer buffer) (kill-buffer buffer)))))
=2D-=20
2.34.1


--=-=-=
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable


=2D-=20
Thierry

--=-=-=--

--==-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQHHBAEBCgAxFiEEI9twfRN7r3nig/xwDsVtFB0W75MFAmVa9foTHHRoaWV2b2xA
cG9zdGVvLm5ldAAKCRAOxW0UHRbvk1OZC/oD6jAYsGPcAsKKCcp/op/lF9d5jiZd
1NXhqjNkKPOiqR1G0texaerIJdPzZM9DrsEPArLrGGEkziwUA6M1rRxx6RB65cTs
ha1dX+RNV1Ha9wr+bIb5cjbHMu1RdGYBP+R54atJn4JJlNsaSy461mkzpDNnrhC9
tudq0Hev6XusKRJPOoJMzQs6OLbEB8N6vk62ZKGj16awOTdQfvYOJug1LTRIJeBZ
pK9KKOZStHPqxC0UpsM4aiTicqT/xId+pxLI3tFh8Yv+qEM22q5e5QDCSqM8YMb5
Sv4WFs29xtPBRAonjljb3k1D6Ge/U3X6vYa7OLAwyhDmvllOoNDbiMfBrqqhAGka
AjP/vqIdl/59+h2ZLOxV6tCNLtbb0ziXEVFMioDo7waSr9zErxwRO3kkJBOTcAsE
kYr7DhuzftD7Ykaz52DwBQwAA62dfbaUEPFw60/DwYJDmquvDaiq4NKPgBX3wDxr
Kk9g+lGZ8OdrILhNnqG1LO+ls6riMjL9uDg=
=KMSD
-----END PGP SIGNATURE-----
--==-=-=--