emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/shell-command+ 1b29abe 03/13: Remove hard dependency on


From: Stefan Monnier
Subject: [elpa] externals/shell-command+ 1b29abe 03/13: Remove hard dependency on eshell
Date: Sun, 23 May 2021 13:41:25 -0400 (EDT)

branch: externals/shell-command+
commit 1b29abef7122ee3b769b7278e685928325ec4e1b
Author: Philip K <philipk@posteo.net>
Commit: Philip K <philipk@posteo.net>

    Remove hard dependency on eshell
---
 shell-command+.el | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 126 insertions(+), 9 deletions(-)

diff --git a/shell-command+.el b/shell-command+.el
index 1bf54b1..4e0bfba 100644
--- a/shell-command+.el
+++ b/shell-command+.el
@@ -61,8 +61,6 @@
 
 (eval-when-compile (require 'rx))
 (eval-when-compile (require 'pcase))
-(require 'eshell)
-(require 'em-unix)
 
 ;;; Code:
 
@@ -71,13 +69,17 @@
   :group 'external
   :prefix "shell-command+-")
 
-(defcustom shell-command+-use-eshell t
+(defcustom shell-command+-use-eshell nil
   "Check for eshell handlers.
 If t, always invoke eshell handlers.  If a list, only invoke
 handlers if the symbol (eg. `man') is contained in the list."
   :type '(choice (boolean :tag "Always active?")
                  (repeat :tag "Selected commands" symbol)))
 
+(make-obsolete-variable 'shell-command+-use-eshell
+                        'shell-command+-substitute-alist
+                        "2.2.0")
+
 (defcustom shell-command+-prompt "Shell command: "
   "Prompt to use when invoking `shell-command+'."
   :type 'string)
@@ -86,6 +88,119 @@ handlers if the symbol (eg. `man') is contained in the 
list."
   "Flip the meaning of < and > at the beginning of a command."
   :type 'boolean)
 
+(defcustom shell-command+-substitute-alist
+  (cond ((eq shell-command+-use-eshell t)
+         (require 'eshell)
+         (require 'em-unix)
+         (let (alist)
+           (mapatoms
+            (lambda (sym)
+              (when (string-match (rx bos "eshell/" (group (+ alnum)) eos)
+                                  (symbol-name sym))
+                (push (cons (match-string 1 (symbol-name sym))
+                            #'eshell-command)
+                      alist))))
+           alist))
+        ((consp shell-command+-use-eshell) ;non-empty list
+         (require 'eshell)
+         (require 'em-unix)
+         (let (alist)
+           (mapatoms
+            (lambda (sym)
+              (when (and (string-match (rx bos "eshell/" (group (+ alnum)) eos)
+                                       (symbol-name sym))
+                         (member (intern (match-string 1 (symbol-name sym)))
+                                 shell-command+-use-eshell))
+                (push (cons (match-string 1 (symbol-name sym))
+                            #'eshell-command)
+                      alist))))
+           alist))
+        (t '(("grep" . shell-command+-cmd-grep)
+             ("fgrep" . shell-command+-cmd-grep)
+             ("agrep" . shell-command+-cmd-grep)
+             ("egrep" . shell-command+-cmd-grep)
+             ("find" . shell-command+-cmd-find)
+             ("locate" . shell-command+-cmd-locate)
+             ("man" . shell-command+-cmd-man)
+             ("info" . shell-command+-cmd-info)
+             ("diff" . shell-command+-cmd-diff)
+             ("make" . compile)
+             ("sudo" . shell-command+-cmd-sudo)
+             ("cd" . shell-command+-cmd-cd))))
+  "Association of command substitutes in Elisp.
+Each entry has the form (COMMAND . FUNC), where FUNC is passed
+the command string"
+  :type 'boolean)
+
+
+
+(defun shell-command+-tokenize (command)
+  "Return list of tokens of COMMAND."
+  (let ((pos 0) tokens)
+    (while (string-match
+            (rx (* space)
+                (or (: ?\" (group-n 1 (* (not ?\"))) ?\")
+                    (: (group-n 1 (+ (not (any ?\" ?\s)))))))
+            command pos)
+      (push (match-string 1 command)
+            tokens)
+      (setq pos (match-end 0)))
+    (nreverse tokens)))
+
+(defun shell-command+-cmd-grep (command)
+  "Convert COMMAND into a `grep' call."
+  (pcase-let ((`(,command . ,args) (shell-command+-tokenize command)))
+    (let ((grep-command command))
+      (grep (mapconcat #'identity args " ")))))
+
+(defun shell-command+-cmd-find (command)
+  "Convert COMMAND into a `find-dired' call."
+  (pcase-let ((`(,_ ,dir . ,args) (shell-command+-tokenize command)))
+    (find-dired dir (mapconcat #'shell-quote-argument args " "))))
+
+(defun shell-command+-cmd-locate (command)
+  "Convert COMMAND into a `locate' call."
+  (pcase-let ((`(,_ . ,search) (shell-command+-tokenize command)))
+    (locate search)))
+
+(defun shell-command+-cmd-man (command)
+  "Convert COMMAND into a `man' call."
+  (pcase-let ((`(,_ . ,args) (shell-command+-tokenize command)))
+    (man (mapconcat #'identity args " "))))
+
+(defun shell-command+-cmd-info (command)
+  "Convert COMMAND into a `info' call."
+  (pcase-let ((`(,_ . ,args) (shell-command+-tokenize command)))
+    (Info-directory)
+    (dolist (menu args)
+      (Info-menu menu))))
+
+(defun shell-command+-cmd-diff (command)
+  "Convert COMMAND into `diff' call."
+  (pcase-let ((`(,_ . ,args) (shell-command+-tokenize command)))
+    (let (files flags)
+      (dolist (arg args)
+        (if (string-match-p (rx bos "-") arg)
+            (push arg flags)
+          (push arg files)))
+      (unless (= (length files) 2)
+        (user-error "Usage: diff [file1] [file2]"))
+      (pop-to-buffer (diff-no-select (car files)
+                                     (cadr files)
+                                     flags)))))
+
+(defun shell-command+-cmd-sudo (command)
+  "Use TRAMP to execute COMMAND."
+  (let ((default-directory (format "/sudo::%s" default-directory)))
+    (shell-command command)))
+
+(defun shell-command+-cmd-cd (command)
+  "Convert COMMAND into a `cd' call."
+  (pcase-let ((`(,_ ,directory) (shell-command+-tokenize command)))
+    (cd directory)))
+
+
+
 (defconst shell-command+--command-regexp
   (rx bos
       ;; ignore all preceding whitespace
@@ -133,7 +248,9 @@ proper upwards directory pointers.  This means that '....' 
becomes
                  (if shell-command+-flip-redirection
                      'input 'output))
                 ((string= (match-string-no-properties 2 command) "|")
-                 'pipe))
+                 'pipe)
+                ((string= (match-string-no-properties 2 command) "!")
+                 'literal))
           (match-string-no-properties 4 command)
           (condition-case nil
               (replace-regexp-in-string
@@ -179,14 +296,14 @@ between BEG and END.  Otherwise the whole buffer is 
processed."
            (shell-command-on-region
             beg end rest nil nil
             shell-command-default-error-buffer t))
-          ((eq mode 'pipe)              ;|
+          ((eq mode 'pipe)
            (shell-command-on-region
             beg end rest t t
             shell-command-default-error-buffer t))
-          ((and (or (eq shell-command+-use-eshell t)
-                    (memq (intern command) shell-command+-use-eshell))
-                (intern-soft (concat "eshell/" command)))
-           (eshell-command rest (and current-prefix-arg t)))
+          ((and (not (eq mode 'literal))
+                (assoc command shell-command+-substitute-alist))
+           (funcall (cdr (assoc command shell-command+-substitute-alist))
+                    rest))
           (t (shell-command rest (and current-prefix-arg t)
                             shell-command-default-error-buffer)))))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]