[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master ed60d31 20/90: Make counsel-git-grep fully async
From: |
Oleh Krehel |
Subject: |
[elpa] master ed60d31 20/90: Make counsel-git-grep fully async |
Date: |
Tue, 30 Jun 2015 07:28:09 +0000 |
branch: master
commit ed60d31fc31de0dc4258696c2ecec9f1c20b06c7
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>
Make counsel-git-grep fully async
* counsel.el (counsel-git-grep-count): Rename to `counsel--gg-count' and
make it async.
(counsel-git-grep-function): Set `ivy--full-length' to -1. It means that
`ivy--exhibit' should do nothing until the length is re-computed.
(counsel-git-grep): Use the sync version of `counsel-git-grep-count' for
the initial repo line count.
(counsel--gg-candidates): New defun. When called, kill the previous
git grep process and start a new one. The sentinel will insert the
candidates, bypassing the `ivy--exhibit'.
(counsel--gg-sentinel): New defun.
(counsel--gg-count): Rename from `counsel-git-grep-count'. When finished
computing, redisplay.
* ivy.el (ivy--exhibit): Don't expect dynamic collection to return the
candidates as before. Just call it and expect it to redisplay the
minibuffer.
---
counsel.el | 81 +++++++++++++++++++++++++++++++++++++++++++++++++----------
ivy.el | 18 +++++++------
2 files changed, 77 insertions(+), 22 deletions(-)
diff --git a/counsel.el b/counsel.el
index 174a1b9..57bad38 100644
--- a/counsel.el
+++ b/counsel.el
@@ -198,14 +198,6 @@
(defvar counsel--git-grep-dir nil
"Store the base git directory.")
-(defun counsel-git-grep-count (str)
- "Quickly count the amount of git grep STR matches."
- (let* ((default-directory counsel--git-grep-dir)
- (out (shell-command-to-string
- (format "git grep -i -c '%s' | sed 's/.*:\\(.*\\)/\\1/g' | awk
'{s+=$1} END {print s}'"
- (ivy--regex str)))))
- (string-to-number out)))
-
(defvar counsel--git-grep-count nil
"Store the line count in current repository.")
@@ -224,10 +216,11 @@
(if (<= counsel--git-grep-count 20000)
(progn
(setq res (shell-command-to-string cmd))
- (setq ivy--full-length nil))
- (setq res (shell-command-to-string (concat cmd " | head -n 2000")))
- (setq ivy--full-length (counsel-git-grep-count ivy-text)))
- (split-string res "\n" t))))
+ (setq ivy--full-length nil)
+ (split-string res "\n" t))
+ (setq ivy--full-length -1)
+ (counsel--gg-candidates (ivy--regex string))
+ nil))))
(defvar counsel-git-grep-map
(let ((map (make-sparse-keymap)))
@@ -237,7 +230,7 @@
(defun counsel-git-grep-recenter ()
(interactive)
(with-selected-window (ivy-state-window ivy-last)
- (counsel-git-grep-action)
+ (counsel-git-grep-action ivy--current)
(recenter-top-bottom)))
(defun counsel-git-grep-action (x)
@@ -257,7 +250,7 @@
(locate-dominating-file default-directory ".git"))
(if (null counsel--git-grep-dir)
(error "Not in a git repository")
- (setq counsel--git-grep-count (counsel-git-grep-count ""))
+ (setq counsel--git-grep-count (counsel--gg-count "" t))
(ivy-read "pattern: " 'counsel-git-grep-function
:initial-input initial-input
:matcher #'counsel-git-grep-matcher
@@ -421,6 +414,66 @@ The libraries are offered from `load-path'."
(get-text-property 0 'full-name x)))
:keymap counsel-describe-map)))
+(defun counsel--gg-candidates (regex)
+ "Return git grep candidates for REGEX."
+ (counsel--gg-count regex)
+ (let* ((default-directory counsel--git-grep-dir)
+ (counsel-gg-process " *counsel-gg*")
+ (proc (get-process counsel-gg-process))
+ (buff (get-buffer counsel-gg-process)))
+ (when proc
+ (delete-process proc))
+ (when buff
+ (kill-buffer buff))
+ (setq proc (start-process-shell-command
+ counsel-gg-process
+ counsel-gg-process
+ (format "git --no-pager grep --full-name -n --no-color -i -e
\"%s\" | head -n 200"
+ regex)))
+ (set-process-sentinel
+ proc
+ #'counsel--gg-sentinel)))
+
+(defun counsel--gg-sentinel (process event)
+ (if (string= event "finished\n")
+ (progn
+ (with-current-buffer (process-buffer process)
+ (setq ivy--all-candidates (split-string (buffer-string) "\n" t))
+ (setq ivy--old-cands ivy--all-candidates))
+ (unless (eq ivy--full-length -1)
+ (ivy--insert-minibuffer
+ (ivy--format ivy--all-candidates))))
+ (if (string= event "exited abnormally with code 1\n")
+ (message "Error"))))
+
+(defun counsel--gg-count (regex &optional no-async)
+ "Quickly and asynchronously count the amount of git grep REGEX matches.
+When NO-ASYNC is non-nil, do it synchronously."
+ (let ((default-directory counsel--git-grep-dir)
+ (cmd (format "git grep -i -c '%s' | sed 's/.*:\\(.*\\)/\\1/g' | awk
'{s+=$1} END {print s}'"
+ regex))
+ (counsel-ggc-process " *counsel-gg-count*"))
+ (if no-async
+ (string-to-number (shell-command-to-string cmd))
+ (let ((proc (get-process counsel-ggc-process))
+ (buff (get-buffer counsel-ggc-process)))
+ (when proc
+ (delete-process proc))
+ (when buff
+ (kill-buffer buff))
+ (setq proc (start-process-shell-command
+ counsel-ggc-process
+ counsel-ggc-process
+ cmd))
+ (set-process-sentinel
+ proc
+ #'(lambda (process event)
+ (when (string= event "finished\n")
+ (with-current-buffer (process-buffer process)
+ (setq ivy--full-length (string-to-number (buffer-string))))
+ (ivy--insert-minibuffer
+ (ivy--format ivy--all-candidates)))))))))
+
(provide 'counsel)
;;; counsel.el ends here
diff --git a/ivy.el b/ivy.el
index 2115555..9ac4917 100644
--- a/ivy.el
+++ b/ivy.el
@@ -1013,12 +1013,14 @@ Should be run via minibuffer `post-command-hook'."
;; while-no-input would cause annoying
;; "Waiting for process to die...done" message interruptions
(let ((inhibit-message t))
- (while-no-input
- (unless (equal ivy--old-text ivy-text)
- (cl-letf ((store (ivy-state-dynamic-collection ivy-last))
- ((ivy-state-dynamic-collection ivy-last) nil))
- (setq ivy--all-candidates (funcall store ivy-text))))
- (ivy--insert-minibuffer (ivy--format ivy--all-candidates))))
+ (unless (equal ivy--old-text ivy-text)
+ (while-no-input
+ ;; dynamic collection should take care of everything
+ (funcall (ivy-state-dynamic-collection ivy-last) ivy-text)
+ (setq ivy--old-text ivy-text)))
+ (unless (eq ivy--full-length -1)
+ (ivy--insert-minibuffer
+ (ivy--format ivy--all-candidates))))
(cond (ivy--directory
(if (string-match "/\\'" ivy-text)
(if (member ivy-text ivy--all-candidates)
@@ -1041,8 +1043,8 @@ Should be run via minibuffer `post-command-hook'."
(setq ivy--old-re nil))))
(ivy--insert-minibuffer
(ivy--format
- (ivy--filter ivy-text ivy--all-candidates))))
- (setq ivy--old-text ivy-text))
+ (ivy--filter ivy-text ivy--all-candidates)))
+ (setq ivy--old-text ivy-text)))
(defun ivy--insert-minibuffer (text)
"Insert TEXT into minibuffer with appropriate cleanup."
- [elpa] master 8212110 15/90: Handle symbol-at-point better in non-Elisp buffers, (continued)
- [elpa] master 8212110 15/90: Handle symbol-at-point better in non-Elisp buffers, Oleh Krehel, 2015/06/30
- [elpa] master fe057eb 14/90: Swiper should preserve column for empty input, Oleh Krehel, 2015/06/30
- [elpa] master 1a193b0 16/90: ivy.el (ivy--done): Set ivy--current, Oleh Krehel, 2015/06/30
- [elpa] master 97abd3c 17/90: ivy.el (ivy-virtual): New defface, Oleh Krehel, 2015/06/30
- [elpa] master 3c8daba 19/90: Fixup compilation warnings, Oleh Krehel, 2015/06/30
- [elpa] master ecb93a6 18/90: Regexp-quote name of candidate buffer to be preselected, Oleh Krehel, 2015/06/30
- [elpa] master 40a938b 21/90: ivy.el (ivy-minibuffer-map): Bind ivy-yank-word to "M-j", Oleh Krehel, 2015/06/30
- [elpa] master 00a1b02 22/90: counsel-git-grep should quote strings better, Oleh Krehel, 2015/06/30
- [elpa] master 52a083e 13/90: ivy.el (ivy-yank-word): New command, Oleh Krehel, 2015/06/30
- [elpa] master 9ae55b4 12/90: ivy.el (ivy-recentf): New command, Oleh Krehel, 2015/06/30
- [elpa] master ed60d31 20/90: Make counsel-git-grep fully async,
Oleh Krehel <=
- [elpa] master bef708c 23/90: ivy.el (ivy--switch-buffer-action): Add work-around, Oleh Krehel, 2015/06/30
- [elpa] master 77e7c8f 24/90: Account for minibuffer-depth-indication-mode, Oleh Krehel, 2015/06/30
- [elpa] master 607d943 25/90: Add a hack for kill-buffer and invisible buffer, Oleh Krehel, 2015/06/30
- [elpa] master 3699897 26/90: counsel.el (counsel-symbol-at-point): Improve, Oleh Krehel, 2015/06/30
- [elpa] master 03e7e70 27/90: counsel.el (counsel-M-x): New command, Oleh Krehel, 2015/06/30
- [elpa] master efa751b 28/90: counsel.el (counsel-M-x): Piggyback on smex for sorting, Oleh Krehel, 2015/06/30
- [elpa] master ebead12 29/90: Add fuzzy matching function, Oleh Krehel, 2015/06/30
- [elpa] master 84e20a3 30/90: Fixup ivy-resume for file completion, Oleh Krehel, 2015/06/30
- [elpa] master d24397b 32/90: counsel.el (counsel-M-x-initial-input): New defcustom, Oleh Krehel, 2015/06/30
- [elpa] master e016d48 31/90: Allow "TAB" to complete when input starts with "^", Oleh Krehel, 2015/06/30