branch: master commit 426cfcba2b75d27bd98a0bad98e100518021f481 Author: Oleh Krehel <ohwoeo...@gmail.com> Commit: Oleh Krehel <ohwoeo...@gmail.com>
ivy.el (ivy-completion-in-region): Fix a few bugs * ivy.el (ivy-completion-common-length): New defun. `all-completions' doesn't always return candidates that can replace the whole region between BEG and END. That's why `completion-all-completions' should be used, which marks the common part with 'completions-common-part face. Then the new region to replace is ((- END common-length) . END). Note also that `text-property-any' doesn't always work in `ivy-completion-common-length', since the 'face property can be a list. (ivy-completion-in-region): Set `enable-recursive-minibuffers'. Fixes #341 --- ivy.el | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/ivy.el b/ivy.el index b91ad4c..e2c5abc 100644 --- a/ivy.el +++ b/ivy.el @@ -1379,18 +1379,37 @@ The previous string is between `ivy-completion-beg' and `ivy-completion-end'." (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* ((str (buffer-substring-no-properties start end)) - (comps (all-completions str collection predicate))) + (let* ((enable-recursive-minibuffers t) + (str (buffer-substring-no-properties start end)) + (comps + (completion-all-completions str collection predicate (- end start)))) (if (null comps) (message "No matches") + (nconc comps nil) (let* ((w (1+ (floor (log (length comps) 10)))) - (ivy-count-format (format "%%-%dd " w))) - (setq ivy-completion-beg start) + (ivy-count-format (and ivy-count-format + (format "%%-%dd " w)))) + (setq ivy-completion-beg (- end (ivy-completion-common-length (car comps)))) (setq ivy-completion-end end) (and - (ivy-read (format "(%s): " str) comps + (ivy-read (format "(%s): " str) + ;; remove 'completions-first-difference face + (mapcar #'substring-no-properties comps) :predicate predicate :action #'ivy-completion-in-region-action :require-match t)