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

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

[elpa] externals/counsel ad0e98e 1/2: Merge branch 'master' into externa


From: Basil L. Contovounesios
Subject: [elpa] externals/counsel ad0e98e 1/2: Merge branch 'master' into externals/counsel
Date: Tue, 9 Mar 2021 14:40:00 -0500 (EST)

branch: externals/counsel
commit ad0e98ee4f11695e8ee3d6c9768c3f0e6d991791
Merge: 52b9abf e005666
Author: Basil L. Contovounesios <contovob@tcd.ie>
Commit: Basil L. Contovounesios <contovob@tcd.ie>

    Merge branch 'master' into externals/counsel
---
 .dir-locals.el |    2 +-
 counsel.el     | 2012 +++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 1488 insertions(+), 526 deletions(-)

diff --git a/.dir-locals.el b/.dir-locals.el
index 3d5e818..4e7d231 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -8,7 +8,7 @@
   (sentence-end-double-space . t))
  (emacs-lisp-mode
   (indent-tabs-mode . nil)
-  (outline-regexp . ";;[;*]+[\s\t]+")
+  (outline-regexp . ";;\\([;*]+ [^\s\t\n]\\|###autoload\\)\\|(")
   ;; extra config here: 
https://github.com/abo-abo/oremacs/blob/github/modes/ora-elisp-style-guide.el
   ;; (lisp-indent-function . common-lisp-indent-function)
   ))
diff --git a/counsel.el b/counsel.el
index 3cb817f..fe48bac 100644
--- a/counsel.el
+++ b/counsel.el
@@ -1,11 +1,11 @@
 ;;; counsel.el --- Various completion functions using Ivy -*- lexical-binding: 
t -*-
 
-;; Copyright (C) 2015-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.13.1
-;; Package-Requires: ((emacs "24.5") (swiper "0.13.1"))
+;; Version: 0.13.2
+;; Package-Requires: ((emacs "24.5") (ivy "0.13.2") (swiper "0.13.2"))
 ;; Keywords: convenience, matching, tools
 
 ;; This file is part of GNU Emacs.
@@ -40,10 +40,15 @@
 
 ;;; Code:
 
