[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: select yank via completion
From: |
Juri Linkov |
Subject: |
Re: select yank via completion |
Date: |
Thu, 19 Nov 2020 09:54:34 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu) |
>> BTW, there is another TODO item in minibuffer.el:
>>
>> ;; - indicate how to display the completions in *Completions* (turn
>> ;; \n into something else, add special boundaries between
>> ;; completions). E.g. when completing from the kill-ring.
>>
>> Such pre-processing can be performed by the caller.
>> For a long time I used the command 'yank-from-kill-ring'
>> bound to 'C-M-y' that relies on query-replace-descr
>> to display newlines as ^J and displays long completions
>> with an ellipsis at the end and an ellipsis on leading whitespace.
>
> Looks great, thanks. Any reason you bind it to C-M-y instead
> of to "M-y that doesn't immediately follow C-y"?
Oops, I don't remember why I forgot about no-op M-y.
Here is a better patch. 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?
diff --git a/lisp/simple.el b/lisp/simple.el
index bb28145502..32850b4b7c 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5362,27 +5362,29 @@ yank-pop
property, in the way that `yank' does."
(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)
(defun yank (&optional arg)
"Reinsert (\"paste\") the last stretch of killed text.
@@ -5449,6 +5451,56 @@ rotate-yank-pointer
With ARG, rotate that many kills forward (or backward, if negative)."
(interactive "p")
(current-kill arg))
+
+(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)
+ ;; 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 "…") s))
+ (when (> (length s) (- 40 b))
+ (add-text-properties
+ (min (+ b 40) (length s)) (length s)
+ `(display "…") s))
+ s))
+ yank-from-kill-ring-history)))
+ (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)
+
;; Some kill commands.
- Re: on helm substantial differences, (continued)
- Re: on helm substantial differences, Juri Linkov, 2020/11/20
- Re: on helm substantial differences, Eli Zaretskii, 2020/11/20
- Re: on helm substantial differences, Eli Zaretskii, 2020/11/20
- Re: on helm substantial differences, Stefan Monnier, 2020/11/20
- Re: on helm substantial differences, Juri Linkov, 2020/11/21
- Re: on helm substantial differences, Jean Louis, 2020/11/17
- Re: on helm substantial differences, Juri Linkov, 2020/11/18
- Re: on helm substantial differences, Juri Linkov, 2020/11/18
- select yank via completion, Stefan Monnier, 2020/11/18
- RE: select yank via completion, Drew Adams, 2020/11/18
- Re: select yank via completion,
Juri Linkov <=
- RE: select yank via completion, Drew Adams, 2020/11/19
- Re: select yank via completion, Juri Linkov, 2020/11/20
- Re: select yank via completion, Eli Zaretskii, 2020/11/20
- Re: select yank via completion, Juri Linkov, 2020/11/21
- Re: select yank via completion, Eli Zaretskii, 2020/11/21
- Re: select yank via completion, Juri Linkov, 2020/11/21
- Re: select yank via completion, Stefan Monnier, 2020/11/20
- Re: select yank via completion, Juri Linkov, 2020/11/21
- Re: select yank via completion, Stefan Monnier, 2020/11/21
- RE: select yank via completion, Drew Adams, 2020/11/21