Emacs之fd-dired命令改造二(一百四十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🌻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 来浏览和操作搜索结果:

  1. 打开Emacs。
  2. 执行 M-x fd-dired 命令。
  3. 在提示符后输入搜索参数,比如要搜索的文件名或模式。
  4. 按回车键执行搜索。
  5. dired buffer将显示搜索结果。
  6. dired buffer中,可以使用Emacs的命令来对文件进行操作。
  • 速度fd 的搜索速度非常快,尤其是在大型文件系统中。

  • 简洁性fd 的语法简单,易于记忆和输入。

  • 交互性dired 提供了丰富的交互方式,用户可以在不离开Emacs的情况下完成文件操作。

  • 集成性:将 fddired 结合使用,可以在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"))))
  )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android系统攻城狮

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值