emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 8b73497 54/54: Merge commit 'ba49407c5b4c719dd5dcc298c2605


From: Oleh Krehel
Subject: [elpa] master 8b73497 54/54: Merge commit 'ba49407c5b4c719dd5dcc298c260513abf0c70df' from swiper
Date: Tue, 29 Sep 2015 14:10:12 +0000

branch: master
commit 8b734977727d8c96e3f716bcda3e0e20ccf70fa1
Merge: af81566 ba49407
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Merge commit 'ba49407c5b4c719dd5dcc298c260513abf0c70df' from swiper
---
 packages/swiper/counsel.el |  240 ++++++++++++++++++++++++++++++++++++++------
 packages/swiper/ivy.el     |  221 +++++++++++++++++++++++++++++++++--------
 packages/swiper/swiper.el  |  181 ++++++++++++++++++++++++++-------
 3 files changed, 531 insertions(+), 111 deletions(-)

diff --git a/packages/swiper/counsel.el b/packages/swiper/counsel.el
index 63c9552..ac04e67 100644
--- a/packages/swiper/counsel.el
+++ b/packages/swiper/counsel.el
@@ -33,6 +33,7 @@
 ;;; Code:
 
 (require 'swiper)
+(require 'etags)
 
 (defvar counsel-completion-beg nil
   "Completion bounds start.")
@@ -81,18 +82,73 @@
               :initial-input str
               :action #'counsel--el-action)))
 
+(declare-function slime-symbol-start-pos "ext:slime")
+(declare-function slime-symbol-end-pos "ext:slime")
+(declare-function slime-contextual-completions "ext:slime-c-p-c")
+
+;;;###autoload
+(defun counsel-cl ()
+  "Common Lisp completion at point."
+  (interactive)
+  (setq counsel-completion-beg (slime-symbol-start-pos))
+  (setq counsel-completion-end (slime-symbol-end-pos))
+  (ivy-read "Symbol name: "
+            (car (slime-contextual-completions
+                  counsel-completion-beg
+                  counsel-completion-end))
+            :action #'counsel--el-action))
+
 (defun counsel--el-action (symbol)
   "Insert SYMBOL, erasing the previous one."
   (when (stringp symbol)
-    (when counsel-completion-beg
-      (delete-region
-       counsel-completion-beg
-       counsel-completion-end))
-    (setq counsel-completion-beg
-          (move-marker (make-marker) (point)))
-    (insert symbol)
-    (setq counsel-completion-end
-          (move-marker (make-marker) (point)))))
+    (with-ivy-window
+      (when counsel-completion-beg
+        (delete-region
+         counsel-completion-beg
+         counsel-completion-end))
+      (setq counsel-completion-beg
+            (move-marker (make-marker) (point)))
+      (insert symbol)
+      (setq counsel-completion-end
+            (move-marker (make-marker) (point))))))
+
+(declare-function deferred:sync! "ext:deferred")
+(declare-function jedi:complete-request "ext:jedi-core")
+(declare-function jedi:ac-direct-matches "ext:jedi")
+
+(defun counsel-jedi ()
+  "Python completion at point."
+  (interactive)
+  (let ((bnd (bounds-of-thing-at-point 'symbol)))
+    (if bnd
+        (progn
+          (setq counsel-completion-beg (car bnd))
+          (setq counsel-completion-end (cdr bnd)))
+      (setq counsel-completion-beg nil)
+      (setq counsel-completion-end nil)))
+  (deferred:sync!
+   (jedi:complete-request))
+  (ivy-read "Symbol name: " (jedi:ac-direct-matches)
+            :action #'counsel--py-action))
+
+(defun counsel--py-action (symbol)
+  "Insert SYMBOL, erasing the previous one."
+  (when (stringp symbol)
+    (with-ivy-window
+      (when counsel-completion-beg
+        (delete-region
+         counsel-completion-beg
+         counsel-completion-end))
+      (setq counsel-completion-beg
+            (move-marker (make-marker) (point)))
+      (insert symbol)
+      (setq counsel-completion-end
+            (move-marker (make-marker) (point)))
+      (when (equal (get-text-property 0 'symbol symbol) "f")
+        (insert "()")
+        (setq counsel-completion-end
+              (move-marker (make-marker) (point)))
+        (backward-char 1)))))
 
 (defvar counsel-describe-map
   (let ((map (make-sparse-keymap)))
@@ -114,6 +170,7 @@
 
 (defun counsel--find-symbol (x)
   "Find symbol definition that corresponds to string X."
+  (ring-insert find-tag-marker-ring (point-marker))
   (let ((full-name (get-text-property 0 'full-name x)))
     (if full-name
         (find-library full-name)
@@ -138,7 +195,7 @@
   "Return current symbol at point as a string."
   (let ((s (thing-at-point 'symbol)))
     (and (stringp s)
-         (if (string-match "\\`[`']?\\(.*\\)'?\\'" s)
+         (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s)
              (match-string 1 s)
            s))))
 
@@ -230,11 +287,16 @@
   (require 'info-look)
   (info-lookup 'symbol symbol mode))
 
+(defvar counsel-unicode-char-history nil
+  "History for `counsel-unicode-char'.")
+
 ;;;###autoload
 (defun counsel-unicode-char ()
   "Insert a Unicode character at point."
   (interactive)
   (let ((minibuffer-allow-text-properties t))
+    (setq counsel-completion-beg (point))
+    (setq counsel-completion-end (point))
     (ivy-read "Unicode name: "
               (mapcar (lambda (x)
                         (propertize
@@ -242,7 +304,12 @@
                          'result (cdr x)))
                       (ucs-names))
               :action (lambda (char)
-                        (insert-char (get-text-property 0 'result char))))))
+                        (with-ivy-window
+                          (delete-region counsel-completion-beg 
counsel-completion-end)
+                          (setq counsel-completion-beg (point))
+                          (insert-char (get-text-property 0 'result char))
+                          (setq counsel-completion-end (point))))
+              :history 'counsel-unicode-char-history)))
 
 (declare-function cider-sync-request:complete "ext:cider-client")
 ;;;###autoload
@@ -288,7 +355,7 @@
       (counsel-more-chars 3)
     (let* ((default-directory counsel--git-grep-dir)
            (cmd (format "git --no-pager grep --full-name -n --no-color -i -e 
%S"
-                        (ivy--regex string t))))
+                        (setq ivy--old-re (ivy--regex string t)))))
       (if (<= counsel--git-grep-count 20000)
           (split-string (shell-command-to-string cmd) "\n" t)
         (counsel--gg-candidates (ivy--regex string))
@@ -430,7 +497,9 @@ Skip some dotfiles unless `ivy-text' requires them."
   (if (string= event "finished\n")
       (progn
         (with-current-buffer (process-buffer process)
-          (setq ivy--all-candidates (split-string (buffer-string) "\n" t))
+          (setq ivy--all-candidates
+                (ivy--sort-maybe
+                 (split-string (buffer-string) "\n" t)))
           (setq ivy--old-cands ivy--all-candidates))
         (ivy--exhibit))
     (if (string= event "exited abnormally with code 1\n")
@@ -444,7 +513,11 @@ Skip some dotfiles unless `ivy-text' requires them."
   (call-process shell-file-name nil
                 nil nil
                 shell-command-switch
-                (format "xdg-open %s" (shell-quote-argument x))))
+                (format "%s %s"
+                        (if (eq system-type 'darwin)
+                                    "open"
+                                  "xdg-open")
+                        (shell-quote-argument x))))
 
 (declare-function dired-jump "dired-x")
 (defun counsel-locate-action-dired (x)
@@ -454,16 +527,33 @@ Skip some dotfiles unless `ivy-text' requires them."
 (defvar counsel-locate-history nil
   "History for `counsel-locate'.")
 
+(defcustom counsel-locate-options (if (eq system-type 'darwin)
+                                      '("-i")
+                                    '("-i" "--regex"))
+  "Command line options for `locate`."
+  :group 'ivy
+  :type  '(repeat string))
+
 (ivy-set-actions
  'counsel-locate
  '(("x" counsel-locate-action-extern "xdg-open")
    ("d" counsel-locate-action-dired "dired")))
 
+(defun counsel-unquote-regex-parens (str)
+  (replace-regexp-in-string
+   "\\\\)" ")"
+   (replace-regexp-in-string
+    "\\\\(" "("
+    str)))
+
 (defun counsel-locate-function (str &rest _u)
   (if (< (length str) 3)
       (counsel-more-chars 3)
     (counsel--async-command
-     (concat "locate -i --regex " (ivy--regex str)))
+     (format "locate %s '%s'"
+             (mapconcat #'identity counsel-locate-options " ")
+             (counsel-unquote-regex-parens
+              (ivy--regex str))))
     '("" "working...")))
 
 ;;;###autoload
@@ -783,22 +873,50 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and
       (t (error "Tags alignment failed")))
     (org-move-to-column col)))
 
+(defun counsel-org--set-tags ()
+  (counsel-org-change-tags
+   (if counsel-org-tags
+       (format ":%s:"
+               (mapconcat #'identity counsel-org-tags ":"))
+     "")))
+
+(defvar org-agenda-bulk-marked-entries)
+
+(declare-function org-get-at-bol "org")
+(declare-function org-agenda-error "org-agenda")
+
 (defun counsel-org-tag-action (x)
   (if (member x counsel-org-tags)
       (progn
         (setq counsel-org-tags (delete x counsel-org-tags)))
-    (setq counsel-org-tags (append counsel-org-tags (list x)))
-    (unless (member x ivy--all-candidates)
-      (setq ivy--all-candidates (append ivy--all-candidates (list x)))))
+    (unless (equal x "")
+      (setq counsel-org-tags (append counsel-org-tags (list x)))
+      (unless (member x ivy--all-candidates)
+        (setq ivy--all-candidates (append ivy--all-candidates (list x))))))
   (let ((prompt (counsel-org-tag-prompt)))
     (setf (ivy-state-prompt ivy-last) prompt)
     (setq ivy--prompt (concat "%-4d " prompt)))
-  (cond ((memq this-command '(ivy-done ivy-alt-done))
-         (counsel-org-change-tags
-          (if counsel-org-tags
-              (format ":%s:"
-                      (mapconcat #'identity counsel-org-tags ":"))
-            "")))
+  (cond ((memq this-command '(ivy-done
+                              ivy-alt-done
+                              ivy-immediate-done))
+         (if (eq major-mode 'org-agenda-mode)
+             (if (null org-agenda-bulk-marked-entries)
+                 (let ((hdmarker (or (org-get-at-bol 'org-hd-marker)
+                                     (org-agenda-error))))
+                   (with-current-buffer (marker-buffer hdmarker)
+                     (goto-char hdmarker)
+                     (counsel-org--set-tags)))
+               (let ((add-tags (copy-sequence counsel-org-tags)))
+                 (dolist (m org-agenda-bulk-marked-entries)
+                   (with-current-buffer (marker-buffer m)
+                     (save-excursion
+                       (goto-char m)
+                       (setq counsel-org-tags
+                             (delete-dups
+                              (append (split-string (org-get-tags-string) ":" 
t)
+                                      add-tags)))
+                       (counsel-org--set-tags))))))
+           (counsel-org--set-tags)))
         ((eq this-command 'ivy-call)
          (delete-minibuffer-contents))))
 
@@ -824,15 +942,25 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and
   "Add or remove tags in org-mode."
   (interactive)
   (save-excursion
-    (unless (org-at-heading-p)
-      (org-back-to-heading t))
-    (setq counsel-org-tags (split-string (org-get-tags-string) ":" t))
+    (if (eq major-mode 'org-agenda-mode)
+        (if org-agenda-bulk-marked-entries
+            (setq counsel-org-tags nil)
+          (let ((hdmarker (or (org-get-at-bol 'org-hd-marker)
+                              (org-agenda-error))))
+            (with-current-buffer (marker-buffer hdmarker)
+              (goto-char hdmarker)
+              (setq counsel-org-tags
+                    (split-string (org-get-tags-string) ":" t)))))
+      (unless (org-at-heading-p)
+        (org-back-to-heading t))
+      (setq counsel-org-tags (split-string (org-get-tags-string) ":" t)))
     (let ((org-setting-tags t)
           (org-last-tags-completion-table
            (append org-tag-persistent-alist
                    (or org-tag-alist (org-get-buffer-tags))
                    (and
-                    org-complete-tags-always-offer-all-agenda-tags
+                    (or org-complete-tags-always-offer-all-agenda-tags
+                        (eq major-mode 'org-agenda-mode))
                     (org-global-tags-completion-table
                      (org-agenda-files))))))
       (ivy-read (counsel-org-tag-prompt)
@@ -858,11 +986,9 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and
   "Grep in the current directory for STRING."
   (if (< (length string) 3)
       (counsel-more-chars 3)
-    (let ((regex (replace-regexp-in-string
-                  "\\\\)" ")"
-                  (replace-regexp-in-string
-                   "\\\\(" "("
-                   (ivy--regex string)))))
+    (let ((regex (counsel-unquote-regex-parens
+                  (setq ivy--old-re
+                        (ivy--regex string)))))
       (counsel--async-command
        (format "ag --noheading --nocolor %S" regex))
       nil)))
@@ -912,6 +1038,54 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
                           (unless (string-match "pdf$" x)
                             (swiper ivy-text)))))))
 
+(defcustom counsel-yank-pop-truncate nil
+  "When non-nil, truncate the display of long strings."
+  :group 'ivy)
+
+;;;###autoload
+(defun counsel-yank-pop ()
+  "Ivy replacement for `yank-pop'."
+  (interactive)
+  (if (eq last-command 'yank)
+      (progn
+        (setq counsel-completion-end (point))
+        (setq counsel-completion-beg
+              (save-excursion
+                (search-backward (car kill-ring))
+                (point))))
+    (setq counsel-completion-beg (point))
+    (setq counsel-completion-end (point)))
+  (let ((candidates (cl-remove-if
+                     (lambda (s)
+                       (or (< (length s) 3)
+                           (string-match "\\`[\n[:blank:]]+\\'" s)))
+                     (delete-dups kill-ring))))
+    (when counsel-yank-pop-truncate
+      (setq candidates
+            (mapcar (lambda (s)
+                      (if (string-match "\\`\\(.*\n.*\n.*\n.*\\)\n" s)
+                          (progn
+                            (let ((s (copy-sequence s)))
+                              (put-text-property
+                               (match-end 1)
+                               (length s)
+                               'display
+                               " [...]"
+                               s)
+                              s))
+                        s))
+                    candidates)))
+    (ivy-read "kill-ring: " candidates
+              :action 'counsel-yank-pop-action)))
+
+(defun counsel-yank-pop-action (s)
+  "Insert S into the buffer, overwriting the previous yank."
+  (with-ivy-window
+    (delete-region counsel-completion-beg
+                   counsel-completion-end)
+    (insert (substring-no-properties s))
+    (setq counsel-completion-end (point))))
+
 (provide 'counsel)
 
 ;;; counsel.el ends here
diff --git a/packages/swiper/ivy.el b/packages/swiper/ivy.el
index 21197c3..04c254e 100644
--- a/packages/swiper/ivy.el
+++ b/packages/swiper/ivy.el
@@ -44,7 +44,10 @@
   :group 'convenience)
 
 (defface ivy-current-match
-  '((t (:inherit highlight)))
+  '((((class color) (background light))
+     :background "#1a4b77" :foreground "white")
+    (((class color) (background dark))
+     :background "#65a7e2" :foreground "black"))
   "Face used by Ivy for highlighting first match.")
 
 (defface ivy-confirm-face
@@ -78,6 +81,17 @@ and the candidate count."
   "Whether to wrap around after the first and last candidate."
   :type 'boolean)
 
+(defcustom ivy-display-style nil
+  "The style for formatting the minibuffer.
+
+By default, the matched strings will be copied as they are.
+
+With the fancy method, the matching parts of the regexp will be
+additionally highlighted, just like `swiper' does it."
+  :type '(choice
+          (const :tag "Plain" nil)
+          (const :tag "Fancy" fancy)))
+
 (defcustom ivy-on-del-error-function 'minibuffer-keyboard-quit
   "The handler for when `ivy-backward-delete-char' throws.
 This is usually meant as a quick exit out of the minibuffer."
@@ -123,8 +137,6 @@ Only \"./\" and \"../\" apply here. They appear in reverse 
order."
     (define-key map (kbd "M-d") 'ivy-kill-word)
     (define-key map (kbd "M-<") 'ivy-beginning-of-buffer)
     (define-key map (kbd "M->") 'ivy-end-of-buffer)
-    (define-key map (kbd "<left>") 'ivy-beginning-of-buffer)
-    (define-key map (kbd "<right>") 'ivy-end-of-buffer)
     (define-key map (kbd "M-n") 'ivy-next-history-element)
     (define-key map (kbd "M-p") 'ivy-previous-history-element)
     (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
@@ -139,6 +151,7 @@ Only \"./\" and \"../\" apply here. They appear in reverse 
order."
     (define-key map (kbd "M-o") 'ivy-dispatching-done)
     (define-key map (kbd "C-k") 'ivy-kill-line)
     (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
+    (define-key map (kbd "M-w") 'ivy-kill-ring-save)
     map)
   "Keymap used in the minibuffer.")
 (autoload 'hydra-ivy/body "ivy-hydra" "" t)
@@ -428,6 +441,7 @@ If the text hasn't changed as a result, forward to 
`ivy-alt-done'."
   (setq ivy-exit 'done)
   (exit-minibuffer))
 
+;;;###autoload
 (defun ivy-resume ()
   "Resume the last completion session."
   (interactive)
@@ -481,6 +495,7 @@ If the text hasn't changed as a result, forward to 
`ivy-alt-done'."
   (interactive)
   (ivy-set-index (max (- ivy--index ivy-height)
                       0)))
+
 (defun ivy-minibuffer-grow ()
   "Grow the minibuffer window by 1 line."
   (interactive)
@@ -875,6 +890,10 @@ candidates with each input."
              (let* ((hist (or history 'ivy-history))
                     (minibuffer-completion-table collection)
                     (minibuffer-completion-predicate predicate)
+                    (resize-mini-windows (cond
+                                          ((display-graphic-p) nil)
+                                          ((null resize-mini-windows) 
'grow-only)
+                                          (t resize-mini-windows)))
                     (res (read-from-minibuffer
                           prompt
                           (ivy-state-initial-input ivy-last)
@@ -954,6 +973,7 @@ This is useful for recursive `ivy-read'."
             ((eq collection 'internal-complete-buffer)
              (setq coll (ivy--buffer-list "" ivy-use-virtual-buffers)))
             ((or (functionp collection)
+                 (byte-code-function-p collection)
                  (vectorp collection)
                  (listp (car collection)))
              (setq coll (all-completions "" collection predicate)))
@@ -1014,6 +1034,7 @@ This is useful for recursive `ivy-read'."
                  nil)))
     (setf (ivy-state-initial-input ivy-last) initial-input)))
 
+;;;###autoload
 (defun ivy-completing-read (prompt collection
                             &optional predicate require-match initial-input
                               history def _inherit-input-method)
@@ -1038,7 +1059,11 @@ The history, defaults and input-method arguments are 
ignored for now."
             :require-match require-match
             :initial-input (if (consp initial-input)
                                (car initial-input)
-                             initial-input)
+                             (if (and (stringp initial-input)
+                                      (string-match "\\+" initial-input))
+                                 (replace-regexp-in-string
+                                  "\\+" "\\\\+" initial-input)
+                               initial-input))
             :preselect (if (listp def) (car def) def)
             :history history
             :keymap nil
@@ -1209,6 +1234,8 @@ Insert .* between each char."
   (set (make-local-variable 'minibuffer-default-add-function)
        (lambda ()
          (list ivy--default)))
+  (when (display-graphic-p)
+    (setq truncate-lines t))
   (setq-local max-mini-window-height ivy-height)
   (add-hook 'post-command-hook #'ivy--exhibit nil t)
   ;; show completions with empty input
@@ -1267,6 +1294,10 @@ Insert .* between each char."
         (save-excursion
           (goto-char (point-min))
           (delete-region (point-min) (minibuffer-prompt-end))
+          (when (> (length n-str) (window-width))
+            (setq n-str (concat (substring n-str 0
+                                           (max (- (window-width) 30)
+                                                10)) "... ")))
           (set-text-properties 0 (length n-str)
                                `(face minibuffer-prompt ,@std-props)
                                n-str)
@@ -1289,6 +1320,23 @@ Insert .* between each char."
 
 (defvar inhibit-message)
 
+(defun ivy--sort-maybe (collection)
+  "Sort COLLECTION if needed."
+  (let ((sort (ivy-state-sort ivy-last))
+        entry)
+    (if (null sort)
+        collection
+      (let ((sort-fn (cond ((functionp sort)
+                            sort)
+                           ((setq entry (assoc (ivy-state-collection ivy-last)
+                                               ivy-sort-functions-alist))
+                            (cdr entry))
+                           (t
+                            (cdr (assoc t ivy-sort-functions-alist))))))
+        (if (functionp sort-fn)
+            (cl-sort (copy-sequence collection) sort-fn)
+          collection)))))
+
 (defun ivy--exhibit ()
   "Insert Ivy completions display.
 Should be run via minibuffer `post-command-hook'."
@@ -1301,7 +1349,8 @@ Should be run via minibuffer `post-command-hook'."
           (unless (equal ivy--old-text ivy-text)
             (while-no-input
               (setq ivy--all-candidates
-                    (funcall (ivy-state-collection ivy-last) ivy-text))
+                    (ivy--sort-maybe
+                     (funcall (ivy-state-collection ivy-last) ivy-text)))
               (setq ivy--old-text ivy-text)))
           (when ivy--all-candidates
             (ivy--insert-minibuffer
@@ -1352,7 +1401,23 @@ Should be run via minibuffer `post-command-hook'."
       (let ((buffer-undo-list t))
         (save-excursion
           (forward-line 1)
-          (insert text))))))
+          (insert text))))
+    (when (display-graphic-p)
+      (ivy--resize-minibuffer-to-fit))))
+
+(defun ivy--resize-minibuffer-to-fit ()
+  "Resize the minibuffer window so it has enough space to display
+all of the text contained in the minibuffer."
+  (with-selected-window (minibuffer-window)
+    (if (fboundp 'window-text-pixel-size)
+        (let ((text-height (cdr (window-text-pixel-size)))
+              (body-height (window-body-height nil t)))
+          (when (> text-height body-height)
+            (window-resize nil (- text-height body-height) nil t t)))
+        (let ((text-height (count-screen-lines))
+              (body-height (window-body-height)))
+          (when (> text-height body-height)
+            (window-resize nil (- text-height body-height) nil t))))))
 
 (declare-function colir-blend-face-background "ext:colir")
 
@@ -1362,7 +1427,15 @@ Should be run via minibuffer `post-command-hook'."
 `propertize' or `add-face-text-property' in this case."
   (require 'colir)
   (condition-case nil
-      (colir-blend-face-background 0 (length str) face str)
+      (progn
+        (colir-blend-face-background 0 (length str) face str)
+        (let ((foreground (face-foreground face)))
+          (when foreground
+            (add-face-text-property
+             0 (length str)
+             `(:foreground ,foreground)
+             nil
+             str))))
     (error
      (ignore-errors
        (font-lock-append-text-property 0 (length str) 'face face str))))
@@ -1372,6 +1445,7 @@ Should be run via minibuffer `post-command-hook'."
   "Return all items that match NAME in CANDIDATES.
 CANDIDATES are assumed to be static."
   (let* ((re (funcall ivy--regex-function name))
+         (re-str (if (listp re) (caar re) re))
          (matcher (ivy-state-matcher ivy-last))
          (case-fold-search (string= name (downcase name)))
          (cands (cond
@@ -1412,17 +1486,17 @@ CANDIDATES are assumed to be static."
          (tail (nthcdr ivy--index ivy--old-cands))
          idx)
     (when (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
-      (unless (and (not (equal re ivy--old-re))
+      (unless (and (not (equal re-str ivy--old-re))
                    (or (setq ivy--index
                              (or
-                              (cl-position (if (and (> (length re) 0)
-                                                    (eq ?^ (aref re 0)))
-                                               (substring re 1)
-                                             re) cands
+                              (cl-position (if (and (> (length re-str) 0)
+                                                    (eq ?^ (aref re-str 0)))
+                                               (substring re-str 1)
+                                             re-str) cands
                                              :test #'equal)
                               (and ivy--directory
                                    (cl-position
-                                    (concat re "/") cands
+                                    (concat re-str "/") cands
                                     :test #'equal))))))
         (while (and tail (null idx))
           ;; Compare with eq to handle equal duplicates in cands
@@ -1433,7 +1507,7 @@ CANDIDATES are assumed to be static."
             (or (cl-position (ivy-state-preselect ivy-last)
                              cands :test #'equal)
                 ivy--index)))
-    (setq ivy--old-re (if cands re ""))
+    (setq ivy--old-re (if cands re-str ""))
     (setq ivy--old-cands cands)))
 
 (defvar ivy-format-function 'ivy-format-function-default
@@ -1442,13 +1516,16 @@ This string will be inserted into the minibuffer.")
 
 (defun ivy-format-function-default (cands)
   "Transform CANDS into a string for minibuffer."
-  (let ((ww (window-width)))
-    (mapconcat
-     (lambda (s)
-       (if (> (length s) ww)
-           (concat (substring s 0 (- ww 3)) "...")
-         s))
-     cands "\n")))
+  (if (bound-and-true-p truncate-lines)
+      (mapconcat #'identity cands "\n")
+    (let ((ww (- (window-width)
+                 (if (and (boundp 'fringe-mode) (eq fringe-mode 0)) 1 0))))
+      (mapconcat
+       (lambda (s)
+         (if (> (length s) ww)
+             (concat (substring s 0 (- ww 3)) "...")
+           s))
+       cands "\n"))))
 
 (defun ivy-format-function-arrow (cands)
   "Transform CANDS into a string for minibuffer."
@@ -1461,6 +1538,48 @@ This string will be inserted into the minibuffer.")
                s))
      cands "\n")))
 
+(defcustom swiper-minibuffer-faces
+  '(swiper-minibuffer-match-face-1
+    swiper-minibuffer-match-face-2
+    swiper-minibuffer-match-face-3
+    swiper-minibuffer-match-face-4)
+  "List of `swiper' faces for minibuffer group matches.")
+
+(defun ivy--format-minibuffer-line (str)
+  (let ((start 0)
+        (str (copy-sequence str)))
+    (when (eq ivy-display-style 'fancy)
+      (unless ivy--old-re
+        (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
+      (while (and (string-match ivy--old-re str start)
+                  (> (- (match-end 0) (match-beginning 0)) 0))
+        (setq start (match-end 0))
+        (let ((i 0))
+          (while (<= i ivy--subexps)
+            (let ((face
+                   (cond ((zerop ivy--subexps)
+                          (cadr swiper-minibuffer-faces))
+                         ((zerop i)
+                          (car swiper-minibuffer-faces))
+                         (t
+                          (nth (1+ (mod (+ i 2) (1- (length 
swiper-minibuffer-faces))))
+                               swiper-minibuffer-faces)))))
+              (if (fboundp 'add-face-text-property)
+                  (add-face-text-property
+                   (match-beginning i)
+                   (match-end i)
+                   face
+                   nil
+                   str)
+                (font-lock-append-text-property
+                 (match-beginning i)
+                 (match-end i)
+                 'face
+                 face
+                 str)))
+            (cl-incf i)))))
+    str))
+
 (defun ivy--format (cands)
   "Return a string for CANDS suitable for display in the minibuffer.
 CANDS is a list of strings."
@@ -1482,18 +1601,11 @@ CANDS is a list of strings."
                                 x))
                             cands)))
       (setq ivy--current (copy-sequence (nth index cands)))
-      (setf (nth index cands)
-            (ivy--add-face ivy--current 'ivy-current-match))
       (setq cands (mapcar
-                   (lambda (s)
-                     (let ((s (copy-sequence s)))
-                       (when (fboundp 'add-face-text-property)
-                         (add-face-text-property
-                          0 (length s)
-                          `(:height ,(face-attribute 'default :height)
-                                    :overline nil) nil s))
-                       s))
+                   #'ivy--format-minibuffer-line
                    cands))
+      (setf (nth index cands)
+            (ivy--add-face (nth index cands) 'ivy-current-match))
       (let* ((ivy--index index)
              (res (concat "\n" (funcall ivy-format-function cands))))
         (put-text-property 0 (length res) 'read-only nil res)
@@ -1556,15 +1668,16 @@ When VIRTUAL is non-nil, add virtual buffers."
 (defun ivy--switch-buffer-action (buffer)
   "Switch to BUFFER.
 BUFFER may be a string or nil."
-  (if (zerop (length buffer))
-      (switch-to-buffer
-       ivy-text nil 'force-same-window)
-    (let ((virtual (assoc buffer ivy--virtual-buffers)))
-      (if (and virtual
-               (not (get-buffer buffer)))
-          (find-file (cdr virtual))
+  (with-ivy-window
+    (if (zerop (length buffer))
         (switch-to-buffer
-         buffer nil 'force-same-window)))))
+         ivy-text nil 'force-same-window)
+      (let ((virtual (assoc buffer ivy--virtual-buffers)))
+        (if (and virtual
+                 (not (get-buffer buffer)))
+            (find-file (cdr virtual))
+          (switch-to-buffer
+           buffer nil 'force-same-window))))))
 
 (defun ivy--switch-buffer-other-window-action (buffer)
   "Switch to BUFFER in other window.
@@ -1577,6 +1690,12 @@ BUFFER may be a string or nil."
           (find-file-other-window (cdr virtual))
         (switch-to-buffer-other-window buffer)))))
 
+(defun ivy--rename-buffer-action (buffer)
+  "Rename BUFFER."
+  (let ((new-name (read-string "Rename buffer (to new name): ")))
+    (with-current-buffer buffer
+      (rename-buffer new-name))))
+
 (defvar ivy-switch-buffer-map (make-sparse-keymap))
 
 (ivy-set-actions
@@ -1588,8 +1707,12 @@ BUFFER may be a string or nil."
     "kill")
    ("j"
     ivy--switch-buffer-other-window-action
-    "other")))
+    "other")
+   ("r"
+    ivy--rename-buffer-action
+    "rename")))
 
+;;;###autoload
 (defun ivy-switch-buffer ()
   "Switch to another buffer."
   (interactive)
@@ -1601,11 +1724,15 @@ BUFFER may be a string or nil."
                 :action #'ivy--switch-buffer-action
                 :keymap ivy-switch-buffer-map))))
 
+;;;###autoload
 (defun ivy-recentf ()
   "Find a file on `recentf-list'."
   (interactive)
   (ivy-read "Recentf: " recentf-list
-            :action #'find-file))
+            :action
+            (lambda (f)
+              (with-ivy-window
+                (find-file f)))))
 
 (defun ivy-yank-word ()
   "Pull next word from buffer into search string."
@@ -1621,6 +1748,18 @@ BUFFER may be a string or nil."
     (when amend
       (insert amend))))
 
+(defun ivy-kill-ring-save ()
+  "Store the current candidates into the kill ring.
+If the region is active, forward to `kill-ring-save' instead."
+  (interactive)
+  (if (region-active-p)
+      (call-interactively 'kill-ring-save)
+    (kill-new
+     (mapconcat
+      #'identity
+      ivy--old-cands
+      "\n"))))
+
 (defun ivy-insert-current ()
   "Make the current candidate into current input.
 Don't finish completion."
diff --git a/packages/swiper/swiper.el b/packages/swiper/swiper.el
index 1032f04..1b2d906 100644
--- a/packages/swiper/swiper.el
+++ b/packages/swiper/swiper.el
@@ -61,6 +61,35 @@
   '((t (:inherit isearch-fail)))
   "Face for `swiper' matches modulo 3.")
 
+(defface swiper-minibuffer-match-face-1
+  '((((class color) (background light))
+     :background "#d3d3d3")
+    (((class color) (background dark))
+     :background "#555555"))
+  "The background face for `swiper' minibuffer matches."
+  :group 'function-args-faces)
+
+(defface swiper-minibuffer-match-face-2
+  '((((class color) (background light))
+     :background "#e99ce8" :weight bold)
+    (((class color) (background dark))
+     :background "#777777" :weight bold))
+  "Face for `swiper' minibuffer matches modulo 1.")
+
+(defface swiper-minibuffer-match-face-3
+  '((((class color) (background light))
+     :background "#bbbbff" :weight bold)
+    (((class color) (background dark))
+     :background "#7777ff" :weight bold))
+  "Face for `swiper' minibuffer matches modulo 2.")
+
+(defface swiper-minibuffer-match-face-4
+  '((((class color) (background light))
+     :background "#ffbbff" :weight bold)
+    (((class color) (background dark))
+     :background "#8a498a" :weight bold))
+  "Face for `swiper' minibuffer matches modulo 3.")
+
 (defface swiper-line-face
   '((t (:inherit highlight)))
   "Face for current `swiper' line.")
@@ -144,7 +173,9 @@
                                  elfeed-search-mode
                                  fundamental-mode
                                  Man-mode
-                                 woman-mode)))
+                                 woman-mode
+                                 mu4e-view-mode
+                                 mu4e-headers-mode)))
     (unless (> (buffer-size) 100000)
       (if (fboundp 'font-lock-ensure)
           (font-lock-ensure)
@@ -162,19 +193,21 @@
     (unless (zerop n-lines)
       (setq swiper--width (1+ (floor (log n-lines 10))))
       (setq swiper--format-spec
-            (format "%%-%dd %%s" swiper--width))
+            (format "%%-%dd " swiper--width))
       (let ((line-number 0)
             candidates)
         (save-excursion
           (goto-char (point-min))
           (swiper-font-lock-ensure)
           (while (< (point) (point-max))
-            (push (format swiper--format-spec
-                          (cl-incf line-number)
-                          (buffer-substring
-                           (line-beginning-position)
-                           (line-end-position)))
-                  candidates)
+            (let ((str (concat " " (buffer-substring
+                                    (line-beginning-position)
+                                    (line-end-position)))))
+              (put-text-property 0 1 'display
+                                 (format swiper--format-spec
+                                         (cl-incf line-number))
+                                 str)
+              (push str candidates))
             (forward-line 1))
           (nreverse candidates))))))
 
@@ -228,17 +261,12 @@ there have line numbers. In the buffer, `ivy--regex' 
should be used."
   "`isearch' with an overview using `ivy'.
 When non-nil, INITIAL-INPUT is the initial search pattern."
   (interactive)
-  (unless (eq (length (help-function-arglist 'ivy-read)) 4)
-    (warn "You seem to be using the outdated stand-alone \"ivy\" package.
-Please remove it and update the \"swiper\" package."))
   (swiper--init)
   (let ((candidates (swiper--candidates))
-        (preselect (format
-                    swiper--format-spec
-                    (line-number-at-pos)
-                    (buffer-substring-no-properties
-                     (line-beginning-position)
-                     (line-end-position))))
+        (preselect (buffer-substring-no-properties
+                    (line-beginning-position)
+                    (line-end-position)))
+        (minibuffer-allow-text-properties t)
         res)
     (unwind-protect
          (setq res (ivy-read
@@ -280,26 +308,28 @@ Please remove it and update the \"swiper\" package."))
   "Called when `ivy' input is updated."
   (with-ivy-window
     (swiper--cleanup)
-    (let* ((re (ivy--regex ivy-text))
-           (str ivy--current)
-           (num (if (string-match "^[0-9]+" str)
-                    (string-to-number (match-string 0 str))
-                  0)))
-      (goto-char (point-min))
-      (when (cl-plusp num)
+    (when (> (length ivy--current) 0)
+      (let* ((re (funcall ivy--regex-function ivy-text))
+             (re (if (stringp re) re (caar re)))
+             (str (get-text-property 0 'display ivy--current))
+             (num (if (string-match "^[0-9]+" str)
+                      (string-to-number (match-string 0 str))
+                    0)))
         (goto-char (point-min))
-        (forward-line (1- num))
-        (if (and (equal ivy-text "")
-                 (>= swiper--opoint (line-beginning-position))
-                 (<= swiper--opoint (line-end-position)))
-            (goto-char swiper--opoint)
-          (re-search-forward re (line-end-position) t))
-        (isearch-range-invisible (line-beginning-position)
-                                 (line-end-position))
-        (unless (and (>= (point) (window-start))
-                     (<= (point) (window-end (ivy-state-window ivy-last) t)))
-          (recenter)))
-      (swiper--add-overlays re))))
+        (when (cl-plusp num)
+          (goto-char (point-min))
+          (forward-line (1- num))
+          (if (and (equal ivy-text "")
+                   (>= swiper--opoint (line-beginning-position))
+                   (<= swiper--opoint (line-end-position)))
+              (goto-char swiper--opoint)
+            (re-search-forward re (line-end-position) t))
+          (isearch-range-invisible (line-beginning-position)
+                                   (line-end-position))
+          (unless (and (>= (point) (window-start))
+                       (<= (point) (window-end (ivy-state-window ivy-last) t)))
+            (recenter)))
+        (swiper--add-overlays re)))))
 
 (defun swiper--add-overlays (re &optional beg end)
   "Add overlays for RE regexp in visible part of the current buffer.
@@ -347,7 +377,7 @@ BEG and END, when specified, are the point bounds."
   (if (null x)
       (user-error "No candidates")
     (goto-char (point-min))
-    (forward-line (1- (read x)))
+    (forward-line (1- (read (get-text-property 0 'display x))))
     (re-search-forward
      (ivy--regex input) (line-end-position) t)
     (swiper--ensure-visible)
@@ -366,6 +396,83 @@ BEG and END, when specified, are the point bounds."
     (isearch-exit)
     (swiper query)))
 
+(defvar swiper-multi-buffers nil
+  "Store the current list of buffers.")
+
+(defvar swiper-multi-candidates nil
+  "Store the list of candidates for `swiper-multi'.")
+
+(defun swiper-multi-prompt ()
+  (format "Buffers (%s): "
+          (mapconcat #'identity swiper-multi-buffers ", ")))
+
+(defun swiper-multi ()
+  "Select one or more buffers.
+Run `swiper' for those buffers."
+  (interactive)
+  (setq swiper-multi-buffers nil)
+  (setq swiper-multi-candidates nil)
+  (ivy-read (swiper-multi-prompt)
+            'internal-complete-buffer
+            :action 'swiper-multi-action-1)
+  (ivy-read "Swiper: " swiper-multi-candidates
+            :action 'swiper-multi-action-2
+            :unwind #'swiper--cleanup))
+
+(defun swiper-multi-action-1 (x)
+  (if (member x swiper-multi-buffers)
+      (progn
+        (setq swiper-multi-buffers (delete x swiper-multi-buffers)))
+    (unless (equal x "")
+      (setq swiper-multi-buffers (append swiper-multi-buffers (list x)))))
+  (let ((prompt (swiper-multi-prompt)))
+    (setf (ivy-state-prompt ivy-last) prompt)
+    (setq ivy--prompt (concat "%-4d " prompt)))
+  (cond ((memq this-command '(ivy-done
+                              ivy-alt-done
+                              ivy-immediate-done))
+         (let ((ww (window-width)))
+           (dolist (buf swiper-multi-buffers)
+             (with-current-buffer buf
+               (setq swiper-multi-candidates
+                     (append
+                      (mapcar
+                       (lambda (s)
+                         (setq s (concat s " "))
+                         (let ((len (length s)))
+                           (put-text-property
+                            (1- len) len 'display
+                            (concat
+                             (make-string
+                              (max
+                               (- ww
+                                  (string-width s)
+                                  (length (buffer-name))
+                                  1)
+                               0)
+                              ?\ )
+                             (buffer-name))
+                            s)
+                           s))
+                       (swiper--candidates))
+                      swiper-multi-candidates))))))
+        ((eq this-command 'ivy-call)
+         (delete-minibuffer-contents))))
+
+(defun swiper-multi-action-2 (x)
+  (let ((buf-space (get-text-property (1- (length x)) 'display x)))
+    (with-ivy-window
+      (when (string-match "\\` *\\([^ ]+\\)\\'" buf-space)
+        (switch-to-buffer (match-string 1 buf-space))
+        (goto-char (point-min))
+        (forward-line (1- (read x)))
+        (re-search-forward
+         (ivy--regex ivy-text)
+         (line-end-position) t)
+        (unless (eq ivy-exit 'done)
+          (swiper--cleanup)
+          (swiper--add-overlays (ivy--regex ivy-text)))))))
+
 (provide 'swiper)
 
 ;;; swiper.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]