Refactor file-exists-p macro

And refactor too doom--resolve-path-forms
This commit is contained in:
Henrik Lissner 2019-07-23 20:32:40 +02:00
parent d95acb4caa
commit d55f284386
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
2 changed files with 37 additions and 34 deletions

View file

@ -63,27 +63,19 @@ This is used by `file-exists-p!' and `project-file-exists-p!'."
(let ((exists-fn (if (fboundp 'projectile-file-exists-p) (let ((exists-fn (if (fboundp 'projectile-file-exists-p)
#'projectile-file-exists-p #'projectile-file-exists-p
#'file-exists-p))) #'file-exists-p)))
(cond ((stringp spec) (if (and (listp spec)
`(let ((--file-- ,(if (file-name-absolute-p spec) (memq (car spec) '(or and)))
spec (cons (car spec)
`(expand-file-name ,spec ,directory)))) (mapcar (doom-rpartial #'doom--resolve-path-forms directory)
(and (,exists-fn --file--) (cdr spec)))
--file--))) (let ((filevar (make-symbol "file")))
((and (listp spec) `(let* ((file-name-handler-alist nil)
(memq (car spec) '(or and))) (,filevar ,spec))
`(,(car spec) (and ,(if directory
,@(cl-loop for i in (cdr spec) `(let ((default-directory ,directory))
collect (doom--resolve-path-forms i directory)))) (,exists-fn ,filevar))
((or (symbolp spec) (list exists-fn filevar))
(listp spec)) ,filevar))))))
`(let ((--file-- ,(if (and directory
(or (not (stringp directory))
(file-name-absolute-p directory)))
`(expand-file-name ,spec ,directory)
spec)))
(and (,exists-fn --file--)
--file--)))
(spec))))
(defun doom--resolve-hook-forms (hooks) (defun doom--resolve-hook-forms (hooks)
"Converts a list of modes into a list of hook symbols. "Converts a list of modes into a list of hook symbols.
@ -357,21 +349,15 @@ If N and M = 1, there's no benefit to using this macro over `remove-hook'.
(cl-loop for (_var _val hook fn) in (doom--setq-hook-fns hooks vars 'singles) (cl-loop for (_var _val hook fn) in (doom--setq-hook-fns hooks vars 'singles)
collect `(remove-hook ',hook #',fn)))) collect `(remove-hook ',hook #',fn))))
(defmacro file-exists-p! (spec &optional directory) (defmacro file-exists-p! (files &optional directory)
"Returns non-nil if the files in SPEC all exist. "Returns non-nil if the FILES in DIRECTORY all exist.
Returns the last file found to meet the rules set by SPEC. SPEC can be a single DIRECTORY is a path; defaults to `default-directory'.
file or a list of forms/files. It understands nested (and ...) and (or ...), as
well.
DIRECTORY is where to look for the files in SPEC if they aren't absolute. Returns the last file found to meet the rules set by FILES, which can be a
single file or nested compound statement of `and' and `or' statements."
For example: `(let ((p ,(doom--resolve-path-forms files directory)))
(file-exists-p! (or doom-core-dir \"~/.config\" \"some-file\") \"~\")" (and p (expand-file-name p ,directory))))
(if directory
`(let ((--directory-- ,directory))
,(doom--resolve-path-forms spec '--directory--))
(doom--resolve-path-forms spec)))
(defmacro load! (filename &optional path noerror) (defmacro load! (filename &optional path noerror)
"Load a file relative to the current executing file (`load-file-name'). "Load a file relative to the current executing file (`load-file-name').

View file

@ -30,6 +30,23 @@ It is integrated into Helpful, in Doom.
...)) ...))
#+END_SRC #+END_SRC
* file-exists-p!
#+BEGIN_SRC elisp
(file-exists-p! "init.el" doom-emacs-dir)
#+END_SRC
#+RESULTS:
: /home/hlissner/.emacs.d/init.el
#+BEGIN_SRC elisp
(file-exists-p! (and (or "doesnotexist" "init.el")
"LICENSE")
doom-emacs-dir)
#+END_SRC
#+RESULTS:
: /home/hlissner/.emacs.d/LICENSE
* remove-hook! * remove-hook!
#+BEGIN_SRC elisp :eval no #+BEGIN_SRC elisp :eval no
;; With only one hook and one function, this is identical to `add-hook'. In that ;; With only one hook and one function, this is identical to `add-hook'. In that