all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Juri Linkov <juri@linkov.net>
To: Drew Adams <drew.adams@oracle.com>
Cc: spacibba@aol.com, Jean Louis <bugs@gnu.support>,
	andreyk.mad@gmail.com, emacs-devel@gnu.org, rudalics@gmx.at,
	Stefan Monnier <monnier@iro.umontreal.ca>,
	Gregory Heytings <ghe@sdf.org>, Eli Zaretskii <eliz@gnu.org>
Subject: Re: select yank via completion
Date: Fri, 20 Nov 2020 10:53:39 +0200	[thread overview]
Message-ID: <87o8jsiems.fsf@mail.linkov.net> (raw)
In-Reply-To: <3341c426-3a86-4ef0-a0ca-9102191a925b@default> (Drew Adams's message of "Thu, 19 Nov 2020 09:00:13 -0800 (PST)")

[-- Attachment #1: Type: text/plain, Size: 1096 bytes --]

>> There is still a small problem:
>> sometimes it's handy to slightly edit a previous string
>> from kill-ring before inserting it.  But with completing-read
>> it's not easy to insert the space character, e.g. after 'M-p'
>> while editing, typing 'SPC' errors with "[No matches]"
>> and doesn't insert a space character.
>> 
>> Could you recommend a more lightweight version of 
>> completing-read that doesn't override the 'SPC' key?
>
> It's _always_ handy to be able to edit a kill-ring entry
> before inserting it into the minibuffer.

BTW, sometimes it's also handy to just browse the kill-ring
without immediately inserting an entry, to copy an edited entry
(that adds a new kill-ring entry) to paste later.  To allow
such browsing we need to remove "*" from the interactive spec of
'yank-pop'.

> It took decades to even get `SPC' to be self-inserting for
> `read-file-name'.  I raised the same issue for `completing-read' at
> that time (and before then).

So now a new patch let-binds (minibuffer-completing-file-name t)
around completing-read to allow inserting SPC, problem solved:


[-- Attachment #2: yank-from-kill-ring.patch --]
[-- Type: text/x-diff, Size: 5156 bytes --]

diff --git a/lisp/simple.el b/lisp/simple.el
index bb28145502..589b3648c2 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5360,29 +5360,83 @@ yank-pop
 "This command honors the `yank-handled-properties' and
 `yank-excluded-properties' variables, and the `yank-handler' text
 property, in the way that `yank' does."
-  (interactive "*p")
+  (interactive "p")
   (if (not (eq last-command 'yank))
-      (user-error "Previous command was not a yank"))
-  (setq this-command 'yank)
-  (unless arg (setq arg 1))
-  (let ((inhibit-read-only t)
-	(before (< (point) (mark t))))
-    (if before
-	(funcall (or yank-undo-function 'delete-region) (point) (mark t))
-      (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
-    (setq yank-undo-function nil)
-    (set-marker (mark-marker) (point) (current-buffer))
-    (insert-for-yank (current-kill arg))
-    ;; Set the window start back where it was in the yank command,
-    ;; if possible.
-    (set-window-start (selected-window) yank-window-start t)
-    (if before
-	;; This is like exchange-point-and-mark, but doesn't activate the mark.
-	;; It is cleaner to avoid activation, even though the command
-	;; loop would deactivate the mark because we inserted text.
-	(goto-char (prog1 (mark t)
-		     (set-marker (mark-marker) (point) (current-buffer))))))
-  nil)
+      (call-interactively 'yank-from-kill-ring)
+    (setq this-command 'yank)
+    (unless arg (setq arg 1))
+    (let ((inhibit-read-only t)
+          (before (< (point) (mark t))))
+      (if before
+          (funcall (or yank-undo-function 'delete-region) (point) (mark t))
+        (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
+      (setq yank-undo-function nil)
+      (set-marker (mark-marker) (point) (current-buffer))
+      (insert-for-yank (current-kill arg))
+      ;; Set the window start back where it was in the yank command,
+      ;; if possible.
+      (set-window-start (selected-window) yank-window-start t)
+      (if before
+          ;; This is like exchange-point-and-mark, but doesn't activate the mark.
+          ;; It is cleaner to avoid activation, even though the command
+          ;; loop would deactivate the mark because we inserted text.
+          (goto-char (prog1 (mark t)
+                       (set-marker (mark-marker) (point) (current-buffer))))))
+    nil))
+
+(put 'yank-pop 'delete-selection t)
+
+(defvar yank-from-kill-ring-history)
+(defun yank-from-kill-ring (string)
+  "Insert the kill-ring item selected from the minibuffer history.
+Use minibuffer navigation and search commands to browse the kill-ring
+in the minibuffer history before typing RET to insert the item,
+or use completion on the elements of the kill-ring."
+  (interactive
+   (list (let* ((history-add-new-input nil)
+                (ellipsis (if (char-displayable-p ?…) "…" "..."))
+                ;; Remove keymaps from text properties of copied string,
+                ;; because typing RET in the minibuffer might call
+                ;; an irrelevant command from the map of copied string.
+                (yank-from-kill-ring-history
+                 (mapcar (lambda (s)
+                           (remove-list-of-text-properties
+                            0 (length s)
+                            '(
+                              keymap local-map action mouse-action
+                              button category help-args)
+                            s)
+                           s)
+                         kill-ring))
+                (completions
+                 (mapcar (lambda (s)
+                           (let* ((s (query-replace-descr s))
+                                  (b 0))
+                             ;; Add ellipsis on leading whitespace
+                             (when (string-match "\\`[[:space:]]+" s)
+                               (setq b (match-end 0))
+                               (add-text-properties 0 b `(display ,ellipsis) s))
+                             (when (> (length s) (- 40 b))
+                               (add-text-properties
+                                (min (+ b 40) (length s)) (length s)
+                                `(display ,ellipsis) s))
+                             s))
+                         yank-from-kill-ring-history))
+                ;; Allow ‘SPC’ to be inserted literally.
+                (minibuffer-completing-file-name t))
+           (completing-read "Yank from kill-ring: "
+                            (lambda (string pred action)
+                              (if (eq action 'metadata)
+                                  ;; Keep sorted by recency
+                                  '(metadata (display-sort-function . identity))
+                                (complete-with-action action completions string pred)))
+                            nil nil nil
+                            'yank-from-kill-ring-history))))
+  (setq yank-window-start (window-start))
+  (push-mark)
+  (insert-for-yank string))
+
+(put 'yank-from-kill-ring 'delete-selection t)
 
 (defun yank (&optional arg)
   "Reinsert (\"paste\") the last stretch of killed text.

  reply	other threads:[~2020-11-20  8:53 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-12 17:42 on helm substantial differences Drew Adams
2020-11-13 21:16 ` Jean Louis
2020-11-15 11:49 ` Jean Louis
2020-11-15 20:07 ` Juri Linkov
2020-11-15 22:01   ` Stefan Monnier
2020-11-15 22:41     ` Drew Adams
2020-11-16  8:58     ` Juri Linkov
2020-11-16 16:03       ` Drew Adams
2020-11-16 17:36       ` Stefan Monnier
2020-11-16 20:38         ` Juri Linkov
2020-11-16 21:54           ` Stefan Monnier
2020-11-17 19:18         ` Juri Linkov
2020-11-17 20:32           ` Juri Linkov
2020-11-18  9:10             ` Juri Linkov
2020-11-18 11:38               ` Basil L. Contovounesios
2020-11-18 19:13                 ` Juri Linkov
2020-11-18 20:33                   ` Juri Linkov
2020-11-20  9:24                     ` Juri Linkov
2020-11-20 11:57                       ` Eli Zaretskii
2020-11-20 12:15                         ` Eli Zaretskii
2020-11-20 14:39                           ` Stefan Monnier
2020-11-21 20:18                           ` Juri Linkov
2020-11-22  3:33                             ` Eli Zaretskii
2020-11-22  8:36                               ` Juri Linkov
2020-11-22 15:19                                 ` Eli Zaretskii
2020-11-22 20:11                                   ` Juri Linkov
2020-11-23  3:24                                     ` Eli Zaretskii
2020-11-25  9:10                                       ` Juri Linkov
2020-11-25 15:51                                         ` Eli Zaretskii
2020-11-25 19:16                                           ` Juri Linkov
2020-11-25 19:59                                             ` Eli Zaretskii
2020-11-25 20:35                                               ` Juri Linkov
2020-11-26 13:45                                                 ` Eli Zaretskii
2020-11-27  8:45                                                   ` Juri Linkov
2020-11-27  8:58                                                     ` Eli Zaretskii
2020-11-27  9:17                                                       ` Juri Linkov
2020-11-17 21:14           ` Jean Louis
2020-11-18  9:03             ` Juri Linkov
2020-11-18 19:21           ` Juri Linkov
2020-11-18 22:04             ` select yank via completion Stefan Monnier
2020-11-18 23:02               ` Drew Adams
2020-11-19  7:54               ` Juri Linkov
2020-11-19 17:00                 ` Drew Adams
2020-11-20  8:53                   ` Juri Linkov [this message]
2020-11-20 11:53                     ` Eli Zaretskii
2020-11-21 19:38                       ` Juri Linkov
2020-11-21 19:57                         ` Eli Zaretskii
2020-11-21 20:43                           ` Juri Linkov
2020-11-20 14:23                     ` Stefan Monnier
2020-11-21 19:42                       ` Juri Linkov
2020-11-21 21:08                         ` Stefan Monnier
2020-11-21 22:21                         ` Drew Adams
2020-11-21 22:48                           ` Jean Louis
2020-11-21 23:00                           ` Jean Louis
2020-11-25 19:25                           ` Juri Linkov
2020-11-25 19:40                             ` Drew Adams
2020-11-21 21:54                       ` Drew Adams
2020-11-21 21:46                     ` Drew Adams
2020-11-24 22:59                     ` Basil L. Contovounesios
2020-11-25  7:36                       ` Juri Linkov
2020-11-25  8:14                         ` Andrii Kolomoiets
2020-11-25 20:24                           ` Juri Linkov
2020-11-26  8:46                             ` Basil L. Contovounesios
2020-11-26  9:26                               ` Juri Linkov
2020-11-26  9:57                                 ` Eli Zaretskii
2020-11-26 21:17                                   ` Basil L. Contovounesios
2020-11-27  7:13                                     ` Eli Zaretskii
2020-11-27  9:01                                       ` Juri Linkov
2020-11-18 22:36             ` on helm substantial differences Drew Adams
2020-11-16 16:13   ` Eli Zaretskii
2020-11-16 20:41     ` Juri Linkov
2020-11-16 21:18       ` Drew Adams
2020-11-16 22:13         ` Juri Linkov
2020-11-17  0:04           ` Drew Adams
2020-11-17  8:38             ` Juri Linkov
2020-11-17 16:56               ` Drew Adams
2020-11-17 12:06             ` Protesilaos Stavrou
2020-11-17 17:29               ` Drew Adams
2020-11-17 19:23               ` Juri Linkov
2020-11-17  3:24       ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o8jsiems.fsf@mail.linkov.net \
    --to=juri@linkov.net \
    --cc=andreyk.mad@gmail.com \
    --cc=bugs@gnu.support \
    --cc=drew.adams@oracle.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=ghe@sdf.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=rudalics@gmx.at \
    --cc=spacibba@aol.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.