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

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

bug#9643: 24.0.90; pcomplete/tar and complete-within


From: Stefan Monnier
Subject: 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  <monnier@iro.umontreal.ca>
+
+       * 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  <cyd@stupidchicken.com>
 
        * 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))))
 





reply via email to

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