Package: emacs;
Reported by: Philip Kaludercic <philipk <at> posteo.net>
Date: Sun, 30 Jan 2022 23:39:01 UTC
Severity: normal
Found in version 29.0.50
Message #47 received at 53644 <at> debbugs.gnu.org (full text, mbox):
From: Philip Kaludercic <philipk <at> posteo.net> To: Michael Albinus <michael.albinus <at> gmx.de> Cc: 53644 <at> debbugs.gnu.org, Dmitry Gutov <dgutov <at> yandex.ru> Subject: Re: bug#53644: 29.0.50; xref-search-program breaks if programm not installed on a remote host Date: Wed, 09 Feb 2022 09:17:27 +0000
[Message part 1 (text/plain, inline)]
Michael Albinus <michael.albinus <at> gmx.de> writes: > Philip Kaludercic <philipk <at> posteo.net> writes: > > Hi Philip, > >> But the question here remains precisely what to use instead of the >> literal "/bin/sh"? > > Well, if there isn't a better value, "/bin/sh" should serve as > fallback. In my experience with Tramp, it works on most of the remote > systems. It doesn't work on remote Android devices, for example. But > the > number of Emacs < 27 users, running xref-* on a remote Android device, > is rather limited I believe. > > POSIX declines this assumptions. It recommends to call "command -v sh" > in order to determine the shell path, see > <https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html>. > > Best regards, Michael. In that case, I'd propose this patch:
[0001-Check-if-xref-search-program-exists-on-a-remote-syst.patch (text/x-patch, inline)]
From da83d403688b4b5771d08c95975c73a1cfd593c1 Mon Sep 17 00:00:00 2001 From: Philip Kaludercic <philipk <at> posteo.net> Date: Wed, 9 Feb 2022 10:14:38 +0100 Subject: [PATCH] Check if xref-search-program exists on a remote system * lisp/progmodes/xref.el (xref-matches-in-files): Loop through all programmes in xref-search-program-alist as a fallback before raising an error that the search query couldn't be executed. --- lisp/progmodes/xref.el | 84 ++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 6677b4f004..759dbb9778 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1751,44 +1751,74 @@ xref-matches-in-files (remote-id (file-remote-p dir)) ;; The 'auto' default would be fine too, but ripgrep can't handle ;; the options we pass in that case. - (grep-highlight-matches nil) - (command (grep-expand-template (cdr - (or - (assoc - xref-search-program - xref-search-program-alist) - (user-error "Unknown search program `%s'" - xref-search-program))) - (xref--regexp-to-extended regexp)))) + (grep-highlight-matches nil)) (when remote-id (require 'tramp) (setq files (mapcar (if (tramp-tramp-file-p dir) #'tramp-file-local-name - #'file-local-name) + #'file-local-name) files))) (when (file-name-quoted-p (car files)) (setq files (mapcar #'file-name-unquote files))) (with-current-buffer output - (erase-buffer) (with-temp-buffer (insert (mapconcat #'identity files "\0")) - (setq default-directory dir) - (setq status - (xref--process-file-region (point-min) - (point-max) - shell-file-name - output - nil - shell-command-switch - command))) - (goto-char (point-min)) - (when (and (/= (point-min) (point-max)) - (not (looking-at grep-re)) - ;; TODO: Show these matches as well somehow? - (not (looking-at "Binary file .* matches"))) - (user-error "Search failed with status %d: %s" status - (buffer-substring (point-min) (line-end-position)))) + (let* ((default-directory dir) + (xref-search-program-alist xref-search-program-alist) + (program (if (bound-and-true-p enable-connection-local-variables) + (with-connection-local-variables + xref-search-program) + xref-search-program)) + (process-file-side-effects nil)) + ;; In case `xref-search-program' is not installed on a + ;; remote system, we will speculatively try to start a + ;; different searcher to see if it is installed and works. + (catch 'ok + (while xref-search-program-alist + (with-current-buffer output + (erase-buffer)) + (setq status + (let ((sfn shell-file-name) + (scs shell-command-switch)) + (when remote-id + (if (bound-and-true-p enable-connection-local-variables) + (with-connection-local-variables + (setq sfn shell-file-name + scs shell-command-switch)) + (setq sfn "/bin/sh"))) + (xref--process-file-region + (point-min) (point-max) + sfn output nil scs + (grep-expand-template + (or (alist-get program xref-search-program-alist) + (user-error "Unknown search program `%s'" program)) + (xref--regexp-to-extended regexp))))) + (with-current-buffer output + (goto-char (point-min)) + (unless (and (/= (point-min) (point-max)) + (not (looking-at grep-re)) + ;; TODO: Show these matches as well somehow? + (not (looking-at "Binary file .* matches"))) + (when (and (not (eq program xref-search-program)) + (version<= "27" emacs-version)) + ;; If possible and necessary, save whatever program + ;; was found as a connection local variable. + (let* ((host (file-remote-p dir 'host)) + (profile (intern (concat "xref-remote-" host)))) + (connection-local-set-profile-variables + profile `((xref-search-program . ,program))) + (connection-local-set-profiles + (list :machine host) profile))) + (throw 'ok t))) + (setq xref-search-program-alist + (remq (assq program xref-search-program-alist) + xref-search-program-alist) + program (caar xref-search-program-alist))) + (with-current-buffer output + (user-error "Search failed with status %d: %s" status + (buffer-string) + (buffer-substring (point-min) (line-end-position))))))) (while (re-search-forward grep-re nil t) (push (list (string-to-number (match-string line-group)) (match-string file-group) -- 2.34.0
[Message part 3 (text/plain, inline)]
-- Philip Kaludercic
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.