emacs-diffs
[Top][All Lists]
Advanced

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

master 0094dde11d: Fix grep-like functions when running on a remote host


From: Michael Albinus
Subject: master 0094dde11d: Fix grep-like functions when running on a remote host
Date: Tue, 22 Mar 2022 05:29:28 -0400 (EDT)

branch: master
commit 0094dde11d97a0e69b053851a87f2934ef0e00aa
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>

    Fix grep-like functions when running on a remote host
    
    * doc/lispref/processes.texi (Shell Arguments):
    * etc/NEWS: Describe change in 'shell-quote-argument'.  Fix typos.
    
    * lisp/subr.el (shell-quote-argument): New optional argument POSIX.
    
    * lisp/progmodes/grep.el (grep-compute-defaults)
    (grep-default-command, grep-expand-keywords, lgrep)
    (rgrep-default-command): Use POSIX argument in
    `shell-quote-argument'.  (Bug#54487)
---
 doc/lispref/processes.texi |  11 ++++-
 etc/NEWS                   |  34 ++++++++------
 lisp/progmodes/grep.el     | 111 ++++++++++++++++++++++++---------------------
 lisp/subr.el               |  14 ++++--
 4 files changed, 97 insertions(+), 73 deletions(-)

diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index ed07c1cbf7..ea51abda4b 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -197,7 +197,7 @@ gives special treatment to certain characters, and if these 
characters
 occur in the file name, they will confuse the shell.  To handle these
 characters, use the function @code{shell-quote-argument}:
 
-@defun shell-quote-argument argument
+@defun shell-quote-argument argument &optional posix
 This function returns a string that represents, in shell syntax,
 an argument whose actual contents are @var{argument}.  It should
 work reliably to concatenate the return value into a shell command
@@ -227,6 +227,15 @@ a shell command:
         " "
         (shell-quote-argument newfile))
 @end example
+
+If the optional @var{posix} argument is non-@code{nil}, @var{argument}
+is quoted according to POSIX shell quoting rules, regardless of the
+system’s shell.  This is useful when your shell could run on a remote
+host, which requires a POSIX shell in general.
+
+@example
+(shell-quote-argument "foo > bar" (file-remote-p default-directory))
+@end example
 @end defun
 
 @cindex quoting and unquoting command-line arguments
diff --git a/etc/NEWS b/etc/NEWS
index ebf1346dae..e64fe2d23b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -578,9 +578,9 @@ the "*Completions*" buffer.  Available styles are no 
sorting,
 alphabetical (the default), or a custom sort function.
 
 +++
-*** New values for the 'completion-auto-help' option.
+*** New values for the 'completion-auto-help' user option.
 There are two new values to control the way "*Completions*" behave after
-a <tab> if completion is not unique.  'always' updates or shows
+a 'TAB' if completion is not unique.  'always' updates or shows
 the "*Completions*" buffer after any attempt to complete.  'visual' is
 like 'always', but only update the completions if they are already
 visible.  The default value 't' always hides the completion buffer after
@@ -591,16 +591,16 @@ some completion is made.
 This option limits the height of the "*Completions*" buffer.
 
 +++
-*** New option 'completions-header-format'
+*** New user option 'completions-header-format'
 This is a string to control the message to show before completions.
-It may contain a "%s" to show the total number of completions. If nil no
+It may contain a "%s" to show the total number of completions.  If nil no
 completions are shown.
 
 +++
-*** New option 'completions-highlight-face'.
-When this variable is a face name, it highlights the current candidate
-in the "*Completions*" buffer with that face.  When the value is nil,
-no highlighting is performed at all.
+*** New user option 'completions-highlight-face'.
+When this user option is a face name, it highlights the current
+candidate in the "*Completions*" buffer with that face.  When the
+value is nil, no highlighting is performed at all.
 
 ** Isearch and Replace
 
@@ -1207,7 +1207,7 @@ like:
 ---
 ** The 'inhibit-changing-match-data' variable is now obsolete.
 Instead, functions like 'string-match' and 'looking-at' now take an
-optional 'inhibit-modify' argument.
+optional INHIBIT-MODIFY argument.
 
 ---
 ** 'gnus-define-keys' is now obsolete.
@@ -1330,7 +1330,7 @@ This allows setting a minimum display width for a region 
of text.
 ** New 'cursor-face' text property.
 This uses 'cursor-face' instead of the default face when cursor is on or
 near the character and 'cursor-face-highlight-mode' is enabled.  The
-variable 'cursor-face-highlight-nonselected-window' is similar to
+user option 'cursor-face-highlight-nonselected-window' is similar to
 'highlight-nonselected-windows', but for this property.
 
 +++
@@ -1470,8 +1470,8 @@ This command lets you examine all data in the current 
selection and
 the clipboard, and insert it into the buffer.
 
 ---
-** New hook 'minibuffer-lazy-highlight-setup'.
-This hook is intended to be added to 'minibuffer-setup-hook'.
+** New function 'minibuffer-lazy-highlight-setup'.
+This function is intended to be added to 'minibuffer-setup-hook'.
 It sets up the minibuffer for lazy highlighting of matches
 in the original window.
 
@@ -1542,8 +1542,7 @@ from a specified amount of pixels above or below a 
position.
 ---
 ** 'eshell-eval-using-options' now follows POSIX/GNU argument syntax 
conventions.
 Built-in commands in Eshell now accept command-line options with
-values passed as a single token, such as '-oVALUE' or
-'--option=VALUE'.
+values passed as a single token, such as '-oVALUE' or '--option=VALUE'.
 
 ** XDG support
 
@@ -1748,11 +1747,16 @@ This is recorded in the `function-history` symbol 
property.
 ** 'indian-tml-base-table' no longer translates digits.
 Use 'indian-tml-base-digits-table' if you want digits translation.
 
---
+---
 ** 'indian-tml-itrans-v5-hash' no longer translates digits.
 Use 'indian-tml-itrans-digits-v5-hash' if you want digits
 translation.
 
++++
+** 'shell-quote-argument' has a new optional parameter POSIX.
+This is useful when quoting shell arguments for a remote shell
+invocation.  Such shells are POSIX conform by default.
+
 
 * Changes in Emacs 29.1 on Non-Free Operating Systems
 
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index ccc58e6773..2128088856 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -632,12 +632,12 @@ The value depends on `grep-command', `grep-template',
               ,grep-use-null-filename-separator)
             (grep-find-use-xargs ,grep-find-use-xargs)
             (grep-highlight-matches ,grep-highlight-matches)))))
