From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Lars Ingebrigtsen Newsgroups: gmane.emacs.bugs Subject: bug#16197: 24.3.50; no completion on commands following "sudo" in shell and eshell Date: Fri, 25 Sep 2020 12:44:29 +0200 Message-ID: <87y2kyqgoi.fsf@gnus.org> References: <87fvpolyuk.fsf@gmail.com> <87zjnshslj.fsf@gmail.com> <87vbyfoojc.fsf@gmail.com> <8738lispja.fsf@gmail.com> <8738licym6.fsf@gmail.com> <874n5kfh0x.fsf@gmail.com> <87bnzoueb8.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="27296"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: 16197@debbugs.gnu.org, Stefan Monnier To: Thierry Volpiatto Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Sep 25 12:45:10 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLlDy-0006ze-Be for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 25 Sep 2020 12:45:10 +0200 Original-Received: from localhost ([::1]:39366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kLlDx-0007ue-Cu for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 25 Sep 2020 06:45:09 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48806) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kLlDq-0007tA-Pc for bug-gnu-emacs@gnu.org; Fri, 25 Sep 2020 06:45:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:59487) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kLlDq-0002X4-Gc for bug-gnu-emacs@gnu.org; Fri, 25 Sep 2020 06:45:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kLlDq-0006jx-Eo for bug-gnu-emacs@gnu.org; Fri, 25 Sep 2020 06:45:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Lars Ingebrigtsen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 25 Sep 2020 10:45:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 16197 X-GNU-PR-Package: emacs Original-Received: via spool by 16197-submit@debbugs.gnu.org id=B16197.160103068425859 (code B ref 16197); Fri, 25 Sep 2020 10:45:02 +0000 Original-Received: (at 16197) by debbugs.gnu.org; 25 Sep 2020 10:44:44 +0000 Original-Received: from localhost ([127.0.0.1]:42797 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kLlDX-0006j0-RH for submit@debbugs.gnu.org; Fri, 25 Sep 2020 06:44:44 -0400 Original-Received: from quimby.gnus.org ([95.216.78.240]:38590) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kLlDU-0006if-CZ for 16197@debbugs.gnu.org; Fri, 25 Sep 2020 06:44:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=UHti5BpTll/1jyOLbbgs2yw/gESZah4DlROiezvBbF0=; b=L22EWHV1tCKoXSLEbNdEh/t1BF tvATFSVMq4GxnCRd2fJ9Y22OcfSeJ5gELvIIKcPZ4rVg7mHMptVqROL+IYsJkuUQEOvpQC/kVE0Ra ADX88Xo9GiKKdfHsxat2CuARCnY1HetMS0AcKel7KHx0Jawo2KhnUIqSONeprRBr5xtM=; Original-Received: from cm-84.212.202.86.getinternet.no ([84.212.202.86] helo=xo) by quimby with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLlDK-0001IB-Ov; Fri, 25 Sep 2020 12:44:33 +0200 X-Now-Playing: Thievery Corporation's _The Mirror Conspiracy_: "The Mirror Conspiracy" In-Reply-To: <87bnzoueb8.fsf@gmail.com> (Thierry Volpiatto's message of "Tue, 07 Jan 2014 14:11:39 +0100") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:188946 Archived-At: Thierry Volpiatto writes: >> Can you send it as a patch against pcmpl-unix.el to fix pcomplete/xargs >> (and add pcomplete/sudo at the same time)? > > * lisp/pcml-unix.el (pcomplete/sudo): New. > * lisp/pcomplete.el (pcomplete-command-name): Allow extracting > command-name in more complex command lines. > * lisp/shell.el (shell-command-completion-function): Fix it (was not > working at all). There was unfortunately no followup to this at the time. I've now respun the patch and tried to do some testing, but... this doesn't seem to work? Here's how I tested: 1) Apply the patch 2) Build Emacs 3) emacs -Q f) M-x shell IV) sudo apt-g Result: "No match" I'm not very familiar with the completion framework, and the code has changed over the years... Anybody? diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el index 74f45b9523..0096020ab4 100644 --- a/lisp/pcmpl-unix.el +++ b/lisp/pcmpl-unix.el @@ -82,9 +82,13 @@ pcomplete/rm ;;;###autoload (defun pcomplete/xargs () "Completion for `xargs'." - (pcomplete-here (funcall pcomplete-command-completion-function)) - (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1)) - pcomplete-default-completion-function))) + (let ((pcomplete-cmd-name (pcomplete-command-name))) + (cond ((string= "xargs" pcomplete-cmd-name) + (while (pcomplete-here* + (funcall pcomplete-command-completion-function) + (pcomplete-arg 'last) t))) + (t (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1)) + pcomplete-default-completion-function)))))) ;;;###autoload (defalias 'pcomplete/time 'pcomplete/xargs) @@ -240,6 +244,22 @@ pcomplete/rsh (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1)) pcomplete-default-completion-function))) +(defun pcomplete/sudo () + (let ((pcomplete-cmd-name (pcomplete-command-name))) + (while (and (string= "sudo" pcomplete-cmd-name) + (pcomplete-match "^-" 'last)) + (when (< pcomplete-index pcomplete-last) + (pcomplete-next-arg)) + (pcomplete-opt "AbCDEegHhiKknPpSsUuVv-")) + (cond ((string= "sudo" pcomplete-cmd-name) + (while (pcomplete-here* + (funcall pcomplete-command-completion-function) + (pcomplete-arg 'last) t))) + (t + (funcall (or (pcomplete-find-completion-function + pcomplete-cmd-name) + pcomplete-default-completion-function)))))) + (provide 'pcmpl-unix) ;;; pcmpl-unix.el ends here diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el index 014f9628b9..9ac4652126 100644 --- a/lisp/pcomplete.el +++ b/lisp/pcomplete.el @@ -119,6 +119,7 @@ ;;; Code: (require 'comint) +(eval-when-compile (require 'cl-lib)) (defgroup pcomplete nil "Programmable completion." @@ -674,9 +675,42 @@ pcomplete-next-arg (message "No completions") (throw 'pcompleted nil)))) +(defvar pcomplete-special-commands '("sudo" "xargs")) (defun pcomplete-command-name () "Return the command name of the first argument." - (file-name-nondirectory (pcomplete-arg 'first))) + (let ((coms (cl-loop with lst = (reverse (pcomplete-parse-arguments)) + for str in (or (member "|" lst) + (member "||" lst) + (member "&" lst) + (member ";" lst) + lst) + for exec = (or (executable-find str) + ;; `executable-find' or 'which' + ;; doesn't return these paths. + (car (member str '("cd" "pushd" "popd")))) + when exec collect exec))) + (file-name-nondirectory + ;; we may have commands embeded in executables that looks + ;; like executables (e.g apt-get install). + ;; Assume that all executables are using only one command + ;; like this. + ;; e.g - if we have (install apt-get sudo) + ;; what we want is apt-get. + ;; - if we have (apt-get sudo) + ;; what we want is sudo, + ;; then pcomplete/sudo will check if + ;; a pcomplete handler exists for apt-get. + (cond (;; e.g (install apt-get sudo) + (> (length coms) 2) (cadr coms)) + (;; e.g (apt-get sudo) + (and (= (length coms) 2) + (member (file-name-nondirectory (cadr coms)) + pcomplete-special-commands)) + (car coms)) + (;; e.g (sudo) + (= (length coms) 1) (car coms)) + (t ;; e.g (install apt-get) + (cadr coms)))))) (defun pcomplete-match (regexp &optional index offset start) "Like `string-match', but on the current completion argument." diff --git a/lisp/shell.el b/lisp/shell.el index 9667dab2af..48eb69f0b6 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -460,9 +460,8 @@ shell-command-completion-function This is the value of `pcomplete-command-completion-function' for Shell buffers. It implements `shell-completion-execonly' for `pcomplete' completion." - (pcomplete-here (pcomplete-entries nil - (if shell-completion-execonly - 'file-executable-p)))) + (let ((data (shell--command-completion-data))) + (and data (pcomplete-here (all-completions "" (nth 2 data)))))) (defun shell-completion-vars () "Setup completion vars for `shell-mode' and `read-shell-command'." -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no