(or emacs irrelevant)

Find file in a Git repo with ivy

I'm really enjoying using ivy for matching stuff.

Here is today's addition:

(defun couns-git ()
  "Find file in the current Git repository."
  (interactive)
  (let* ((default-directory (locate-dominating-file
                             default-directory ".git"))
         (cands (split-string
                 (shell-command-to-string
                  "git ls-files --full-name --")
                 "\n"))
         (file (ivy-read "Find file: " cands)))
    (when file
      (find-file file))))

This one will allow you to find a file in your Git repository. I've bound it like this:

(global-set-key (kbd "C-c f") 'couns-git)

Here's how it looks like for selecting a file in the Emacs repo:

couns-git.png

The speed isn't an issue for 3500 candidates, although I should try to add the number of candidates display pretty soon. It's just that there isn't a good spot in the minibuffer to show that.

I've also updated ivy-next-line and ivy-previous-line to switch to the previous history element in case ivy-text is empty. This is the exact behavior of isearch, so if you bind swiper to C-s and C-r like I do, you'll find that C-s C-s and C-r C-r work as expected. Thanks to @johnmastro for the suggestion.

Here's the current state of the keymap:

(defvar ivy-minibuffer-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-m") 'ivy-done)
    (define-key map (kbd "C-n") 'ivy-next-line)
    (define-key map (kbd "C-p") 'ivy-previous-line)
    (define-key map (kbd "C-s") 'ivy-next-line)
    (define-key map (kbd "C-r") 'ivy-previous-line)
    (define-key map (kbd "SPC") 'self-insert-command)
    (define-key map (kbd "DEL") 'ivy-backward-delete-char)
    (define-key map (kbd "M-<") 'ivy-beginning-of-buffer)
    (define-key map (kbd "M->") 'ivy-end-of-buffer)
    (define-key map (kbd "M-n") 'ivy-next-history-element)
    (define-key map (kbd "M-p") 'ivy-previous-history-element)
    (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
    map)
  "Keymap used in the minibuffer.")

You can also try counsel for completing Elisp and couns-clj for completing Clojure. As you can see, the implementation is very simple: you just get a list of strings, and you're done.

If you want to implement some ivy completion for your favorite mode, I recommend to find the corresponding ac-source and see where it gets its list of strings.