[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
- [elpa] master 33fa81e 14/54: counsel.el (counsel-jedi): New command, (continued)
- [elpa] master 33fa81e 14/54: counsel.el (counsel-jedi): New command, Oleh Krehel, 2015/10/07
- [elpa] master 435f2b6 38/54: Add work-around for minibuffer not re-sizing for many frames, Oleh Krehel, 2015/10/07
- [elpa] master 438e51d 24/54: counsel.el (counsel-git-grep-function): Fix up, Oleh Krehel, 2015/10/07
- [elpa] master 478e4e4 32/54: Make line numbers in swiper into display properties, Oleh Krehel, 2015/10/07
- [elpa] master 8fccfd3 03/54: (counsel-locate): Support OS X, Oleh Krehel, 2015/10/07
- [elpa] master 7684455 15/54: counsel.el (counsel--py-action): Work with "C-M-n", Oleh Krehel, 2015/10/07
- [elpa] master 9a509df 47/54: ivy.el (ivy--resize-minibuffer-to-fit): Make compatible with 24.3, Oleh Krehel, 2015/10/07
- [elpa] master d5ae6a3 30/54: ivy.el (ivy--resize-minibuffer-to-fit): Make compatible with 24.3, Oleh Krehel, 2015/10/07
- [elpa] master d8d7ed4 42/54: Fix minibuffer collapses to one line, Oleh Krehel, 2015/10/07
- [elpa] master db8fb1b 39/54: Make "<left>" and "<right>" behave as in fundamental-mode, Oleh Krehel, 2015/10/07
- [elpa] master 8b73497 54/54: Merge commit 'ba49407c5b4c719dd5dcc298c260513abf0c70df' from swiper,
Oleh Krehel <=
- [elpa] master 9413acb 52/54: counsel.el (counsel--find-symbol): Allow to jump back with pop-tag-mark, Oleh Krehel, 2015/10/07
- [elpa] master aa3e1dd 51/54: swiper.el (swiper-font-lock-ensure): Add mu4e, Oleh Krehel, 2015/10/07
- [elpa] master 680f6e2 44/54: swiper.el (swiper--ivy): Use minibuffer-allow-text-properties, Oleh Krehel, 2015/10/07
- [elpa] master 5fef653 08/54: ivy.el (ivy-completing-read): Fix up last commit, Oleh Krehel, 2015/10/07
- [elpa] master 1f93f40 16/54: counsel.el (counsel-cl): New command, Oleh Krehel, 2015/10/07
- [elpa] master 67cd682 06/54: Fix #126 again., Oleh Krehel, 2015/10/07
- [elpa] master 1f64cb8 11/54: ivy: enlarge the minibuffer window if the candiate list doesn't fit, Oleh Krehel, 2015/10/07
- [elpa] master f164cfe 33/54: counsel.el (counsel-yank-pop): New command, Oleh Krehel, 2015/10/07
- [elpa] master 03d93f7 40/54: ivy.el (ivy-switch-buffer): Make "M-o r" rename buffer, Oleh Krehel, 2015/10/07
- [elpa] master 8d754de 17/54: ivy.el (ivy-display-style): New defcustom, Oleh Krehel, 2015/10/07