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.
next prev parent 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.