branch: externals/ivy commit b37ba530c657aa27719532f0d0029d89a437281c Merge: 4db4001 7c5d49f Author: Basil L. Contovounesios <conto...@tcd.ie> Commit: Basil L. Contovounesios <conto...@tcd.ie>
Merge branch 'master' into externals/ivy --- ivy-test.el | 35 +++++++++++++++++++++++++++++++++++ ivy.el | 29 +++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/ivy-test.el b/ivy-test.el index 2062b81..44f293e 100644 --- a/ivy-test.el +++ b/ivy-test.el @@ -1688,6 +1688,41 @@ a buffer visiting a file." "k789")) (should (equal ivy-text "k7")))) +(ert-deftest ivy--break-lines () + "Test `ivy--break-lines' behavior." + (dolist (width '(-1 0)) + (dolist (str '("" "\n" "a" "a\nb")) + (should (equal (ivy--break-lines str width) str)))) + (should (equal (ivy--break-lines "" 1) "")) + (should (equal (ivy--break-lines "a" 1) "a")) + (should (equal (ivy--break-lines "a" 2) "a")) + (should (equal (ivy--break-lines "ab" 1) "a\nb")) + (should (equal (ivy--break-lines "ab" 2) "ab")) + (should (equal (ivy--break-lines "abc" 1) "a\nb\nc")) + (should (equal (ivy--break-lines "abc" 2) "ab\nc")) + (should (equal (ivy--break-lines "abc" 3) "abc")) + (should (equal (ivy--break-lines "\^X" 1) "\^X")) + (should (equal (ivy--break-lines "\^X" 2) "\^X")) + (should (equal (ivy--break-lines "a\^X" 1) "a\n\^X")) + (should (equal (ivy--break-lines "a\^X" 2) "a\n\^X")) + (should (equal (ivy--break-lines "a\^X" 3) "a\^X")) + (should (equal (ivy--break-lines "\^X\^X" 1) "\^X\n\^X")) + (should (equal (ivy--break-lines "\^X\^X" 2) "\^X\n\^X")) + (should (equal (ivy--break-lines "\^X\^X" 3) "\^X\n\^X")) + (should (equal (ivy--break-lines "\^X\^X" 4) "\^X\^X")) + (should (equal (ivy--break-lines "\nfoo\n\^X\^X\^X\nbar\n" 1) + "\nf\no\no\n\^X\n\^X\n\^X\nb\na\nr\n")) + (should (equal (ivy--break-lines "\nfoo\n\^X\^X\^X\nbar\n" 2) + "\nfo\no\n\^X\n\^X\n\^X\nba\nr\n")) + (should (equal (ivy--break-lines "\nfoo\n\^X\^X\^X\nbar\n" 3) + "\nfoo\n\^X\n\^X\n\^X\nbar\n")) + (should (equal (ivy--break-lines "\nfoo\n\^X\^X\^X\nbar\n" 4) + "\nfoo\n\^X\^X\n\^X\nbar\n")) + (should (equal (ivy--break-lines "\nfoo\n\^X\^X\^X\nbar\n" 5) + "\nfoo\n\^X\^X\n\^X\nbar\n")) + (should (equal (ivy--break-lines "\nfoo\n\^X\^X\^X\nbar\n" 6) + "\nfoo\n\^X\^X\^X\nbar\n"))) + (defun ivy-test-run-tests () (let ((test-sets '( diff --git a/ivy.el b/ivy.el index a8d2682..655d777 100644 --- a/ivy.el +++ b/ivy.el @@ -3068,6 +3068,26 @@ parts beyond their respective faces `ivy-confirm-face' and (funcall fn (ivy-state-prompt ivy-last)))) ivy--prompt))) +(defun ivy--break-lines (str width) + "Break each line in STR with newlines to fit into WIDTH columns." + (if (<= width 0) + str + (let (lines) + (dolist (line (split-string str "\n")) + (while (and line (> (string-width line) width)) + (let ((prefix "") (extra 0)) + (while (string-empty-p prefix) + ;; Grow `width' until it fits at least one char from `line'. + (setq prefix (truncate-string-to-width line (+ width extra))) + (setq extra (1+ extra))) + ;; Avoid introducing spurious newline if `prefix' and `line' are + ;; equal, i.e., if `line' couldn't be truncated to `width'. + (setq line (and (> (length line) (length prefix)) + (substring line (length prefix)))) + (push prefix lines))) + (when line (push line lines))) + (string-join (nreverse lines) "\n")))) + (defun ivy--insert-prompt () "Update the prompt according to `ivy--prompt'." (when (setq ivy--prompt (ivy-prompt)) @@ -3122,14 +3142,7 @@ parts beyond their respective faces `ivy-confirm-face' and (setq n-str (concat (funcall ivy-pre-prompt-function) n-str))) (when ivy-add-newline-after-prompt (setq n-str (concat n-str "\n"))) - ;; FIXME: This does not take character widths into account! - ;; Should ideally let the display engine wrap text, otherwise - ;; use `window-text-pixel-size'. See e.g. #2869. - (let ((regex (format "\\([^\n]\\{%d\\}\\)[^\n]" (window-width)))) - (while (string-match regex n-str) - (setq n-str (replace-match - (concat (match-string 1 n-str) "\n") - nil t n-str 1)))) + (setq n-str (ivy--break-lines n-str (window-width))) (set-text-properties 0 (length n-str) `(face minibuffer-prompt ,@std-props) n-str)