疑问: 我想批量的定义一系列dired排序命令, 有更好的写法吗?

最好不用 eval 命令?

(defmacro define-dired--sort (sort-by)
  "Define sorting command in dired with SORT-BY and REVERSER."
  (let* ((func-name (intern (concat "dired-sort-by-" sort-by)))
         (func-name-r (intern (concat "dired-sort-by-" sort-by "-reverse")))
         (docstring sort-by)
         (docstring-r (concat sort-by " reversely"))
         (switch (concat (pcase sort-by
                           ("name" "")
                           ((or "size" "version" "extension" "width")
                            (concat "--sort=" sort-by))
                           ((or "mtime" "atime" "ctime" "birth")
                            (concat "--sort=time --time=" sort-by)))))
         (switch-r (concat switch " --reverse"))
         (key (substring sort-by 0 1))
         (key-r (upcase key)))
    `(progn
       (defun ,func-name ()
         ,(concat (format "Sorting files in dired by %s." docstring))
         (declare (modes dired-mode))
         (interactive)
         (dired-sort-other ,(concat dired-listing-switches " " switch)))
       (keymap-set dired-mode-map ,(concat "s " key) #',func-name)
       (defun ,func-name-r ()
         ,(concat (format "Sorting files in dired by %s." docstring-r))
         (declare (modes dired-mode))
         (interactive)
         (dired-sort-other ,(concat dired-listing-switches " " switch-r)))
       (keymap-set dired-mode-map ,(concat "s " key-r) #',func-name-r))))

(dolist (sort-by '("name" "size" "version" "extension" "width"
                   "mtime" "atime" "ctime" "birth"))
  (eval `(define-dired--sort ,sort-by)))
(cl-macrolet ((d-d-l (&rest names)
                `(progn ,@(cl-loop for n in names
                                   collect `(define-dired--sort ,n)))))
  (d-d-l "name" "size" "version" "extension" "width"
         "mtime" "atime" "ctime" "birth"))
2 个赞

我只知道有 cl-flet, 原来还有对应的macro形式, 学习了 :grinning: