]> code.delx.au - gnu-emacs-elpa/commitdiff
Merge commit '675bd5ff97f75fb7d838e6056442ce71adf85e56' from swiper
authorOleh Krehel <ohwoeowho@gmail.com>
Tue, 21 Apr 2015 12:02:16 +0000 (14:02 +0200)
committerOleh Krehel <ohwoeowho@gmail.com>
Tue, 21 Apr 2015 12:02:16 +0000 (14:02 +0200)
1  2 
packages/swiper/counsel.el
packages/swiper/ivy.el
packages/swiper/swiper.el

index 03c0b296a6d0ee9d3b767a1e946c1270ee2bf9dc,7ad7787ff92f6df90543efe81703b83ea40a6e1d..7ad7787ff92f6df90543efe81703b83ea40a6e1d
@@@ -32,7 -32,7 +32,7 @@@
  
  ;;; Code:
  
- (require 'ivy)
+ (require 'swiper)
  
  (defun counsel-el ()
    "Elisp completion at point."
@@@ -73,6 -73,7 +73,7 @@@
           (enable-recursive-minibuffers t)
           (preselect (thing-at-point 'symbol))
           val)
+      (setq ivy--action nil)
       (setq val (ivy-read
                  (if (symbolp v)
                      (format
                                 (and (boundp vv) (not (keywordp vv))))
                         (push (symbol-name vv) cands))))
                    cands)
-                 nil nil counsel-describe-map preselect))
+                 nil nil counsel-describe-map preselect
+                 nil t))
       (list (if (equal val "")
                 v
               (intern val)))))
-   (describe-variable variable buffer frame))
+   (unless (eq ivy--action 'counsel--find-symbol)
+     (describe-variable variable buffer frame)))
  
  (defun counsel-describe-function (function)
    "Forward to (`describe-function' FUNCTION) with ivy completion."
           (enable-recursive-minibuffers t)
           (preselect (thing-at-point 'symbol))
           val)
+      (setq ivy--action nil)
       (setq val (ivy-read (if fn
                               (format "Describe function (default %s): " fn)
                             "Describe function: ")
                                (when (fboundp x)
                                  (push (symbol-name x) cands))))
                             cands)
-                          nil nil counsel-describe-map preselect))
+                          nil nil counsel-describe-map preselect
+                          nil t))
       (list (if (equal val "")
                 fn (intern val)))))
-   (describe-function function))
+   (unless (eq ivy--action 'counsel--find-symbol)
+     (describe-function function)))
  
  (defvar info-lookup-mode)
  (declare-function info-lookup->completions "info-look")
          (setq ivy--full-length counsel--git-grep-count)
          (list ""
                (format "%d chars more" (- 3 (length ivy-text)))))
