branch: externals/shell-command+ commit 2895bc04cf7a27b9bc519aa034a6f47fd138d91d Author: Philip K <phil...@posteo.net> Commit: Philip K <phil...@posteo.net>
Extract parsing into shell-command+-parse --- shell-command+.el | 75 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/shell-command+.el b/shell-command+.el index c482449..7d309d3 100644 --- a/shell-command+.el +++ b/shell-command+.el @@ -60,6 +60,7 @@ ;; is interpreted.. (eval-when-compile (require 'rx)) +(eval-when-compile (require 'pcase)) (require 'eshell) (require 'em-unix) @@ -115,6 +116,29 @@ proper upwards directory pointers. This means that '....' becomes (mapconcat #'identity (make-list (1- (length sub)) "..") "/")) path))) +(defun shell-command+-parse (command) + "Return parsed representation of COMMAND." + (save-match-data + (unless (string-match shell-command+--command-regexp command) + (error "Invalid command")) + (list (match-string-no-properties 1 command) + (cond ((match-string-no-properties 2 command) ;< + 'input) + ((match-string-no-properties 3 command) ;> + 'output) + ((match-string-no-properties 4 command) ;| + 'pipe)) + (match-string-no-properties 6 command) + (condition-case nil + (replace-regexp-in-string + (rx (* ?\\ ?\\) (or ?\\ (group "%"))) + buffer-file-name + (match-string-no-properties 5 command) + nil nil 1) + (error (match-string-no-properties 5 command)))))) + +(shell-command+-parse "ls %") + ;;;###autoload (defun shell-command+ (command beg end) "Intelligently execute string COMMAND in inferior shell. @@ -141,37 +165,26 @@ between BEG and END. Otherwise the whole buffer is processed." (interactive (list (read-shell-command shell-command+-prompt) (if (use-region-p) (region-beginning) (point-min)) (if (use-region-p) (region-end) (point-max)))) - (save-match-data - (unless (string-match shell-command+--command-regexp command) - (error "Invalid command")) - (let ((path (match-string-no-properties 1 command)) - (cmd (match-string-no-properties 6 command)) - (rest (condition-case nil - (replace-regexp-in-string - (rx (* ?\\ ?\\) (or ?\\ (group "%"))) - buffer-file-name - (match-string-no-properties 5 command) - nil nil 1) - (error (match-string-no-properties 5 command))))) - (let ((default-directory (shell-command+-expand-path (or path ".")))) - (cond ((match-string-no-properties 2 command) ;< - (delete-region beg end) - (shell-command rest t shell-command-default-error-buffer) - (exchange-point-and-mark)) - ((match-string-no-properties 3 command) ;> - (shell-command-on-region - beg end rest nil nil - shell-command-default-error-buffer t)) - ((match-string-no-properties 4 command) ;| - (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 cmd) shell-command+-use-eshell)) - (intern-soft (concat "eshell/" cmd))) - (eshell-command rest (and current-prefix-arg t))) - (t (shell-command rest (and current-prefix-arg t) - shell-command-default-error-buffer))))))) + (pcase-let* ((`(,path ,mode ,command ,rest) (shell-command+-parse command)) + (default-directory (shell-command+-expand-path (or path ".")))) + (cond ((eq mode 'input) + (delete-region beg end) + (shell-command rest t shell-command-default-error-buffer) + (exchange-point-and-mark)) + ((eq mode 'output) + (shell-command-on-region + beg end rest nil nil + shell-command-default-error-buffer t)) + ((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))) + (t (shell-command rest (and current-prefix-arg t) + shell-command-default-error-buffer))))) (provide 'shell-command+)