all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 58921@debbugs.gnu.org, reza <reza@housseini.me>
Subject: bug#58921: Tab completion hangs in eshell
Date: Thu, 23 Feb 2023 12:43:54 -0800	[thread overview]
Message-ID: <fdef055d-0975-c216-844e-ffbd0cc3e573@gmail.com> (raw)
In-Reply-To: <jwvttzcdvrt.fsf-monnier+emacs@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 987 bytes --]

On 2/23/2023 11:34 AM, Stefan Monnier via Bug reports for GNU Emacs, the 
Swiss army knife of text editors wrote:
> The way I see it, either we still have an inf-loop or your
> (pcomplete-match "\\`--.*=" 0) condition is redundant.
> 
>  From what you say the inf-loop should only manifest if we match neither
> 
>      (pcomplete-match "^--\\([^= \t\n\f]*\\)\\'" 0)
> 
> nor
> 
>      (pcomplete-match "\\`--.*=" 0)
> 
> and indeed:
> 
>      tar --pot\ <TAB>
> 
> seems to hang.

Ah, good point. Instead of '(pcomplete-match "\\`--.*=" 0)', I think we 
want to handle all args starting with "--", but not matching "^--\\([^= 
\t\n\f]*\\)\\'". The goal is to call 'pcomplete-here*' exactly once per 
option.

I did this a slightly different way in the updated patch by moving all 
the "--" cases into a single place (likewise with the "-" options). I 
think this is easier to follow than before, and makes it more obvious 
that we're calling 'pcomplete-here*' the right number of times.

[-- Attachment #2: 0001-Fix-Pcompletion-of-tar-when-using-unrecognized-argum.patch --]
[-- Type: text/plain, Size: 11413 bytes --]

From 1b84e2cbf2fbfa0acde84d6fd5298a9997f6c8b8 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Thu, 9 Feb 2023 23:27:50 -0800
Subject: [PATCH] Fix Pcompletion of "tar" when using unrecognized arguments

Previously, arguments to tar like "--warning=no-timestamp" would cause
Pcompletion to hang (bug#58921).

This simplifies the logic flow by moving all the cases for "--"
arguments inside the THEN form of '(if (pcomplete-match "^--" 0)', and
for all "-" arguments inside the ELSE form.

* lisp/pcmpl-gnu.el (pcmpl-gnu--tar-long-options): New variable.
(pcomplete/tar): Properly handle completion of arguments that look
like "--ARG=", even if they're not recognized by this function.
---
 lisp/pcmpl-gnu.el | 269 ++++++++++++++++++++++------------------------
 1 file changed, 127 insertions(+), 142 deletions(-)

diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el
index 7d270ea789f..1553c3efed7 100644
--- a/lisp/pcmpl-gnu.el
+++ b/lisp/pcmpl-gnu.el
@@ -184,6 +184,86 @@ pcmpl-gnu-with-file-buffer
          (when (and (not ,exist) (buffer-live-p ,buf))
            (kill-buffer ,buf))))))
 
