unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Lars Ingebrigtsen <larsi@gnus.org>
To: Thierry Volpiatto <thierry.volpiatto@gmail.com>
Cc: 16197@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>
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	[thread overview]
Message-ID: <87y2kyqgoi.fsf@gnus.org> (raw)
In-Reply-To: <87bnzoueb8.fsf@gmail.com> (Thierry Volpiatto's message of "Tue,  07 Jan 2014 14:11:39 +0100")

Thierry Volpiatto <thierry.volpiatto@gmail.com> 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<TAB>

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





  reply	other threads:[~2020-09-25 10:44 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-20  8:18 bug#16197: 24.3.50; no completion on commands following "sudo" in shell and eshell Thierry Volpiatto
2013-12-23  8:36 ` Thierry Volpiatto
2013-12-23 10:21   ` Thierry Volpiatto
2013-12-24  6:59     ` Thierry Volpiatto
2013-12-24 10:49       ` Thierry Volpiatto
2014-01-03 22:53         ` Stefan Monnier
2014-01-04  5:33           ` Thierry Volpiatto
2014-01-04  7:11             ` Thierry Volpiatto
2014-01-04 20:26             ` Stefan Monnier
2014-01-05  7:35               ` Thierry Volpiatto
2020-09-25 17:51                 ` Stefan Monnier
2020-09-26 13:09                   ` Lars Ingebrigtsen
2020-09-26 22:17                     ` Stefan Monnier
2020-09-27 12:08                       ` Lars Ingebrigtsen
2020-09-28  2:07                         ` Stefan Monnier
2020-09-28 11:12                           ` Lars Ingebrigtsen
2014-01-07 13:11               ` Thierry Volpiatto
2020-09-25 10:44                 ` Lars Ingebrigtsen [this message]
2014-01-07 15:26               ` Thierry Volpiatto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y2kyqgoi.fsf@gnus.org \
    --to=larsi@gnus.org \
    --cc=16197@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=thierry.volpiatto@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).