[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)))))
- [elpa] externals/shell-command+ updated (7d818ba -> f65aca2), Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 7d39cf5 01/13: Simplify shell-command+--command-regexp, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ c190d6c 02/13: Add shell-command+-flip-redirection option, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 1b29abe 03/13: Remove hard dependency on eshell,
Stefan Monnier <=
- [elpa] externals/shell-command+ ca82436 12/13: Update documentation to reflect eshell deprecation, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ a891756 04/13: Detect errors during tokenization, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ f65aca2 13/13: Bump version to 2.2.0, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ d0004fa 05/13: Add EXPAND parameter to shell-command+-tokenize, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 13980c6 11/13: Fix copyright header in shell-command+-tests.el, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ e76acf5 10/13: Remove test code from main file, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 9aaa4cb 07/13: Accept only one argument in locate, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 86caf3d 09/13: Add tests for shell-command+-tokenize, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 9b1d98e 06/13: Fix shell-command+-cmd-grep invocation, Stefan Monnier, 2021/05/23
- [elpa] externals/shell-command+ 6c7a95b 08/13: Fix quoted shell expansion, Stefan Monnier, 2021/05/23