-     (let ((cmd-t "git --no-pager grep --full-name -n --no-color -i -e \"%s\"")
+     (let ((cmd (format "git --no-pager grep --full-name -n --no-color -i -e \"%s\""
+                        (ivy--regex string t)))
            res)
        (if (<= counsel--git-grep-count 20000)
            (progn
-             (setq res (shell-command-to-string (format cmd-t string)))
+             (setq res (shell-command-to-string cmd))
              (setq ivy--full-length nil))
-         (setq res (shell-command-to-string (concat (format cmd-t (ivy--regex string)) " | head -n 5000")))
+         (setq res (shell-command-to-string (concat cmd " | head -n 5000")))
          (setq ivy--full-length (counsel-git-grep-count ivy-text)))
        (split-string res "\n" t))))
  
  (defun counsel-git-grep ()
    "Grep for a string in the current git repository."
    (interactive)
-   (let* ((counsel--git-grep-count (counsel-git-grep-count ""))
-          (ivy--dynamic-function (when (> counsel--git-grep-count 20000)
-                                   'counsel-git-grep-function))
-          (default-directory (locate-dominating-file
-                              default-directory ".git"))
-          (val (ivy-read "pattern: " 'counsel-git-grep-function))
-          lst)
-     (when val
-       (setq lst (split-string val ":"))
-       (find-file (car lst))
-       (goto-char (point-min))
-       (forward-line (1- (string-to-number (cadr lst)))))))
+   (unwind-protect
+        (let* ((counsel--git-grep-count (counsel-git-grep-count ""))
+               (ivy--dynamic-function (when (> counsel--git-grep-count 20000)
+                                        'counsel-git-grep-function))
+               (git-dir (locate-dominating-file
+                         default-directory ".git"))
+               (ivy--persistent-action (lambda (x)
+                                         (setq lst (split-string x ":"))
+                                         (find-file (expand-file-name (car lst) git-dir))
+                                         (goto-char (point-min))
+                                         (forward-line (1- (string-to-number (cadr lst))))
+                                         (setq swiper--window (selected-window))
+                                         (swiper--cleanup)
+                                         (swiper--add-overlays (ivy--regex ivy-text))))
+               (val (ivy-read "pattern: " 'counsel-git-grep-function))
+               lst)
+          (when val
+            (funcall ivy--persistent-action val)))
+     (swiper--cleanup)))
  
  (defun counsel-locate-function (str &rest _u)
    (if (< (length str) 3)
diff --combined packages/swiper/ivy.el
index 131ad0d5fd3771b6880c4eca52adbbe5c4fcaac7,3b4fd5ddd9c93fb53b80412a9a3eb0901cc3e3ed..b83b1f0ab693a0f5ded51407d7c1c7feb943eea7
--- 2/ivy.el
@@@ -36,8 -36,6 +36,8 @@@
  ;; re-building it into a regex.
  ;; So "for example" is transformed into "\\(for\\).*\\(example\\)".
  
 +(require 'cl-lib)
 +
  ;;; Code:
  (require 'cl-lib)
  
@@@ -101,6 -99,8 +101,8 @@@ Only \"./\" and \"../\" apply here. The
      (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
      (define-key map (kbd "C-v") 'ivy-scroll-up-command)
      (define-key map (kbd "M-v") 'ivy-scroll-down-command)
+     (define-key map (kbd "C-M-n") 'ivy-next-line-and-call)
+     (define-key map (kbd "C-M-p") 'ivy-previous-line-and-call)
      map)
    "Keymap used in the minibuffer.")
  
@@@ -122,6 -122,9 +124,9 @@@ of `history-length', which see."
  (defvar ivy-text ""
    "Store the user's string as it is typed in.")
  
+ (defvar ivy-window nil
+   "Store the window in which `ivy-read' was called.")
  (defvar ivy--current ""
    "Current candidate.")
  
@@@ -135,6 -138,9 +140,9 @@@ Otherwise, store nil."
  (defvar ivy--action nil
    "Store a function to call at the end of `ivy--read'.")
  
+ (defvar ivy--persistent-action nil
+   "Store a function to call for current candidate without exiting.")
  (defvar ivy--all-candidates nil
    "Store the candidates passed to `ivy-read'.")
  
@@@ -164,7 -170,9 +172,9 @@@ When non-nil, it should contain one %d.
            (cond ((string= ivy-text "")
                   (if (equal ivy--current "./")
                       ivy--directory
-                    ivy--current))
+                    (if (string-match "\\*" ivy--current)
+                        ivy--current
+                      (expand-file-name ivy--current ivy--directory))))
                  ((zerop ivy--length)
                   (expand-file-name ivy-text ivy--directory))
                  (t
@@@ -258,6 -266,24 +268,24 @@@ If the input is empty, select the previ
      (ivy-previous-history-element 1))
    (ivy-previous-line arg))
  
+ (defun ivy-next-line-and-call (&optional arg)
+   "Move cursor vertically down ARG candidates."
+   (interactive "p")
+   (ivy-next-line arg)
+   (ivy--exhibit)
+   (when ivy--persistent-action
+     (with-selected-window ivy-window
+       (funcall ivy--persistent-action ivy--current))))
+ (defun ivy-previous-line-and-call (&optional arg)
+   "Move cursor vertically down ARG candidates."
+   (interactive "p")
+   (ivy-previous-line arg)
+   (ivy--exhibit)
+   (when ivy--persistent-action
+     (with-selected-window ivy-window
+       (funcall ivy--persistent-action ivy--current))))
  (defun ivy-previous-history-element (arg)
    "Forward to `previous-history-element' with ARG."
    (interactive "p")
@@@ -306,30 -332,49 +334,49 @@@ Prioritize directories.
          nil
        (string< x y))))
  
- (defvar ivy-sort-file-function 'ivy-sort-file-function-default
-   "The function that compares file names.
- It should take two string arguments and return nil and non-nil.")
+ (defvar ivy-sort-functions-alist
+   '((read-file-name-internal . ivy-sort-file-function-default)
+     (internal-complete-buffer . nil)
+     (counsel-git-grep-function . nil)
+     (t . string-lessp))
+   "And alist of sorting functions for each collection function.
+ For each entry, nil means no sorting.
+ The entry associated to t is used for all fall-through cases.")
+ (defcustom ivy-sort-max-size 30000
+   "Sorting won't be done for collections larger than this."
+   :type 'integer)
  
  (defun ivy--sorted-files (dir)
    "Return the list of files in DIR.
  Directories come first."
    (let* ((default-directory dir)
-          (seq (all-completions "" 'read-file-name-internal)))
+          (seq (all-completions "" 'read-file-name-internal))
+          sort-fn)
      (if (equal dir "/")
          seq
        (setq seq (delete "./" (delete "../" seq)))
-       (when (eq ivy-sort-file-function 'ivy-sort-file-function-default)
+       (when (eq (setq sort-fn (cdr (assoc 'read-file-name-internal
+                                           ivy-sort-functions-alist)))
+                 'ivy-sort-file-function-default)
          (setq seq (mapcar (lambda (x)
                              (propertize x 'dirp (string-match-p "/$" x)))
-                           (delete "./" (delete "../" seq)))))
-       (setq seq (cl-sort seq ivy-sort-file-function))
+                           seq)))
+       (when sort-fn
+         (setq seq (cl-sort seq sort-fn)))
        (dolist (dir ivy-extra-directories)
          (push dir seq))
-       seq)))
+       (cl-case (length seq)
+         (0
+          '("" ""))
+         (1
+          (cons "" seq))
+         (t
+          seq)))))
  
  ;;** Entry Point
  (defun ivy-read (prompt collection
-                  &optional predicate initial-input keymap preselect update-fn)
+                  &optional predicate initial-input keymap preselect update-fn sort)
    "Read a string in the minibuffer, with completion.
  
  PROMPT is a string to prompt with; normally it ends in a colon
@@@ -346,76 -391,90 +393,90 @@@ KEYMAP is composed together with `ivy-m
  If PRESELECT is non-nil select the corresponding candidate out of
  the ones that match INITIAL-INPUT.
  
- UPDATE-FN is called each time the current candidate(s) is changed."
+ UPDATE-FN is called each time the current candidate(s) is changed.
+ When SORT is t, refer to `ivy-sort-functions-alist' for sorting."
    (setq ivy--directory nil)
-   (cond ((eq collection 'Info-read-node-name-1)
-          (if (equal Info-current-file "dir")
-              (setq collection
-                    (mapcar (lambda (x) (format "(%s)" x))
-                            (cl-delete-duplicates
-                             (all-completions "(" collection predicate)
-                             :test 'equal)))
-            (setq collection (all-completions "" collection predicate))))
-         ((eq collection 'read-file-name-internal)
-          (setq ivy--directory default-directory)
-          (setq initial-input nil)
-          (setq collection
-                (ivy--sorted-files default-directory)))
-         ((or (functionp collection)
-              (vectorp collection))
-          (setq collection (all-completions "" collection predicate)))
-         ((hash-table-p collection)
-          (error "Hash table as a collection unsupported"))
-         ((listp (car collection))
-          (setq collection (all-completions "" collection predicate))))
-   (when preselect
-     (unless (or ivy-require-match
-                 (all-completions preselect collection))
-       (setq collection (cons preselect collection))))
-   (cl-case (length collection)
-     (0 nil)
-     (1 (car collection))
-     (t
-      (setq ivy--index (or
-                        (and preselect
-                             (ivy--preselect-index
-                              collection initial-input preselect))
-                        0))
-      (setq ivy--old-re nil)
-      (setq ivy--old-cands nil)
-      (setq ivy-text "")
-      (setq ivy--all-candidates collection)
-      (setq ivy--update-fn update-fn)
-      (setq ivy-exit nil)
-      (setq ivy--default (or (thing-at-point 'symbol) ""))
-      (setq ivy--prompt
-            (cond ((string-match "%.*d" prompt)
-                   prompt)
-                  ((string-match "%.*d" ivy-count-format)
-                   (concat ivy-count-format prompt))
-                  (ivy--directory
-                   prompt)
-                  (t
-                   nil)))
-      (setq ivy--action nil)
-      (prog1
-          (unwind-protect
-               (minibuffer-with-setup-hook
-                   #'ivy--minibuffer-setup
-                 (let ((res (read-from-minibuffer
-                             prompt
-                             initial-input
-                             (make-composed-keymap keymap ivy-minibuffer-map)
-                             nil
-                             'ivy-history)))
-                   (when (eq ivy-exit 'done)
-                     (pop ivy-history)
-                     (setq ivy-history
-                           (cons ivy-text (delete ivy-text ivy-history)))
-                     res)))
-            (remove-hook 'post-command-hook #'ivy--exhibit))
-        (when ivy--action
-          (funcall ivy--action))))))
+   (setq ivy-window (selected-window))
+   (let (coll sort-fn)
+     (cond ((eq collection 'Info-read-node-name-1)
+            (if (equal Info-current-file "dir")
+                (setq coll
+                      (mapcar (lambda (x) (format "(%s)" x))
+                              (cl-delete-duplicates
+                               (all-completions "(" collection predicate)
+                               :test 'equal)))
+              (setq coll (all-completions "" collection predicate))))
+           ((eq collection 'read-file-name-internal)
+            (setq ivy--directory default-directory)
+            (setq initial-input nil)
+            (setq coll
+                  (ivy--sorted-files default-directory)))
+           ((or (functionp collection)
+                (vectorp collection)
+                (listp (car collection)))
+            (setq coll (all-completions "" collection predicate)))
+           ((hash-table-p collection)
+            (error "Hash table as a collection unsupported"))
+           (t
+            (setq coll collection)))
+     (when sort
+       (if (and (functionp collection)
+                (setq sort-fn (assoc collection ivy-sort-functions-alist)))
+           (when (and (setq sort-fn (cdr sort-fn))
+                      (not (eq collection 'read-file-name-internal)))
+             (setq coll (cl-sort coll sort-fn)))
+         (if (and (setq sort-fn (cdr (assoc t ivy-sort-functions-alist)))
+                  (<= (length coll) ivy-sort-max-size))
+             (setq coll (cl-sort (copy-sequence coll) sort-fn)))))
+     (when preselect
+       (unless (or ivy-require-match
+                   (all-completions preselect collection))
+         (setq coll (cons preselect coll))))
+     (cl-case (length coll)
+       (0 nil)
+       (1 (car coll))
+       (t
+        (setq ivy--index (or
+                          (and preselect
+                               (ivy--preselect-index
+                                coll initial-input preselect))
+                          0))
+        (setq ivy--old-re nil)
+        (setq ivy--old-cands nil)
+        (setq ivy-text "")
+        (setq ivy--all-candidates coll)
+        (setq ivy--update-fn update-fn)
+        (setq ivy-exit nil)
+        (setq ivy--default (or (thing-at-point 'symbol) ""))
+        (setq ivy--prompt
+              (cond ((string-match "%.*d" prompt)
+                     prompt)
+                    ((string-match "%.*d" ivy-count-format)
+                     (concat ivy-count-format prompt))
+                    (ivy--directory
+                     prompt)
+                    (t
+                     nil)))
+        (setq ivy--action nil)
+        (prog1
+            (unwind-protect
+                 (minibuffer-with-setup-hook
+                     #'ivy--minibuffer-setup
+                   (let ((res (read-from-minibuffer
+                               prompt
+                               initial-input
+                               (make-composed-keymap keymap ivy-minibuffer-map)
+                               nil
+                               'ivy-history)))
+                     (when (eq ivy-exit 'done)
+                       (pop ivy-history)
+                       (setq ivy-history
+                             (cons ivy-text (delete ivy-text ivy-history)))
+                       res)))
+              (remove-hook 'post-command-hook #'ivy--exhibit))
+          (when ivy--action
+            (funcall ivy--action)))))))
  
  (defun ivy-completing-read (prompt collection
                              &optional predicate require-match initial-input
@@@ -439,7 -498,7 +500,7 @@@ The history, defaults and input-method 
    (when (listp def)
      (setq def (car def)))
    (setq ivy-require-match require-match)
-   (ivy-read prompt collection predicate initial-input nil def))
+   (ivy-read prompt collection predicate initial-input nil def nil t))
  
  ;;;###autoload
  (define-minor-mode ivy-mode
@@@ -479,9 -538,11 +540,11 @@@ Turning on Ivy mode will set `completin
    (make-hash-table :test 'equal)
    "Store pre-computed regex.")
  
- (defun ivy--regex (str)
-   "Re-build regex from STR in case it has a space."
-   (let ((hashed (gethash str ivy--regex-hash)))
+ (defun ivy--regex (str &optional greedy)
+   "Re-build regex from STR in case it has a space.
+ When GREEDY is non-nil, join words in a greedy way."
+   (let ((hashed (unless greedy
+                   (gethash str ivy--regex-hash))))
      (if hashed
          (prog1 (cdr hashed)
            (setq ivy--subexps (car hashed)))
                          (cons
                           (setq ivy--subexps (length subs))
                           (mapconcat
-                           (lambda (x) (format "\\(%s\\)" x))
+                           (lambda (x)
+                             (if (string-match "^\\\\(.*\\\\)$" x)
+                                 x
+                               (format "\\(%s\\)" x)))
                            subs
-                           ".*"))))
+                           (if greedy
+                               ".*"
+                             ".*?")))))
                      ivy--regex-hash)))))
  
  ;;** Rest
index 1afd056548c6bb09137689e7c38b7ffdb712aef7,b46702bf5c6c503008cde56959b3177cb94f096d..b46702bf5c6c503008cde56959b3177cb94f096d
@@@ -234,48 -234,47 +234,47 @@@ When non-nil, INITIAL-INPUT is the init
          (unless (and (>= (point) (window-start))
                       (<= (point) (window-end swiper--window t)))
            (recenter)))
-       (let ((ov (make-overlay
-                  (line-beginning-position)
-                  (1+ (line-end-position)))))
-         (overlay-put ov 'face 'swiper-line-face)
-         (overlay-put ov 'window swiper--window)
-         (push ov swiper--overlays))
-       (let ((wh (window-height)))
-         (swiper--add-overlays
-          re
-          (save-excursion
-            (forward-line (- wh))
-            (point))
-          (save-excursion
-            (forward-line wh)
-            (point)))))))
- (defun swiper--add-overlays (re beg end)
-   "Add overlays for RE regexp in current buffer between BEG and END."
-   (when (>= (length re) swiper-min-highlight)
-     (save-excursion
-       (goto-char beg)
-       ;; RE can become an invalid regexp
-       (while (and (ignore-errors (re-search-forward re end t))
-                   (> (- (match-end 0) (match-beginning 0)) 0))
-         (let ((i 0))
-           (while (<= i ivy--subexps)
-             (when (match-beginning i)
-               (let ((overlay (make-overlay (match-beginning i)
-                                            (match-end i)))
-                     (face
-                      (cond ((zerop ivy--subexps)
-                             (cl-caddr swiper-faces))
-                            ((zerop i)
-                             (car swiper-faces))
-                            (t
-                             (nth (1+ (mod (1- i) (1- (length swiper-faces))))
-                                  swiper-faces)))))
-                 (push overlay swiper--overlays)
-                 (overlay-put overlay 'face face)
-                 (overlay-put overlay 'window swiper--window)
-                 (overlay-put overlay 'priority i)))
-             (cl-incf i)))))))
+       (swiper--add-overlays re))))
+ (defun swiper--add-overlays (re)
+   "Add overlays for RE regexp in visible part of the current buffer."
+   (let ((ov (make-overlay
+              (line-beginning-position)
+              (1+ (line-end-position)))))
+     (overlay-put ov 'face 'swiper-line-face)
+     (overlay-put ov 'window swiper--window)
+     (push ov swiper--overlays))
+   (let* ((wh (window-height))
+          (beg (save-excursion
+                 (forward-line (- wh))
+                 (point)))
+          (end (save-excursion
+                 (forward-line wh)
+                 (point))))
+     (when (>= (length re) swiper-min-highlight)
+       (save-excursion
+         (goto-char beg)
+         ;; RE can become an invalid regexp
+         (while (and (ignore-errors (re-search-forward re end t))
+                     (> (- (match-end 0) (match-beginning 0)) 0))
+           (let ((i 0))
+             (while (<= i ivy--subexps)
+               (when (match-beginning i)
+                 (let ((overlay (make-overlay (match-beginning i)
+                                              (match-end i)))
+                       (face
+                        (cond ((zerop ivy--subexps)
+                               (cl-caddr swiper-faces))
+                              ((zerop i)
+                               (car swiper-faces))
+                              (t
+                               (nth (1+ (mod (1- i) (1- (length swiper-faces))))
+                                    swiper-faces)))))
+                   (push overlay swiper--overlays)
+                   (overlay-put overlay 'face face)
+                   (overlay-put overlay 'window swiper--window)
+                   (overlay-put overlay 'priority i)))
+               (cl-incf i))))))))
  
  (defun swiper--action (x input)
    "Goto line X and search for INPUT."