New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some ivy-kill-ring to complete M-y? #218

Closed
josuah opened this Issue Sep 10, 2015 · 4 comments

Comments

Projects
None yet
3 participants
@josuah

josuah commented Sep 10, 2015

Helm has a convenient feature: the ability to display a list of kill ring entries (most recent kills). I miss this feature, but still prefer ivy. Thank you for your work!

@abo-abo

This comment has been minimized.

Show comment
Hide comment
@abo-abo

abo-abo Sep 10, 2015

Owner

You mean helm-show-kill-ring? Here is something similar, but Ivy doesn't currently work well with multi-line candidates:

(defun ivy-show-kill-ring ()
  (interactive)
  (ivy-read "kill-ring: " (helm-kill-ring-candidates)
            :action 'insert))

Making multi-line selection work better might take some time.

Owner

abo-abo commented Sep 10, 2015

You mean helm-show-kill-ring? Here is something similar, but Ivy doesn't currently work well with multi-line candidates:

(defun ivy-show-kill-ring ()
  (interactive)
  (ivy-read "kill-ring: " (helm-kill-ring-candidates)
            :action 'insert))

Making multi-line selection work better might take some time.

@josuah

This comment has been minimized.

Show comment
Hide comment
@josuah

josuah Sep 10, 2015

I will try this and the other solutions from http://emacswiki.org/emacs/BrowseKillRing

[EDIT] This snippet actually worked without extra package.

(defun yank-browse (string)
      "Browse the `kill-ring' to choose which entry to yank."
      (interactive
       (minibuffer-with-setup-hook #'minibuffer-completion-help
         (let* ((kills (delete-dups (append kill-ring-yank-pointer kill-ring nil)))
                (entries
                 (mapcar (lambda (string)
                           (let ((pos 0))
                             ;; FIXME: Maybe we should start by removing
                             ;; all properties.
                             (setq string (copy-sequence string))
                             (while (string-match "\n" string pos)
                               ;; FIXME: Maybe completion--insert-strings should
                               ;; do that for us.
                               (put-text-property
                                (match-beginning 0) (match-end 0)
                                'display (eval-when-compile
                                           (propertize "\\n" 'face 'escape-glyph))
                                string)
                               (setq pos (match-end 0)))
                             ;; FIXME: We may use the window-width of the
                             ;; wrong window.
                             (when (>= (* 3 (string-width string))
                                       (* 2 (window-width)))
                               (let ((half (- (/ (window-width) 3) 1)))
                                 ;; FIXME: We're using char-counts rather than
                                 ;; width-count.
                                 (put-text-property
                                  half (- (length string) half)
                                  'display (eval-when-compile
                                             (propertize "……" 'face 'escape-glyph))
                                  string)))
                             string))
                         kills))
                (table (lambda (string pred action)
                         (cond
                          ((eq action 'metadata)
                           '(metadata (category . kill-ring)))
                          (t
                           (complete-with-action action entries string pred))))))
           ;; FIXME: We should return the entry from the kill-ring rather than
           ;; the entry from the completion-table.
           ;; FIXME: substring completion doesn't work well because it only matches
           ;; subtrings before the first \n.
           ;; FIXME: completion--insert-strings assumes that boundaries of
           ;; candidates are obvious enough, but with kill-ring entries this is not
           ;; true, so we'd probably want to display them with «...» around them.
           (list (completing-read "Yank: " table nil t)))))
      (setq this-command 'yank)
      (insert-for-yank string))

Here is how it is rendered:
screenshot from 2015-09-10 17-57-22
I inserted the highlighted item then called the function again.

It suits for me: I prefer totally avoid to install the heavy Helm.

Thank you for your answer.

josuah commented Sep 10, 2015

I will try this and the other solutions from http://emacswiki.org/emacs/BrowseKillRing

[EDIT] This snippet actually worked without extra package.

(defun yank-browse (string)
      "Browse the `kill-ring' to choose which entry to yank."
      (interactive
       (minibuffer-with-setup-hook #'minibuffer-completion-help
         (let* ((kills (delete-dups (append kill-ring-yank-pointer kill-ring nil)))
                (entries
                 (mapcar (lambda (string)
                           (let ((pos 0))
                             ;; FIXME: Maybe we should start by removing
                             ;; all properties.
                             (setq string (copy-sequence string))
                             (while (string-match "\n" string pos)
                               ;; FIXME: Maybe completion--insert-strings should
                               ;; do that for us.
                               (put-text-property
                                (match-beginning 0) (match-end 0)
                                'display (eval-when-compile
                                           (propertize "\\n" 'face 'escape-glyph))
                                string)
                               (setq pos (match-end 0)))
                             ;; FIXME: We may use the window-width of the
                             ;; wrong window.
                             (when (>= (* 3 (string-width string))
                                       (* 2 (window-width)))
                               (let ((half (- (/ (window-width) 3) 1)))
                                 ;; FIXME: We're using char-counts rather than
                                 ;; width-count.
                                 (put-text-property
                                  half (- (length string) half)
                                  'display (eval-when-compile
                                             (propertize "……" 'face 'escape-glyph))
                                  string)))
                             string))
                         kills))
                (table (lambda (string pred action)
                         (cond
                          ((eq action 'metadata)
                           '(metadata (category . kill-ring)))
                          (t
                           (complete-with-action action entries string pred))))))
           ;; FIXME: We should return the entry from the kill-ring rather than
           ;; the entry from the completion-table.
           ;; FIXME: substring completion doesn't work well because it only matches
           ;; subtrings before the first \n.
           ;; FIXME: completion--insert-strings assumes that boundaries of
           ;; candidates are obvious enough, but with kill-ring entries this is not
           ;; true, so we'd probably want to display them with «...» around them.
           (list (completing-read "Yank: " table nil t)))))
      (setq this-command 'yank)
      (insert-for-yank string))

Here is how it is rendered:
screenshot from 2015-09-10 17-57-22
I inserted the highlighted item then called the function again.

It suits for me: I prefer totally avoid to install the heavy Helm.

Thank you for your answer.

@abo-abo abo-abo closed this in 4ca93d6 Sep 11, 2015

@abo-abo

This comment has been minimized.

Show comment
Hide comment
@abo-abo

abo-abo Sep 11, 2015

Owner

I've added a new command counsel-yank-pop. It's more-or-less functional now, some improvements may come in the future.

Owner

abo-abo commented Sep 11, 2015

I've added a new command counsel-yank-pop. It's more-or-less functional now, some improvements may come in the future.

abo-abo added a commit that referenced this issue Sep 11, 2015

counsel.el (counsel-yank-pop): New command
* counsel.el (counsel-yank-pop-truncate): New defcustom. Choose whether
  to truncate strings over 4 lines.
(counsel-yank-pop-action): New defun.

Fixes #218
@Pitometsu

This comment has been minimized.

Show comment
Hide comment
@Pitometsu

Pitometsu Oct 27, 2017

Here much more interesting, interactive and emacs-way solution http://www.namazu.org/~tsuchiya/elisp/yank-pop-summary.el

Could counsel-yank-pop work this way?

Pitometsu commented Oct 27, 2017

Here much more interesting, interactive and emacs-way solution http://www.namazu.org/~tsuchiya/elisp/yank-pop-summary.el

Could counsel-yank-pop work this way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment