From 20ed2505c93e021d5516b212dae4746ccd2413bd Mon Sep 17 00:00:00 2001 From: JSDurand Date: Wed, 22 Feb 2023 02:40:42 +0800 Subject: eshell: Add wildcard expansion support in GraphViz command. * eshell-conf.el (eshell/gv, eshell-gv): Now a star in the filename will trigger the wildcard expansion. This is much more flexible and convenient when dealing with many files. --- eshell-conf.el | 121 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 27 deletions(-) (limited to 'eshell-conf.el') diff --git a/eshell-conf.el b/eshell-conf.el index 6e1b545..1d0871f 100644 --- a/eshell-conf.el +++ b/eshell-conf.el @@ -565,6 +565,8 @@ For example, \"...\" expands into \"../..\"." ;; It is convenient to be able to compile multiple GraphViz files or ;; delete multiple image files simultaneously. +(require 'vc) + (defun eshell/gv (&rest args) "Compile GraphViz files into images, or delete images, depending \ on `args'." @@ -575,7 +577,8 @@ on `args'." (?r "remove" nil removep "Whether to remove images or not") (?R "remove-all" nil remove-allp "Whether to remove images and sources or not") (?d "root" t dir "Set the directory that contains the output directory") - :usage "[-f format] [-r|-R] [graphviz file names...] + (?v "vertical" nil verticalp "Set the drawing direction to be from top to bottom") + :usage "[-f format] [-r|-R] [-v] [-d directory] [graphviz file names...] This little command can perform two tasks: - Compile multiple GraphViz files. @@ -586,41 +589,105 @@ The file names should not include any extension." :parse-leading-options-only :show-usage) (let ((removep (cond (remove-allp 'all) (removep)))) - (eshell-gv image-format removep dir args)))) - -(require 'vc) + (eshell-gv image-format removep dir verticalp args)))) -(defun eshell-gv (image-format removep dir &rest args) +(defun eshell-gv (image-format removep dir verticalp &rest args) "Internal function for `eshell/gv'." - (let ((args (car args)) - (image-format (cond (image-format) ("png"))) - (root-dir - (expand-file-name "output" (cond (dir) ((vc-root-dir)))))) + (let* ((args (car args)) + (args (cond ((listp (car args)) (car args)) (args))) + (image-format (cond (image-format) ("png"))) + (root-dir + (expand-file-name "output" (cond (dir) ((vc-root-dir)))))) (cond (removep (mapc (lambda (arg) - (let* ((file-name (expand-file-name - (format "%s.%s" arg image-format))) - (source-file-name (format "%s.gv" arg)) - (source-file-name - (expand-file-name source-file-name root-dir))) - (delete-file file-name) - (cond - ((eq removep 'all) (delete-file source-file-name))))) + (cond + ((memq ?* (mapcar #'identity arg)) + (let* ((splitted (split-string arg "*")) + (matching-re (format "%s.*%s\\.%s" + (car splitted) + (apply #'concat (cdr splitted)) + image-format)) + (source-matching-re + (format "%s.*%s\\.gv" + (car splitted) + (apply #'concat (cdr splitted)))) + (files + (directory-files + default-directory t matching-re t)) + (source-files + (directory-files + root-dir t source-matching-re t))) + (mapc #'delete-file files) + (cond + ((eq removep 'all) (mapc #'delete-file source-files))))) + (t + (let* ((arg (file-name-base arg)) + (file-name + (expand-file-name + (format "%s.%s" arg image-format))) + (source-file-name (format "%s.gv" arg)) + (source-file-name + (expand-file-name source-file-name root-dir))) + (delete-file file-name) + (cond + ((eq removep 'all) (delete-file source-file-name))))))) args)) ((mapc (lambda (arg) - (let* ((out-file-name (format "%s.%s" arg image-format)) - (source-file-name (format "%s.gv" arg)) - (source-file-name - (expand-file-name source-file-name root-dir))) - (eshell-command-result - (format - "dot -T%s \"%s\" -o \"%s\"" - image-format - source-file-name - out-file-name)))) + (cond + ((memq ?* (mapcar #'identity arg)) + (let* ((inhibit-message t) + (splitted (split-string arg "*")) + (matching-re + (format "%s.*%s\\.gv" + (car splitted) + (apply #'concat (cdr splitted)))) + (source-files + (directory-files root-dir t matching-re t))) + (mapc + (lambda (file) + (let ((output-file-name + (expand-file-name + (concat + (file-name-base file) "." image-format)))) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (search-forward "rankdir=" nil t) + (delete-char 2) + (cond (verticalp (insert ?T ?B)) + ((insert ?L ?R))) + (write-region nil nil file)) + (eshell-command-result + (format + "dot -T%s \"%s\" -o \"%s\"" + image-format + file + output-file-name)))) + source-files))) + (t + (let* ((arg (file-name-base arg)) + (out-file-name (format "%s.%s" arg image-format)) + (source-file-name (format "%s.gv" arg)) + (source-file-name + (expand-file-name source-file-name root-dir)) + (inhibit-message t)) + (with-temp-buffer + (insert-file-contents source-file-name) + (goto-char (point-min)) + (search-forward "rankdir=" nil t) + (delete-char 2) + (cond (verticalp (insert ?T ?B)) + ((insert ?L ?R))) + (write-region nil nil source-file-name)) + (eshell-command-result + (format + "dot -T%s \"%s\" -o \"%s\"" + image-format + source-file-name + out-file-name)))))) args)))) nil) -- cgit v1.2.3-18-g5258