branch: externals/ivy-posframe commit 3c00455a233cff7a09274b975c77dfa602ea413b Author: Fox Kiester <n...@posteo.net> Commit: Fox Kiester <n...@posteo.net>
Add ivy-posframe-swiper-avy --- ivy-posframe.el | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/ivy-posframe.el b/ivy-posframe.el index 816a497..692600f 100644 --- a/ivy-posframe.el +++ b/ivy-posframe.el @@ -294,6 +294,12 @@ selection, non-nil otherwise." (substring-no-properties (nth (- (line-number-at-pos pt) 2) ivy--old-cands))))) +(defun ivy-posframe--window () + "Return the posframe window displaying `ivy-posframe-buffer'." + (frame-selected-window + (buffer-local-value 'posframe--frame + (get-buffer ivy-posframe-buffer)))) + (defvar avy-all-windows) (defvar avy-keys) (defvar avy-keys-alist) @@ -315,13 +321,11 @@ selection, non-nil otherwise." (avy-style (or (cdr (assq 'ivy-avy avy-styles-alist)) avy-style)) - (window (frame-selected-window - (buffer-local-value 'posframe--frame - (get-buffer ivy-posframe-buffer)))) ;; prevent default pre action, which calls ;; `select-frame-set-input-focus', deselecting the minibuffer and ;; causing `ivy-posframe-cleanup' to run prematurely (avy-pre-action #'ignore) + (window (ivy-posframe--window)) candidates) (with-current-buffer ivy-posframe-buffer (save-excursion @@ -339,6 +343,90 @@ selection, non-nil otherwise." (nreverse candidates) (avy--style-fn avy-style)))) +(declare-function avy--make-backgrounds "avy") +(declare-function avy-window-list "avy") +(declare-function avy-read-de-bruijn "avy") +(declare-function avy-read "avy") +(declare-function avy-tree "avy") +(declare-function avy--overlay-post "avy") +(declare-function avy--remove-leading-chars "avy") +(declare-function avy-push-mark "avy") +(declare-function avy--done "avy") +(defun ivy-posframe--swiper-avy-candidate () + (let* ((avy-all-windows nil) + ;; We'll have overlapping overlays, so we sort all the + ;; overlays in the visible region by their start, and then + ;; throw out non-Swiper overlays or overlapping Swiper + ;; overlays. + (visible-overlays (cl-sort (with-ivy-window + (overlays-in (window-start) + (window-end))) + #'< :key #'overlay-start)) + (min-overlay-start 0) + (overlays-for-avy (cl-remove-if-not + (lambda (ov) + (when (and (>= (overlay-start ov) + min-overlay-start) + (memq (overlay-get ov 'face) + swiper-faces)) + (setq min-overlay-start (overlay-start ov)))) + visible-overlays)) + (offset (if (eq (ivy-state-caller ivy-last) 'swiper) 1 0)) + (window (ivy-posframe--window)) + (candidates (nconc + (mapcar (lambda (ov) + (cons (overlay-start ov) + (overlay-get ov 'window))) + overlays-for-avy) + (with-current-buffer ivy-posframe-buffer + (save-excursion + (save-restriction + (narrow-to-region (window-start window) + (window-end window)) + (goto-char (point-min)) + (forward-line) + (let (cands) + (while (not (eobp)) + (push (cons (+ (point) offset) window) + cands) + (forward-line)) + cands))))))) + (unwind-protect + (prog2 + (avy--make-backgrounds + (append (avy-window-list) + (list (ivy-state-window ivy-last)))) + (if (eq avy-style 'de-bruijn) + (avy-read-de-bruijn candidates avy-keys) + (avy-read (avy-tree candidates avy-keys) + #'avy--overlay-post + #'avy--remove-leading-chars)) + (avy-push-mark)) + (avy--done)))) + +(declare-function avy-action-goto "avy") +(declare-function avy-candidate-beg "avy") +(defun ivy-posframe-swiper-avy () + "Jump to one of the current swiper candidates." + (interactive) + (unless (require 'avy nil 'noerror) + (error "Package avy isn't installed")) + (unless (string= ivy-text "") + (let ((candidate (ivy-posframe--swiper-avy-candidate))) + (if (eq (cdr candidate) (ivy-posframe--window)) + (let ((cand-text (with-current-buffer ivy-posframe-buffer + (save-excursion + (goto-char (car candidate)) + (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))))) + (ivy-set-index (cl-position cand-text ivy--old-cands :test #'string=)) + (ivy--exhibit) + (ivy-done) + (ivy-call)) + (ivy-quit-and-run + (avy-action-goto (avy-candidate-beg candidate))))))) + (defun ivy-posframe--minibuffer-setup (orig-func) "Advice function of `ivy--minibuffer-setup'." (funcall orig-func) @@ -359,6 +447,7 @@ selection, non-nil otherwise." (define-key ivy-minibuffer-map (kbd "C-M-a") 'ivy-posframe-read-action) (define-key ivy-minibuffer-map (kbd "M-o") 'ivy-posframe-dispatching-done) (define-key ivy-minibuffer-map (kbd "C-'") 'ivy-posframe-avy) + (define-key ivy-minibuffer-map [remap swiper-avy] 'ivy-posframe-swiper-avy) (advice-add 'ivy--minibuffer-setup :around #'ivy-posframe--minibuffer-setup) (message "ivy-posframe is enabled, disabling it need to reboot emacs."))