core-lib: rename helper fns; move doom-resolve-vim-path

+ doom--resolve-paths => doom--resolve-path-forms
+ doom--resolve-hooks => doom--resolve-hook-forms
+ +evil*ex-replace-special-filenames => doom-resolve-vim-path
This commit is contained in:
Henrik Lissner 2017-09-27 01:21:48 +02:00
parent 04a3db3d2b
commit 6cb5efc929
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
5 changed files with 88 additions and 84 deletions

View file

@ -29,7 +29,7 @@
;; Helpers
;;
(defun doom--resolve-paths (paths &optional root)
(defun doom--resolve-path-forms (paths &optional root)
(cond ((stringp paths)
`(file-exists-p
(expand-file-name
@ -39,10 +39,10 @@
(or root `(doom-project-root))))))
((listp paths)
(cl-loop for i in paths
collect (doom--resolve-paths i root)))
collect (doom--resolve-path-forms i root)))
(t paths)))
(defun doom--resolve-hooks (hooks)
(defun doom--resolve-hook-forms (hooks)
(cl-loop with quoted-p = (eq (car-safe hooks) 'quote)
for hook in (doom-enlist (doom-unquote hooks))
if (eq (car-safe hook) 'quote)
@ -61,6 +61,81 @@
"Return EXP wrapped in a list, or as-is if already a list."
(if (listp exp) exp (list exp)))
(defun doom-resolve-vim-path (file-name)
"Take a path and resolve any vim-like filename modifiers in it. This adds
support for these special modifiers:
%:P Resolves to `doom-project-root'.
See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers."
(let* (case-fold-search
(regexp (concat "\\(?:^\\|[^\\\\]\\)"
"\\([#%]\\)"
"\\(\\(?::\\(?:[PphtreS~.]\\|g?s[^:\t\n ]+\\)\\)*\\)"))
(matches
(cl-loop with i = 0
while (and (< i (length file-name))
(string-match regexp file-name i))
do (setq i (1+ (match-beginning 0)))
and collect
(cl-loop for j to (/ (length (match-data)) 2)
collect (match-string j file-name)))))
(dolist (match matches)
(let ((flags (split-string (car (cdr (cdr match))) ":" t))
(path (and buffer-file-name
(pcase (car (cdr match))
("%" (file-relative-name buffer-file-name))
("#" (save-excursion (other-window 1) (file-relative-name buffer-file-name))))))
flag global)
(if (not path)
(setq path "")
(while flags
(setq flag (pop flags))
(when (string-suffix-p "\\" flag)
(setq flag (concat flag (pop flags))))
(when (string-prefix-p "gs" flag)
(setq global t
flag (substring flag 1)))
(setq path
(or (pcase (substring flag 0 1)
("p" (expand-file-name path))
("~" (concat "~/" (file-relative-name path "~")))
("." (file-relative-name path default-directory))
("t" (file-name-nondirectory (directory-file-name path)))
("r" (file-name-sans-extension path))
("e" (file-name-extension path))
("S" (shell-quote-argument path))
("h"
(let ((parent (file-name-directory (expand-file-name path))))
(unless (equal (file-truename path)
(file-truename parent))
(if (file-name-absolute-p path)
(directory-file-name parent)
(file-relative-name parent)))))
("s"
(if (featurep 'evil)
(when-let (args (evil-delimited-arguments (substring flag 1) 2))
(let ((pattern (evil-transform-vim-style-regexp (car args)))
(replace (cadr args)))
(replace-regexp-in-string
(if global pattern (concat "\\(" pattern "\\).*\\'"))
(evil-transform-vim-style-regexp replace) path t t
(unless global 1))))
path))
("P"
(let ((default-directory (file-name-directory (expand-file-name path))))
(abbreviate-file-name (doom-project-root))))
(_ path))
"")))
;; strip trailing slash, if applicable
(when (and (not (string= path "")) (equal (substring path -1) "/"))
(setq path (substring path 0 -1))))
(setq file-name
(replace-regexp-in-string (format "\\(?:^\\|[^\\\\]\\)\\(%s\\)"
(regexp-quote (string-trim-left (car match))))
path file-name t t 1))))
(replace-regexp-in-string regexp "\\1" file-name t)))
;;
;; Library
@ -153,7 +228,7 @@ Body forms can access the hook's arguments through the let-bound variable
(:append (setq append-p t))
(:local (setq local-p t))
(:remove (setq hook-fn 'remove-hook))))
(let ((hooks (doom--resolve-hooks (pop args)))
(let ((hooks (doom--resolve-hook-forms (pop args)))
(funcs
(let ((val (car args)))
(if (memq (car-safe val) '(quote function))
@ -199,11 +274,11 @@ Body forms can access the hook's arguments through the let-bound variable
(not ,mode)
(and buffer-file-name (not (file-remote-p buffer-file-name)))
,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t)
,(if files (doom--resolve-paths files) t)
,(if files (doom--resolve-path-forms files) t)
,(or pred-form t))
(,mode 1)))
,@(if (and modes (listp modes))
(cl-loop for hook in (doom--resolve-hooks modes)
(cl-loop for hook in (doom--resolve-hook-forms modes)
collect `(add-hook ',hook ',hook-name))
`((add-hook 'after-change-major-mode-hook ',hook-name))))))
(match