+(require 'ivy)
 (require 'swiper)
+
 (require 'compile)
 (require 'dired)
 
+(eval-when-compile
+  (require 'subr-x))
+
 (defgroup counsel nil
   "Completion functions using Ivy."
   :group 'matching
@@ -110,17 +115,25 @@ complex regexes."
      str)
     str))
 
+(defalias 'counsel--executable-find
+  ;; Gained optional argument in 27.1.
+  (if (>= emacs-major-version 27)
+      #'executable-find
+    (lambda (command &optional _remote)
+      (executable-find command)))
+  "Compatibility shim for `executable-find'.")
+
 (defun counsel-require-program (cmd)
   "Check system for program used in CMD, printing error if not found.
 CMD is either a string or a list of strings.
 To skip the `executable-find' check, start the string with a space."
-  (unless (and (stringp cmd) (string-match-p "^ " cmd))
+  (unless (and (stringp cmd) (string-prefix-p " " cmd))
     (let ((program (if (listp cmd)
                        (car cmd)
                      (car (split-string cmd)))))
       (or (and (stringp program)
                (not (string= program ""))
-               (executable-find program))
+               (counsel--executable-find program t))
           (user-error "Required program \"%s\" not found in your path" 
program)))))
 
 (declare-function eshell-split-path "esh-util")
@@ -135,14 +148,44 @@ To skip the `executable-find' check, start the string 
with a space."
      (replace-regexp-in-string          ; Insert dir before any trailing colon.
       "\\(?:: ?\\)?\\'" dir (ivy-state-prompt ivy-last) t t))))
 
+(defalias 'counsel--flatten
+  ;; Added in Emacs 27.1
+  (if (fboundp 'flatten-tree)
+      #'flatten-tree
+    (lambda (tree)
+      (let (elems)
+        (while (consp tree)
+          (let ((elem (pop tree)))
+            (while (consp elem)
+              (push (cdr elem) tree)
+              (setq elem (car elem)))
+            (if elem (push elem elems))))
+        (if tree (push tree elems))
+        (nreverse elems))))
+  "Compatibility shim for `flatten-tree'.")
+
+(defun counsel--format (formatter &rest args)
+  "Like `format' but FORMATTER can be a list.
+When FORMATTER is a list, only `%s' is replaced with ARGS.
+
+Return a list or string depending on input."
+  (cond
+   ((listp formatter)
+    (counsel--flatten (mapcar
+                       (lambda (it) (if (equal it "%s") (pop args) it))
+                       formatter)))
+   (t (apply #'format formatter args))))
+
 ;;* Async Utility
 (defvar counsel--async-time nil
   "Store the time when a new process was started.
 Or the time of the last minibuffer update.")
 
 (defvar counsel--async-start nil
-  "Store the time when a new process was started.
-Or the time of the last minibuffer update.")
+  "Store the time when a new process was started.")
+
+(defvar counsel--async-timer nil
+  "Timer used to dispose `counsel--async-command.")
 
 (defvar counsel--async-duration nil
   "Store the time a process takes to gather all its candidates.
@@ -164,16 +207,16 @@ descriptions.")
                      cmd
                      (plist-put plist number str)))))
 
-(defvar counsel-async-split-string-re-alist '((t . "\n"))
+(defvar counsel-async-split-string-re-alist '((t . "[\r\n]"))
   "Store the regexp for splitting shell command output.")
 
 (defvar counsel-async-ignore-re-alist nil
   "An alist of regexp matching candidates to ignore in 
`counsel--async-filter'.")
 
 (defvar counsel--async-last-command nil
-  "Store the last command ran by `counsel--async-command'.")
+  "Store the last command ran by `counsel--async-command-1'.")
 
-(defun counsel--async-command (cmd &optional sentinel filter name)
+(defun counsel--async-command-1 (cmd &optional sentinel filter name)
   "Start and return new counsel process by calling CMD.
 CMD can be either a shell command as a string, or a list of the
 program name to be called directly, followed by its arguments.
@@ -197,48 +240,76 @@ respectively."
     (set-process-filter proc (or filter #'counsel--async-filter))
     proc))
 
+(defcustom counsel-async-command-delay 0
+  "Number of seconds to wait before spawning another async command."
+  :type 'number)
+
+(defun counsel--async-command (&rest args)
+  "Like `counsel--async-command-1', with same ARGS, but debounced.
+Calls to `counsel--async-command-1' are separated by at least
+`counsel-async-command-delay' seconds, so as to avoid issues
+caused by spawning too many subprocesses too quickly."
+  (if (zerop counsel-async-command-delay)
+      (apply #'counsel--async-command-1 args)
+    (when counsel--async-timer
+      (cancel-timer counsel--async-timer))
+    (setq counsel--async-timer
+          (apply #'run-with-timer
+                 counsel-async-command-delay
+                 nil
+                 #'counsel--async-command-1
+                 args))))
+
 (defun counsel--split-string (&optional str)
   (split-string
    (or str (buffer-string))
    (ivy-alist-setting counsel-async-split-string-re-alist)
    t))
 
+(defun counsel--sync-sentinel-on-exit (process)
+  (if (zerop (process-exit-status process))
+      (let ((cur (ivy-state-current ivy-last)))
+        (ivy--set-candidates
+         (ivy--sort-maybe
+          (with-current-buffer (process-buffer process)
+            (counsel--split-string))))
+        (when counsel--async-start
+          (setq counsel--async-duration
+                (time-to-seconds (time-since counsel--async-start))))
+        (let ((re (ivy-re-to-str ivy-regex)))
+          (if ivy--old-cands
+              (if (eq (ivy-alist-setting ivy-index-functions-alist) 
'ivy-recompute-index-zero)
+                  (ivy-set-index 0)
+                (ivy--recompute-index re ivy--all-candidates))
+            ;; index was changed before a long-running query exited
+            (unless (string= cur (nth ivy--index ivy--all-candidates))
+              (let ((func (ivy-alist-setting ivy-index-functions-alist)))
+                (if func
+                    (funcall func re ivy--all-candidates)
+                  (ivy--preselect-index
+                   (if (> (length re) 0)
+                       cur
+                     (ivy-state-preselect ivy-last))
+                   ivy--all-candidates))))))
+        (setq ivy--old-cands ivy--all-candidates)
+        (if ivy--all-candidates
+            (ivy--exhibit)
+          (ivy--insert-minibuffer "")))
+    (setq counsel--async-last-error-string
+          (with-current-buffer (process-buffer process) (buffer-string)))
+    (setq ivy--all-candidates
+          (let ((status (process-exit-status process))
+                (plist (plist-get counsel--async-exit-code-plist
+                                  (ivy-state-caller ivy-last))))
+            (list (or (plist-get plist status)
+                      (format "error code %d" status)))))
+    (setq ivy--old-cands ivy--all-candidates)
+    (ivy--exhibit)))
+
 (defun counsel--async-sentinel (process _msg)
   "Sentinel function for an asynchronous counsel PROCESS."
   (when (eq (process-status process) 'exit)
-    (if (zerop (process-exit-status process))
-        (progn
-          (ivy--set-candidates
-           (ivy--sort-maybe
-            (with-current-buffer (process-buffer process)
-              (counsel--split-string))))
-          (when counsel--async-start
-            (setq counsel--async-duration
-                  (time-to-seconds (time-since counsel--async-start))))
-          (let ((re (ivy-re-to-str (funcall ivy--regex-function ivy-text))))
-            (if ivy--old-cands
-                (if (eq (ivy-alist-setting ivy-index-functions-alist) 
'ivy-recompute-index-zero)
-                    (ivy-set-index 0)
-                  (ivy--recompute-index ivy-text re ivy--all-candidates))
-              (unless (ivy-set-index
-                       (ivy--preselect-index
-                        (ivy-state-preselect ivy-last)
-                        ivy--all-candidates))
-                (ivy--recompute-index ivy-text re ivy--all-candidates))))
-          (setq ivy--old-cands ivy--all-candidates)
-          (if ivy--all-candidates
-              (ivy--exhibit)
-            (ivy--insert-minibuffer "")))
-      (setq counsel--async-last-error-string
-            (with-current-buffer (process-buffer process) (buffer-string)))
-      (setq ivy--all-candidates
-            (let ((status (process-exit-status process))
-                  (plist (plist-get counsel--async-exit-code-plist
-                                    (ivy-state-caller ivy-last))))
-              (list (or (plist-get plist status)
-                        (format "error code %d" status)))))
-      (setq ivy--old-cands ivy--all-candidates)
-      (ivy--exhibit))))
+    (counsel--sync-sentinel-on-exit process)))
 
 (defcustom counsel-async-filter-update-time 500000
   "The amount of microseconds to wait until updating `counsel--async-filter'."
@@ -274,113 +345,10 @@ Update the minibuffer with the amount of lines collected 
every
       (delete-process process))))
 
 ;;* Completion at point
-;;** `counsel-el'
-;;;###autoload
-(defun counsel-el ()
-  "Elisp completion at point."
-  (interactive)
-  (let* ((bnd (unless (and (looking-at ")")
-                           (eq (char-before) ?\())
-                (bounds-of-thing-at-point 'symbol)))
-         (str (if bnd
-                  (buffer-substring-no-properties
-                   (car bnd)
-                   (cdr bnd))
-                ""))
-         (pred (and (eq (char-before (car bnd)) ?\()
-                    #'fboundp))
-         symbol-names)
-    (setq ivy-completion-beg (car bnd))
-    (setq ivy-completion-end (cdr bnd))
-    (if (string= str "")
-        (mapatoms
-         (lambda (x)
-           (when (and (symbolp x) (funcall pred x))
-             (push (symbol-name x) symbol-names))))
-      (setq symbol-names (all-completions str obarray pred)))
-    (ivy-read "Symbol name: " symbol-names
-              :initial-input str
-              :action #'ivy-completion-in-region-action
-              :caller 'counsel-el)))
-
-(ivy-configure 'counsel-el
-  :height 7)
-
-;;** `counsel-cl'
-(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 ivy-completion-beg (slime-symbol-start-pos))
-  (setq ivy-completion-end (slime-symbol-end-pos))
-  (ivy-read "Symbol name: "
-            (car (slime-contextual-completions
-                  ivy-completion-beg
-                  ivy-completion-end))
-            :action #'ivy-completion-in-region-action))
-
-;;** `counsel-jedi'
-(declare-function deferred:sync! "ext:deferred")
-(declare-function jedi:complete-request "ext:jedi-core")
-(declare-function jedi:ac-direct-matches "ext:jedi")
-
-;;;###autoload
-(defun counsel-jedi ()
-  "Python completion at point."
-  (interactive)
-  (let ((bnd (bounds-of-thing-at-point 'symbol)))
-    (setq ivy-completion-beg (car bnd))
-    (setq ivy-completion-end (cdr bnd)))
-  (deferred:sync!
-      (jedi:complete-request))
-  (ivy-read "Symbol name: " (jedi:ac-direct-matches)
-            :action #'counsel--py-action))
-
-(defun counsel--py-action (symbol-name)
-  "Insert SYMBOL-NAME, erasing the previous one."
-  (when (stringp symbol-name)
-    (with-ivy-window
-      (when ivy-completion-beg
-        (delete-region
-         ivy-completion-beg
-         ivy-completion-end))
-      (setq ivy-completion-beg (point))
-      (insert symbol-name)
-      (setq ivy-completion-end (point)))))
-
-;;** `counsel-clj'
-(declare-function cider-sync-request:complete "ext:cider-client")
-(defun counsel--generic (completion-fn)
-  "Complete thing at point with COMPLETION-FN."
-  (let* ((bnd (or (bounds-of-thing-at-point 'symbol)
-                  (cons (point) (point))))
-         (str (buffer-substring-no-properties
-               (car bnd) (cdr bnd)))
-         (candidates (funcall completion-fn str))
-         (res (ivy-read (format "pattern (%s): " str)
-                        candidates
-                        :caller 'counsel--generic)))
-    (when (stringp res)
-      (when bnd
-        (delete-region (car bnd) (cdr bnd)))
-      (insert res))))
-
-(ivy-configure 'counsel--generic
-  :height 7)
-
-;;;###autoload
-(defun counsel-clj ()
-  "Clojure completion at point."
-  (interactive)
-  (counsel--generic
-   (lambda (str)
-     (mapcar
-      #'cl-caddr
-      (cider-sync-request:complete str ":same")))))
+(define-obsolete-function-alias 'counsel-el 'complete-symbol "<2020-05-20 
Wed>")
+(define-obsolete-function-alias 'counsel-cl 'complete-symbol "<2020-05-20 
Wed>")
+(define-obsolete-function-alias 'counsel-jedi 'complete-symbol "<2020-05-20 
Wed>")
+(define-obsolete-function-alias 'counsel-clj 'complete-symbol "<2020-05-20 
Wed>")
 
 ;;** `counsel-company'
 (defvar company-candidates)
@@ -389,6 +357,8 @@ Update the minibuffer with the amount of lines collected 
every
 (declare-function company-abort "ext:company")
 (declare-function company-complete "ext:company")
 (declare-function company-mode "ext:company")
+(declare-function company-call-backend "ext:company")
+(declare-function company--clean-string "ext:company")
 
 ;;;###autoload
 (defun counsel-company ()
@@ -397,8 +367,13 @@ Update the minibuffer with the amount of lines collected 
every
   (company-mode 1)
   (unless company-candidates
     (company-complete))
-  (let ((len (cond (company-common
-                    (length company-common))
+  (let ((len (cond ((let (l)
+                      (and company-common
+                           (string= company-common
+                                    (buffer-substring
+                                     (- (point) (setq l (length 
company-common)))
+                                     (point)))
+                           l)))
                    (company-prefix
                     (length company-prefix)))))
     (when len
@@ -409,8 +384,14 @@ Update the minibuffer with the amount of lines collected 
every
                 :caller 'counsel-company))))
 
 (ivy-configure 'counsel-company
+  :display-transformer-fn #'counsel--company-display-transformer
   :unwind-fn #'company-abort)
 
+(defun counsel--company-display-transformer (s)
+  (concat s (let ((annot (company-call-backend 'annotation s)))
+              (when annot
+                (company--clean-string annot)))))
+
 ;;** `counsel-irony'
 (declare-function irony-completion-candidates-async "ext:irony-completion")
 (declare-function irony-completion-symbol-bounds "ext:irony-completion")
@@ -442,7 +423,8 @@ Update the minibuffer with the amount of lines collected 
every
   (cons (concat (car x) (irony-completion-annotation x))
         (car x)))
 
-(add-to-list 'ivy-display-functions-alist '(counsel-irony . 
ivy-display-function-overlay))
+(ivy-configure #'counsel-irony
+  :display-fn #'ivy-display-function-overlay)
 
 ;;* Elisp symbols
 ;;** `counsel-describe-variable'
@@ -459,8 +441,8 @@ Update the minibuffer with the amount of lines collected 
every
 
 (defvar counsel-describe-symbol-history ()
   "History list for variable and function names.
-Used by commands `counsel-describe-variable' and
-`counsel-describe-function'.")
+Used by commands `counsel-describe-symbol',
+`counsel-describe-variable', and `counsel-describe-function'.")
 
 (defun counsel-find-symbol ()
   "Jump to the definition of the current symbol."
@@ -477,6 +459,7 @@ Used by commands `counsel-describe-variable' and
 (declare-function xref-push-marker-stack "xref")
 
 (defalias 'counsel--push-xref-marker
+  ;; Added in Emacs 25.1.
   (if (require 'xref nil t)
       #'xref-push-marker-stack
     (require 'etags)
@@ -544,9 +527,8 @@ Variables declared using `defcustom' are highlighted 
according to
               :caller 'counsel-describe-variable)))
 
 (ivy-configure 'counsel-describe-variable
-  :initial-input "^"
-  :display-transformer-fn #'counsel-describe-variable-transformer
-  :sort-fn #'ivy-string<)
+  :parent 'counsel-describe-symbol
+  :display-transformer-fn #'counsel-describe-variable-transformer)
 
 ;;** `counsel-describe-function'
 (ivy-set-actions
@@ -595,10 +577,44 @@ to `ivy-highlight-face'."
               :caller 'counsel-describe-function)))
 
 (ivy-configure 'counsel-describe-function
+  :parent 'counsel-describe-symbol
+  :display-transformer-fn #'counsel-describe-function-transformer)
+
+;;** `counsel-describe-symbol'
+(defcustom counsel-describe-symbol-function #'describe-symbol
+  "Function to call to describe a symbol passed as parameter."
+  :type 'function)
+
+;;;###autoload
+(defun counsel-describe-symbol ()
+  "Forward to `describe-symbol'."
+  (interactive)
+  (unless (functionp 'describe-symbol)
+    (user-error "This command requires Emacs 25.1 or later"))
+  (require 'help-mode)
+  (let ((enable-recursive-minibuffers t))
+    (ivy-read "Describe symbol: " obarray
+              :predicate (lambda (sym)
+                           (cl-some (lambda (backend)
+                                      (funcall (cadr backend) sym))
+                                    describe-symbol-backends))
+              :require-match t
+              :history 'counsel-describe-symbol-history
+              :keymap counsel-describe-map
+              :preselect (ivy-thing-at-point)
+              :action (lambda (x)
+                        (funcall counsel-describe-symbol-function (intern x)))
+              :caller 'counsel-describe-symbol)))
+
+(ivy-configure 'counsel-describe-symbol
   :initial-input "^"
-  :display-transformer-fn #'counsel-describe-function-transformer
   :sort-fn #'ivy-string<)
 
+(ivy-set-actions
+ 'counsel-describe-symbol
+ `(("I" ,#'counsel-info-lookup-symbol "info")
+   ("d" ,#'counsel--find-symbol "definition")))
+
 ;;** `counsel-set-variable'
 (defvar counsel-set-variable-history nil
   "Store history for `counsel-set-variable'.")
@@ -606,26 +622,35 @@ to `ivy-highlight-face'."
 (defun counsel-read-setq-expression (sym)
   "Read and eval a setq expression for SYM."
   (setq this-command 'eval-expression)
-  (let* ((minibuffer-completing-symbol t)
-         (sym-value (symbol-value sym))
-         (expr (minibuffer-with-setup-hook
-                   (lambda ()
-                     (add-function :before-until (local 
'eldoc-documentation-function)
-                                   #'elisp-eldoc-documentation-function)
-                     (add-hook 'completion-at-point-functions 
#'elisp-completion-at-point nil t)
-                     (run-hooks 'eval-expression-minibuffer-setup-hook)
-                     (goto-char (minibuffer-prompt-end))
-                     (forward-char 6)
-                     (insert (format "%S " sym)))
-                 (read-from-minibuffer "Eval: "
-                                       (format
-                                        (if (and sym-value (consp sym-value))
-                                            "(setq '%S)"
-                                          "(setq %S)")
-                                        sym-value)
-                                       read-expression-map t
-                                       'read-expression-history))))
-    (eval-expression expr)))
+  (let* ((sym-value (symbol-value sym))
+         (init (format "(setq %s%S)"
+                       (if (or (consp sym-value)
+                               (and sym-value (symbolp sym-value)))
+                           "'"
+                         "")
+                       sym-value)))
+    ;; Most of this duplicates `read--expression'.
+    (minibuffer-with-setup-hook
+        (lambda ()
+          (set-syntax-table emacs-lisp-mode-syntax-table)
+          ;; Added in Emacs 25.1.
+          (when (fboundp 'elisp-completion-at-point)
+            (add-hook 'completion-at-point-functions
+                      #'elisp-completion-at-point nil t))
+          ;; Emacs 27+ already sets up ElDoc in this hook.  Emacs 25 added
+          ;; `elisp-eldoc-documentation-function' and Emacs 28 obsoletes it.
+          (when (< emacs-major-version 27)
+            (when (fboundp 'elisp-eldoc-documentation-function)
+              (add-function :before-until (local 'eldoc-documentation-function)
+                            #'elisp-eldoc-documentation-function))
+            (eldoc-mode))
+          (run-hooks 'eval-expression-minibuffer-setup-hook)
+          ;; The following diverges from `read--expression'.
+          (goto-char (minibuffer-prompt-end))
+          (forward-char 6)
+          (insert (format "%S " sym)))
+      (read-from-minibuffer "Eval: " init read-expression-map t
+                            'read-expression-history))))
 
 (defun counsel--setq-doconst (x)
   "Return a cons of description and value for X.
@@ -702,12 +727,15 @@ With a prefix arg, restrict list to variables defined 
using
                          (if (assoc res cands)
                              (cdr (assoc res cands))
                            (read res)))
+                   (kill-new (format "(setq %S %S)" sym res))
                    (set sym (if (and (listp res) (eq (car res) 'quote))
                                 (cadr res)
                               res))))
              (unless (boundp sym)
                (set sym nil))
-             (counsel-read-setq-expression sym)))
+             (let ((expr (counsel-read-setq-expression sym)))
+               (kill-new (format "%S" expr))
+               (eval-expression expr))))
       (when doc
         (lv-delete-window)))))
 
@@ -853,6 +881,23 @@ packages are, in order of precedence, `amx' and `smex'."
            (smex-update))
          smex-ido-cache)))
 
+(defun counsel--M-x-externs-predicate (cand)
+  "Return non-nil if `counsel-M-x' should complete CAND.
+CAND is a string returned by `counsel--M-x-externs'."
+  (not (get (intern cand) 'no-counsel-M-x)))
+
+(defun counsel--M-x-make-predicate ()
+  "Return a predicate for `counsel-M-x' in the current buffer."
+  (defvar read-extended-command-predicate)
+  (let ((buf (current-buffer)))
+    (lambda (sym)
+      (and (commandp sym)
+           (not (get sym 'byte-obsolete-info))
+           (not (get sym 'no-counsel-M-x))
+           (or (not (bound-and-true-p read-extended-command-predicate))
+               (and (functionp read-extended-command-predicate)
+                    (funcall read-extended-command-predicate sym buf)))))))
+
 (defun counsel--M-x-prompt ()
   "String for `M-x' plus the string representation of `current-prefix-arg'."
   (concat (cond ((null current-prefix-arg)
@@ -872,7 +917,8 @@ packages are, in order of precedence, `amx' and `smex'."
 
 (defun counsel-M-x-action (cmd)
   "Execute CMD."
-  (setq cmd (intern cmd))
+  (setq cmd (intern
+             (subst-char-in-string ?\s ?- (string-remove-prefix "^" cmd))))
   (cond ((bound-and-true-p amx-initialized)
          (amx-rank cmd))
         ((bound-and-true-p smex-initialized-p)
@@ -897,12 +943,8 @@ when available, in that order of precedence."
   (let ((externs (counsel--M-x-externs)))
     (ivy-read (counsel--M-x-prompt) (or externs obarray)
               :predicate (if externs
-                             (lambda (x)
-                               (not (get (intern x) 'no-counsel-M-x)))
-                           (lambda (sym)
-                             (and (commandp sym)
-                                  (not (get sym 'byte-obsolete-info))
-                                  (not (get sym 'no-counsel-M-x)))))
+                             #'counsel--M-x-externs-predicate
+                           (counsel--M-x-make-predicate))
               :require-match t
               :history 'counsel-M-x-history
               :action #'counsel-M-x-action
@@ -1079,17 +1121,17 @@ See `describe-buffer-bindings' for further information."
         (describe-buffer-bindings buffer prefix))
       (goto-char (point-min))
       ;; Skip the "Key translations" section
-      (re-search-forward "")
-      (forward-char 1)
+      (skip-chars-forward "^\C-l")
+      (forward-char 2)
       (while (not (eobp))
         (when (looking-at "^\\([^\t\n]+\\)[\t ]*\\(.*\\)$")
           (let ((key (match-string 1))
                 (fun (match-string 2))
                 cmd)
             (unless (or (member fun '("??" "self-insert-command"))
-                        (string-match re-exclude key)
+                        (string-match-p re-exclude key)
                         (not (or (commandp (setq cmd (intern-soft fun)))
-                                 (member fun '("Prefix Command")))))
+                                 (equal fun "Prefix Command"))))
               (push
                (cons (format
                       "%-15s %s"
@@ -1097,7 +1139,7 @@ See `describe-buffer-bindings' for further information."
                       fun)
                      (cons key cmd))
                res))))
-        (forward-line 1)))
+        (forward-line)))
     (nreverse res)))
 
 (defcustom counsel-descbinds-function #'describe-function
@@ -1173,6 +1215,15 @@ back to the face of the character after point, and 
finally the
   "Customize face with NAME in another window."
   (customize-face-other-window (intern name)))
 
+(declare-function hi-lock-set-pattern "hi-lock")
+(defun counsel-highlight-with-face (face)
+  "Highlight thing-at-point with FACE."
+  (hi-lock-mode 1)
+  (let ((thing (ivy-thing-at-point)))
+    (when (use-region-p)
+      (deactivate-mark))
+    (hi-lock-set-pattern (regexp-quote thing) (intern face))))
+
 (ivy-set-actions
  'counsel-describe-face
  '(("c" counsel-customize-face "customize")
@@ -1211,17 +1262,18 @@ selected face."
               :caller 'counsel-faces)))
 
 (ivy-configure 'counsel-faces
-  :sort-fn #'ivy-string<
+  :parent 'counsel-describe-face
   :format-fn #'counsel--faces-format-function)
 
 (ivy-set-actions
  'counsel-faces
  '(("c" counsel-customize-face "customize")
-   ("C" counsel-customize-face-other-window "customize other window")))
+   ("C" counsel-customize-face-other-window "customize other window")
+   ("h" counsel-highlight-with-face "highlight")))
 
 ;;* Git
 ;;** `counsel-git'
-(defvar counsel-git-cmd "git ls-files --full-name --"
+(defvar counsel-git-cmd "git ls-files -z --full-name --"
   "Command for `counsel-git'.")
 
 (ivy-set-actions
@@ -1241,11 +1293,11 @@ Like `locate-dominating-file', but DIR defaults to
   (or (counsel--git-root)
       (error "Not in a Git repository")))
 
-(defun counsel-git-cands ()
-  (let ((default-directory (counsel-locate-git-root)))
+(defun counsel-git-cands (dir)
+  (let ((default-directory dir))
     (split-string
      (shell-command-to-string counsel-git-cmd)
-     "\n"
+     "\0"
      t)))
 
 ;;;###autoload
@@ -1255,7 +1307,7 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
   (interactive)
   (counsel-require-program counsel-git-cmd)
   (let ((default-directory (counsel-locate-git-root)))
-    (ivy-read "Find file: " (counsel-git-cands)
+    (ivy-read "Find file: " (counsel-git-cands default-directory)
               :initial-input initial-input
               :action #'counsel-git-action
               :caller 'counsel-git)))
@@ -1275,7 +1327,7 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
   (counsel-cmd-to-dired
    (counsel--expand-ls
     (format "%s | %s | xargs ls"
-            counsel-git-cmd
+            (replace-regexp-in-string "\\(-0\\)\\|\\(-z\\)" "" counsel-git-cmd)
             (counsel--file-name-filter)))))
 
 (defvar counsel-dired-listing-switches "-alh"
@@ -1316,7 +1368,7 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
     (define-key map (kbd "C-x C-d") 'counsel-cd)
     map))
 
-(defvar counsel-git-grep-cmd-default "git --no-pager grep --full-name -n 
--no-color -i -I -e \"%s\""
+(defvar counsel-git-grep-cmd-default "git --no-pager grep -n --no-color -I -e 
\"%s\""
   "Initial command for `counsel-git-grep'.")
 
 (defvar counsel-git-grep-cmd nil
@@ -1335,7 +1387,8 @@ Typical value: '(recenter)."
   :type 'hook)
 
 (defcustom counsel-git-grep-cmd-function 
#'counsel-git-grep-cmd-function-default
-  "How a git-grep shell call is built from the input."
+  "How a git-grep shell call is built from the input.
+This function should set `ivy--old-re'."
   :type '(radio
           (function-item counsel-git-grep-cmd-function-default)
           (function-item counsel-git-grep-cmd-function-ignore-order)
@@ -1362,7 +1415,9 @@ Typical value: '(recenter)."
    (ivy-more-chars)
    (progn
      (counsel--async-command
-      (funcall counsel-git-grep-cmd-function string))
+      (concat
+       (funcall counsel-git-grep-cmd-function string)
+       (if (ivy--case-fold-p string) " -i" "")))
      nil)))
 
 (defun counsel-git-grep-action (x)
@@ -1385,14 +1440,12 @@ Typical value: '(recenter)."
         (swiper--add-overlays (ivy--regex ivy-text))))))
 
 (defun counsel-git-grep-transformer (str)
-  "Higlight file and line number in STR."
+  "Highlight file and line number in STR."
   (when (string-match "\\`\\([^:]+\\):\\([^:]+\\):" str)
-    (ivy-add-face-text-property (match-beginning 1) (match-end 1)
-                                'ivy-grep-info
-                                str)
-    (ivy-add-face-text-property (match-beginning 2) (match-end 2)
-                                'ivy-grep-line-number
-                                str))
+    (add-face-text-property (match-beginning 1) (match-end 1)
+                            'ivy-grep-info nil str)
+    (add-face-text-property (match-beginning 2) (match-end 2)
+                            'ivy-grep-line-number nil str))
   str)
 
 (defvar counsel-git-grep-projects-alist nil
@@ -1495,12 +1548,36 @@ When CMD is non-nil, prompt for a specific \"git grep\" 
command."
                 :keymap counsel-git-grep-map
                 :action #'counsel-git-grep-action
                 :history 'counsel-git-grep-history
+                :require-match t
                 :caller 'counsel-git-grep))))
 
+(defun counsel--git-grep-index (_re-str cands)
+  (let (name ln)
+    (cond
+      (ivy--old-cands
+       (ivy-recompute-index-swiper-async nil cands))
+      ((unless (with-ivy-window
+                 (when buffer-file-name
+                   (setq ln (line-number-at-pos))
+                   (setq name (file-name-nondirectory buffer-file-name))))
+         0))
+      ;; Closest to current line going forwards.
+      ((let ((beg (1+ (length name))))
+         (cl-position-if (lambda (x)
+                           (and (string-prefix-p name x)
+                                (>= (string-to-number (substring x beg)) ln)))
+                         cands)))
+      ;; Closest to current line going backwards.
+      ((cl-position-if (lambda (x)
+                         (string-prefix-p name x))
+                       cands
+                       :from-end t))
+      (t 0))))
+
 (ivy-configure 'counsel-git-grep
   :occur #'counsel-git-grep-occur
   :unwind-fn #'counsel--grep-unwind
-  :index-fn #'ivy-recompute-index-swiper-async
+  :index-fn #'counsel--git-grep-index
   :display-transformer-fn #'counsel-git-grep-transformer
   :grep-p t
   :exit-codes '(1 "No matches found"))
@@ -1511,7 +1588,10 @@ When CMD is non-nil, prompt for a specific \"git grep\" 
command."
    (ivy-more-chars)
    (let ((regex (setq ivy--old-re
                       (ivy--regex str t))))
-     (counsel--async-command (format counsel-git-grep-cmd regex))
+     (counsel--async-command
+      (concat
+       (format counsel-git-grep-cmd regex)
+       (if (ivy--case-fold-p str) " -i" "")))
      nil)))
 
 (defun counsel-git-grep-switch-cmd ()
@@ -1539,10 +1619,7 @@ When CMD is non-nil, prompt for a specific \"git grep\" 
command."
   str)
 
 (defun counsel--git-grep-occur-cmd (input)
-  (let* ((regex (funcall ivy--regex-function input))
-         (regex (if (eq ivy--regex-function #'ivy--regex-fuzzy)
-                    (replace-regexp-in-string "\n" "" regex)
-                  regex))
+  (let* ((regex ivy--old-re)
          (positive-pattern (replace-regexp-in-string
                             ;; git-grep can't handle .*?
                             "\\.\\*\\?" ".*"
@@ -1554,7 +1631,10 @@ When CMD is non-nil, prompt for a specific \"git grep\" 
command."
                               (format "| grep -v %s" (car x))))
                        regex
                        " "))))
-    (concat (format counsel-git-grep-cmd positive-pattern) negative-patterns)))
+    (concat
+     (format counsel-git-grep-cmd positive-pattern)
+     negative-patterns
+     (if (ivy--case-fold-p input) " -i" ""))))
 
 (defun counsel-git-grep-occur (&optional _cands)
   "Generate a custom occur buffer for `counsel-git-grep'."
@@ -1607,16 +1687,16 @@ done") "\n" t)))
               :caller 'counsel-git-stash)))
 
 ;;** `counsel-git-log'
-(defvar counsel-git-log-cmd "GIT_PAGER=cat git log --grep '%s'"
+(defvar counsel-git-log-cmd "GIT_PAGER=cat git log --no-color --grep '%s'"
   "Command used for \"git log\".")
 
-(defun counsel-git-log-function (str)
-  "Search for STR in git log."
+(defun counsel-git-log-function (_)
+  "Search for `ivy-regex' in git log."
   (or
    (ivy-more-chars)
    (progn
      ;; `counsel--yank-pop-format-function' uses this
-     (setq ivy--old-re (funcall ivy--regex-function str))
+     (setq ivy--old-re ivy-regex)
      (counsel--async-command
       ;; "git log --grep" likes to have groups quoted e.g. \(foo\).
       ;; But it doesn't like the non-greedy ".*?".
@@ -1682,7 +1762,7 @@ TREE is the selected candidate."
     (ivy-read "Select worktree: "
               (or (cl-delete default-directory (counsel-git-worktree-list)
                              :key #'counsel-git-worktree-parse-root :test 
#'string=)
-                  (error "No other worktrees!"))
+                  (error "No other worktrees"))
               :action (lambda (tree)
                         (counsel-git-change-worktree-action
                          (ivy-state-directory ivy-last) tree))
@@ -1748,9 +1828,17 @@ currently checked out."
   (let ((map (make-sparse-keymap)))
     (define-key map (kbd "C-DEL") 'counsel-up-directory)
     (define-key map (kbd "C-<backspace>") 'counsel-up-directory)
-    (define-key map (kbd "`") (ivy-make-magic-action 'counsel-find-file "b"))
+    (define-key map (kbd "`") #'counsel-file-jump-from-find)
+    (define-key map (kbd "C-`") (ivy-make-magic-action 'counsel-find-file "b"))
+    (define-key map [remap undo] 'counsel-find-file-undo)
     map))
 
+(defun counsel-file-jump-from-find ()
+  "Switch to `counsel-file-jump' from `counsel-find-file'."
+  (interactive)
+  (ivy-quit-and-run
+    (counsel-file-jump ivy-text (ivy-state-directory ivy-last))))
+
 (when (executable-find "git")
   (add-to-list 'ivy-ffap-url-functions 'counsel-github-url-p)
   (add-to-list 'ivy-ffap-url-functions 'counsel-emacs-url-p))
@@ -1848,6 +1936,7 @@ choose between `yes-or-no-p' and `y-or-n-p'; otherwise 
default to
    ("x" counsel-find-file-extern "open externally")
    ("r" counsel-find-file-as-root "open as root")
    ("R" find-file-read-only "read only")
+   ("l" find-file-literally "open literally")
    ("k" counsel-find-file-delete "delete")
    ("c" counsel-find-file-copy "copy file")
    ("m" counsel-find-file-move "move or rename")
@@ -1897,7 +1986,7 @@ Skip some dotfiles unless `ivy-text' requires them."
         (setq res (cl-remove-if-not counsel--find-file-predicate res))))
     (if (or (null ivy-use-ignore)
             (null counsel-find-file-ignore-regexp)
-            (string-match-p "\\`\\." ivy-text))
+            (string-match-p counsel-find-file-ignore-regexp ivy-text))
         res
       (or (cl-remove-if
            (lambda (x)
@@ -1918,15 +2007,14 @@ Skip some dotfiles unless `ivy-text' requires them."
 
 (defun counsel-find-file-action (x)
   "Find file X."
-  (with-ivy-window
-    (cond ((and counsel-find-file-speedup-remote
-                (file-remote-p ivy--directory))
-           (let ((find-file-hook nil))
-             (find-file (expand-file-name x ivy--directory))))
-          ((member (file-name-extension x) counsel-find-file-extern-extensions)
-           (counsel-find-file-extern x))
-          (t
-           (find-file (expand-file-name x ivy--directory))))))
+  (cond ((and counsel-find-file-speedup-remote
+              (file-remote-p ivy--directory))
+         (let ((find-file-hook nil))
+           (find-file (expand-file-name x ivy--directory))))
+        ((member (file-name-extension x) counsel-find-file-extern-extensions)
+         (counsel-find-file-extern x))
+        (t
+         (find-file (expand-file-name x ivy--directory)))))
 
 (defun counsel--preselect-file ()
   "Return candidate to preselect during filename completion.
@@ -1937,7 +2025,8 @@ The preselect behavior can be customized via user options
    (when counsel-find-file-at-point
      (require 'ffap)
      (let ((f (ffap-guesser)))
-       (when f (expand-file-name f))))
+       (when (and f (not (ivy-ffap-url-p f)))
+         (expand-file-name f))))
    (and counsel-preselect-current-file
         buffer-file-name
         (file-name-nondirectory buffer-file-name))))
@@ -1958,18 +2047,18 @@ The preselect behavior can be customized via user 
options
               :caller caller)))
 
 ;;;###autoload
-(defun counsel-find-file (&optional initial-input)
+(defun counsel-find-file (&optional initial-input initial-directory)
   "Forward to `find-file'.
 When INITIAL-INPUT is non-nil, use it in the minibuffer during completion."
   (interactive)
-  (counsel--find-file-1
-   "Find file: " initial-input
-   #'counsel-find-file-action
-   'counsel-find-file))
+  (let ((default-directory (or initial-directory default-directory)))
+    (counsel--find-file-1 "Find file: " initial-input
+                          #'counsel-find-file-action
+                          'counsel-find-file)))
 
 (ivy-configure 'counsel-find-file
-  :occur #'counsel-find-file-occur
-  :display-transformer-fn #'ivy-read-file-transformer)
+  :parent 'read-file-name-internal
+  :occur #'counsel-find-file-occur)
 
 (defvar counsel-find-file-occur-cmd "ls -a | %s | xargs -d '\\n' ls -d 
--group-directories-first"
   "Format string for `counsel-find-file-occur'.")
@@ -1984,7 +2073,7 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer 
during completion."
 (defvar counsel-file-name-filter-alist
   '(("ag -i '%s'" . t)
     ("ack -i '%s'" . t)
-    ("perl -ne '/(%s.*)/i && print \"$1\\n\";'" . t)
+    ("perl -ne '/(.*%s.*)/i && print \"$1\\n\";'" . t)
     ("grep -i -E '%s'"))
   "Alist of file name filtering commands.
 The car is a shell command and the cdr is t when the shell
@@ -2008,7 +2097,7 @@ If USE-IGNORE is non-nil, try to generate a command that 
respects
         (when (and use-ignore ivy-use-ignore
                    counsel-find-file-ignore-regexp
                    (cdr filter-cmd)
-                   (not (string-match-p "\\`\\." ivy-text))
+                   (not (string-match-p counsel-find-file-ignore-regexp 
ivy-text))
                    (not (string-match-p counsel-find-file-ignore-regexp
                                         (or (car ivy--old-cands) ""))))
           (let ((ignore-re (list (counsel--elisp-to-pcre
@@ -2084,7 +2173,7 @@ See variable `counsel-up-directory-level'."
           (ivy-set-index 0)
           (setq ivy--directory "")
           (setq ivy--all-candidates nil)
-          (setq ivy-text "")
+          (ivy-set-text "")
           (delete-minibuffer-contents)
           (insert up-dir))
       (if (and counsel-up-directory-level (not (string= ivy-text "")))
@@ -2098,6 +2187,16 @@ See variable `counsel-up-directory-level'."
   (interactive)
   (ivy--directory-enter))
 
+(defun counsel-find-file-undo ()
+  (interactive)
+  (if (string= ivy-text "")
+      (let ((dir (progn
+                   (pop ivy--directory-hist)
+                   (pop ivy--directory-hist))))
+        (when dir
+          (ivy--cd dir)))
+    (undo)))
+
 (defun counsel-at-git-issue-p ()
   "When point is at an issue in a Git-versioned file, return the issue string."
   (and (looking-at "#[0-9]+")
@@ -2196,29 +2295,111 @@ When INITIAL-INPUT is non-nil, use it in the 
minibuffer during completion."
      'counsel-dired)))
 
 (ivy-configure 'counsel-dired
-  :display-transformer-fn #'ivy-read-file-transformer)
+  :parent 'read-file-name-internal)
 
 ;;** `counsel-recentf'
 (defvar recentf-list)
 (declare-function recentf-mode "recentf")
 
+(defcustom counsel-recentf-include-xdg-list nil
+  "Include recently used files listed by XDG-compliant environments.
+Examples of such environments are GNOME and KDE.  See the URL
+`https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec'."
+  :type 'boolean
+  :link '(url-link "\
+https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec";))
+
 ;;;###autoload
 (defun counsel-recentf ()
   "Find a file on `recentf-list'."
   (interactive)
   (require 'recentf)
   (recentf-mode)
-  (ivy-read "Recentf: " (mapcar #'substring-no-properties recentf-list)
+  (ivy-read "Recentf: " (counsel-recentf-candidates)
             :action (lambda (f)
                       (with-ivy-window
                         (find-file f)))
             :require-match t
             :caller 'counsel-recentf))
+
 (ivy-set-actions
  'counsel-recentf
- '(("j" find-file-other-window "other window")
+ `(("j" find-file-other-window "other window")
    ("f" find-file-other-frame "other frame")
-   ("x" counsel-find-file-extern "open externally")))
+   ("x" counsel-find-file-extern "open externally")
+   ("d" ,(lambda (file) (setq recentf-list (delete file recentf-list)))
+    "delete from recentf")))
+
+(defun counsel-recentf-candidates ()
+  "Return candidates for `counsel-recentf'.
+
+When `counsel-recentf-include-xdg-list' is non-nil, also include
+the files in said list, sorting the combined list by file access
+time."
+  (if (and counsel-recentf-include-xdg-list
+           (>= emacs-major-version 26))
+      (delete-dups
+       (sort (nconc (mapcar #'substring-no-properties recentf-list)
+                    (counsel--recentf-get-xdg-recent-files))
+             (lambda (file1 file2)
+               (cond ((file-remote-p file1)
+                      nil)
+                     ((file-remote-p file2))
+                     (t
+                      ;; Added in Emacs 26.1.
+                      (declare-function file-attribute-access-time "files"
+                                        (attributes))
+                      (time-less-p (file-attribute-access-time
+                                    (file-attributes file2))
+                                   (file-attribute-access-time
+                                    (file-attributes file1))))))))
+    (mapcar #'substring-no-properties recentf-list)))
+
+(defalias 'counsel--xml-parse-region
+  (if (cond ((fboundp 'libxml-available-p)
+             ;; Added in Emacs 27.1.
+             (libxml-available-p))
+            ((fboundp 'libxml-parse-xml-region)
+             ;; Checking for `fboundp' is not enough on Windows, where it
+             ;; will return non-nil even if the library is not installed.
+             (with-temp-buffer
+               (insert "<xml/>")
+               (libxml-parse-xml-region (point-min) (point-max)))))
+      (lambda (&optional beg end)
+        (libxml-parse-xml-region (or beg (point-min)) (or end (point-max))))
+    #'xml-parse-region)
+  "Compatibility shim for `libxml-parse-xml-region'.
+For convenience, BEG and END default to `point-min' and
+`point-max', respectively.
+
+\(fn &optional BEG END)")
+
+(defun counsel--recentf-get-xdg-recent-files ()
+  "Return list of XDG recent files.
+
+This information is parsed from the file \"recently-used.xbel\",
+which lists both files and directories, under `xdg-data-home'.
+This function uses the `dom' library from Emacs 25.1 or later."
+  (unless (require 'dom nil t)
+    (user-error "This function requires Emacs 25.1 or later"))
+  (declare-function dom-attr "dom" (node attr))
+  (declare-function dom-by-tag "dom" (dom tag))
+  (let ((file-of-recent-files
+         (expand-file-name "recently-used.xbel" (counsel--xdg-data-home))))
+    (unless (file-readable-p file-of-recent-files)
+      (user-error "List of XDG recent files not found: %s"
+                  file-of-recent-files))
+    (cl-mapcan (lambda (bookmark-node)
+                 (let* ((file (dom-attr bookmark-node 'href))
+                        (file (string-remove-prefix "file://" file))
+                        (file (url-unhex-string file t))
+                        (file (decode-coding-string file 'utf-8 t)))
+                   (and (file-exists-p file)
+                        (list file))))
+               (let ((dom (with-temp-buffer
+                            (insert-file-contents file-of-recent-files)
+                            (counsel--xml-parse-region))))
+                 (nreverse (dom-by-tag dom 'bookmark))))))
 
 (defun counsel-buffer-or-recentf-candidates ()
   "Return candidates for `counsel-buffer-or-recentf'."
@@ -2233,7 +2414,7 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer 
during completion."
     (append
      buffers
      (cl-remove-if (lambda (f) (member f buffers))
-                   (mapcar #'substring-no-properties recentf-list)))))
+                   (counsel-recentf-candidates)))))
 
 ;;;###autoload
 (defun counsel-buffer-or-recentf ()
@@ -2306,6 +2487,7 @@ By default `counsel-bookmark' opens a dired buffer for 
directories."
  'counsel-bookmark
  `(("d" bookmark-delete "delete")
    ("e" bookmark-rename "edit")
+   ("s" bookmark-set "overwrite")
    ("x" ,(counsel--apply-bookmark-fn #'counsel-find-file-extern)
         "open externally")
    ("r" ,(counsel--apply-bookmark-fn #'counsel-find-file-as-root)
@@ -2334,12 +2516,12 @@ current value of `default-directory'."
             :action #'dired))
 
 (ivy-set-actions 'counsel-bookmarked-directory
-                 '(("j" dired-other-window "other window")
+                 `(("j" dired-other-window "other window")
                    ("x" counsel-find-file-extern "open externally")
                    ("r" counsel-find-file-as-root "open as root")
-                   ("f" (lambda (dir)
-                          (let ((default-directory dir))
-                            (call-interactively #'find-file)))
+                   ("f" ,(lambda (dir)
+                           (let ((default-directory dir))
+                             (call-interactively #'find-file)))
                     "find-file")))
 
 ;;** `counsel-file-register'
@@ -2381,13 +2563,13 @@ can use `C-x r j i' to open that file."
 
 ;;** `counsel-locate'
 (defcustom counsel-locate-cmd (cond ((memq system-type '(darwin berkeley-unix))
-                                     'counsel-locate-cmd-noregex)
+                                     #'counsel-locate-cmd-noregex)
                                     ((and (eq system-type 'windows-nt)
                                           (executable-find "es.exe"))
-                                     'counsel-locate-cmd-es)
+                                     #'counsel-locate-cmd-es)
                                     (t
-                                     'counsel-locate-cmd-default))
-  "The function for producing a locate command string from the input.
+                                     #'counsel-locate-cmd-default))
+  "The function for producing a `locate' command string from the input.
 
 The function takes a string - the current input, and returns a
 string - the full shell command to run."
@@ -2395,7 +2577,8 @@ string - the full shell command to run."
           (const :tag "Default" counsel-locate-cmd-default)
           (const :tag "No regex" counsel-locate-cmd-noregex)
           (const :tag "mdfind" counsel-locate-cmd-mdfind)
-          (const :tag "everything" counsel-locate-cmd-es)))
+          (const :tag "everything" counsel-locate-cmd-es)
+          (function :tag "Custom")))
 
 (ivy-set-actions
  'counsel-locate
@@ -2430,33 +2613,33 @@ string - the full shell command to run."
   (dired-jump nil x))
 
 (defun counsel-locate-cmd-default (input)
-  "Return a shell command based on INPUT."
+  "Return a `locate' shell command based on regexp INPUT."
   (counsel-require-program "locate")
-  (format "locate -i --regex '%s'"
-          (counsel--elisp-to-pcre
-           (ivy--regex input))))
+  (format "locate -i --regex %s"
+          (shell-quote-argument
+           (counsel--elisp-to-pcre
+            (ivy--regex input)))))
 
 (defun counsel-locate-cmd-noregex (input)
-  "Return a shell command based on INPUT."
+  "Return a `locate' shell command based on INPUT."
   (counsel-require-program "locate")
-  (format "locate -i '%s'" input))
+  (format "locate -i %s" (shell-quote-argument input)))
 
 (defun counsel-locate-cmd-mdfind (input)
-  "Return a shell command based on INPUT."
+  "Return a `mdfind' shell command based on INPUT."
   (counsel-require-program "mdfind")
-  (format "mdfind -name '%s'" input))
-
-(defvar w32-ansi-code-page)
+  (format "mdfind -name %s" (shell-quote-argument input)))
 
 (defun counsel-locate-cmd-es (input)
-  "Return a shell command based on INPUT."
+  "Return a `es' shell command based on INPUT."
+  (defvar w32-ansi-code-page)
   (counsel-require-program "es.exe")
-  (let ((raw-string (format "es.exe -i -r -p %s"
+  (let ((raw-string (format "es.exe -i -p -r %s"
                             (counsel--elisp-to-pcre
                              (ivy--regex input t)))))
-    ;; W32 don't use Unicode by default, so we encode search command
-    ;; to local codepage to support searching filename contains non-ASCII
-    ;; characters.
+    ;; W32 doesn't use Unicode by default, so we encode search command
+    ;; to local codepage to support searching file names containing
+    ;; non-ASCII characters.
     (if (and (eq system-type 'windows-nt)
              (boundp 'w32-ansi-code-page))
         (encode-coding-string raw-string
@@ -2464,7 +2647,7 @@ string - the full shell command to run."
       raw-string)))
 
 (defun counsel-locate-function (input)
-  "Call the \"locate\" shell command with INPUT."
+  "Call a \"locate\" style shell command with INPUT."
   (or
    (ivy-more-chars)
    (progn
@@ -2478,10 +2661,7 @@ string - the full shell command to run."
 
 (defun counsel-file-stale-p (fname seconds)
   "Return non-nil if FNAME was modified more than SECONDS ago."
-  (> (time-to-seconds
-      (time-subtract
-       (current-time)
-       (nth 5 (file-attributes fname))))
+  (> (float-time (time-subtract nil (nth 5 (file-attributes fname))))
      seconds))
 
 (defun counsel--locate-updatedb ()
@@ -2496,7 +2676,7 @@ string - the full shell command to run."
 
 ;;;###autoload
 (defun counsel-locate (&optional initial-input)
-  "Call the \"locate\" shell command.
+  "Call a \"locate\" style shell command.
 INITIAL-INPUT can be given as the initial minibuffer input."
   (interactive)
   (counsel--locate-updatedb)
@@ -2515,6 +2695,35 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
   :unwind-fn #'counsel-delete-process
   :exit-codes '(1 "Nothing found"))
 
+;;** `counsel-tracker'
+(defun counsel-tracker-function (input)
+  "Call the \"tracker\" shell command with INPUT."
+  (or
+   (ivy-more-chars)
+   (progn
+     (counsel--async-command
+      (format
+       "tracker sparql -q \"SELECT ?url WHERE { ?s a nfo:FileDataObject ; 
nie:url ?url . FILTER (STRSTARTS (?url, 'file://$HOME/')) . FILTER regex(?url, 
'%s') }\" | tail -n +2 | head -n -1"
+       (counsel--elisp-to-pcre (funcall ivy--regex-function input))))
+     '("" "working..."))))
+
+(defun counsel-tracker-transformer (str)
+  (if (string-match "file:///" str)
+      (decode-coding-string (url-unhex-string (substring str 9)) 'utf-8)
+    str))
+
+;;;###autoload
+(defun counsel-tracker ()
+  (interactive)
+  (ivy-read "Tracker: " 'counsel-tracker-function
+            :dynamic-collection t
+            :action (lambda (s) (find-file (counsel-tracker-transformer s)))
+            :caller 'counsel-tracker))
+
+(ivy-configure 'counsel-tracker
+  :display-transformer-fn #'counsel-tracker-transformer
+  :unwind-fn #'counsel-delete-process)
+
 ;;** `counsel-fzf'
 (defvar counsel-fzf-cmd "fzf -f \"%s\""
   "Command for `counsel-fzf'.")
@@ -2634,7 +2843,8 @@ FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt 
argument."
 
 (defun counsel--find-return-list (args)
   (unless (listp args)
-    (user-error "`counsel-file-jump-args' is a list now, please customize 
accordingly."))
+    (user-error
+     "`counsel-file-jump-args' is a list now; please customize accordingly"))
   (counsel--call
    (cons find-program args)
    (lambda ()
@@ -2652,6 +2862,18 @@ FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt 
argument."
   :type '(repeat string))
 
 ;;** `counsel-file-jump'
+(defvar counsel-file-jump-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "`") #'counsel-find-file-from-jump)
+    map)
+  "Key bindings to be used when in a file-jump minibuffer.")
+
+(defun counsel-find-file-from-jump ()
+  "Switch to `counsel-find-file' from `counsel-file-jump'."
+  (interactive)
+  (ivy-quit-and-run
+    (counsel-find-file ivy-text (ivy-state-directory ivy-last))))
+
 ;;;###autoload
 (defun counsel-file-jump (&optional initial-input initial-directory)
   "Jump to a file below the current directory.
@@ -2672,7 +2894,7 @@ INITIAL-DIRECTORY, if non-nil, is used as the root 
directory for search."
               :preselect (counsel--preselect-file)
               :require-match 'confirm-after-completion
               :history 'file-name-history
-              :keymap counsel-find-file-map
+              :keymap counsel-file-jump-map
               :caller 'counsel-file-jump)))
 
 (ivy-set-actions
@@ -2709,26 +2931,6 @@ INITIAL-DIRECTORY, if non-nil, is used as the root 
directory for search."
               :caller 'counsel-dired-jump)))
 
 ;;* Grep
-(defun counsel--grep-mode-occur (git-grep-dir-is-file)
-  "Generate a custom occur buffer for grep like commands.
-If GIT-GREP-DIR-IS-FILE is t, then `ivy-state-directory' is treated as a full
-path to a file rather than a directory (e.g. for `counsel-grep-occur').
-
-This function expects that the candidates have already been filtered.
-It applies no filtering to ivy--all-candidates."
-  (unless (eq major-mode 'ivy-occur-grep-mode)
-    (ivy-occur-grep-mode))
-  (let ((directory
-         (if git-grep-dir-is-file
-             (file-name-directory (ivy-state-directory ivy-last))
-           (ivy-state-directory ivy-last))))
-    (setq default-directory directory)
-    ;; Need precise number of header lines for `wgrep' to work.
-    (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n" 
default-directory))
-    (insert (format "%d candidates:\n" (length ivy--all-candidates)))
-    (ivy--occur-insert-lines
-     (mapcar #'counsel--normalize-grep-match ivy--all-candidates))))
-
 ;;** `counsel-ag'
 (defvar counsel-ag-map
   (let ((map (make-sparse-keymap)))
@@ -2738,14 +2940,14 @@ It applies no filtering to ivy--all-candidates."
     (define-key map (kbd "C-x C-d") 'counsel-cd)
     map))
 
-(defcustom counsel-ag-base-command
-  (if (memq system-type '(ms-dos windows-nt))
-      "ag --vimgrep %s"
-    "ag --nocolor --nogroup %s")
+(defcustom counsel-ag-base-command "ag --vimgrep %s"
   "Format string to use in `counsel-ag-function' to construct the command.
 The %s will be replaced by optional extra ag arguments followed by the
 regex string."
-  :type 'string)
+  :type '(radio
+          (const "ag --vimgrep %s")
+          (const "ag --nocolor --nogroup %s")
+          (string :tag "custom")))
 
 (defvar counsel-ag-command nil)
 
@@ -2753,34 +2955,38 @@ regex string."
 
 (defvar counsel--regex-look-around nil)
 
-(defconst counsel--command-args-separator "-- ")
+(defconst counsel--command-args-separator " -- ")
 
 (defun counsel--split-command-args (arguments)
   "Split ARGUMENTS into its switches and search-term parts.
 Return pair of corresponding strings (SWITCHES . SEARCH-TERM)."
-  (let ((switches "")
-        (search-term arguments))
-    (when (string-prefix-p "-" arguments)
-      (let ((index (string-match counsel--command-args-separator arguments)))
-        (when index
-          (setq search-term
-                (substring arguments (+ (length 
counsel--command-args-separator) index)))
-          (setq switches (substring arguments 0 index)))))
-    (cons switches search-term)))
+  (if (string-match counsel--command-args-separator arguments)
+      (let ((args (substring arguments (match-end 0)))
+            (search-term (substring arguments 0 (match-beginning 0))))
+        (if (string-prefix-p "-" arguments)
+            (cons search-term args)
+          (cons args search-term)))
+    (cons "" arguments)))
 
 (defun counsel--format-ag-command (extra-args needle)
   "Construct a complete `counsel-ag-command' as a string.
 EXTRA-ARGS is a string of the additional arguments.
 NEEDLE is the search string."
-  (format counsel-ag-command
-          (if (string-match " \\(--\\) " extra-args)
-              (replace-match needle t t extra-args 1)
-            (concat extra-args " " needle))))
+  (counsel--format counsel-ag-command
+                   (if (listp counsel-ag-command)
+                       (if (string-match " \\(--\\) " extra-args)
+                           (counsel--format
+                            (split-string (replace-match "%s" t t extra-args 
1))
+                            needle)
+                         (nconc (split-string extra-args) needle))
+                     (if (string-match " \\(--\\) " extra-args)
+                         (replace-match needle t t extra-args 1)
+                       (concat extra-args " " needle)))))
 
 (defun counsel--grep-regex (str)
   (counsel--elisp-to-pcre
    (setq ivy--old-re
-         (funcall ivy--regex-function str))
+         (funcall (ivy-state-re-builder ivy-last) str))
    counsel--regex-look-around))
 
 (defun counsel--ag-extra-switches (regex)
@@ -2799,51 +3005,65 @@ NEEDLE is the search string."
        (ivy-more-chars))
      (let* ((default-directory (ivy-state-directory ivy-last))
             (regex (counsel--grep-regex search-term))
-            (switches (concat (car command-args)
+            (switches (concat (if (ivy--case-fold-p string)
+                                  " -i "
+                                " -s ")
                               (counsel--ag-extra-switches regex)
-                              (and (ivy--case-fold-p string) " -i "))))
+                              (car command-args))))
        (counsel--async-command (counsel--format-ag-command
                                 switches
-                                (shell-quote-argument regex)))
+                                (funcall (if (listp counsel-ag-command) 
#'identity
+                                           #'shell-quote-argument)
+                                         regex)))
        nil))))
 
 ;;;###autoload
 (cl-defun counsel-ag (&optional initial-input initial-directory extra-ag-args 
ag-prompt
                       &key caller)
-  "Grep for a string in the current directory using ag.
+  "Grep for a string in a root directory using ag.
+
+By default, the root directory is the first directory containing a .git 
subdirectory.
+
 INITIAL-INPUT can be given as the initial minibuffer input.
 INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
-EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'.
+EXTRA-AG-ARGS, if non-nil, is appended to `counsel-ag-base-command'.
 AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.
-CALLER is passed to `ivy-read'."
+CALLER is passed to `ivy-read'.
+
+With a `\\[universal-argument]' prefix argument, prompt for INITIAL-DIRECTORY.
+With a `\\[universal-argument] \\[universal-argument]' prefix argument, \
+prompt additionally for EXTRA-AG-ARGS."
   (interactive)
   (setq counsel-ag-command counsel-ag-base-command)
   (setq counsel--regex-look-around counsel--grep-tool-look-around)
   (counsel-require-program counsel-ag-command)
-  (when current-prefix-arg
-    (setq initial-directory
-          (or initial-directory
-              (counsel-read-directory-name (concat
-                                            (car (split-string 
counsel-ag-command))
-                                            " in directory: "))))
-    (setq extra-ag-args
-          (or extra-ag-args
-              (read-from-minibuffer (format
-                                     "%s args: "
-                                     (car (split-string 
counsel-ag-command)))))))
-  (setq counsel-ag-command (counsel--format-ag-command (or extra-ag-args "") 
"%s"))
-  (let ((default-directory (or initial-directory
-                               (counsel--git-root)
-                               default-directory)))
-    (ivy-read (or ag-prompt
-                  (concat (car (split-string counsel-ag-command)) ": "))
-              #'counsel-ag-function
-              :initial-input initial-input
-              :dynamic-collection t
-              :keymap counsel-ag-map
-              :history 'counsel-git-grep-history
-              :action #'counsel-git-grep-action
-              :caller (or caller 'counsel-ag))))
+  (let ((prog-name (car (if (listp counsel-ag-command) counsel-ag-command
+                          (split-string counsel-ag-command))))
+        (arg (prefix-numeric-value current-prefix-arg)))
+    (when (>= arg 4)
+      (setq initial-directory
+            (or initial-directory
+                (counsel-read-directory-name (concat
+                                              prog-name
+                                              " in directory: ")))))
+    (when (>= arg 16)
+      (setq extra-ag-args
+            (or extra-ag-args
+                (read-from-minibuffer (format "%s args: " prog-name)))))
+    (setq counsel-ag-command (counsel--format-ag-command (or extra-ag-args "") 
"%s"))
+    (let ((default-directory (or initial-directory
+                                 (counsel--git-root)
+                                 default-directory)))
+      (ivy-read (or ag-prompt
+                    (concat prog-name ": "))
+                #'counsel-ag-function
+                :initial-input initial-input
+                :dynamic-collection t
+                :keymap counsel-ag-map
+                :history 'counsel-git-grep-history
+                :action #'counsel-git-grep-action
+                :require-match t
+                :caller (or caller 'counsel-ag)))))
 
 (ivy-configure 'counsel-ag
   :occur #'counsel-ag-occur
@@ -2852,47 +3072,74 @@ CALLER is passed to `ivy-read'."
   :grep-p t
   :exit-codes '(1 "No matches found"))
 
-(defun counsel-read-directory-name (prompt)
+(defun counsel-read-directory-name (prompt &optional default)
   "Read a directory name from user, a (partial) replacement of 
`read-directory-name'."
   (let ((counsel--find-file-predicate #'file-directory-p))
     (ivy-read prompt
               #'read-file-name-internal
               :matcher #'counsel--find-file-matcher
+              :def default
               :history 'file-name-history
               :keymap counsel-find-file-map
               :caller 'counsel-read-directory-name)))
 
 (ivy-configure 'counsel-read-directory-name
-  :display-transformer-fn #'ivy-read-file-transformer)
+  :parent 'read-file-name-internal)
 
 (defun counsel-cd ()
   "Change the directory for the currently running Ivy grep-like command.
 Works for `counsel-git-grep', `counsel-ag', etc."
   (interactive)
-  (let ((input ivy-text)
-        (new-dir (counsel-read-directory-name "cd: ")))
+  (counsel-delete-process)
+  (let* ((input ivy-text)
+         (enable-recursive-minibuffers t)
+         (def-dir (buffer-file-name (ivy-state-buffer ivy-last)))
+         (def-dir (and def-dir (file-name-directory def-dir)))
+         (new-dir (counsel-read-directory-name "cd: " def-dir)))
     (ivy-quit-and-run
       (funcall (ivy-state-caller ivy-last) input new-dir))))
 
+(defun counsel--grep-smart-case-flag ()
+  (if (ivy--case-fold-p ivy-text)
+      "-i"
+    (if (and (stringp counsel-ag-base-command)
+             (string-match-p "\\`pt" counsel-ag-base-command))
+        "-S"
+      "-s")))
+
 (defun counsel-grep-like-occur (cmd-template)
   (unless (eq major-mode 'ivy-occur-grep-mode)
     (ivy-occur-grep-mode)
     (setq default-directory (ivy-state-directory ivy-last)))
-  (setq ivy-text
-        (and (string-match "\"\\(.*\\)\"" (buffer-name))
-             (match-string 1 (buffer-name))))
+  (ivy-set-text
+   (if (string-match "\"\\(.*\\)\"" (buffer-name))
+       (match-string 1 (buffer-name))
+     (ivy-state-text ivy-occur-last)))
   (let* ((cmd
           (if (functionp cmd-template)
               (funcall cmd-template ivy-text)
             (let* ((command-args (counsel--split-command-args ivy-text))
                    (regex (counsel--grep-regex (cdr command-args)))
-                   (switches (concat (car command-args)
-                                     (counsel--ag-extra-switches regex))))
-              (format cmd-template
-                      (concat
-                       switches
-                       (shell-quote-argument regex))))))
-         (cands (counsel--split-string (shell-command-to-string cmd))))
+                   (extra-switches (counsel--ag-extra-switches regex))
+                   (all-args (append
+                              (when (car command-args)
+                                (split-string (car command-args)))
+                              (when extra-switches
+                                (split-string extra-switches))
+                              (list
+                               (counsel--grep-smart-case-flag)
+                               regex))))
+              (if (stringp cmd-template)
+                  (counsel--format
+                   cmd-template
+                   (mapconcat #'shell-quote-argument all-args " "))
+                (cl-mapcan
+                 (lambda (x) (if (string= x "%s") (copy-sequence all-args) 
(list x)))
+                 cmd-template)))))
+         (cands (counsel--split-string
+                 (if (stringp cmd)
+                     (shell-command-to-string cmd)
+                   (counsel--call cmd)))))
     (swiper--occur-insert-lines (mapcar #'counsel--normalize-grep-match 
cands))))
 
 (defun counsel-ag-occur (&optional _cands)
@@ -2914,7 +3161,7 @@ This uses `counsel-ag' with `counsel-pt-base-command' 
instead of
   (interactive)
   (let ((counsel-ag-base-command counsel-pt-base-command)
         (counsel--grep-tool-look-around nil))
-    (counsel-ag initial-input :caller 'counsel-pt)))
+    (counsel-ag initial-input nil nil nil :caller 'counsel-pt)))
 
 (ivy-configure 'counsel-pt
   :unwind-fn #'counsel--grep-unwind
@@ -2939,35 +3186,36 @@ This uses `counsel-ag' with `counsel-ack-base-command' 
replacing
   (interactive)
   (let ((counsel-ag-base-command counsel-ack-base-command)
         (counsel--grep-tool-look-around t))
-    (counsel-ag initial-input :caller 'counsel-ack)))
+    (counsel-ag
+     initial-input nil nil nil
+     :caller 'counsel-ack)))
 
 
 ;;** `counsel-rg'
 (defcustom counsel-rg-base-command
-  (if (memq system-type '(ms-dos windows-nt))
-      "rg --with-filename --no-heading --line-number --path-separator / 
--color never %s ."
-    "rg --with-filename --no-heading --line-number --color never %s")
+  (split-string
+   (if (memq system-type '(ms-dos windows-nt))
+       "rg -M 240 --with-filename --no-heading --line-number --color never %s 
--path-separator / ."
+     "rg -M 240 --with-filename --no-heading --line-number --color never %s"))
   "Alternative to `counsel-ag-base-command' using ripgrep.
 
 Note: don't use single quotes for the regex."
-  :type 'string)
+  :type '(choice
+          (repeat :tag "List to be used in `process-file'." string)
+          (string :tag "String to be used in `shell-command-to-string'.")))
 
 (defun counsel--rg-targets ()
   "Return a list of files to operate on, based on `dired-mode' marks."
-  (if (eq major-mode 'dired-mode)
-      (let ((files
-             (dired-get-marked-files 'no-dir nil nil t)))
-        (if (and (null (cdr files))
-                 (not (when (string-match-p "\\*ivy-occur" (buffer-name))
-                        (dired-toggle-marks)
-                        (setq files (dired-get-marked-files 'no-dir))
-                        (dired-toggle-marks)
-                        t)))
-            ""
-          (concat
-           " "
-           (mapconcat #'shell-quote-argument (delq t files) " "))))
-    ""))
+  (when (eq major-mode 'dired-mode)
+    (let ((files
+           (dired-get-marked-files 'no-dir nil nil t)))
+      (when (or (cdr files)
+                (when (string-match-p "\\*ivy-occur" (buffer-name))
+                  (dired-toggle-marks)
+                  (setq files (dired-get-marked-files 'no-dir))
+                  (dired-toggle-marks)
+                  t))
+        (delq t files)))))
 
 ;;;###autoload
 (defun counsel-rg (&optional initial-input initial-directory extra-rg-args 
rg-prompt)
@@ -2978,14 +3226,18 @@ EXTRA-RG-ARGS string, if non-nil, is appended to 
`counsel-rg-base-command'.
 RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.
 
 Example input with inclusion and exclusion file patterns:
-    -g*.py -g!*test* -- ..."
+    require i -- -g*.el"
   (interactive)
   (let ((counsel-ag-base-command
-         (concat counsel-rg-base-command (counsel--rg-targets)))
+         (if (listp counsel-rg-base-command)
+             (append counsel-rg-base-command (counsel--rg-targets))
+           (concat counsel-rg-base-command " "
+                   (mapconcat #'shell-quote-argument (counsel--rg-targets) " 
"))))
         (counsel--grep-tool-look-around
-         (let ((rg (car (split-string counsel-rg-base-command)))
+         (let ((rg (car (if (listp counsel-rg-base-command) 
counsel-rg-base-command
+                          (split-string counsel-rg-base-command))))
                (switch "--pcre2"))
-           (and (eq 0 (call-process rg nil nil nil switch "--version"))
+           (and (eq 0 (call-process rg nil nil nil switch "--pcre2-version"))
                 switch))))
     (counsel-ag initial-input initial-directory extra-rg-args rg-prompt
                 :caller 'counsel-rg)))
@@ -3018,11 +3270,18 @@ substituted by the search regexp and file, 
respectively.  Neither
   "Grep in the current directory for STRING."
   (or
    (ivy-more-chars)
-   (let ((regex (counsel--elisp-to-pcre
-                 (setq ivy--old-re
-                       (ivy--regex string)))))
+   (let* ((regex (counsel--grep-regex string))
+          (cmd (counsel--format
+                counsel-grep-command
+                (funcall (if (listp counsel-grep-command) #'identity
+                           #'shell-quote-argument)
+                         regex))))
      (counsel--async-command
-      (format counsel-grep-command (shell-quote-argument regex)))
+      (if (ivy--case-fold-p regex)
+          (if (listp cmd) (nconc (list (car cmd) "-i") (cdr cmd))
+            (string-match " " cmd)
+            (replace-match " -i " nil nil cmd))
+        cmd))
      nil)))
 
 (defvar counsel--grep-last-pos nil
@@ -3088,10 +3347,11 @@ When non-nil, INITIAL-INPUT is the initial search 
pattern."
     (user-error "Current buffer is not visiting a file"))
   (counsel-require-program counsel-grep-base-command)
   (setq counsel-grep-command
-        (format counsel-grep-base-command
-                "%s" (shell-quote-argument
-                      (file-name-nondirectory
-                       buffer-file-name))))
+        (counsel--format counsel-grep-base-command "%s"
+                         (funcall (if (listp counsel-grep-base-command) 
#'identity
+                                    #'shell-quote-argument)
+                                  (file-name-nondirectory
+                                   buffer-file-name))))
   (let ((default-directory (file-name-directory buffer-file-name))
         (init-point (point))
         res)
@@ -3327,7 +3587,9 @@ otherwise continue prompting for tags."
                              (delete-dups
                               (append (counsel--org-get-tags) add-tags)))
                        (counsel-org--set-tags))))))
-           (counsel-org--set-tags)))
+           (counsel-org--set-tags)
+           (unless (member x counsel-org-tags)
+             (message "Tag %S has been removed." x))))
         ((eq this-command 'ivy-call)
          (with-selected-window (active-minibuffer-window)
            (delete-minibuffer-contents)))))
@@ -3416,6 +3678,14 @@ otherwise continue prompting for tags."
   "If non-nil, display priorities in matched `org-mode' headlines."
   :type 'boolean)
 
+(defcustom counsel-org-headline-display-comment nil
+  "If non-nil, display COMMENT string in matched `org-mode' headlines."
+  :type 'boolean)
+
+(defcustom counsel-org-headline-display-statistics nil
+  "If non-nil, display statistics cookie in matched `org-mode' headlines."
+  :type 'boolean)
+
 (declare-function org-get-heading "org")
 (declare-function org-goto-marker-or-bmk "org")
 (declare-function outline-next-heading "outline")
@@ -3535,11 +3805,13 @@ version.  Argument values are based on the
 `counsel-org-headline-display-*' user options."
   (nbutlast (mapcar #'not (list counsel-org-headline-display-tags
                                 counsel-org-headline-display-todo
-                                counsel-org-headline-display-priority))
+                                counsel-org-headline-display-priority
+                                counsel-org-headline-display-comment))
+            ;; Added in Emacs 26.1.
             (if (if (fboundp 'func-arity)
                     (< (cdr (func-arity #'org-get-heading)) 3)
                   (version< org-version "9.1.1"))
-                1 0)))
+                2 0)))
 
 ;;** `counsel-org-file'
 (declare-function org-attach-dir "org-attach")
@@ -3556,7 +3828,7 @@ include attachments of other Org buffers."
   (let (dirs)
     (save-excursion
       (goto-char (point-min))
-      (while (re-search-forward "^:\\(ATTACH_DIR\\|ID\\):[\t ]+\\(.*\\)$" nil 
t)
+      (while (re-search-forward ":\\(?:ATTACH_DIR\\|ID\\):[\t ]+.*$" nil t)
         (let ((dir (org-attach-dir)))
           (when dir
             (push dir dirs)))))
@@ -3622,18 +3894,28 @@ include attachments of other Org buffers."
   (interactive)
   (require 'org-capture)
   (ivy-read "Capture template: "
-            (delq nil
-                  (mapcar
-                   (lambda (x)
-                     (when (> (length x) 2)
-                       (format "%-5s %s" (nth 0 x) (nth 1 x))))
-                   ;; We build the list of capture templates as in
-                   ;; `org-capture-select-template':
-                   (or (org-contextualize-keys
-                        (org-capture-upgrade-templates org-capture-templates)
-                        org-capture-templates-contexts)
-                       '(("t" "Task" entry (file+headline "" "Tasks")
-                          "* TODO %?\n  %u\n  %a")))))
+            ;; We build the list of capture templates as in 
`org-capture-select-template':
+            (let (prefixes)
+              (cl-mapcan
+               (lambda (x)
+                 (let ((x-keys (car x)))
+                   ;; Remove prefixed keys until we get one that matches the 
current item.
+                   (while (and prefixes
+                               (let ((p1-keys (caar prefixes)))
+                                 (or
+                                  (<= (length x-keys) (length p1-keys))
+                                  (not (string-prefix-p p1-keys x-keys)))))
+                     (pop prefixes))
+                   (if (> (length x) 2)
+                       (let ((desc (mapconcat #'cadr (reverse (cons x 
prefixes)) " | ")))
+                         (list (format "%-5s %s" x-keys desc)))
+                     (push x prefixes)
+                     nil)))
+               (or (org-contextualize-keys
+                    (org-capture-upgrade-templates org-capture-templates)
+                    org-capture-templates-contexts)
+                   '(("t" "Task" entry (file+headline "" "Tasks")
+                      "* TODO %?\n  %u\n  %a")))))
             :require-match t
             :action (lambda (x)
                       (org-capture nil (car (split-string x))))
@@ -3757,10 +4039,31 @@ This variable has no effect unless
               :history 'counsel-org-agenda-headlines-history
               :caller 'counsel-org-agenda-headlines)))
 
-;;* Misc. Emacs
+;;** `counsel-org-link'
+(declare-function org-insert-link "ol")
+(declare-function org-id-get-create "org-id")
+
+(defun counsel-org-link-action (x)
+  "Insert a link to X."
+  (let ((id (save-excursion
+              (goto-char (cdr x))
+              (org-id-get-create))))
+    (org-insert-link nil (concat "id:" id) (car x))))
+
+;;;###autoload
+(defun counsel-org-link ()
+  "Insert a link to an headline with completion."
+  (interactive)
+  (ivy-read "Link: " (counsel-outline-candidates
+                      '(:outline-title counsel-outline-title-org ))
+            :action #'counsel-org-link-action
+            :history 'counsel-org-link-history
+            :caller 'counsel-org-link))
+
+;; Misc. Emacs
 ;;** `counsel-mark-ring'
 (defface counsel--mark-ring-highlight
-  '((t (:inherit highlight)))
+  '((t :inherit highlight))
   "Face for current `counsel-mark-ring' line."
   :group 'ivy-faces)
 
@@ -3801,15 +4104,6 @@ This variable has no effect unless
 Obeys `widen-automatically', which see."
   (interactive)
   (let* ((counsel--mark-ring-calling-point (point))
-         (width (length (number-to-string (line-number-at-pos (point-max)))))
-         (fmt (format "%%%dd %%s" width))
-         (make-candidate
-          (lambda (mark)
-            (goto-char (marker-position mark))
-            (let ((linum (line-number-at-pos))
-                  (line (buffer-substring
-                         (line-beginning-position) (line-end-position))))
-              (propertize (format fmt linum line) 'point (point)))))
          (marks (copy-sequence mark-ring))
          (marks (delete-dups marks))
          (marks
@@ -3817,33 +4111,125 @@ Obeys `widen-automatically', which see."
           (if (equal (mark-marker) (make-marker))
               marks
             (cons (copy-marker (mark-marker)) marks)))
-         (cands
-          ;; Widen, both to save `line-number-at-pos' the trouble
-          ;; and for `buffer-substring' to work.
-          (save-excursion
-            (save-restriction
-              (widen)
-              (mapcar make-candidate marks)))))
-    (if cands
-        (ivy-read "Mark: " cands
-                  :require-match t
-                  :action (lambda (cand)
-                            (let ((pos (get-text-property 0 'point cand)))
-                              (when pos
-                                (unless (<= (point-min) pos (point-max))
-                                  (if widen-automatically
-                                      (widen)
-                                    (error "\
-Position of selected mark outside accessible part of buffer")))
-                                (goto-char pos))))
-                  :caller 'counsel-mark-ring)
+         (candidates (counsel-mark--get-candidates marks)))
+    (if candidates
+        (counsel-mark--ivy-read "Mark: " candidates 'counsel-mark-ring)
       (message "Mark ring is empty"))))
 
+(defun counsel-mark--get-candidates (marks)
+  "Convert a list of MARKS into mark candidates.
+candidates are simply strings formatted to have the line number of the
+associated mark prepended to them and having an extra text property of
+point to indicarte where the candidate mark is."
+  (when marks
+    (save-excursion
+      (save-restriction
+        ;; Widen, both to save `line-number-at-pos' the trouble
+        ;; and for `buffer-substring' to work.
+        (widen)
+        (let* ((width (length (number-to-string (line-number-at-pos 
(point-max)))))
+               (fmt (format "%%%dd %%s" width)))
+          (mapcar (lambda (mark)
+                    (goto-char (marker-position mark))
+                    (let ((linum (line-number-at-pos))
+                          (line  (buffer-substring
+                                  (line-beginning-position) 
(line-end-position))))
+                      (propertize (format fmt linum line) 'point (point))))
+                  marks))))))
+
+(defun counsel-mark--ivy-read (prompt candidates caller)
+  "call `ivy-read' with sane defaults for traversing marks.
+CANDIDATES should be an alist with the `car' of the list being
+the string displayed by ivy and the `cdr' being the point that
+mark should take you to.
+
+NOTE This has been abstracted out into it's own method so it can
+be used by both `counsel-mark-ring' and `counsel-evil-marks'"
+  (ivy-read prompt candidates
+            :require-match t
+            :update-fn #'counsel--mark-ring-update-fn
+            :action (lambda (cand)
+                      (let ((pos (get-text-property 0 'point cand)))
+                        (when pos
+                          (unless (<= (point-min) pos (point-max))
+                            (if widen-automatically
+                                (widen)
+                              (error "\
+Position of selected mark outside accessible part of buffer")))
+                          (goto-char pos))))
+            :unwind #'counsel--mark-ring-unwind
+            :caller caller))
+
 (ivy-configure 'counsel-mark-ring
   :update-fn #'counsel--mark-ring-update-fn
   :unwind-fn #'counsel--mark-ring-unwind
   :sort-fn #'ivy-string<)
 
+;;** `counsel-evil-marks'
+(defvar counsel-evil-marks-exclude-registers nil
+  "List of evil registers to not display in `counsel-evil-marks' by default.
+Each member of the list should be a character (stored as an integer).")
+
+(defvar evil-markers-alist)
+(declare-function evil-global-marker-p "ext:evil-common")
+
+(defun counsel-mark--get-evil-candidates (all-markers-p)
+  "Convert all evil MARKS in the current buffer to mark candidates.
+Works like `counsel-mark--get-candidates' but also prepends the
+register tied to a mark in the message string."
+  ;; evil doesn't provide a standalone method to access the list of
+  ;; marks in the current buffer, as it does with registers.
+  (let* ((all-markers
+          (append
+           (cl-remove-if (lambda (m)
+                           (or (evil-global-marker-p (car m))
+                               (not (markerp (cdr m)))))
+                         evil-markers-alist)
+           (cl-remove-if (lambda (m)
+                           (or (not (evil-global-marker-p (car m)))
+                               (not (markerp (cdr m)))))
+                         (default-value 'evil-markers-alist))))
+
+         (all-markers
+          ;; with prefix, ignore register exclusion list.
+          (if all-markers-p
+              all-markers
+            (cl-remove-if-not
+             (lambda (x) (not (member (car x) 
counsel-evil-marks-exclude-registers)))
+             all-markers)))
+         ;; separate the markers from the evil registers
+         ;; for call to `counsel-mark--get-candidates'
+         (registers (mapcar #'car all-markers))
+         (markers (mapcar #'cdr all-markers))
+         (candidates (counsel-mark--get-candidates markers)))
+    (when candidates
+      (let (register candidate result)
+        (while (and (setq register (pop registers))
+                    (setq candidate (pop candidates)))
+          (let ((point (get-text-property 0 'point candidate))
+                (evil-candidate
+                 (format "[%s]: %s"
+                         (propertize (char-to-string register)
+                                     'face 'counsel-evil-register-face)
+                         candidate)))
+            (push (propertize evil-candidate 'point point) result)))
+        result))))
+
+;;;###autoload
+(defun counsel-evil-marks (&optional arg)
+  "Ivy replacement for `evil-show-marks'.
+By default, this function respects `counsel-evil-marks-exclude-registers'.
+When ARG is non-nil, display all active evil registers."
+  (interactive "P")
+  (if (and (boundp 'evil-markers-alist)
+           (fboundp 'evil-global-marker-p))
+      (let* ((counsel--mark-ring-calling-point (point))
+             (candidates (counsel-mark--get-evil-candidates arg)))
+        (if candidates
+            (counsel-mark--ivy-read "Evil mark: " candidates 
'counsel-evil-marks)
+          (message "No evil marks are active")))
+    (user-error "Required feature `evil' not installed or loaded")))
+
 ;;** `counsel-package'
 (defvar package--initialized)
 (defvar package-alist)
@@ -3901,7 +4287,8 @@ Additional actions:\\<ivy-minibuffer-map>
             :history 'counsel-package-history
             :caller 'counsel-package))
 
-(cl-pushnew '(counsel-package . "^+") ivy-initial-inputs-alist :key #'car)
+(ivy-configure 'counsel-package
+  :initial-input "^+")
 
 (defun counsel-package-action (package)
   "Delete or install PACKAGE."
@@ -4077,13 +4464,18 @@ Signal a `buffer-read-only' error if called from a 
read-only
 buffer position."
   (with-ivy-window
     (barf-if-buffer-read-only)
-    (setq last-command 'yank)
     (setq yank-window-start (window-start))
+    (unless (eq last-command 'yank)
+      ;; Avoid unexpected deletions with `yank-handler' properties.
+      (setq yank-undo-function nil))
     (condition-case nil
-        ;; Avoid unexpected additions to `kill-ring'
-        (let (interprogram-paste-function)
+        (let (;; Deceive `yank-pop'.
+              (last-command 'yank)
+              ;; Avoid unexpected additions to `kill-ring'.
+              interprogram-paste-function)
           (yank-pop (counsel--yank-pop-position s)))
       (error
+       ;; Support strings not present in the kill ring.
        (insert s)))
     (when (funcall (if counsel-yank-pop-after-point #'> #'<)
                    (point) (mark t))
@@ -4130,6 +4522,7 @@ preselected.  Otherwise, the prefix argument defaults to 
0, which
 results in the most recent kill being preselected."
   :type 'boolean)
 
+;; Moved to subr.el in Emacs 27.1.
 (autoload 'xor "array")
 
 ;;;###autoload
@@ -4173,14 +4566,14 @@ Note: Duplicate elements of `kill-ring' are always 
deleted."
 
 ;;** `counsel-register'
 (defvar counsel-register-actions
-  '(("\\`buffer position" . jump-to-register)
+  '(("\\`buffer" . jump-to-register)
     ("\\`text" . insert-register)
     ("\\`rectangle" . insert-register)
-    ("\\`window configuration" . jump-to-register)
-    ("\\`frame configuration" . jump-to-register)
+    ("\\`window" . jump-to-register)
+    ("\\`frame" . jump-to-register)
     ("\\`[-+]?[0-9]+\\(?:\\.[0-9]\\)?\\'" . insert-register)
-    ("\\`the file" . jump-to-register)
-    ("\\`keyboard macro" . jump-to-register)
+    ("\\`\\(?:the \\)?file " . jump-to-register)
+    ("\\`keyboard" . jump-to-register)
     ("\\`file-query" . jump-to-register))
   "Alist of (REGEXP . FUNCTION) pairs for `counsel-register'.
 Selecting a register whose description matches REGEXP specifies
@@ -4226,6 +4619,11 @@ matching the register's value description against a 
regexp in
   :sort-fn #'ivy-string<)
 
 ;;** `counsel-evil-registers'
+(defface counsel-evil-register-face
+  '((t :inherit counsel-outline-1))
+  "Face for highlighting `evil' registers in ivy."
+  :group 'ivy-faces)
+
 ;;;###autoload
 (defun counsel-evil-registers ()
   "Ivy replacement for `evil-show-registers'."
@@ -4233,11 +4631,15 @@ matching the register's value description against a 
regexp in
   (if (fboundp 'evil-register-list)
       (ivy-read "evil-registers: "
                 (cl-loop for (key . val) in (evil-register-list)
-                   collect (format "[%c]: %s" key (if (stringp val) val "")))
+                   collect (format "[%s]: %s"
+                                   (propertize (char-to-string key)
+                                               'face 
'counsel-evil-register-face)
+                                   (if (stringp val) val "")))
                 :require-match t
                 :action #'counsel-evil-registers-action
                 :caller 'counsel-evil-registers)
-    (user-error "Required feature `evil' not installed.")))
+    (user-error "Required feature `evil' not installed")))
+
 (ivy-configure 'counsel-evil-registers
   :height 5
   :format-fn #'counsel--yank-pop-format-function)
@@ -4257,15 +4659,16 @@ S will be of the form \"[register]: content\"."
 (declare-function imenu--make-index-alist "imenu")
 
 (defun counsel--imenu-candidates ()
-  (unless (featurep 'imenu)
-    (require 'imenu nil t))
+  (require 'imenu)
   (let* ((imenu-auto-rescan t)
          (imenu-auto-rescan-maxout (if current-prefix-arg
                                        (buffer-size)
                                      imenu-auto-rescan-maxout))
          (items (imenu--make-index-alist t))
          (items (delete (assoc "*Rescan*" items) items))
-         (items (counsel-imenu-categorize-functions items)))
+         (items (if (eq major-mode 'emacs-lisp-mode)
+                    (counsel-imenu-categorize-functions items)
+                  items)))
     (counsel-imenu-get-candidates-from items)))
 
 (defun counsel-imenu-get-candidates-from (alist &optional prefix)
@@ -4308,6 +4711,9 @@ PREFIX is used to create the key."
   (with-ivy-window
     (imenu (cdr x))))
 
+(defvar counsel-imenu-history nil
+  "History for `counsel-imenu'.")
+
 ;;;###autoload
 (defun counsel-imenu ()
   "Jump to a buffer position indexed by imenu."
@@ -4317,6 +4723,7 @@ PREFIX is used to create the key."
             :require-match t
             :action #'counsel-imenu-action
             :keymap counsel-imenu-map
+            :history 'counsel-imenu-history
             :caller 'counsel-imenu))
 
 ;;** `counsel-list-processes'
@@ -4389,36 +4796,92 @@ An extra action allows to switch to the process buffer."
   (let ((enable-recursive-minibuffers t))
     (ivy-read "History: " (ivy-history-contents minibuffer-history-variable)
               :keymap ivy-reverse-i-search-map
-              :action #'insert
+              :action (lambda (x)
+                        (insert (substring-no-properties (car x))))
               :caller 'counsel-minibuffer-history)))
 
 ;;** `counsel-esh-history'
-(defun counsel--browse-history (ring)
+(defvar comint-input-ring-index)
+(defvar eshell-history-index)
+(defvar slime-repl-input-history-position)
+
+(defvar counsel-esh--index-last nil
+  "Index corresponding to last selection with `counsel-esh-history'.")
+
+(defvar counsel-shell-history--index-last nil
+  "Index corresponding to last selection with `counsel-shell-history'.")
+
+(defun counsel--browse-history-action (pair)
+  (let ((snd (cdr pair)))
+    (cl-case (ivy-state-caller ivy-last)
+      (counsel-esh-history
+       (setq eshell-history-index snd
+             counsel-esh--index-last snd))
+      (counsel-shell-history
+       (setq comint-input-ring-index snd
+             counsel-shell-history--index-last snd))
+      ;; Leave this as a no-op. If someone decides to patch
+      ;; `slime-repl-previous-input' or one of its utility functions,
+      ;; or to add history-replay to Slime, then this section can be
+      ;; updated to add the relevant support for those commands.
+      (counsel-slime-repl-history
+       nil))
+    (ivy-completion-in-region-action (car pair))))
+
+(cl-defun counsel--browse-history (ring &key caller)
   "Use Ivy to navigate through RING."
-  (setq ivy-completion-beg (point))
-  (setq ivy-completion-end (point))
-  (ivy-read "History: " (ivy-history-contents ring)
-            :keymap ivy-reverse-i-search-map
-            :action #'ivy-completion-in-region-action
-            :caller 'counsel-shell-history))
+  (let* ((proc (get-buffer-process (current-buffer)))
+         (end (point))
+         (beg (if proc
+                  (min (process-mark proc) end)
+                end))
+         (input (when (< beg end)
+                  (concat "^" (buffer-substring beg end)))))
+    (setq ivy-completion-beg beg)
+    (setq ivy-completion-end end)
+    (ivy-read "History: " (ivy-history-contents ring)
+              :keymap ivy-reverse-i-search-map
+              :initial-input input
+              :action #'counsel--browse-history-action
+              :caller caller)))
 
 (defvar eshell-history-ring)
+(defvar eshell-matching-input-from-input-string)
 
 ;;;###autoload
 (defun counsel-esh-history ()
   "Browse Eshell history."
   (interactive)
   (require 'em-hist)
-  (counsel--browse-history eshell-history-ring))
+  (counsel--browse-history eshell-history-ring
+                           :caller #'counsel-esh-history))
+
+(defadvice eshell-previous-matching-input (before
+                                           counsel-set-eshell-history-index
+                                           activate)
+  "Reassign `eshell-history-index'."
+  (when (and (memq last-command '(ivy-alt-done ivy-done))
+             (equal (ivy-state-caller ivy-last) 'counsel-esh-history))
+    (setq eshell-history-index counsel-esh--index-last)))
 
 (defvar comint-input-ring)
+(defvar comint-matching-input-from-input-string)
 
 ;;;###autoload
 (defun counsel-shell-history ()
   "Browse shell history."
   (interactive)
   (require 'comint)
-  (counsel--browse-history comint-input-ring))
+  (counsel--browse-history comint-input-ring
+                           :caller #'counsel-shell-history))
+
+(defadvice comint-previous-matching-input (before
+                                           counsel-set-comint-history-index
+                                           activate)
+  "Reassign `comint-input-ring-index'."
+  (when (and (memq last-command '(ivy-alt-done ivy-done))
+             (equal (ivy-state-caller ivy-last) 'counsel-shell-history))
+    (setq comint-input-ring-index counsel-shell-history--index-last)))
 
 (defvar slime-repl-input-history)
 
@@ -4427,7 +4890,13 @@ An extra action allows to switch to the process buffer."
   "Browse Slime REPL history."
   (interactive)
   (require 'slime-repl)
-  (counsel--browse-history slime-repl-input-history))
+  (counsel--browse-history slime-repl-input-history
+                           :caller #'counsel-slime-repl-history))
+
+;; TODO: add advice for slime-repl-input-previous/next to properly
+;; reassign the ring index and match string.  This requires a case for
+;; `counsel-slime-repl-history' within
+;; `counsel--browse-history-action'.
 
 ;;** `counsel-hydra-heads'
 (defvar hydra-curr-body-fn)
@@ -4532,6 +5001,8 @@ TREEP is used to expand internal nodes."
     (counsel-imenu)))
 
 ;;** `counsel-outline'
+(declare-function org-trim "org-macs")
+
 (defcustom counsel-outline-face-style nil
   "Determines how to style outline headings during completion.
 
@@ -4591,7 +5062,12 @@ Intended as a value for the `:outline-title' setting in
   "Return title of current outline heading.
 Like `counsel-outline-title' (which see), but for `org-mode'
 buffers."
-  (apply #'org-get-heading (counsel--org-get-heading-args)))
+  (let ((statistics-re "\\[[0-9]*\\(?:%\\|/[0-9]*\\)]")
+        (heading (apply #'org-get-heading (counsel--org-get-heading-args))))
+    (cond (counsel-org-headline-display-statistics
+           heading)
+          (heading
+           (org-trim (replace-regexp-in-string statistics-re " " heading))))))
 
 (defun counsel-outline-title-markdown ()
   "Return title of current outline heading.
@@ -5046,11 +5522,257 @@ selected color."
 
 You can insert or kill the name of the selected font."
   (interactive)
-  (ivy-read "Font: " (delete-dups (font-family-list))
+  (let ((current-font
+         (symbol-name (font-get (face-attribute 'default :font) :family))))
+    (ivy-read "Font: " (delete-dups (font-family-list))
+              :preselect current-font
+              :require-match t
+              :history 'counsel-fonts-history
+              :action #'insert
+              :caller 'counsel-fonts)))
+
+(ivy-configure 'counsel-fonts
+  :display-transformer-fn #'counsel--font-with-sample)
+
+(defun counsel--font-with-sample (font-name)
+  "Format function for `counsel-fonts'."
+  (format "%-75s%s" font-name
+          (propertize "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                      'face (list :family font-name))))
+
+;;** `counsel-kmacro'
+(defvar counsel-kmacro-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-k") #'counsel-kmacro-kill)
+    map))
+
+(defun counsel-kmacro-kill ()
+  "Kill the line, or delete the keyboard macro."
+  (interactive)
+  (if (not (eolp))
+      (ivy-kill-line)
+    (counsel-kmacro-action-delete-kmacro
+     (assoc
+      (ivy-state-current ivy-last)
+      (ivy-state-collection ivy-last)))
+    (ivy--kill-current-candidate)))
+
+;;;###autoload
+(defun counsel-kmacro ()
+  "Interactively choose and run a keyboard macro.
+
+With prefix argument, run macro that many times.
+
+Macros are run using the current value of `kmacro-counter-value'
+and their respective counter format. Displayed next to each macro is
+the counter's format and initial value.
+
+One can use actions to copy the counter format or initial counter
+value of a macro, using them for a new macro."
+  (interactive)
+  (if (or last-kbd-macro kmacro-ring)
+      (ivy-read
+       (concat "Execute macro (counter at "
+               (number-to-string (or kmacro-initial-counter-value 
kmacro-counter))
+               "): ")
+       (counsel--kmacro-candidates)
+       :keymap counsel-kmacro-map
+       :require-match t
+       :action #'counsel-kmacro-action-run
+       :caller 'counsel-kmacro)
+    (user-error "No keyboard macros defined")))
+
+(ivy-configure 'counsel-kmacro
+  :format-fn #'counsel--kmacro-format-function)
+
+(defcustom counsel-kmacro-separator "\n------------------------\n"
+  "Separator displayed between keyboard macros in `counsel-kmacro'."
+  :type 'string)
+
+(defun counsel--kmacro-format-function (formatted-kmacro)
+  "Transform FORMATTED-KMACRO into a string for `counsel-kmacro'."
+  (ivy--format-function-generic
+   (lambda (str) (ivy--add-face str 'ivy-current-match))
+   (lambda (str) str)
+   formatted-kmacro
+   (propertize counsel-kmacro-separator 'face 'ivy-separator)))
+
+(defun counsel--kmacro-candidates ()
+  "Create the list of keyboard macros used by `counsel-kmacro'.
+This is a combination of `kmacro-ring' and, together in a list, 
`last-kbd-macro',
+`kmacro-counter-format-start', and `kmacro-counter-value-start'."
+  (mapcar
+   (lambda (kmacro)
+     (cons
+      (concat "(" (nth 2 kmacro) "," (number-to-string (nth 1 kmacro)) "): "
+              (condition-case nil
+                  (format-kbd-macro (if (listp kmacro) (car kmacro) kmacro) 1)
+                ;; Recover from error from `edmacro-fix-menu-commands'.
+                (error "Warning: Cannot display macros containing mouse 
clicks")))
+      kmacro))
+   (cons
+    (if (listp last-kbd-macro)
+        last-kbd-macro
+      (list
+       last-kbd-macro
+       kmacro-counter-value-start
+       kmacro-counter-format-start))
+    kmacro-ring)))
+
+(defun counsel-kmacro-action-run (x)
+  "Run keyboard macro."
+  (let* ((actual-kmacro (cdr x))
+         (kmacro-keys (nth 0 actual-kmacro))
+         (kmacro-counter-format-start (nth 2 actual-kmacro)))
+    ;; With prefix argument, call the macro that many times.
+    (kmacro-call-macro (or current-prefix-arg 1) t nil kmacro-keys)))
+
+(defun counsel-kmacro-action-delete-kmacro (x)
+  "Delete a keyboard macro from within `counsel-kmacro'.
+
+Either delete a macro from `kmacro-ring', or set `last-kbd-macro'
+to the popped head of the ring."
+  (let ((actual-macro (cdr x)))
+    (if (eq (nth 0 actual-macro) last-kbd-macro)
+        (setq last-kbd-macro
+              (if (eq kmacro-ring nil)
+                  nil
+                (let ((prev-macro (pop kmacro-ring)))
+                  (if (listp prev-macro)
+                      (nth 0 prev-macro)
+                    prev-macro))))
+      (setq kmacro-ring (delq actual-macro kmacro-ring)))))
+
+(defun counsel-kmacro-action-copy-initial-counter-value (x)
+  "Pass an existing keyboard macro's original value to `kmacro-set-counter'.
+This value will be used by the next executed macro, or as an
+initial value by the next macro defined.
+
+Note that calling an existing macro that itself uses a counter
+effectively resets the initial counter value for the next defined macro
+to 0."
+  ;; NOTE:
+  ;; Calling `kmacro-start-macro' without an argument sets `kmacro-counter'
+  ;; to 0 if `kmacro-initial-counter'is nil, and sets `kmacro-initial-counter'
+  ;; to nil regardless.
+  ;; Using `kmacro-insert-counter' sets `kmacro-initial-counter' to nil.
+  (let* ((actual-kmacro (cdr x))
+         (number (nth 1 actual-kmacro)))
+    (kmacro-set-counter number)))
+
+(defun counsel-kmacro-action-copy-counter-format-for-new-macro (x)
+  "Set `kmacro-default-counter-format' to an existing keyboard macro's counter 
format.
+This will apply to the next macro a user defines."
+  (let* ((actual-kmacro (cdr x))
+         (format (nth 2 actual-kmacro)))
+    (kmacro-set-format format)))
+
+(defun counsel-kmacro-action-cycle-ring-to-macro (x)
+  "Cycle `kmacro-ring' until `last-kbd-macro' is the selected macro.
+This is convenient when using \\[kmacro-end-or-call-macro] to call macros.
+Note that cycling the ring changes the starting value of the current macro
+to changes the current macro counter."
+  (let ((actual-kmacro (cdr x)))
+    (unless (equal last-kbd-macro
+                   (if (listp last-kbd-macro)
+                       last-kbd-macro
+                     (car actual-kmacro)))
+      (while (not (equal actual-kmacro
+                         (car kmacro-ring)))
+        (kmacro-cycle-ring-previous))
+      ;; Once selected macro is at the head of the ring,
+      ;; cycle one last time.
+      (kmacro-cycle-ring-previous))))
+
+(defun counsel-kmacro-action-set-saved-starting-counter (x)
+  "Set the starting counter value of the chosen macro.
+
+By default, sets to current value of the counter. It has no
+effect when selecting the current macro.
+
+Normally, when cycling keyboard macro ring with \\[kmacro-cycle-ring-previous]
+or \\[kmacro-cycle-ring-next], the current value of the macro counter is
+included with the current macro definition. Then, when cycling
+back, that counter value is restored.  This function is meant to
+achieve something similar when cycling macros in the context of
+using `counsel-kmacro', which does not use different counter
+values when running different macros."
+  (let ((actual-kmacro (cdr x))
+        (default-kmacro-counter-string (number-to-string kmacro-counter)))
+    (setq kmacro-ring (mapcar (lambda (this-macro-in-ring)
+                                (if (equal this-macro-in-ring actual-kmacro)
+                                    (list (car this-macro-in-ring)
+                                          (read-from-minibuffer (concat "Set 
initial counter for macro (default: "
+                                                                        
default-kmacro-counter-string
+                                                                        "): ")
+                                                                nil nil t nil
+                                                                
default-kmacro-counter-string)
+                                          (cl-caddr this-macro-in-ring))
+                                  this-macro-in-ring))
+                              kmacro-ring))))
+
+(defun counsel-kmacro-action-execute-after-prompt (x)
+  "Execute an existing keyboard macro, prompting for a starting counter value, 
a
+counter format, and the number of times to execute the macro.
+
+If called with a prefix, will suggest that value for both the
+counter value and iteration amount."
+  (let* ((default-string (if current-prefix-arg
+                             (number-to-string current-prefix-arg)
+                           nil))
+         (actual-kmacro (cdr x))
+         (kmacro-keys (nth 0 actual-kmacro))
+         (kmacro-starting-counter (number-to-string (nth 1 actual-kmacro)))
+         (kmacro-starting-format (nth 2 actual-kmacro))
+         (number-of-iterations
+          (read-from-minibuffer
+           (concat "Enter number of iterations for macro (default: "
+                   (or default-string (number-to-string 2))
+                   "): ")
+           nil nil t nil
+           (or default-string (number-to-string 2))))
+         (kmacro-initial-counter-value
+          (read-from-minibuffer
+           (concat "Enter a starting counter for macro (default: "
+                   (or default-string kmacro-starting-counter)
+                   "): ")
+           nil nil t nil
+           (or default-string kmacro-starting-counter)))
+         (kmacro-counter-format-start
+          (symbol-name (read-from-minibuffer
+                        (concat "Enter format for macro counter (default: "
+                                kmacro-starting-format
+                                "): ")
+                        nil nil t nil
+                        kmacro-starting-format))))
+    (kmacro-call-macro number-of-iterations t nil kmacro-keys)))
+
+(ivy-set-actions
+ 'counsel-kmacro
+ '(("c" counsel-kmacro-action-cycle-ring-to-macro "cycle to")
+   ("d" counsel-kmacro-action-delete-kmacro "delete")
+   ("e" counsel-kmacro-action-execute-after-prompt "execute after prompt")
+   ("f" counsel-kmacro-action-copy-counter-format-for-new-macro "copy counter 
format for new macro")
+   ("s" counsel-kmacro-action-set-saved-starting-counter "set this counter 
value")
+   ("v" counsel-kmacro-action-copy-initial-counter-value "copy initial counter 
value")))
+
+;;** `counsel-geiser-doc-look-up-manual'
+(declare-function geiser-doc-manual-for-symbol "ext:geiser-doc")
+(defvar geiser-completion-symbol-list-func)
+
+(defvar counsel-geiser-doc-look-up-manual-history ()
+  "History for `counsel-geiser-doc-look-up-manual'.")
+
+;;;###autoload
+(defun counsel-geiser-doc-look-up-manual ()
+  "Search Scheme documentation."
+  (interactive)
+  (ivy-read "Symbol: " geiser-completion-symbol-list-func
             :require-match t
-            :history 'counsel-fonts-history
-            :action #'insert
-            :caller 'counsel-fonts))
+            :history 'counsel-geiser-doc-look-up-manual-history
+            :action (lambda (cand)
+                      (geiser-doc-manual-for-symbol (intern cand)))
+            :caller 'counsel-geiser-doc-look-up-manual))
 
 ;;* Misc. OS
 ;;** `counsel-rhythmbox'
@@ -5093,6 +5815,15 @@ You can insert or kill the name of the selected font."
     (dbus-call-method :session service path interface
                       "AddToQueue" (cdr song))))
 
+(defun counsel-rhythmbox-playpause-current-song ()
+  "Play/pause the current song."
+  (interactive)
+  (let ((service "org.gnome.Rhythmbox3")
+        (path "/org/mpris/MediaPlayer2")
+        (interface "org.mpris.MediaPlayer2.Player"))
+    (dbus-call-method :session service path interface
+                      "PlayPause")))
+
 (defun counsel-rhythmbox-toggle-shuffle (_song)
   "Toggle Rhythmbox shuffle setting."
   (let* ((old-order (counsel--command "dconf" "read" 
"/org/gnome/rhythmbox/player/play-order"))
@@ -5164,6 +5895,8 @@ You can insert or kill the name of the selected font."
             :caller 'counsel-rhythmbox))
 
 ;;** `counsel-linux-app'
+
+;; Added in Emacs 26.1.
 (require 'xdg nil t)
 
 (defalias 'counsel--xdg-data-home
@@ -5201,6 +5934,7 @@ as arguments."
           (const :tag "Command : Name - Comment" 
counsel-linux-app-format-function-default)
           (const :tag "Name - Comment (Command)" 
counsel-linux-app-format-function-name-first)
           (const :tag "Name - Comment" 
counsel-linux-app-format-function-name-only)
+          (const :tag "Name - Comment (Pretty)" 
counsel-linux-app-format-function-name-pretty)
           (const :tag "Command" counsel-linux-app-format-function-command-only)
           (function :tag "Custom")))
 
@@ -5275,7 +6009,9 @@ NAME is the name of the application, COMMENT its comment 
and EXEC
 the command to launch it."
   (format "% -45s: %s%s"
           (propertize
-           (ivy--truncate-string exec 45)
+           (ivy--truncate-string
+            (replace-regexp-in-string "env +[^ ]+ +" "" exec)
+            45)
            'face 'counsel-application-name)
           name
           (if comment
@@ -5304,6 +6040,16 @@ EXEC is the command to launch the application."
   "Display only the command EXEC when formatting Linux application names."
   exec)
 
+(defun counsel-linux-app-format-function-name-pretty (name comment _exec)
+  "Format Linux application names with the NAME (and COMMENT) only, but 
pretty."
+  (format "% -45s%s"
+          (propertize
+           (ivy--truncate-string name 45)
+           'face 'counsel-application-name)
+          (if comment
+              (concat ": " comment)
+            "")))
+
 (defun counsel-linux-apps-list-desktop-files ()
   "Return an alist of all Linux applications.
 Each list entry is a pair of (desktop-name . desktop-file).
@@ -5313,6 +6059,7 @@ This function always returns its elements in a stable 
order."
     (dolist (dir counsel-linux-apps-directories)
       (when (file-exists-p dir)
         (let ((dir (file-name-as-directory dir)))
+          ;; Function `directory-files-recursively' added in Emacs 25.1.
           (dolist (file (directory-files-recursively dir ".*\\.desktop$"))
             (let ((id (subst-char-in-string ?/ ?- (file-relative-name file 
dir))))
               (when (and (not (gethash id hash)) (file-readable-p file))
@@ -5433,7 +6180,7 @@ Any desktop entries that fail to parse are recorded in
   "Launch a Linux desktop application, similar to Alt-<F2>.
 When ARG is non-nil, ignore NoDisplay property in *.desktop files."
   (interactive "P")
-  (ivy-read "Run a command: " (counsel-linux-apps-list)
+  (ivy-read "Run application: " (counsel-linux-apps-list)
             :predicate (unless arg (lambda (x) (get-text-property 0 'visible 
(car x))))
             :action #'counsel-linux-app-action-default
             :caller 'counsel-linux-app))
@@ -5481,15 +6228,22 @@ The buffers are those opened during a session of 
`counsel-switch-buffer'."
   (setq counsel--switch-buffer-temporary-buffers nil
         counsel--switch-buffer-previous-buffers nil))
 
+(defcustom counsel-switch-buffer-preview-virtual-buffers t
+  "When non-nil, `counsel-switch-buffer' will preview virtual buffers."
+  :type 'boolean)
+
 (defun counsel--switch-buffer-update-fn ()
   (unless counsel--switch-buffer-previous-buffers
     (setq counsel--switch-buffer-previous-buffers (buffer-list)))
-  (let* ((current (ivy-state-current ivy-last))
-         (virtual (assoc current ivy--virtual-buffers)))
+  (let* ((virtual (assoc (ivy-state-current ivy-last) ivy--virtual-buffers)))
+    (when (member (ivy-state-current ivy-last) ivy-marked-candidates)
+      (setf (ivy-state-current ivy-last)
+            (substring (ivy-state-current ivy-last) (length ivy-mark-prefix))))
     (cond
-      ((get-buffer current)
-       (ivy-call))
-      ((and virtual (file-exists-p (cdr virtual)))
+      ((get-buffer (ivy-state-current ivy-last))
+       (let ((ivy-marked-candidates nil))
+         (ivy-call)))
+      ((and counsel-switch-buffer-preview-virtual-buffers virtual 
(file-exists-p (cdr virtual)))
        (let ((buf (ignore-errors
                     ;; may not open due to `large-file-warning-threshold' etc.
                     (find-file-noselect (cdr virtual)))))
@@ -5572,7 +6326,8 @@ This variable is suitable for addition to
 `savehist-additional-variables'.")
 
 (defvar counsel-compile-root-functions
-  '(counsel--project-current
+  '(counsel--projectile-root
+    counsel--project-current
     counsel--configure-root
     counsel--git-root
     counsel--dir-locals-root)
@@ -5587,6 +6342,12 @@ The root is determined by 
`counsel-compile-root-functions'."
   (or (run-hook-with-args-until-success 'counsel-compile-root-functions)
       (error "Couldn't find project root")))
 
+(defun counsel--projectile-root ()
+  "Return root of current projectile project or nil on failure.
+Use `projectile-project-root' to determine the root."
+  (and (fboundp 'projectile-project-root)
+       (projectile-project-root)))
+
 (defun counsel--project-current ()
   "Return root of current project or nil on failure.
 Use `project-current' to determine the root."
@@ -5611,7 +6372,8 @@ Use the presence of a `dir-locals-file' to determine the 
root."
 (defvar counsel-compile-local-builds
   '(counsel-compile-get-filtered-history
     counsel-compile-get-build-directories
-    counsel-compile-get-make-invocation)
+    counsel-compile-get-make-invocation
+    counsel-compile-get-make-help-invocations)
   "Additional compile invocations to feed into `counsel-compile'.
 
 This can either be a list of compile invocation strings or
@@ -5651,26 +6413,30 @@ list is passed to `compilation-environment'."
 (defvar counsel-compile-phony-pattern "^\\.PHONY:[\t ]+\\(.+\\)$"
   "Regexp for extracting phony targets from Makefiles.")
 
-;; This is loosely based on the Bash Make completion code
+(defvar counsel-compile-help-pattern
+  "\\(?:^\\(\\*\\)?[[:space:]]+\\([^[:space:]]+\\)[[:space:]]+-\\)"
+  "Regexp for extracting help targets from a make help call.")
+
+;; This is loosely based on the Bash Make completion code which
+;; relies on GNUMake having the following return codes:
+;;   0 = no-rebuild, -q & 1 needs rebuild, 2 error
 (defun counsel-compile--probe-make-targets (dir)
   "Return a list of Make targets for DIR.
 
-Return an empty list is Make exits with an error.  This might
-happen because some sort of configuration needs to be done first
-or the source tree is pristine and being used for multiple build
-trees."
-  (let ((default-directory dir)
-        (targets nil))
-    (with-temp-buffer
-      ;; 0 = no-rebuild, -q & 1 needs rebuild, 2 error (for GNUMake at
-      ;; least)
-      (when (< (call-process "make" nil t nil "-nqp") 2)
+Return a single blank target (so we invoke the default target)
+if Make exits with an error.  This might happen because some sort
+of configuration needs to be done first or the source tree is
+pristine and being used for multiple build trees."
+  (with-temp-buffer
+    (let* ((default-directory dir)
+           (res (call-process "make" nil t nil "-nqp"))
+           targets)
+      (if (or (not (numberp res)) (> res 1))
+          (list "")
         (goto-char (point-min))
         (while (re-search-forward counsel-compile-phony-pattern nil t)
-          (setq targets
-                (nconc targets (split-string
-                                (match-string-no-properties 1)))))))
-    (sort targets #'string-lessp)))
+          (push (split-string (match-string-no-properties 1)) targets))
+        (sort (apply #'nconc targets) #'string-lessp)))))
 
 (defun counsel-compile--pretty-propertize (leader text face)
   "Return a pretty string of the form \" LEADER TEXT\".
@@ -5681,12 +6447,13 @@ text with FACE."
                       'font-lock-warning-face)
           (propertize text 'face face)))
 
-(defun counsel--compile-get-make-targets (srcdir &optional blddir)
-  "Return a list of Make targets for a given SRCDIR/BLDDIR combination.
+(defun counsel--compile-get-make-targets (probe-fn srcdir &optional blddir)
+  "Return propertized make targets returned by PROBE-FN in SRCDIR.
 
-We search the Makefile for a list of phony targets which are
-generally the top level targets a Make system provides.
-The resulting strings are tagged with properties that
+The optional BLDDIR allows for handling build directories.  We
+search the Makefile for a list of phony targets which are
+generally the top level targets a Make system provides.  The
+resulting strings are tagged with properties that
 `counsel-compile-history' can use for filtering results."
   (let ((fmt (format (propertize "make %s %%s" 'cmd t)
                      counsel-compile-make-args))
@@ -5703,7 +6470,7 @@ The resulting strings are tagged with properties that
               (setq target (concat (format fmt target) suffix build-env))
               (add-text-properties 0 (length target) props target)
               target)
-            (counsel-compile--probe-make-targets (or blddir srcdir)))))
+            (funcall probe-fn (or blddir srcdir)))))
 
 (defun counsel-compile-get-make-invocation (&optional blddir)
   "Have a look in the root directory for any build control files.
@@ -5713,7 +6480,41 @@ sub-directories that builds may be invoked in."
   (let ((srcdir (counsel--compile-root)))
     (when (directory-files (or blddir srcdir) nil
                            counsel-compile-make-pattern t)
-      (counsel--compile-get-make-targets srcdir blddir))))
+      (counsel--compile-get-make-targets
+       #'counsel-compile--probe-make-targets srcdir blddir))))
+
+(defun counsel-compile--probe-make-help (dir)
+  "Return a list of Make targets based on help for DIR.
+
+It is quite common for a 'make help' invocation to return a human
+readable list of targets.  Often common targets are marked with a
+leading asterisk.  The exact search pattern is controlled by
+`counsel-compile-help-pattern'."
+  (let ((default-directory dir)
+        primary-targets targets)
+    ;; Only proceed if the help target exists.
+    (when (eql 1 (apply #'call-process "make" nil nil nil "-q" "help"
+                        counsel-compile-env))
+      (with-temp-buffer
+        (when (eql 0 (apply #'call-process "make" nil t nil "help"
+                            counsel-compile-env))
+          (goto-char (point-min))
+          (while (re-search-forward counsel-compile-help-pattern nil t)
+            (push (match-string 2)
+                  (if (match-beginning 1) primary-targets targets)))
+          (nconc (sort primary-targets #'string-lessp)
+                 (sort targets #'string-lessp)))))))
+
+(defun counsel-compile-get-make-help-invocations (&optional blddir)
+  "Query the root directory for makefiles with help output.
+
+The optional BLDDIR is useful for other helpers that have found
+sub-directories that builds may be invoked in."
+  (let ((srcdir (counsel--compile-root)))
+    (when (directory-files (or blddir srcdir) nil
+                           counsel-compile-make-pattern t)
+      (counsel--compile-get-make-targets
+       #'counsel-compile--probe-make-help srcdir blddir))))
 
 (defun counsel--find-build-subdir (srcdir)
   "Return builds subdirectory of SRCDIR, if one exists."
@@ -5827,9 +6628,36 @@ specified by the `blddir' property."
              (compile cmd)
           (remove-hook 'compilation-start-hook 
#'counsel-compile--update-history))))))
 
+(defun counsel-compile-edit-command ()
+  "Insert current compile command into the minibuffer for editing.
+
+This mirrors the behavior of `ivy-insert-current' but with specific
+handling for the `counsel-compile' metadata."
+  (interactive)
+  (delete-minibuffer-contents)
+  (let* ((cmd (ivy-state-current ivy-last))
+         (blddir (get-text-property 0 'blddir cmd)))
+    (when blddir
+      (setq counsel-compile--current-build-dir blddir))
+    (insert (substring-no-properties
+             cmd 0 (and (get-text-property 0 'cmd cmd)
+                        (next-single-property-change 0 'cmd cmd))))))
+
+;; Currently the only thing we do is override ivy's default insert
+;; operation which doesn't include the metadata we want.
+(defvar counsel-compile-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap ivy-insert-current] #'counsel-compile-edit-command)
+    map)
+  "Additional ivy keybindings during command selection.")
+
 ;;;###autoload
 (defun counsel-compile (&optional dir)
-  "Call `compile' completing with smart suggestions, optionally for DIR."
+  "Call `compile' completing with smart suggestions, optionally for DIR.
+
+Additional actions:
+
+\\{counsel-compile-map}"
   (interactive)
   (setq counsel-compile--current-build-dir (or dir
                                                (counsel--compile-root)
@@ -5837,8 +6665,17 @@ specified by the `blddir' property."
   (ivy-read "Compile command: "
             (delete-dups (counsel--get-compile-candidates dir))
             :action #'counsel-compile--action
+            :keymap counsel-compile-map
             :caller 'counsel-compile))
 
+(ivy-add-actions
+ 'counsel-compile
+ '(("d" counsel-compile-forget-command "delete")))
+
+(defun counsel-compile-forget-command (cmd)
+  "Delete CMD from `counsel-compile-history'."
+  (setq counsel-compile-history
+        (delete cmd counsel-compile-history)))
 
 (defun counsel-compile-env--format-hint (cands)
   "Return a formatter for compile-env CANDS."
@@ -5893,7 +6730,7 @@ and minor mode symbol."
         (mapcar
          (lambda (mode)
            (when (and (boundp mode) (commandp mode))
-             (let ((lighter (alist-get mode minor-mode-alist)))
+             (let ((lighter (cdr (assq mode minor-mode-alist))))
                (cons (concat
                       (if (symbol-value mode) "-" "+")
                       (symbol-name mode)
@@ -5951,19 +6788,42 @@ Additional actions:\\<ivy-minibuffer-map>
             :action #'counsel-M-x-action
             :caller 'counsel-major))
 
-;;* `counsel-google'
+;;** `counsel-search'
 (declare-function request "ext:request")
-(defun counsel-google-function (input)
-  "Create a request to Google with INPUT.
+
+(defcustom counsel-search-engine 'ddg
+  "The search engine choice in `counsel-search-engines-alist'."
+  :type '(choice
+          (const ddg)
+          (const google)))
+
+(defcustom counsel-search-engines-alist
+  '((google
+     "http://suggestqueries.google.com/complete/search";
+     "https://www.google.com/search?q=";
+     counsel--search-request-data-google)
+    (ddg
+     "https://duckduckgo.com/ac/";
+     "https://duckduckgo.com/html/?q=";
+     counsel--search-request-data-ddg))
+  "Search engine parameters for `counsel-search'."
+  :type '(list))
+
+(defun counsel--search-request-data-google (data)
+  (mapcar #'identity (aref data 1)))
+
+(defun counsel--search-request-data-ddg (data)
+  (mapcar #'cdar data))
+
+(defun counsel-search-function (input)
+  "Create a request to a search engine with INPUT.
 Return 0 tells `ivy--exhibit' not to update the minibuffer.
 We update it in the callback with `ivy-update-candidates'."
   (or
    (ivy-more-chars)
-   (progn
-     (require 'request)
-     (require 'json)
+   (let ((engine (cdr (assoc counsel-search-engine 
counsel-search-engines-alist))))
      (request
-      "http://suggestqueries.google.com/complete/search";
+      (nth 0 engine)
       :type "GET"
       :params (list
                (cons "client" "firefox")
@@ -5972,17 +6832,119 @@ We update it in the callback with 
`ivy-update-candidates'."
       :success (cl-function
                 (lambda (&key data &allow-other-keys)
                   (ivy-update-candidates
-                   (mapcar #'identity (aref data 1))))))
+                   (funcall (nth 2 engine) data)))))
      0)))
 
-(defun counsel-google ()
-  "Ivy interface for Google."
+(defun counsel-search-action (x)
+  "Search for X."
+  (browse-url
+   (concat
+    (nth 2 (assoc counsel-search-engine counsel-search-engines-alist))
+    (url-hexify-string x))))
+
+(defun counsel-search ()
+  "Ivy interface for dynamically querying a search engine."
   (interactive)
-  (ivy-read "search: " #'counsel-google-function
-            :action (lambda (x)
-                      (browse-url (concat "https://www.google.com/search?q="; 
x)))
+  (require 'request)
+  (require 'json)
+  (ivy-read "search: " #'counsel-search-function
+            :action #'counsel-search-action
             :dynamic-collection t
-            :caller 'counsel-google))
+            :caller 'counsel-search))
+
+(define-obsolete-function-alias 'counsel-google
+    'counsel-search "<2019-10-17 Thu>")
+
+;;** `counsel-compilation-errors'
+(defun counsel--compilation-errors-buffer (buf)
+  (with-current-buffer buf
+    (let ((res nil)
+          (pt (point-min)))
+      (save-excursion
+        (while (setq pt (compilation-next-single-property-change
+                         pt 'compilation-message))
+          (let ((loc (get-text-property pt 'compilation-message)))
+            (when (and loc (setq loc (compilation--message->loc loc)))
+              (goto-char pt)
+              (push
+               (propertize
+                (buffer-substring-no-properties pt (line-end-position))
+                'pt pt
+                'buffer buf)
+               res)))))
+      (nreverse res))))
+
+(defun counsel-compilation-errors-cands ()
+  (cl-loop
+     for buf in (buffer-list)
+     when (compilation-buffer-p buf)
+     nconc (counsel--compilation-errors-buffer buf)))
+
+(defun counsel-compilation-errors-action (x)
+  (pop-to-buffer (get-text-property 0 'buffer x))
+  (goto-char (get-text-property 0 'pt x))
+  (compile-goto-error))
+
+;;;###autoload
+(defun counsel-compilation-errors ()
+  "Compilation errors."
+  (interactive)
+  (ivy-read "compilation errors: " (counsel-compilation-errors-cands)
+            :require-match t
+            :action #'counsel-compilation-errors-action
+            :history 'counsel-compilation-errors-history))
+
+;;** `counsel-flycheck'
+(defvar flycheck-current-errors)
+(declare-function flycheck-error-filename "ext:flycheck")
+(declare-function flycheck-error-line "ext:flycheck")
+(declare-function flycheck-error-message "ext:flycheck")
+(declare-function flycheck-jump-to-error "ext:flycheck")
+
+(defun counsel-flycheck-errors-cands ()
+  (mapcar
+   (lambda (err)
+     (propertize
+      (format "%s:%d:%s"
+              (file-name-base (flycheck-error-filename err))
+              (flycheck-error-line err)
+              (flycheck-error-message err)) 'error err))
+   flycheck-current-errors))
+
+(defun counsel-flycheck-occur (cands)
+  "Generate a custom occur buffer for `counsel-flycheck'."
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode)
+    (setq default-directory (ivy-state-directory ivy-last)))
+  (swiper--occur-insert-lines
+   (mapcar
+    (lambda (cand)
+      (let ((err (get-text-property 0 'error cand)))
+        (propertize
+         (format
+          "%s:%d:%s"
+          (flycheck-error-filename err)
+          (flycheck-error-line err)
+          cand)
+         'error err)))
+    cands)))
+
+(defun counsel-flycheck-errors-action (err)
+  (flycheck-jump-to-error (get-text-property 0 'error err)))
+
+(ivy-configure 'counsel-flycheck
+  :occur #'counsel-flycheck-occur)
+
+;;;###autoload
+(defun counsel-flycheck ()
+  "Flycheck errors."
+  (interactive)
+  (require 'flycheck)
+  (ivy-read "flycheck errors: " (counsel-flycheck-errors-cands)
+            :require-match t
+            :action #'counsel-flycheck-errors-action
+            :history 'counsel-flycheck-errors-history))
+
 
 ;;* `counsel-mode'
 (defvar counsel-mode-map
@@ -5992,6 +6954,7 @@ We update it in the callback with 
`ivy-update-candidates'."
                 (describe-bindings . counsel-descbinds)
                 (describe-function . counsel-describe-function)
                 (describe-variable . counsel-describe-variable)
+                (describe-symbol . counsel-describe-symbol)
                 (apropos-command . counsel-apropos)
                 (describe-face . counsel-describe-face)
                 (list-faces-display . counsel-faces)
@@ -6003,6 +6966,7 @@ We update it in the callback with 
`ivy-update-candidates'."
                 (yank-pop . counsel-yank-pop)
                 (info-lookup-symbol . counsel-info-lookup-symbol)
                 (pop-to-mark-command . counsel-mark-ring)
+                (geiser-doc-look-up-manual . counsel-geiser-doc-look-up-manual)
                 (bookmark-jump . counsel-bookmark)))
       (define-key map (vector 'remap (car binding)) (cdr binding)))
     map)
@@ -6027,13 +6991,11 @@ Local bindings (`counsel-mode-map'):
   :lighter " counsel"
   (if counsel-mode
       (progn
-        (when (and (fboundp 'advice-add)
-                   counsel-mode-override-describe-bindings)
+        (when counsel-mode-override-describe-bindings
           (advice-add #'describe-bindings :override #'counsel-descbinds))
         (define-key minibuffer-local-map (kbd "C-r")
           'counsel-minibuffer-history))
-    (when (fboundp 'advice-remove)
-      (advice-remove #'describe-bindings #'counsel-descbinds))))
+    (advice-remove #'describe-bindings #'counsel-descbinds)))
 
 (provide 'counsel)
 



reply via email to

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