-
Notifications
You must be signed in to change notification settings - Fork 0
/
fd-dired.el
137 lines (115 loc) · 4.65 KB
/
fd-dired.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
;;; fd-dired.el --- fd dired tool. -*- lexical-binding: t -*-
;; Author: Jian Wang <leuven65@gmail.com>
;; URL: https://github.com/leuven65/fd-dired
;; Version: 0.1.0
;; Keywords: fd, dired
;; This file is not part of GNU Emacs
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; For a full copy of the GNU General Public License
;; see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(defvar fd-dired-args-history nil
"history of fd dired command")
(defun fd-dired-fd-verison ()
(string-trim (shell-command-to-string "fd -V") "fd "))
(defvar fd-dired-command-template
(if (eq system-type 'windows-nt)
;; windows
(if (version< (fd-dired-fd-verison) "8.0")
"fd -x ls -ld \\; --full-path --path-separator '//' %s &"
"fd -l --full-path --path-separator '//' %s &")
;; linux
(if (version< (fd-dired-fd-verison) "8.0")
;; -b: print C-style escapes for nongraphic characters
"fd -x ls -ldb \\; --full-path %s &"
"fd -l --full-path %s &")))
;; just a hack on the original function `find-dired'
;; it is not good idea to rewrite the function, so hacking is good idea here
;; Maybe I am the first person to hack this function for `fd' ^-^.
(defun fd-dired-hacked-find-dired (dir my-cmd-args)
(let ((default-directory dir))
;; define advice on the shell-command to replace the command
(define-advice shell-command (:around (orig-fun find-cmd-args &rest r) my-cmd)
(advice-remove 'shell-command #'shell-command@my-cmd)
(message "shell-command@my-cmd: %s" my-cmd-args)
(cl-assert (string-match-p "^find" find-cmd-args))
;; call origin function with my command
(apply orig-fun my-cmd-args r))
;; call function
;; the above advice will be called
(find-dired dir my-cmd-args)
;; replace the 2nd line by my command
(save-excursion
(goto-char (point-min))
(forward-line 1)
(let ((buffer-read-only nil))
(let ((beg (line-beginning-position))
(end (line-end-position)))
(delete-region beg end)
(insert " " my-cmd-args)
(cl-assert (> end (point)))
;; insert space to keep this line length is same as before
;; as find-dired passed the position to process-filter
(insert (make-string (- end (point)) ?\s))
)
)
)
;; set refresh function
(when (local-variable-p 'revert-buffer-function)
(setq revert-buffer-function
`(lambda (ignore-auto noconfirm)
(fd-dired-hacked-find-dired ,dir ,my-cmd-args)))
)
))
(defun fd-dired-read-fd-args ()
(read-string "Run fd (with args): "
(let ((ss (thing-at-point 'sexp)))
(when ss (format "%s" ss)))
'fd-dired-args-history))
(defun fd-dired-find-dired (dir args)
(interactive (list (read-directory-name "Run fd in directory: " nil "" t)
(fd-dired-read-fd-args)))
(let ((fd-cmd-args (format fd-dired-command-template args)))
(fd-dired-hacked-find-dired dir fd-cmd-args)
))
;;;###autoload
(defun fd-dired (dir args)
"Like find-dired, run command `fd' and put output to dired mode."
(interactive (list (if current-prefix-arg
(read-directory-name "Run fd in directory: " nil "" t)
default-directory)
(fd-dired-read-fd-args)))
(fd-dired-find-dired dir args))
;; (defalias 'fd 'fd-dired)
;; support fd in eshell
(with-eval-after-load 'esh-mode
(defun eshell/fd (&rest args)
"Use fd in eshell"
(let ((sh-cmd (mapconcat #'shell-quote-argument args " ")))
;; (message "fd: %s" sh-cmd)
(eshell-printn (format fd-dired-command-template sh-cmd))
(fd-dired-find-dired default-directory sh-cmd))
)
)
;; add it to action of helm
(with-eval-after-load "helm-files"
(defun fd-dired-helm-find-file-action (file-path)
(fd-dired-find-dired (if (file-directory-p file-path)
file-path
(file-name-directory file-path))
(fd-dired-read-fd-args)))
(add-to-list 'helm-find-files-actions
'("Find dired by fd" . fd-dired-helm-find-file-action)
t)
)
(provide 'fd-dired)
;;; fd-dired.el ends here