+(defvar pcmpl-gnu--tar-long-options
+  ;; FIXME: Extract this list from "tar --help".
+  '("--absolute-names"
+    "--after-date="
+    "--append"
+    "--atime-preserve"
+    "--backup"
+    "--block-number"
+    "--blocking-factor="
+    "--catenate"
+    "--checkpoint"
+    "--compare"
+    "--compress"
+    "--concatenate"
+    "--confirmation"
+    "--create"
+    "--delete"
+    "--dereference"
+    "--diff"
+    "--directory="
+    "--exclude="
+    "--exclude-from="
+    "--extract"
+    "--file="
+    "--files-from="
+    "--force-local"
+    "--get"
+    "--group="
+    "--gzip"
+    "--help"
+    "--ignore-failed-read"
+    "--ignore-zeros"
+    "--incremental"
+    "--info-script="
+    "--interactive"
+    "--keep-old-files"
+    "--label="
+    "--list"
+    "--listed-incremental"
+    "--mode="
+    "--modification-time"
+    "--multi-volume"
+    "--new-volume-script="
+    "--newer="
+    "--newer-mtime"
+    "--no-recursion"
+    "--null"
+    "--numeric-owner"
+    "--old-archive"
+    "--one-file-system"
+    "--owner="
+    "--portability"
+    "--posix"
+    "--preserve"
+    "--preserve-order"
+    "--preserve-permissions"
+    "--read-full-records"
+    "--record-size="
+    "--recursive-unlink"
+    "--remove-files"
+    "--rsh-command="
+    "--same-order"
+    "--same-owner"
+    "--same-permissions"
+    "--sparse"
+    "--starting-file="
+    "--suffix="
+    "--tape-length="
+    "--to-stdout"
+    "--totals"
+    "--uncompress"
+    "--ungzip"
+    "--unlink-first"
+    "--update"
+    "--use-compress-program="
+    "--verbose"
+    "--verify"
+    "--version"
+    "--volno-file="))
+
 ;;;###autoload
 (defun pcomplete/tar ()
   "Completion for the GNU tar utility."
@@ -192,148 +272,53 @@ pcomplete/tar
     (while (pcomplete-match "^-" 0)
       (setq saw-option t)
       (if (pcomplete-match "^--" 0)
-          (if (pcomplete-match "^--\\([^= \t\n\f]*\\)\\'" 0)
-              ;; FIXME: Extract this list from "tar --help".
-              (pcomplete-here*
-               '("--absolute-names"
-                 "--after-date="
-                 "--append"
-                 "--atime-preserve"
-                 "--backup"
-                 "--block-number"
-                 "--blocking-factor="
-                 "--catenate"
-                 "--checkpoint"
-                 "--compare"
-                 "--compress"
-                 "--concatenate"
-                 "--confirmation"
-                 "--create"
-                 "--delete"
-                 "--dereference"
-                 "--diff"
-                 "--directory="
-                 "--exclude="
-                 "--exclude-from="
-                 "--extract"
-                 "--file="
-                 "--files-from="
-                 "--force-local"
-                 "--get"
-                 "--group="
-                 "--gzip"
-                 "--help"
-                 "--ignore-failed-read"
-                 "--ignore-zeros"
-                 "--incremental"
-                 "--info-script="
-                 "--interactive"
-                 "--keep-old-files"
-                 "--label="
-                 "--list"
-                 "--listed-incremental"
-                 "--mode="
-                 "--modification-time"
-                 "--multi-volume"
-                 "--new-volume-script="
-                 "--newer="
-                 "--newer-mtime"
-                 "--no-recursion"
-                 "--null"
-                 "--numeric-owner"
-                 "--old-archive"
-                 "--one-file-system"
-                 "--owner="
-                 "--portability"
-                 "--posix"
-                 "--preserve"
-                 "--preserve-order"
-                 "--preserve-permissions"
-                 "--read-full-records"
-                 "--record-size="
-                 "--recursive-unlink"
-                 "--remove-files"
-                 "--rsh-command="
-                 "--same-order"
-                 "--same-owner"
-                 "--same-permissions"
-                 "--sparse"
-                 "--starting-file="
-                 "--suffix="
-                 "--tape-length="
-                 "--to-stdout"
-                 "--totals"
-                 "--uncompress"
-                 "--ungzip"
-                 "--unlink-first"
-                 "--update"
-                 "--use-compress-program="
-                 "--verbose"
-                 "--verify"
-                 "--version"
-                 "--volno-file=")))
-        (pcomplete-opt "01234567ABCFGKLMNOPRSTUVWXZbcdfghiklmoprstuvwxz"))
-      (cond
-       ((pcomplete-match "\\`-\\'" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--after-date=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--backup=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--blocking-factor=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--directory=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-dirs)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--exclude-from=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-entries)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--exclude=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--\\(extract\\|list\\)\\'" 0)
-        (setq complete-within t))
-       ((pcomplete-match "\\`--file=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-dirs-or-entries pcmpl-gnu-tarfile-regexp)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--files-from=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-entries)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--group=\\(.*\\)" 0)
-        (pcomplete-here* (pcmpl-unix-group-names)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--info-script=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-entries)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--label=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--mode=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--new-volume-script=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-entries)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--newer=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--owner=\\(.*\\)" 0)
-        (pcomplete-here* (pcmpl-unix-user-names)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--record-size=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--rsh-command=\\(.*\\)" 0)
-        (pcomplete-here* (funcall pcomplete-command-completion-function)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--starting-file=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-entries)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--suffix=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--tape-length=" 0)
-        (pcomplete-here*))
-       ((pcomplete-match "\\`--use-compress-program=\\(.*\\)" 0)
-        (pcomplete-here* (funcall pcomplete-command-completion-function)
-                         (pcomplete-match-string 1 0)))
-       ((pcomplete-match "\\`--volno-file=\\(.*\\)" 0)
-        (pcomplete-here* (pcomplete-entries)
-                         (pcomplete-match-string 1 0)))))
+          (cond
+           ((pcomplete-match "^--\\([^= \t\n\f]*\\)\\'" 0)
+            (pcomplete-here* pcmpl-gnu--tar-long-options))
+           ((pcomplete-match "\\`--directory=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-dirs)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--exclude-from=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-entries)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--\\(extract\\|list\\)\\'" 0)
+            (setq complete-within t))
+           ((pcomplete-match "\\`--file=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-dirs-or-entries
+                              pcmpl-gnu-tarfile-regexp)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--files-from=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-entries)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--group=\\(.*\\)" 0)
+            (pcomplete-here* (pcmpl-unix-group-names)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--info-script=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-entries)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--new-volume-script=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-entries)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--owner=\\(.*\\)" 0)
+            (pcomplete-here* (pcmpl-unix-user-names)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--rsh-command=\\(.*\\)" 0)
+            (pcomplete-here* (funcall pcomplete-command-completion-function)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--starting-file=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-entries)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--use-compress-program=\\(.*\\)" 0)
+            (pcomplete-here* (funcall pcomplete-command-completion-function)
+                             (pcomplete-match-string 1 0)))
+           ((pcomplete-match "\\`--volno-file=\\(.*\\)" 0)
+            (pcomplete-here* (pcomplete-entries)
+                             (pcomplete-match-string 1 0)))
+           (t
+            (pcomplete-here*)))
+        (pcomplete-opt "01234567ABCFGKLMNOPRSTUVWXZbcdfghiklmoprstuvwxz")
+        (when (pcomplete-match "\\`-\\'" 0)
+          (pcomplete-here*))))
     (unless saw-option
       (pcomplete-here
        (mapcar #'char-to-string
-- 
2.25.1


  reply	other threads:[~2023-02-23 20:43 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <2cb2b8aa-0813-5eae-3bfc-27831b3d50dd@housseini.me>
2022-10-31  9:04 ` bug#58921: Tab completion hangs in eshell reza via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-02  7:28   ` Gerd Möllmann
2023-02-10  7:34   ` Jim Porter
2023-02-23  6:57     ` Jim Porter
2023-02-23 18:08     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-23 19:25       ` Jim Porter
2023-02-23 19:34         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-23 20:43           ` Jim Porter [this message]
2023-03-04  5:37             ` Jim Porter
2023-03-08 23:53               ` Jim Porter

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

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

  git send-email \
    --in-reply-to=fdef055d-0975-c216-844e-ffbd0cc3e573@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=58921@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=reza@housseini.me \
    /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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.