简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
🌻1.前言
本篇目的:Emacs之fd-dired二命令改造
🌻2.fd-dired命令介绍
-
fd-dired
并不是一个独立的命令,而是将fd
(一个更简单、更快速、更友好的查找文件的命令行工具)与dired
(一个Emacs内置的目录编辑器)结合使用的解决方案。fd
用于在文件系统中搜索文件,而dired
是Emacs中的一个模式,可以用来列出目录内容,并允许用户对文件进行操作,如复制、删除和重命名等。 -
fd
是一个基于Rust编写,用于替代传统find
命令的工具。它提供更简洁的语法和更快的搜索速度。fd
的设计哲学是提供良好的默认设置,以便用户可以快速开始使用,而不需要记住复杂的参数组合。 -
dired
是Emacs的一个功能强大的文件管理器。它允许用户以列表的形式查看文件系统,并提供一系列的命令来对这些文件进行操作。dired
可以启动默认的文件查看器或编辑器来打开文件,也可以执行外壳命令来操作文件,如复制、移动、删除等。 -
在Emacs中使用
fd-dired
需要事先安装fd
工具和配置Emacs以支持dired
。安装fd
后,可以通过以下步骤在Emacs中使用fd
来搜索文件并使用dired
来浏览和操作搜索结果:
- 打开Emacs。
- 执行
M-x fd-dired
命令。 - 在提示符后输入搜索参数,比如要搜索的文件名或模式。
- 按回车键执行搜索。
dired
buffer将显示搜索结果。- 在
dired
buffer中,可以使用Emacs的命令来对文件进行操作。
-
速度:
fd
的搜索速度非常快,尤其是在大型文件系统中。 -
简洁性:
fd
的语法简单,易于记忆和输入。 -
交互性:
dired
提供了丰富的交互方式,用户可以在不离开Emacs的情况下完成文件操作。 -
集成性:将
fd
和dired
结合使用,可以在Emacs内部完成从文件搜索到文件管理的全部工作。 -
fd-dired
结合了fd
的强大搜索能力和dired
的灵活文件操作功能,为那些希望在Emacs中高效管理文件系统的用户提供了理想的工具。通过fd-dired
,用户可以快速定位到所需的文件,并立即进行编辑或其他操作,极大地提高了工作效率。
🌻3.代码实例
🐓3.1 去掉文件名前缀
(defun delete-file-name-prefix (filename)
"去掉文件名前缀."
(when (string-match "\\.\\([^.]*\\)$" filename)
(match-string 0 filename)))
🐓3.2 改造fd-dired v1.0
- fd-dired.el
(defun delete-file-name-prefix (filename)
"去掉文件名前缀."
(when (string-match "\\.\\([^.]*\\)$" filename)
(match-string 0 filename)))
;;add end
;;;###autoload
(defun fd-dired (args dir)
;;add being
(interactive (list
;;v1.0
;;(read-from-minibuffer "查文件: " (concat (thing-at-point 'symbol) (delete-file-name-prefix (file-name-nondirectory (buffer-file-name)))));;第一个参数:文件名:args
;;v1.1
;;(read-from-minibuffer "查文件: " (or (thing-at-point 'symbol) (concat (thing-at-point 'symbol) (delete-file-name-prefix (file-name-nondirectory (buffer-file-name))))));;第一个参数:文件名:args
;;v1.2
;;(read-from-minibuffer "查文件: " (or (thing-at-point 'symbol) (concat (thing-at-point 'symbol) (delete-file-name-prefix (file-name-nondirectory (buffer-file-name))))));;第一个参数:文件名:args
;;v1.3 如果symbol-at-point为nil,则提供一个空字符串.
(let ((symbol-at-point (thing-at-point 'symbol)))
(read-from-minibuffer
"查文件: "
(if symbol-at-point
(concat symbol-at-point (delete-file-name-prefix (file-name-nondirectory (buffer-file-name))))
"")))
;;v2.0
(read-directory-name "Directory: ");;第二个参数目录名:dir
;;v2.1 设置固定路径
"/home/android"
))
;;add end
}
🐓3.3 改造fd-dired v2.0
(defcustom fd-dired-ls-option
(pcase system-type
('darwin
;; NOTE: here `gls' need to `brew install coreutils'
(if (executable-find "gls")
`(,(concat "| xargs -0 " "gls -ld --quoting-style=literal | uniq") . "-ld")
(warn "macOS system default 'ls' command does not support option --quoting-style=literal.\n Please install with: brew install coreutils")))
(_
;;del begin
;;`(,(concat "| xargs -0 " insert-directory-program " -ld --quoting-style=literal | uniq") . "-ld")))
;;del end
;;v1.0 去掉用户名,可以进入文件.(ok)
;;`(,(concat "| xargs -0 " insert-directory-program " -ldn --quoting-style=literal | uniq") . "-ld")))
;;v2.0:只显示文件名,但是不能进入文件.
;;`(,(concat "| xargs -0 " insert-directory-program " -ld --quoting-style=literal | awk '{print $NF}' ") . "-ld")))
;;v3.0 去掉用户名、组名、组id,可以进入文件.(ok)
`(,(concat "| xargs -0 " insert-directory-program " -lno --quoting-style=literal | uniq") . "-ld")))
"A pair of options to produce and parse an `ls -l'-type list from `fd'.
This is a cons of two strings (FD-ARGUMENTS . LS-SWITCHES).
FD-ARGUMENTS is the option passed to `fd' to produce a file
listing in the desired format. LS-SWITCHES is a set of `ls'
switches that tell dired how to parse the output of `fd'.
For more information, see `FIND-LS-OPTION'."
:type '(cons :tag "Fd arguments pair"
(string :tag "Fd arguments")
(string :tag "Ls Switches"))
:group 'fd-dired)
🐓3.4 Final version
- fd-dired.el
- 第一处:
(defcustom fd-dired-pre-fd-args "-0 -c never -i -I -H"
;;modified end
"Fd arguments inserted before user arguments."
:type 'string
:group 'fd-dired)
- 第二处:
(defcustom fd-grep-dired-pre-grep-args "--color alway--regexp"
"Fd grep arguments inserted before user arguments."
:type 'string
:group 'fd-dired)
- 第三处:
(defcustom fd-dired-ls-option
(pcase system-type
('darwin
;; NOTE: here `gls' need to `brew install coreutils'
(if (executable-find "gls")
`(,(concat "| xargs -0 " "gls -ld --quoting-style=literal | uniq") . "-ld")
(warn "macOS system default 'ls' command does not support option --quoting-style=literal.\n Please install with: brew install coreutils")))
(
;;v1.0 去掉用户名,可以进入文件.(ok)
`(,(concat "| xargs -0 " insert-directory-program " -ldn --quoting-style=literal | uniq") . "-ld")))
;;v2.0:只显示文件名,但是不能进入文件.
;;`(,(concat "| xargs -0 " insert-directory-program " -ld --quoting-style=literal | awk '{print $NF}' ") . "-ld")))
;;v3.0 去掉用户名,可以进入文件.(ok)
;;`(,(concat "| xargs -0 " insert-directory-program " -lno --quoting-style=literal | uniq") . "-ld")))
"A pair of options to produce and parse an `ls -l'-type list from `fd'.
This is a cons of two strings (FD-ARGUMENTS . LS-SWITCHES).
FD-ARGUMENTS is the option passed to `fd' to produce a file
listing in the desired format. LS-SWITCHES is a set of `ls'
switches that tell dired how to parse the output of `fd'.
For more information, see `FIND-LS-OPTION'."
:type '(cons :tag "Fd arguments pair"
(string :tag "Fd arguments")
(string :tag "Ls Switches"))
:group 'fd-dired)
- 第四处:
(defun fd-dired (args dir)
;;add end
"Run `fd' and go into Dired mode on a buffer of the output.
The command run (after changing into DIR) is essentially
fd . ARGS -ls
except that the car of the variable `fd-dired-ls-option' specifies what to
use in place of \"-ls\" as the final argument."
;;add being
(interactive (list
;;v1.0
;;(read-from-minibuffer "Ripgrep search for: " (thing-at-point 'symbol));;第一个参数:文件名:args
;;v1.1
;;(read-from-minibuffer "查文件: " (concat (thing-at-point 'symbol) (delete-file-name-prefix (file-name-nondirectory (buffer-file-name)))));;第一个参数:文件名:args
;;v1.2
(read-from-minibuffer "查文件: " (or (thing-at-point 'symbol) (concat (thing-at-point 'symbol) (delete-file-name-prefix (file-name-nondirectory (buffer-file-name))))));;第一个参数:文件名:args
;;v2.0
(read-directory-name "Directory: ");;第二个参数目录名:dir
;;v2.1设置固定路径
;;"/home/android"
))
(let ((dired-buffers dired-buffers)
(fd-dired-buffer-name (if fd-dired-generate-random-buffer
(format " *%s*" (make-temp-name "Fd "))
"*Fd*")))
;; Expand DIR ("" means default-directory), and make sure it has a
;; trailing slash.
(setq dir (file-name-as-directory (expand-file-name (or dir default-directory))))
;; Check that it's really a directory.
(or (file-directory-p dir)
(error "Fd-dired needs a directory: %s" dir))
(get-buffer-create fd-dired-buffer-name)
(if fd-dired-display-in-current-window
(display-buffer (get-buffer fd-dired-buffer-name) nil)
(display-buffer-below-selected (get-buffer fd-dired-buffer-name) nil)
(select-window (get-buffer-window fd-dired-buffer-name)))
(with-current-buffer (get-buffer fd-dired-buffer-name)
;; prepare buffer
(widen)
(kill-all-local-variables)
(setq buffer-read-only nil)
(erase-buffer)
;; Start the process.
(setq default-directory dir
fd-dired-input-fd-args args ; save for next interactive call
args (concat fd-dired-program " " fd-dired-pre-fd-args
;; " . "
(if (string= args "")
""
(concat
" " args " "
" "))
(if (string-match "\\`\\(.*\\) {} \\(\\\\;\\|+\\)\\'"
(car fd-dired-ls-option))
(format "%s %s %s"
(match-string 1 (car fd-dired-ls-option))
(shell-quote-argument "{}")
find-exec-terminator)
(car fd-dired-ls-option))))
(shell-command (concat args " &") (get-buffer-create fd-dired-buffer-name))
;; enable Dired mode
;; The next statement will bomb in classic dired (no optional arg allowed)
(dired-mode dir (cdr fd-dired-ls-option))
;; provide a keybinding to kill the find process
(let ((map (make-sparse-keymap)))
(set-keymap-parent map (current-local-map))
(define-key map "\C-c\C-k" #'kill-find)
(define-key map (kbd "M-S") #'fd-dired-save-search-as-name)
(use-local-map map))
;; disable Dired sort
(make-local-variable 'dired-sort-inhibit)
(setq dired-sort-inhibit t)
(set (make-local-variable 'revert-buffer-function)
`(lambda (ignore-auto noconfirm)
(fd-dired ,dir ,fd-dired-input-fd-args)))
;; Set `subdir-alist' so that Tree Dired will work:
(if (fboundp 'dired-simple-subdir-alist)
;; will work even with nested dired format (dired-nstd.el,v 1.15
;; and later)
(dired-simple-subdir-alist)
;; else we have an ancient tree dired (or classic dired, where
;; this does no harm)
(set (make-local-variable 'dired-subdir-alist)
(list (cons default-directory (point-min-marker)))))
(set (make-local-variable 'dired-subdir-switches) find-ls-subdir-switches)
(setq buffer-read-only nil)
;; Subdir headlerline must come first because the first marker in
;; `subdir-alist' points there.
(insert " " dir ":\n")
;; Make second line a ``find'' line in analogy to the ``total'' or
;; ``wildcard'' line.
(let ((point (point)))
(insert " " args "\n")
(dired-insert-set-properties point (point)))
(setq buffer-read-only t)
(let ((proc (get-buffer-process (get-buffer fd-dired-buffer-name))))
(set-process-filter proc (function find-dired-filter))
(set-process-sentinel proc (function find-dired-sentinel))
;; Initialize the process marker; it is used by the filter.
(move-marker (process-mark proc) (point) (get-buffer fd-dired-buffer-name)))
(setq mode-line-process '(":%s"))))
)