+(defvar ivy-completion-beg nil
+ "Completion bounds start.")
+
+(defvar ivy-completion-end nil
+ "Completion bounds end.")
+
+(defun ivy-completion-in-region-action (str)
+ "Insert STR, erasing the previous one.
+The previous string is between `ivy-completion-beg' and `ivy-completion-end'."
+ (when (stringp str)
+ (with-ivy-window
+ (when ivy-completion-beg
+ (delete-region
+ ivy-completion-beg
+ ivy-completion-end))
+ (setq ivy-completion-beg
+ (move-marker (make-marker) (point)))
+ (insert str)
+ (setq ivy-completion-end
+ (move-marker (make-marker) (point))))))
+
+(defun ivy-completion-common-length (str)
+ "Return the length of the first `completions-common-part' face in STR."
+ (let ((pos 0)
+ (len (length str)))
+ (while (and (<= pos len)
+ (let ((prop (get-text-property pos 'face str)))
+ (not (eq 'completions-common-part
+ (if (listp prop) (car prop) prop)))))
+ (setq pos (1+ pos)))
+ (if (< pos len)
+ (or (next-single-property-change pos 'face str) len)
+ 0)))
+
+(defun ivy-completion-in-region (start end collection &optional predicate)
+ "An Ivy function suitable for `completion-in-region-function'."
+ (let* ((enable-recursive-minibuffers t)
+ (str (buffer-substring-no-properties start end))
+ (completion-ignore-case case-fold-search)
+ (comps
+ (completion-all-completions str collection predicate (- end start))))
+ (if (null comps)
+ (message "No matches")
+ (nconc comps nil)
+ (setq ivy-completion-beg (- end (ivy-completion-common-length (car comps))))
+ (setq ivy-completion-end end)
+ (if (null (cdr comps))
+ (if (string= str (car comps))
+ (message "Sole match")
+ (setf (ivy-state-window ivy-last) (selected-window))
+ (ivy-completion-in-region-action
+ (substring-no-properties
+ (car comps))))
+ (let* ((w (1+ (floor (log (length comps) 10))))
+ (ivy-count-format (if (string= ivy-count-format "")
+ ivy-count-format
+ (format "%%-%dd " w)))
+ (prompt (format "(%s): " str)))
+ (and
+ (ivy-read (if (string= ivy-count-format "")
+ prompt
+ (replace-regexp-in-string "%" "%%" prompt))
+ ;; remove 'completions-first-difference face
+ (mapcar #'substring-no-properties comps)
+ :predicate predicate
+ :action #'ivy-completion-in-region-action
+ :require-match t)
+ t))))))
+
+(defcustom ivy-do-completion-in-region t
+ "When non-nil `ivy-mode' will set `completion-in-region-function'."
+ :type 'boolean)
+