From 52b5db587407c4270d06c9f66a0673142a2391e8 Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <contovob@tcd.ie>
Date: Wed, 22 Sep 2021 14:17:03 +0100
Subject: [PATCH] Reabsorb ivy-avy into ivy

For some discussion, see the following threads:
https://lists.gnu.org/r/emacs-devel/2021-02/msg01935.html
https://lists.gnu.org/r/emacs-devel/2021-03/msg00490.html

* ivy-avy.el: Move contents to ivy.el.  Bump package versions to
0.13.5.  Mention deprecation in Commentary and warning message.

* ivy.el: Bump package version to 0.13.5.
(ivy-define-key): Use function-put in place of put.
(ivy-minibuffer-map): Bind ivy-avy.
(ivy-avy-style): Moved from ivy-avy.el.  Add a nil option for
falling through to the default avy-styles-alist or avy-style.
(ivy--avy-candidates, ivy--avy-action, ivy--avy-handler-function)
(ivy-avy): Moved from ivy-avy.el with some cleanups.

* swiper.el: Bump package versions to 0.13.5.
Localize external variable and function declarations.
(swiper-avy): Fix error message and docstring.

* counsel.el:
* ivy-hydra.el
* doc/ivy.org: Bump package versions to 0.13.5.
* doc/ivy.texi: Regenerate.

* Makefile (compile): Don't byte-compile ivy-avy.el.
* ivy-test.el (ivy-avy):
* targets/plain.el: Don't load ivy-avy.el.

Closes #2574, closes #2583.
---
 Makefile         |  3 +-
 counsel.el       |  4 +-
 doc/ivy.org      |  2 +-
 doc/ivy.texi     |  2 +-
 ivy-avy.el       | 98 +++++++++---------------------------------------
 ivy-hydra.el     |  2 +-
 ivy-test.el      |  1 -
 ivy.el           | 85 +++++++++++++++++++++++++++++++++++++++--
 swiper.el        | 37 +++++++++---------
 targets/plain.el |  7 +---
 10 files changed, 127 insertions(+), 114 deletions(-)

diff --git a/Makefile b/Makefile
index c5ee6c359..23bc76333 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,8 @@ checkdoc:
 	$(emacs) -batch -l targets/checkdoc.el
 
 compile:
-	$(emacs) -batch -l elpa.el -L . -f batch-byte-compile colir.el ivy-faces.el ivy-overlay.el ivy.el ivy-avy.el swiper.el counsel.el
+	$(emacs) -batch -l elpa.el -L . -f batch-byte-compile \
+	  colir.el ivy-faces.el ivy-overlay.el ivy.el swiper.el counsel.el
 
 plain:
 	$(emacs) --version
diff --git a/counsel.el b/counsel.el
index 8c1f38108..12f4d9ab0 100644
--- a/counsel.el
+++ b/counsel.el
@@ -4,8 +4,8 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.13.4
-;; Package-Requires: ((emacs "24.5") (ivy "0.13.4") (swiper "0.13.4"))
+;; Version: 0.13.5
+;; Package-Requires: ((emacs "24.5") (ivy "0.13.5") (swiper "0.13.5"))
 ;; Keywords: convenience, matching, tools
 
 ;; This file is part of GNU Emacs.
diff --git a/doc/ivy.org b/doc/ivy.org
index bd4e14e67..784fdc5b9 100644
--- a/doc/ivy.org
+++ b/doc/ivy.org
@@ -58,7 +58,7 @@ ivy-ox.el then ~C-c C-e i t~ in the ivy.org buffer.
 :CUSTOM_ID: copying
 :END:
 #+TEXINFO: @ifnottex
-Ivy manual, version 0.13.4
+Ivy manual, version 0.13.5
 
 Ivy is an interactive interface for completion in Emacs. Emacs uses
 completion mechanism in a variety of contexts: code, menus, commands,
diff --git a/doc/ivy.texi b/doc/ivy.texi
index 9d068bfcd..6e1de173a 100644
--- a/doc/ivy.texi
+++ b/doc/ivy.texi
@@ -8,7 +8,7 @@
 
 @copying
 @ifnottex
-Ivy manual, version 0.13.4
+Ivy manual, version 0.13.5
 
 Ivy is an interactive interface for completion in Emacs. Emacs uses
 completion mechanism in a variety of contexts: code, menus, commands,
diff --git a/ivy-avy.el b/ivy-avy.el
index e4c97b407..86c2f66c3 100644
--- a/ivy-avy.el
+++ b/ivy-avy.el
@@ -4,8 +4,8 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.13.4
-;; Package-Requires: ((emacs "24.5") (ivy "0.13.4") (avy "0.5.0"))
+;; Version: 0.13.5
+;; Package-Requires: ((ivy "0.13.5") (avy "0.5.0"))
 ;; Keywords: convenience
 
 ;; This program is free software; you can redistribute it and/or modify
