emacs-bug-tracker
[Top][All Lists]
Advanced

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

[debbugs-tracker] bug#9643: closed (24.0.90; pcomplete/tar and complete-


From: GNU bug Tracking System
Subject: [debbugs-tracker] bug#9643: closed (24.0.90; pcomplete/tar and complete-within)
Date: Sun, 02 Oct 2011 01:04:03 +0000

Your message dated Sat, 01 Oct 2011 21:01:43 -0400
with message-id <address@hidden>
and subject line Re: bug#9643: 24.0.90; pcomplete/tar and complete-within
has caused the debbugs.gnu.org bug report #9643,
regarding 24.0.90; pcomplete/tar and complete-within
to be marked as done.

(If you believe you have received this mail in error, please contact
address@hidden)


-- 
9643: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9643
GNU Bug Tracking System
Contact address@hidden with problems
--- Begin Message --- Subject: 24.0.90; pcomplete/tar and complete-within Date: Sat, 1 Oct 2011 02:05:05 +0200
    $ touch foo bar
    $ tar cf test.tar foo bar
    $ emacs -Q -f shell
    tar xf test. TAB

yields

    Error in post-command-hook (completion-in-region--postch):
    (wrong-type-argument listp [tar-header #<marker at 513 in  *tar-data
    test.tar*> foo 436 324 324 0 (20102 20143) 5077 nil  ustar  starback
    starback 0 0 nil])

I expected getting a completion of ".tar " to my command.

Reason: pcomplete/tar in pcmpl-gnu.el has an erroneous notion of how
tar-parse-info entries look like.

With this fix the example above will work, and it can complete "foo" and
"bar" inside the tar file as arguments after "test.tar":

----------------------------------------------------------------------
$ diff -u pcmpl-gnu.el~ pcmpl-gnu.el
--- pcmpl-gnu.el~       2011-01-26 17:16:33.000000000 +0100
+++ pcmpl-gnu.el        2011-10-01 01:24:45.000000000 +0200
@@ -298,7 +298,7 @@
                  (mapcar
                   (function
                    (lambda (entry)
-                     (tar-header-name (cdr entry))))
+                     (tar-header-name entry)))
                   tar-parse-info))
              (pcomplete-entries))
            nil 'identity))))
----------------------------------------------------------------------

I don't totally like this anyway. I get an extra buffer for "test.tar"
even though I never explicitly opened the file.

Next problem, also in "*shell*", when I have a large tar file,
in this case emacs-24.0.90.tar.gz:

    tar xf emacs-24.0.90.t TAB

yields (with the patch above) completion and a question

    File emacs-24.0.90.tar.gz is large (48MB), really open? (y or n)

This was what I first encountered, and not knowing about pcomplete
beforehand I was really surprised, as I had no intention of opening that
file in Emacs. Even if I had known about it I wouldn't have liked
this. I was only trying to complete the tar filename!

* In both my examples I'm trying to complete the tar filename, and it
  looked inside it to prepare for doing completion of arguments after
  this. If it only opened the tar file if I actually tried to complete
  more arguments *after* the tar filename it would be a lot better.



--- End Message ---
--- Begin Message --- Subject: Re: bug#9643: 24.0.90; pcomplete/tar and complete-within Date: Sat, 01 Oct 2011 21:01:43 -0400 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.90 (gnu/linux)
>> * In both my examples I'm trying to complete the tar filename, and it
>> looked inside it to prepare for doing completion of arguments after
>> this. If it only opened the tar file if I actually tried to complete
>> more arguments *after* the tar filename it would be a lot better.
> I agree.

I've installed the patch below, which should fix this problem.


        Stefan


=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog      2011-10-02 00:25:27 +0000
+++ lisp/ChangeLog      2011-10-02 00:59:53 +0000
@@ -1,3 +1,11 @@
+2011-10-02  Stefan Monnier  <address@hidden>
+
+       * pcmpl-gnu.el (pcmpl-gnu-with-file-buffer): New macro (bug#9643).
+       (pcmpl-gnu-tar-buffer): Remove.
+       (pcmpl-gnu-with-file-buffer): Use it to avoid leaving the tar's buffer
+       avoid.  Make sure pcomplete-suffix-list is only changed temporarily.
+       Don't look inside the tar's file is it's too large.
+
 2011-10-01  Chong Yidong  <address@hidden>
 
        * cus-edit.el (custom-mode-map):

=== modified file 'lisp/pcmpl-gnu.el'
--- lisp/pcmpl-gnu.el   2011-10-01 02:38:46 +0000
+++ lisp/pcmpl-gnu.el   2011-10-02 00:56:47 +0000
@@ -128,22 +128,36 @@
   :type 'regexp
   :group 'pcmpl-gnu)
 
-(defvar pcmpl-gnu-tar-buffer nil)
-
 ;; Only used in tar-mode buffers.
 (defvar tar-parse-info)
 (declare-function tar-header-name "tar-mode" t t)
 
+(defmacro pcmpl-gnu-with-file-buffer (file &rest body)
+  "Run BODY inside a buffer visiting FILE."
+  (declare (debug t) (indent 1))
+  (let ((exist (make-symbol "exist"))
+        (filesym (make-symbol "file"))
+        (buf (make-symbol "buf")))
+    `(let* ((,filesym ,file)
+            (,exist (find-buffer-visiting ,filesym))
+            (,buf (or ,exist (find-file-noselect ,filesym))))
+       (unwind-protect
+           (with-current-buffer ,buf
+             ,@body)
+         (when (and (not ,exist) (buffer-live-p ,buf))
+           (kill-buffer ,buf))))))
+
 ;;;###autoload
 (defun pcomplete/tar ()
   "Completion for the GNU tar utility."
   ;; options that end in an equal sign will want further completion...
   (let (saw-option complete-within)
-    (setq pcomplete-suffix-list (cons ?= pcomplete-suffix-list))
+    (let ((pcomplete-suffix-list (cons ?= pcomplete-suffix-list)))
     (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="
@@ -281,8 +295,7 @@
                         (pcomplete-match-string 1 0)))
        ((pcomplete-match "\\`--volno-file=\\(.*\\)" 0)
        (pcomplete-here* (pcomplete-entries)
-                        (pcomplete-match-string 1 0)))))
-    (setq pcomplete-suffix-list (cdr pcomplete-suffix-list))
+                           (pcomplete-match-string 1 0))))))
     (unless saw-option
       (pcomplete-here
        (mapcar 'char-to-string
@@ -291,15 +304,16 @@
       (if (pcomplete-match "[xt]" 'first 1)
          (setq complete-within t)))
     (pcomplete-here (pcomplete-dirs-or-entries pcmpl-gnu-tarfile-regexp))
-    (setq pcmpl-gnu-tar-buffer (find-file-noselect (pcomplete-arg 1)))
     (while (pcomplete-here
-           (if complete-within
-               (with-current-buffer pcmpl-gnu-tar-buffer
-                 (mapcar
-                  (function
-                   (lambda (entry)
-                     (tar-header-name entry)))
-                  tar-parse-info))
+           (if (and complete-within
+                     (let* ((fa (file-attributes (pcomplete-arg 1)))
+                            (size (nth 7 fa)))
+                       (and (numberp size)
+                            (< size large-file-warning-threshold))))
+                (completion-table-dynamic
+                 (lambda (string)
+                   (pcmpl-gnu-with-file-buffer (pcomplete-arg 1)
+                     (mapcar #'tar-header-name tar-parse-info))))
              (pcomplete-entries))
            nil 'identity))))
 



--- End Message ---

reply via email to

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