-  (let* ((host-id
-         (intern (or (file-remote-p default-directory) "localhost")))
+  (let* ((remote (file-remote-p default-directory))
+         (host-id (intern (or remote "localhost")))
         (host-defaults (assq host-id grep-host-defaults-alist))
         (defaults (assq nil grep-host-defaults-alist))
-         (quot-braces (shell-quote-argument "{}"))
-         (quot-scolon (shell-quote-argument ";")))
+         (quot-braces (shell-quote-argument "{}" remote))
+         (quot-scolon (shell-quote-argument ";" remote)))
     ;; There are different defaults on different hosts.  They must be
     ;; computed for every host once.
     (dolist (setting '(grep-command grep-template
@@ -820,7 +820,9 @@ The value depends on `grep-command', `grep-template',
 
 (defun grep-default-command ()
   "Compute the default grep command for \\[universal-argument] \\[grep] to 
offer."
-  (let ((tag-default (shell-quote-argument (grep-tag-default)))
+  (let ((tag-default
+         (shell-quote-argument
+          (grep-tag-default) (file-remote-p default-directory)))
        ;; This a regexp to match single shell arguments.
        ;; Could someone please add comments explaining it?
        (sh-arg-re
@@ -963,7 +965,8 @@ easily repeat a find command."
     ("<F>" . files)
     ("<N>" . (null-device))
     ("<X>" . excl)
-    ("<R>" . (shell-quote-argument (or regexp ""))))
+    ("<R>" . (shell-quote-argument
+              (or regexp "") (file-remote-p (expand-file-name (or dir "."))))))
   "List of substitutions performed by `grep-expand-template'.
 If car of an element matches, the cdr is evalled in order to get the
 substitution string.
@@ -1112,11 +1115,12 @@ command before it's run."
   (when (and (stringp regexp) (> (length regexp) 0))
     (unless (and dir (file-accessible-directory-p dir))
       (setq dir default-directory))
-    (let ((command regexp))
+    (let ((command regexp) remote)
       (if (null files)
          (if (string= command grep-command)
              (setq command nil))
-       (setq dir (file-name-as-directory (expand-file-name dir)))
+       (setq dir (file-name-as-directory (expand-file-name dir))
+              remote (file-remote-p dir))
        (unless (or (not grep-use-directories-skip)
                     (eq grep-use-directories-skip t))
          (setq grep-use-directories-skip
@@ -1134,11 +1138,12 @@ command before it's run."
                                    (mapconcat
                                      (lambda (ignore)
                                        (cond ((stringp ignore)
-                                              (shell-quote-argument ignore))
+                                              (shell-quote-argument
+                                               ignore remote))
                                              ((consp ignore)
                                               (and (funcall (car ignore) dir)
                                                    (shell-quote-argument
-                                                    (cdr ignore))))))
+                                                    (cdr ignore) remote)))))
                                     grep-find-ignored-files
                                     " --exclude=")))
                       (and (eq grep-use-directories-skip t)
@@ -1242,48 +1247,50 @@ command before it's run."
 (defun rgrep-default-command (regexp files dir)
   "Compute the command for \\[rgrep] to use by default."
   (require 'find-dired)      ; for `find-name-arg'
-  (grep-expand-template
-   grep-find-template
-   regexp
-   (concat (shell-quote-argument "(")
-           " " find-name-arg " "
-           (mapconcat
-            #'shell-quote-argument
-            (split-string files)
-            (concat " -o " find-name-arg " "))
-           " "
-           (shell-quote-argument ")"))
-   dir
-   (concat
-    (and grep-find-ignored-directories
-         (concat "-type d "
-                 (shell-quote-argument "(")
-                 ;; we should use shell-quote-argument here
-                 " -path "
-                 (mapconcat (lambda (d) (shell-quote-argument (concat "*/" d)))
-                            (rgrep-find-ignored-directories dir)
-                            " -o -path ")
-                 " "
-                 (shell-quote-argument ")")
-                 " -prune -o "))
-    (and grep-find-ignored-files
-         (concat (shell-quote-argument "!") " -type d "
-                 (shell-quote-argument "(")
-                 ;; we should use shell-quote-argument here
-                 " -name "
-                 (mapconcat
-                  (lambda (ignore)
-                    (cond ((stringp ignore)
-                           (shell-quote-argument ignore))
-                          ((consp ignore)
-                           (and (funcall (car ignore) dir)
-                                (shell-quote-argument
-                                 (cdr ignore))))))
-                  grep-find-ignored-files
-                  " -o -name ")
-                 " "
-                 (shell-quote-argument ")")
-                 " -prune -o ")))))
+  (let ((remote (file-remote-p (or dir default-directory))))
+    (grep-expand-template
+     grep-find-template
+     regexp
+     (concat (shell-quote-argument "(" remote)
+             " " find-name-arg " "
+             (mapconcat
+              (lambda (x) (shell-quote-argument x remote))
+              (split-string files)
+              (concat " -o " find-name-arg " "))
+             " "
+             (shell-quote-argument ")" remote))
+     dir
+     (concat
+      (and grep-find-ignored-directories
+           (concat "-type d "
+                   (shell-quote-argument "(" remote)
+                   ;; we should use shell-quote-argument here
+                   " -path "
+                   (mapconcat
+                    (lambda (d) (shell-quote-argument (concat "*/" d) remote))
+                    (rgrep-find-ignored-directories dir)
+                    " -o -path ")
+                   " "
+                   (shell-quote-argument ")" remote)
+                   " -prune -o "))
+      (and grep-find-ignored-files
+           (concat (shell-quote-argument "!" remote) " -type d "
+                   (shell-quote-argument "(" remote)
+                   ;; we should use shell-quote-argument here
+                   " -name "
+                   (mapconcat
+                    (lambda (ignore)
+                      (cond ((stringp ignore)
+                             (shell-quote-argument ignore remote))
+                            ((consp ignore)
+                             (and (funcall (car ignore) dir)
+                                  (shell-quote-argument
+                                   (cdr ignore) remote)))))
+                    grep-find-ignored-files
+                    " -o -name ")
+                   " "
+                   (shell-quote-argument ")" remote)
+                   " -prune -o "))))))
 
 (defun grep-find-toggle-abbreviation ()
   "Toggle showing the hidden part of rgrep/lgrep/zrgrep command line."
diff --git a/lisp/subr.el b/lisp/subr.el
index 8aadcfd453..603acffea7 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3760,14 +3760,18 @@ Note: :data and :device are currently not supported on 
Windows."
 
 (declare-function w32-shell-dos-semantics "w32-fns" nil)
 
-(defun shell-quote-argument (argument)
+(defun shell-quote-argument (argument &optional posix)
   "Quote ARGUMENT for passing as argument to an inferior shell.
 
 This function is designed to work with the syntax of your system's
 standard shell, and might produce incorrect results with unusual shells.
-See Info node `(elisp)Security Considerations'."
-  (cond
-   ((eq system-type 'ms-dos)
+See Info node `(elisp)Security Considerations'.
+
+If the optional POSIX argument is non-nil, ARGUMENT is quoted
+according to POSIX shell quoting rules, regardless of the
+system's shell."
+(cond
+   ((and (not posix) (eq system-type 'ms-dos))
     ;; Quote using double quotes, but escape any existing quotes in
     ;; the argument with backslashes.
     (let ((result "")
@@ -3782,7 +3786,7 @@ See Info node `(elisp)Security Considerations'."
                   start (1+ end))))
       (concat "\"" result (substring argument start) "\"")))
 
-   ((and (eq system-type 'windows-nt) (w32-shell-dos-semantics))
+   ((and (not posix) (eq system-type 'windows-nt) (w32-shell-dos-semantics))
 
     ;; First, quote argument so that CommandLineToArgvW will
     ;; understand it.  See



reply via email to

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