@@ -22,90 +22,28 @@
 ;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 ;;; Commentary:
+
+;; *N.B.:* This package has been absorbed, and is therefore made
+;; obsolete, by the `ivy' package, version 0.13.5.
+;;
+;; If you maintain a package that depends on `ivy-avy', then you
+;; should change that to instead depend on `ivy' version 0.13.5, and
+;; remove all references to `ivy-avy'.
 ;;
-;; This package adds a "C-'" binding to Ivy minibuffer that uses Avy.
+;; If you use any packages that depend on `ivy-avy', either directly
+;; or indirectly, then you will have to wait until all of them have
+;; transitioned away from it before you can uninstall it.
 
 ;;; Code:
 
-(require 'ivy)
 (require 'avy)
+(require 'ivy)
 
-(defcustom ivy-avy-style 'pre
-  "The `avy-style' setting for `ivy-avy'."
-  :type '(choice
-          (const :tag "Pre" pre)
-          (const :tag "At" at)
-          (const :tag "At Full" at-full)
-          (const :tag "Post" post)
-          (const :tag "De Bruijn" de-bruijn)
-          (const :tag "Words" words))
-  :group 'ivy)
-
-(defun ivy-avy--candidates ()
-  "List of candidates for `ivy-avy'."
-  (let (candidates)
-    (save-excursion
-      (save-restriction
-        (narrow-to-region
-         (window-start)
-         (window-end))
-        (goto-char (point-min))
-        (forward-line)
-        (while (< (point) (point-max))
-          (push
-           (cons (point)
-                 (selected-window))
-           candidates)
-          (forward-line))))
-    (nreverse candidates)))
-
-(defun ivy-avy--action (pt)
-  "Select the candidate represented by PT."
-  (when (number-or-marker-p pt)
-    (let ((bnd (ivy--minibuffer-index-bounds
-                ivy--index ivy--length ivy-height)))
-      (ivy--done
-       (substring-no-properties
-        (nth (+ (car bnd) (- (line-number-at-pos pt) 2)) ivy--old-cands))))))
-
-(defun ivy-avy--handler-function (char)
-  "Handle CHAR that's not on `avy-keys'."
-  (let (cmd)
-    (cond ((memq char '(?\C-\[ ?\C-g))
-           ;; exit silently
-           (throw 'done 'abort))
-          ((memq (setq cmd (lookup-key ivy-minibuffer-map (vector char)))
-                 '(ivy-scroll-up-command
-                   ivy-scroll-down-command))
-           (funcall cmd)
-           (ivy--exhibit)
-           (throw 'done 'exit))
-          ;; ignore wrong key
-          (t
-           (throw 'done 'restart)))))
-
-(defun ivy-avy ()
-  "Jump to one of the current ivy candidates."
-  (interactive)
-  (if (= (minibuffer-depth) 0)
-      (user-error
-       "This command is intended to be called from within `ivy-read'")
-    (let* ((avy-all-windows nil)
-           (avy-keys (or (cdr (assq 'ivy-avy avy-keys-alist))
-                         avy-keys))
-           (avy-style (or (cdr (assq 'ivy-avy avy-styles-alist))
-                          avy-style))
-           (avy-action #'identity)
-           (avy-handler-function #'ivy-avy--handler-function)
-           res)
-      (while (eq (setq res (avy-process (ivy-avy--candidates))) t))
-      (when res
-        (ivy-avy--action res)))))
-
-(put 'ivy-avy 'no-counsel-M-x t)
-(unless (lookup-key ivy-minibuffer-map (kbd "C-'"))
-  (define-key ivy-minibuffer-map (kbd "C-'") 'ivy-avy))
-(add-to-list 'avy-styles-alist `(ivy-avy . ,ivy-avy-style))
+(eval-and-compile
+  (let ((msg "Package ivy-avy is obsolete; use ivy 0.13.5 instead"))
+    (if (and noninteractive (fboundp 'byte-compile-warn))
+        (byte-compile-warn msg)
+      (message "%s" msg))))
 
 (provide 'ivy-avy)
 
diff --git a/ivy-hydra.el b/ivy-hydra.el
index 0f3d81867..875370024 100644
--- a/ivy-hydra.el
+++ b/ivy-hydra.el
@@ -5,7 +5,7 @@
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
 ;; Version: 0.13.5
-;; Package-Requires: ((emacs "24.5") (ivy "0.13.4") (hydra "0.14.0"))
+;; Package-Requires: ((emacs "24.5") (ivy "0.13.5") (hydra "0.14.0"))
 ;; Keywords: convenience
 
 ;; This file is part of GNU Emacs.
diff --git a/ivy-test.el b/ivy-test.el
index e44f15db9..ee09f9851 100644
--- a/ivy-test.el
+++ b/ivy-test.el
@@ -1590,7 +1590,6 @@ a buffer visiting a file."
 
 (ert-deftest ivy-avy ()
   (skip-unless (require 'avy nil t))
-  (require 'ivy-avy)
   (let ((enable-recursive-minibuffers t)
         (read-numbers '(ivy-read "test: " (mapcar #'number-to-string
                                                   (number-sequence 1 100)))))
diff --git a/ivy.el b/ivy.el
index 33cf95d2f..783c7d5f4 100644
--- a/ivy.el
+++ b/ivy.el
@@ -4,7 +4,7 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.13.4
+;; Version: 0.13.5
 ;; Package-Requires: ((emacs "24.5"))
 ;; Keywords: matching
 
@@ -303,8 +303,8 @@ action functions.")
 (require 'delsel)
 (defun ivy-define-key (keymap key def)
   "Forward to (`define-key' KEYMAP KEY DEF).
-Remove DEF from `counsel-M-x' list."
-  (put def 'no-counsel-M-x t)
+Remove DEF (a function symbol) from `counsel-M-x' completion."
+  (function-put def 'no-counsel-M-x t)
   (define-key keymap key def))
 
 (defvar ivy-minibuffer-map
@@ -353,6 +353,7 @@ Remove DEF from `counsel-M-x' list."
     (ivy-define-key map [remap kill-whole-line] 'ivy-kill-whole-line)
     (ivy-define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
     (ivy-define-key map [remap kill-ring-save] 'ivy-kill-ring-save)
+    (ivy-define-key map (kbd "C-'") 'ivy-avy)
     (ivy-define-key map (kbd "C-M-a") 'ivy-read-action)
     (ivy-define-key map (kbd "C-c C-o") 'ivy-occur)
     (ivy-define-key map (kbd "C-c C-a") 'ivy-toggle-ignore)
@@ -1708,6 +1709,84 @@ This string is inserted into the minibuffer."
            (const :tag "Full line" ivy-format-function-line)
            (function :tag "Custom function"))))
 
+(defcustom ivy-avy-style 'pre
+  "The `avy-style' setting for `ivy-avy'."
+  :type '(choice
+          (const :tag "Pre" pre)
+          (const :tag "At" at)
+          (const :tag "At Full" at-full)
+          (const :tag "Post" post)
+          (const :tag "De Bruijn" de-bruijn)
+          (const :tag "Words" words)
+          (const :tag "Default" nil)))
+
+(defun ivy--avy-candidates ()
+  "List of candidates for `ivy-avy'."
+  (let (candidates)
+    (save-excursion
+      (save-restriction
+        (narrow-to-region (window-start) (window-end))
+        (goto-char (point-min))
+        (forward-line)
+        (while (< (point) (point-max))
+          (push (cons (point) (selected-window))
+                candidates)
+          (forward-line))))
+    (nreverse candidates)))
+
+(defun ivy--avy-action (pt)
+  "Select the candidate represented by PT."
+  (when (number-or-marker-p pt)
+    (let ((bnd (ivy--minibuffer-index-bounds
+                ivy--index ivy--length ivy-height)))
+      (ivy--done
+       (substring-no-properties
+        (nth (+ (car bnd) (- (line-number-at-pos pt) 2)) ivy--old-cands))))))
+
+(defun ivy--avy-handler-function (char)
+  "Handle CHAR that's not on `avy-keys'."
+  (cond ((memql char '(?\C-\[ ?\C-g))
+         ;; Exit silently.
+         (throw 'done 'abort))
+        ((let ((cmd (lookup-key ivy-minibuffer-map (vector char))))
+           (when (memq cmd '(ivy-scroll-up-command
+                             ivy-scroll-down-command))
+             (funcall cmd)
+             (ivy--exhibit)
+             (throw 'done 'exit))))
+        ;; Ignore wrong key.
+        ((throw 'done 'restart))))
+
+(defun ivy-avy ()
+  "Jump to one of the current `ivy' candidates with `avy'."
+  (interactive)
+  (unless (require 'avy nil t)
+    (user-error "Package `avy' is not installed"))
+  (when (zerop (minibuffer-depth))
+    (user-error
+     "Command `ivy-avy' is intended to be called from within `ivy-read'"))
+  (defvar avy-action)
+  (defvar avy-all-windows)
+  (defvar avy-handler-function)
+  (defvar avy-keys)
+  (defvar avy-keys-alist)
+  (defvar avy-style)
+  (defvar avy-styles-alist)
+  (declare-function avy-process "avy"
+                    (candidates &optional overlay-fn cleanup-fn))
+  (let ((avy-all-windows nil)
+        (avy-keys (or (cdr (assq #'ivy-avy avy-keys-alist))
+                      avy-keys))
+        (avy-style (or ivy-avy-style
+                       (cdr (assq #'ivy-avy avy-styles-alist))
+                       avy-style))
+        (avy-action #'identity)
+        (avy-handler-function #'ivy--avy-handler-function)
+        res)
+    (while (eq (setq res (avy-process (ivy--avy-candidates))) t))
+    (when res
+      (ivy--avy-action res))))
+
 (defun ivy-sort-file-function-default (x y)
   "Compare two files X and Y.
 Prioritize directories."
diff --git a/swiper.el b/swiper.el
index f3bebab85..c6833640a 100644
--- a/swiper.el
+++ b/swiper.el
@@ -4,8 +4,8 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.13.4
-;; Package-Requires: ((emacs "24.5") (ivy "0.13.4"))
+;; Version: 0.13.5
+;; Package-Requires: ((emacs "24.5") (ivy "0.13.5"))
 ;; Keywords: matching
 
 ;; This file is part of GNU Emacs.
@@ -262,21 +262,6 @@ If the input is empty, select the previous history element instead."
              (set-window-configuration wnd-conf))))))))
 (put 'swiper-all-query-replace 'no-counsel-M-x t)
 
-(defvar avy-all-windows)
-(defvar avy-style)
-(defvar avy-keys)
-(declare-function avy--overlay-post "ext:avy")
-(declare-function avy-action-goto "ext:avy")
-(declare-function avy-candidate-beg "ext:avy")
-(declare-function avy--done "ext:avy")
-(declare-function avy--make-backgrounds "ext:avy")
-(declare-function avy-window-list "ext:avy")
-(declare-function avy-read "ext:avy")
-(declare-function avy-read-de-bruijn "ext:avy")
-(declare-function avy-tree "ext:avy")
-(declare-function avy-push-mark "ext:avy")
-(declare-function avy--remove-leading-chars "ext:avy")
-
 (defun swiper--avy-candidates ()
   (let* (
          ;; We'll have overlapping overlays, so we sort all the
@@ -317,6 +302,18 @@ If the input is empty, select the previous history element instead."
            cands))))))
 
 (defun swiper--avy-candidate ()
+  (defvar avy-all-windows)
+  (defvar avy-keys)
+  (defvar avy-style)
+  (declare-function avy--done "ext:avy" ())
+  (declare-function avy--make-backgrounds "ext:avy" (wnd-list))
+  (declare-function avy--overlay-post "ext:avy" (path leaf))
+  (declare-function avy--remove-leading-chars "ext:avy" ())
+  (declare-function avy-push-mark "ext:avy" ())
+  (declare-function avy-read "ext:avy" (tree display-fn cleanup-fn))
+  (declare-function avy-read-de-bruijn "ext:avy" (lst keys))
+  (declare-function avy-tree "ext:avy" (lst keys))
+  (declare-function avy-window-list "ext:avy" ())
   (let ((candidates (swiper--avy-candidates))
         (avy-all-windows nil))
     (unwind-protect
@@ -351,6 +348,8 @@ If the input is empty, select the previous history element instead."
           -2)))))
 
 (defun swiper--avy-goto (candidate)
+  (declare-function avy-action-goto "ext:avy" (pt))
+  (declare-function avy-candidate-beg "ext:avy" (leaf))
   (cond ((let ((win (cdr-safe candidate)))
            (and win (window-minibuffer-p win)))
          (setq ivy--index (swiper--avy-index (car candidate)))
@@ -364,10 +363,10 @@ If the input is empty, select the previous history element instead."
 
 ;;;###autoload
 (defun swiper-avy ()
-  "Jump to one of the current swiper candidates with `avy'."
+  "Jump to one of the current `swiper' candidates with `avy'."
   (interactive)
   (unless (require 'avy nil 'noerror)
-    (user-error "Package avy isn't installed"))
+    (user-error "Package `avy' is not installed"))
   (cl-case (length ivy-text)
     (0
      (user-error "Need at least one char of input"))
diff --git a/targets/plain.el b/targets/plain.el
index 70cedbc90..b208f54a6 100644
--- a/targets/plain.el
+++ b/targets/plain.el
@@ -10,8 +10,5 @@
 (global-set-key (kbd "<f2> j") 'counsel-set-variable)
 (global-set-key (kbd "C-c s") 'isearch-forward-regexp)
 (setq ivy-use-virtual-buffers t)
-(condition-case nil
-    (require 'ivy-avy)
-  (error
-   (require 'targets/install-deps)
-   (require 'ivy-avy)))
+(unless (require 'avy nil t)
+  (require 'targets/install-deps))