feat: rename to quick-find-file, make it completing-read-agnostic

This commit is contained in:
Lucien Cartier-Tilet 2023-11-05 22:18:23 +01:00
parent 7c4af643f9
commit 2909823905
Signed by: phundrak
GPG Key ID: BD7789E705CB8DCA
3 changed files with 100 additions and 97 deletions

4
.dir-locals.el Normal file
View File

@ -0,0 +1,4 @@
;;; Directory Local Variables -*- no-byte-compile: t -*-
;;; For more information see (info "(emacs) Directory Variables")
((emacs-lisp-mode . ((sentence-end-double-space . t))))

View File

@ -1,11 +1,11 @@
#+title: ivy-quick-find-files.el #+title: quick-find-files.el
#+author: Lucien Cartier-Tilet #+author: Lucien Cartier-Tilet
#+email: lucien@phundrak.com #+email: lucien@phundrak.com
* Introduction * Introduction
~ivy-quick-find-files.el~ is a utility package for all of you out there ~quick-find-files.el~ is a utility package for all of you out there that
that often find themselves looking for the right file in the right often find themselves looking for the right file in the right place,
place, but you cant be bothered to have a specific keybinding for but you cant be bothered to have a specific keybinding for that
that particular file for one reason or another. particular file for one reason or another.
Now, you have a utility for finding files by directory with an Now, you have a utility for finding files by directory with an
associated extension! Lets say you often open files with a ~.org~ associated extension! Lets say you often open files with a ~.org~
@ -22,37 +22,38 @@ for my various org files alone! Unmanageable!
* Installation * Installation
** Prerequisites ** Prerequisites
First of all, make sure either ~find~ (which is fairly standard, it First of all, make sure either ~find~ (which is fairly standard, it
should be there by default) or [[https://github.com/sharkdp/fd][fd]] are installed on your system, as should be there by default) or [[https://github.com/sharkdp/fd][~fd~]] are installed on your system, as
this package relies on one or the other depending on your choices this package relies on one or the other depending on your choices
(~find~ by default). (~find~ by default).
** Local installation ** Local installation
The vanilla way of installing this package would be to clone this The vanilla way of installing this package would be to clone this
repository somewhere in your Emacs ~load-path~, or add the following repository somewhere in your Emacs ~load-path~, or add the following
line to your ~.emacs~ or ~init.el~: line to your Emacs configuration:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(add-to-list 'load-path "/path/to/ivy-quick-find-files.el") (add-to-list 'load-path "/path/to/quick-find-files.el")
#+end_src #+end_src
Then add the following lines to your ~.emacs~ or ~init.el~: Then add the following lines to your configuration:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(require 'ivy-quick-find-files) (require 'quick-find-files)
#+end_src #+end_src
** Straight + use-package ** Straight + use-package
My personnal choice in terms of installing packages is using straight My personnal choice in terms of installing packages is using straight
with use-package. If you are using it too, add the following code to with use-package. Here is my own configuration of ~quick-find-files.el~:
your ~.emacs~ or ~init.el~:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package ivy-quick-find-files (use-package quick-find-files
:defer t :defer t
:ensure t :ensure t
:straight (ivy-quick-find-files :type git :straight (quick-find-files :type git
:host github :host github
:repo "Phundrak/ivy-quick-find-files.el") :repo "Phundrak/quick-find-files.el")
:config ; Depending on your preferences of course :config ; Depending on your preferences of course
(setq ivy-quick-find-files-program 'fd (setq quick-find-files-program 'fd
ivy-quick-find-files-dirs-and-exts '(("~/org" . "org")))) ; I like ivy
quick-find-files-completing-read #'ivy-completing-read
quick-find-files-dirs-and-exts '(("~/org" . "org"))))
#+end_src #+end_src
** Other methods ** Other methods
@ -63,41 +64,28 @@ do, feel free to submit a PR with new instructions!
* Customizing * Customizing
A couple of variables can be editer by the user in order to configure A couple of variables can be editer by the user in order to configure
~ivy-quick-find-files.el~: ~quick-find-files.el~:
- ~ivy-quick-find-files-program~ :: The program to use in order to find - ~quick-find-files-program~ :: The program to use in order to find your
your files. The two currently supported options are ~'find~ and ~'fd~. files. The two currently supported options are ~'find~ and ~'fd~.
- ~ivy-quick-find-files-fd-executable~ :: Specify the executable to use - ~quick-find-files-fd-executable~ :: Specify the executable to use when
when using the option ~'fd~. using the option ~'fd~.
- ~ivy-quick-find-files-find-executable~ :: Specify the executable to - ~quick-find-files-find-executable~ :: Specify the executable to use
use when using the option ~'find~. when using the option ~'find~.
- ~ivy-quick-find-files-dirs-and-exts~ :: List of pairs between - ~quick-find-files-dirs-and-exts~ :: List of pairs between directories
directories and extensions. For one directory, the program will be and extensions. For one directory, the program will be searching
searching recursively all files with the specified recursively all files with the specified extension. Possible value:
extension. Possible value:
#+begin_src emacs-lisp #+begin_src emacs-lisp
'(("~/org" . "org") '(("~/org" . "org")
("/tmp" . "html") ("/tmp" . "html")
("~/code/C" . "h")) ("~/code/C" . "h"))
#+end_src #+end_src
This specific example will recursively search for all ~.org~ files in This specific example will recursively search for all ~.org~ files in
=~/org=, all ~.html~ files in ~/tmp~, and all ~.h~ files in =~/code/C=. =~/org=, all ~.html~ files in ~/tmp~, and all ~.h~ files in =~/code/C=.
* I dont want to use Ivy, I want to use <insert ivy alternative here>
You can still use this package then! I made the function
~ivy-quick-find-files-list-files~ specifically for this kind of
situation. For instance, if you are an ido user, you could write an
~ido-quick-find-files-list-files~ function like so:
#+begin_src emacs-lisp
(defun my/ido-quick-find-files ()
(interactive)
(find-file (ido-completing-read "Open file: "
(ivy-quick-find-files-list-files))))
#+end_src
* Upcoming changes * Upcoming changes
Plans exist to customize the maximum depth at which ~find~ and ~fd~ are to - Plans exist to customize the maximum depth at which ~find~ and ~fd~ are to
search for files. search for files.
* License * License
~ivy-quick-find-files.el~ is available under the GNU GPL-3.0 ~quick-find-files.el~ is available under the GNU GPL-3.0 license. You
license. You can find the full text in [[file:LICENSE.md][LICENSE.md]]. can find the full text in [[file:LICENSE.md][LICENSE.md]].

View File

@ -1,10 +1,10 @@
;;; ivy-quick-find-files.el --- Quickly find files in directories and by extension -*- lexical-binding: t -*- ;;; quick-find-files.el --- Quickly find files in directories and by extension -*- lexical-binding: t -*-
;; Author: Lucien Cartier-Tilet <lucien@phundrak.com> ;; Author: Lucien Cartier-Tilet <lucien@phundrak.com>
;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com> ;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com>
;; Version: 0.1.0 ;; Version: 0.1.0
;; Package-Requires: ((emacs "24") (ivy "0.13")) ;; Package-Requires: ((emacs "24"))
;; Homepage: https://labs.phundrak.com/phundrak/ivy-quick-find-files.el ;; Homepage: https://labs.phundrak.com/phundrak/quick-find-files.el
;; This file is not part of GNU Emacs ;; This file is not part of GNU Emacs
@ -24,122 +24,133 @@
;;; Commentary: ;;; Commentary:
;;; Code: ;; quick-find-files.el is a utlity to quickly find files in a specific
;; directory, with maybe a specific file extension. It can use both
;; the shell utilities find and fd to quickly find your files and let
;; you select the file youre looking for in a completing read
;; prompt. Refer to the README for more information.
(require 'ivy) ;;; Code:
; Group ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Group ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defgroup ivy-quick-find-files nil (defgroup quick-find-files nil
"Quickly find files by directory and extension." "Quickly find files by directory and extension."
:group 'convenience :group 'convenience
:prefix "ivy-quick-find-files-" :prefix "quick-find-files-"
:link '(url-link :tag "Github" "https://github.com/phundrak/ivy-quick-find-files.el") :link '(url-link :tag "Github" "https://github.com/phundrak/quick-find-files.el")
:link '(url-link :tag "Gitea" "https://labs.phundrak.com/phundrak/ivy-quick-find-files.el")) :link '(url-link :tag "Gitea" "https://labs.phundrak.com/phundrak/quick-find-files.el"))
; Custom variables ;;;;;;;;;;;;;;;;;;;; ; Custom variables ;;;;;;;;;;;;;;;;;;;;
(defcustom ivy-quick-find-files-program (if (executable-find "fd") (defcustom quick-find-files-program (if (executable-find "fd")
'fd 'fd
'find) 'find)
"Program to find files on your system. "Program to find files on your system.
By default, the value is 'fd, but you can change it to 'find too. By default, the value is 'fd, but you can change it to 'find too.
For now, no other program is supported. For now, no other program is supported.
By default, ivy-quick-find-files will try to find fd or find in your By default, `quick-find-files' will try to find fd or find in
path. You can customize the executable to use with your path. You can customize the executable to use with
`ivy-quick-find-files-fd-executable' and `quick-find-files-fd-executable' and
`quind-find-files-find-executable'." `quind-find-files-find-executable'."
:group 'ivy-quick-find-files :group 'quick-find-files
:type 'symbol) :type 'symbol)
(defcustom ivy-quick-find-files-fd-executable (executable-find "fd") (defcustom quick-find-files-fd-executable (executable-find "fd")
"Executable name or path to the executable of fd." "Executable name or path to the executable of fd."
:group 'ivy-quick-find-files :group 'quick-find-files
:type 'string) :type 'string)
(defcustom ivy-quick-find-files-find-executable (executable-find "find") (defcustom quick-find-files-find-executable (executable-find "find")
"Executable name or path to the executable of find." "Executable name or path to the executable of find."
:group 'ivy-quick-find-files :group 'quick-find-files
:type 'string) :type 'string)
(defcustom ivy-quick-find-files-dirs-and-exts '() (defcustom quick-find-files-dirs-and-exts '()
"List of pairs of directories and extensions. "List of pairs of directories and extensions.
Each element should be a pair of a directory path and an Each element should be a pair of a directory path and an
extension, such as extension, such as
'((\"~/Documents/org/\" . \"org\"))" '((\"~/Documents/org/\" . \"org\"))"
:group 'ivy-quick-find-files :group 'quick-find-files
:type 'list) :type 'list)
(defcustom ivy-quick-find-files-fd-additional-options "" (defcustom quick-find-files-fd-additional-options ""
"Additional command-line options for fd." "Additional command-line options for fd."
:group 'ivy-quick-find-files :group 'quick-find-files
:type 'string) :type 'string)
(defcustom ivy-quick-find-files-find-additional-options "" (defcustom quick-find-files-find-additional-options ""
"Additional command-line options for find." "Additional command-line options for find."
:group 'ivy-quick-find-files :group 'quick-find-files
:type 'string) :type 'string)
(defcustom quick-find-files-completing-read #'completing-read
"Completing read function.
The function must accept a prompt as its first argument and the
collection of elements to choose from as its second argument."
:group 'quick-find-files)
; Internal functions ;;;;;;;;;;;;;;;;;; ; Internal functions ;;;;;;;;;;;;;;;;;;
(defun ivy-quick-find-files--split-lines (str &optional omit-null) (defun quick-find-files--split-lines (str &optional omit-null)
"Split a multilines `STR' into a list of strings. "Split a multilines `STR' into a list of strings.
If `OMIT-NULL' is non-null, ignore empty strings." If `OMIT-NULL' is non-null, ignore empty strings."
(declare (side-effect-free t)) (declare (side-effect-free t))
(split-string str "\\(\r\n\\|[\n\r]\\)" omit-null)) (split-string str "\\(\r\n\\|[\n\r]\\)" omit-null))
(defun ivy-quick-find-files--find-files (dir ext) (defun quick-find-files--find-files (dir ext)
"Find files in directory DIR with extension EXT. "Find files in directory DIR with extension EXT.
Use `fd' or `find' depending on `ivy-quick-find-files-program'. Use fd or find depending on `quick-find-files-program'.
Return files as a list of absolute paths." Return files as a list of absolute paths."
(declare (side-effect-free t)) (declare (side-effect-free t))
(ivy-quick-find-files--split-lines (quick-find-files--split-lines
(shell-command-to-string (format (shell-command-to-string (format
(pcase ivy-quick-find-files-program (pcase quick-find-files-program
('fd "fd . %s -e %s -c never %s") ('fd "fd . %s -e %s -c never %s")
('find "find %s -name \"*.%s\" %s") ('find "find %s -name \"*.%s\" %s")
(otherwise (error "Find program %s not implemented" otherwise))) (otherwise (error "Find program %s not implemented" otherwise)))
dir dir
ext ext
(pcase ivy-quick-find-files-program (pcase quick-find-files-program
('fd ivy-quick-find-files-fd-additional-options) ('fd quick-find-files-fd-additional-options)
('find ivy-quick-find-files-find-additional-options) ('find quick-find-files-find-additional-options)
(otherwise (error "Find program %s not implemented" otherwise))))))) (otherwise (error "Find program %s not implemented" otherwise)))))))
; Public functions ;;;;;;;;;;;;;;;;;;;; ; Public functions ;;;;;;;;;;;;;;;;;;;;
;;;###autoload ;;;###autoload
(defun ivy-quick-find-files-list-files () (defun quick-find-files-list-files ()
"List files in directories and with specific extensions. "List files in directories and with specific extensions.
The directories and extensions are specified in the variable The directories and extensions are specified in the variable
`ivy-quick-find-files-dirs-and-exts'. `quick-find-files-dirs-and-exts'.
Return a list of paths to files." Return a list of paths to files."
(declare (side-effect-free t)) (declare (side-effect-free t))
(mapcan (lambda (dir-ext) (mapcan (lambda (dir-ext)
(ivy-quick-find-files--find-files (car dir-ext) (quick-find-files--find-files (car dir-ext)
(cdr dir-ext))) (cdr dir-ext)))
ivy-quick-find-files-dirs-and-exts)) quick-find-files-dirs-and-exts))
;;;###autoload ;;;###autoload
(defun ivy-quick-find-files () (defmacro quick-find-files()
"Quickly find and open files in directories with specific extensions. "Quickly find and open files in directories with specific extensions.
Directories in which to look for files with specific extensions Directories in which to look for files with specific extensions
are specified in `ivy-quick-find-files-dirs-and-exts'." are specified in `quick-find-files-dirs-and-exts'."
(interactive) (interactive)
(find-file (ivy-completing-read "Open file: " `(find-file (,quick-find-files-completing-read "Open File: "
(ivy-quick-find-files-list-files)))) (quick-find-files-list-files))))
; Provides ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Provides ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'ivy-quick-find-files) (provide 'quick-find-files)
;;; ivy-quick-find-files.el ends here ;;; quick-find-files.el ends here