Anonymous avatar Anonymous committed 971d827

Import author version 1.1.6

Comments (0)

Files changed (13)

+2000-03-06  John Wiegley  <johnw@gnu.org>
+
+	* pcmpl-gnu.el (pcomplete/tar): use tar-mode to read the contents
+	of a tar file.  Only complete names internal to the tar file in
+	extraction mode.  Otherwise, complete against filesystem entries.
+
+2000-03-03  John Wiegley  <johnw@gnu.org>
+
+	* pcomplete.el (pcomplete-window-restore-timer): this variable
+	needs to be buffer local.
+
+2000-02-10  John Wiegley  <johnw@gnu.org>
+
+	* pcomplete.el: Released 1.1.3.
+
+	* pcmpl-linux.el (pcomplete/umount): Fixed a mispelling, which
+	caused an unknown function to be called.
+
+2000-02-03  John Wiegley  <johnw@gnu.org>
+
+	* pcomplete.el: Released 1.1.2.
+
+	* pcomplete.el (pcomplete-do-complete): improved the paring
+	algorithm, since it wasn't working in all cases (especially when
+	symlinks were involved).
+
+	* pcmpl-unix.el (pcomplete/rm): don't pare symbolic links, since
+	the user might want to remove both the link, and what it points
+	to.
+
+	* pcmpl-gnu.el: added completion support for bzip2.
+
+	* Makefile: removed unnecessary `add-to-list' code.
+	(install_elc): install pcmpl-auto.el.
+
+	* INSTALL: added this file.
+
+1999-12-06  John Wiegley  <johnw@gnu.org>
+
+	* pcomplete.el (pcomplete-version): Released 1.1.1.
+
+	* pcomplete.el (pcomplete-dirs-or-entries): in the first call to
+	`pcomplete-entries', `pcomplete-stub' needs to be guarded from
+	change
+	(pcomplete-version): added version variable
+
+	* pcmpl-gnu.el (pcomplete/gzip): made the completions for 'gzip
+	-t' the same as that for 'gzip -d'
+Installing Pcomplete
+====================
+
+1. Edit the file `Makefile' in the directory containing the Pcomplete
+   sources to reflect the location of certain Emacs dircetories at
+   your site.  The only things you really have to change is the
+   definitions of `lispdir'.  The elisp files will be copied to
+   `lispdir'.
+
+2. Type `make install' in the directory containing the Pcomplete
+   sources.  This will byte-compile all of the `.el' files and copy
+   both the source and compiled versions to the directories specified
+   in the previous step.
+
+   If you only want to create the compiled elisp files, but don't want
+   to install them, you can type just `make' instead.
+
+3. Add the directory into which Pcomplete was installed to your
+   `load-path' variable.  This can be done by adding the following
+   line to your .emacs file:
+
+     (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/pcomplete")
+
+   The actual directory on your system may differ.
+
+4. To install Pcomplete privately, edit your .emacs file; to install
+   Pcomplete site-wide, edit the file `site-start.el' in your
+   site-lisp directory (usually `/usr/local/share/emacs/site-lisp' or
+   something similar).  In either case enter the following line into
+   the appropriate file:
+
+     (load "pcmpl-auto")
+
+5. Restart Emacs.
+# Makefile for pcomplete
+
+# This file is part of XEmacs.
+
+# XEmacs is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+
+# XEmacs is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with XEmacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+VERSION = 1.01
+AUTHOR_VERSION = 1.1.6
+MAINTAINER = John Wiegley <johnw@gnu.org>
+PACKAGE = pcomplete
+PKG_TYPE = regular
+REQUIRES = sh-script
+CATEGORY = os
+
+ELCS = pcmpl-cvs.elc pcmpl-gnu.elc pcmpl-linux.elc \
+	pcmpl-maint.elc pcmpl-rpm.elc pcmpl-unix.elc pcomplete.elc
+DATA_FILES = 
+DATA_DEST =
+EXTRA_SOURCES =
+
+include ../../XEmacs.rules
+
+GENERATED += custom-load.elc
+
+all:: $(ELCS) auto-autoloads.elc custom-load.elc
+
+srckit: srckit-std
+
+binkit: binkit-common

Makefile.upstream

+# Makefile for pcomplete lisp code
+
+# Copyright (C) 1998-1999  John Wiegley <johnw@gnu.org>
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+
+# This file is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+prefix  = /usr/local
+datadir = $(prefix)/share
+
+# the directory where you install third-party emacs packges
+lispdir = $(datadir)/emacs/site-lisp
+
+# the directory where you install the info doc
+infodir = $(prefix)/info
+docdir = $(prefix)/doc
+
+EMACS	= emacs
+MAKEINFO= makeinfo
+TEXI2DVI= texi2dvi
+SHELL	= /bin/sh
+DVIPS	= dvips
+CP	= cp
+MKDIR	= mkdir -p
+ETAGS	= etags
+
+######################################################################
+###        No changes below this line should be necessary          ###
+######################################################################
+
+PACKAGE = pcomplete
+
+# the directory where the .elc files will be installed
+elcdir  = $(lispdir)/$(PACKAGE)
+eldir   = $(elcdir)
+
+MARGS   = --no-init-file --no-site-file -l ./pcmpl-maint.el -batch
+BEMACS  = $(EMACS) $(MARGS)
+ELC	= $(BEMACS) -f batch-byte-compile
+
+ELFILES =		\
+	pcomplete.el	\
+	pcmpl-cvs.el	\
+	pcmpl-gnu.el	\
+	pcmpl-linux.el	\
+	pcmpl-rpm.el	\
+	pcmpl-unix.el
+
+ELCFILES = $(ELFILES:.el=.elc)
+
+TEXEXTS =  *.cps *.fns *.kys *.vr *.tp *.pg *.log *.aux *.toc *.cp *.ky *.fn
+
+.SUFFIXES: .elc .el
+.PHONY: elcfiles clean distclean default
+.PHONY: install_elc install install_el
+
+.el.elc:
+	$(ELC) $<
+
+######################################################################
+
+default: pcmpl-auto.el elcfiles
+
+elcfiles: Makefile $(ELCFILES)
+
+install_elc: $(ELCFILES) pcmpl-auto.el _pkg.el
+	$(MKDIR) $(elcdir)
+	$(CP) $(ELCFILES) auto-autoloads.el pcmpl-auto.el _pkg.el $(elcdir)/
+
+install_el:
+	$(MKDIR) $(eldir)
+	$(CP) $(ELFILES) $(eldir)/
+
+install: install_elc install_el
+
+clean:
+	$(RM) *~ core .\#* $(TEXEXTS)
+
+TAGS tags:
+	$(ETAGS) $(ELFILES)
+
+distclean: clean
+	$(RM) *.elc TAGS
+	$(RM) pcmpl-auto.el* auto-autoloads.el*
+
+pcmpl-auto.el: $(ELFILES)
+	echo ";;; DO NOT MODIFY THIS FILE" > pcmpl-auto.el
+	echo "(if (featurep 'pcmpl-auto) (error \"Already loaded\"))" \
+		>> pcmpl-auto.el
+	$(BEMACS) -f pcomplete-generate-autoloads ./pcmpl-auto.el .
+	echo "(provide 'pcmpl-auto)" >> pcmpl-auto.el
+	ln pcmpl-auto.el auto-autoloads.el
+
+TAG = $(shell echo v$(VERSION) | tr '.' '_')
+ftpdir=/home/johnw/public_html/Emacs/packages
+
+dist:
+	cvs tag -F $(TAG) &&\
+	cd /tmp &&\
+	cvs export -r $(TAG) -d $(PACKAGE)-$(VERSION) $(PACKAGE) &&\
+	cd $(PACKAGE)-$(VERSION) &&\
+	make pcmpl-auto.el &&\
+	chmod ugo+rX * &&\
+	cd .. &&\
+	tar cvzf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) &&\
+	zip -r $(PACKAGE)-$(VERSION).zip $(PACKAGE)-$(VERSION) &&\
+	rm -rf $(PACKAGE)-$(VERSION)
+	mv /tmp/$(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/
+	mv /tmp/$(PACKAGE)-$(VERSION).zip $(ftpdir)/
+	ln -sf $(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/$(PACKAGE).tar.gz
+	ln -sf $(PACKAGE)-$(VERSION).zip $(ftpdir)/$(PACKAGE).zip
+pcomplete provides a facility for using programmatic completion in
+Emacs.	It is especially useful for utilities like shells and command
+interpretors, but can in fact be used anywhere within Emacs.
+
+The simple way to begin using pcomplete is with comint-derived modes.
+To do this, add the following to that mode's mode-hook.	 shell-mode is
+given as an example:
+
+  (load "pcmpl-auto")
+  (add-hook 'shell-mode-hook 'pcomplete-shell-setup)
+
+Now just type `M-x shell' and press TAB.  Enter a command name, like
+"cvs", and press TAB again.  You should see a context-sensitive list
+of completions for the first argument (which for cvs is the command
+argument).
+
+			John Wiegley <johnw@gnu.org>
+			http://www.emacs.org/~johnw/emacs.html
+(eterm
+  (standards-version 1.1
+   version VERSION
+   author-version AUTHOR_VERSION
+   date DATE
+   build-date BUILD_DATE
+   maintainer MAINTAINER
+   distribution xemacs
+   priority medium
+   category CATEGORY
+   dump nil
+   description "Provides programmatic completion."
+   filename FILENAME
+   md5sum MD5SUM
+   size SIZE
+   provides (pcomplete)
+   requires (REQUIRES)
+   type regular
+))
+;;; pcmpl-cvs --- functions for dealing with cvs completions
+
+;; Copyright (C) 1999, 2000 Free Software Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; These functions provide completion rules for the `cvs' tool.
+
+;;; Code:
+
+(provide 'pcmpl-cvs)
+
+(require 'pcomplete)
+(require 'executable)
+
+(defgroup pcmpl-cvs nil
+  "Functions for dealing with CVS completions"
+  :group 'pcomplete)
+
+;; User Variables:
+
+(defcustom pcmpl-cvs-binary (or (executable-find "cvs") "cvs")
+  "*The full path of the 'cvs' binary."
+  :type 'file
+  :group 'pcmpl-cvs)
+
+;; Functions:
+
+;;;###autoload
+(defun pcomplete/cvs ()
+  "Completion rules for the `cvs' command."
+  (let ((pcomplete-help "(cvs)Invoking CVS"))
+    (pcomplete-opt "HQqrwlntvfab/T/e*d/z?s")
+    (pcomplete-here* (pcmpl-cvs-commands))
+    (cond ((pcomplete-test "add")
+	   (setq pcomplete-help "(cvs)Adding files")
+	   (pcomplete-opt "k?m?")
+	   (while (pcomplete-here (pcmpl-cvs-entries '(??)))))
+	  ((pcomplete-test "remove")
+	   (setq pcomplete-help "(cvs)Removing files")
+	   (pcomplete-opt "flR")
+	   (while (pcomplete-here (pcmpl-cvs-entries '(?U)))))
+	  ((pcomplete-test "init")
+	   (setq pcomplete-help "(cvs)Creating a repository"))
+	  ((pcomplete-test '("login" "logout"))
+	   (setq pcomplete-help "(cvs)Password authentication client"))
+	  ((pcomplete-test "import")
+	   (setq pcomplete-help "(cvs)import")
+	   (pcomplete-opt "dk?I(pcmpl-cvs-entries '(??))b?m?W?"))
+	  ((pcomplete-test "checkout")
+	   (setq pcomplete-help "(cvs)checkout")
+	   (pcomplete-opt "ANPRcflnpsr?D?d/k?j?")
+	   (pcomplete-here (pcmpl-cvs-modules)))
+	  ((pcomplete-test "rtag")
+	   (setq pcomplete-help "(cvs)Creating a branch")
+	   (pcomplete-opt "aflRndbr?DF")
+	   (pcomplete-here (pcmpl-cvs-modules)))
+	  ((pcomplete-test "release")
+	   (setq pcomplete-help "(cvs)release")
+	   (pcomplete-opt "d")
+	   (while (pcomplete-here (pcomplete-dirs))))
+	  ((pcomplete-test "export")
+	   (setq pcomplete-help "(cvs)export")
+	   (pcomplete-opt "NflRnr?D?d/k?")
+	   (pcomplete-here (pcmpl-cvs-modules)))
+	  ((pcomplete-test "commit")
+	   (setq pcomplete-help "(cvs)commit files")
+	   (pcomplete-opt "nRlfF.m?r(pcmpl-cvs-tags '(?M ?R ?A))")
+	   (while (pcomplete-here (pcmpl-cvs-entries '(?M ?R ?A)))))
+	  ((pcomplete-test "diff")
+	   (setq pcomplete-help "(cvs)Viewing differences")
+	   (let ((opt-index pcomplete-index)
+		 saw-backdate)
+	     (pcomplete-opt "lRD?Nr(pcmpl-cvs-tags)")
+	     (while (< opt-index pcomplete-index)
+	       (if (pcomplete-match "^-[Dr]" (- pcomplete-index opt-index))
+		   (setq saw-backdate t opt-index pcomplete-index)
+		 (setq opt-index (1+ opt-index))))
+	     (while (pcomplete-here
+		     (pcmpl-cvs-entries (unless saw-backdate '(?M)))))))
+	  ((pcomplete-test "unedit")
+	   (setq pcomplete-help "(cvs)Editing files")
+	   (pcomplete-opt "lR")
+	   (while (pcomplete-here (pcmpl-cvs-entries '(?M ?R ?A)))))
+	  ((pcomplete-test "update")
+	   (setq pcomplete-help "(cvs)update")
+	   (pcomplete-opt
+	    (concat "APdflRpk?r(pcmpl-cvs-tags '(?U ?P))D?"
+		    "j(pcmpl-cvs-tags '(?U ?P))"
+		    "I(pcmpl-cvs-entries '(??))W?"))
+	   (while (pcomplete-here (pcmpl-cvs-entries '(?U ?P)))))
+	  (t
+	   (while (pcomplete-here (pcmpl-cvs-entries)))))))
+
+(defun pcmpl-cvs-commands ()
+  "Return a list of available CVS commands."
+  (with-temp-buffer
+    (call-process pcmpl-cvs-binary nil t nil "--help-commands")
+    (goto-char (point-min))
+    (let (cmds)
+      (while (re-search-forward "^\\s-+\\([a-z]+\\)" nil t)
+	(setq cmds (cons (match-string 1) cmds)))
+      (pcomplete-uniqify-list cmds))))
+
+(defun pcmpl-cvs-modules ()
+  "Return a list of available modules under CVS."
+  (with-temp-buffer
+    (call-process pcmpl-cvs-binary nil t nil "checkout" "-c")
+    (goto-char (point-min))
+    (let (entries)
+      (while (re-search-forward "\\(\\S-+\\)$" nil t)
+	(setq entries (cons (match-string 1) entries)))
+      (pcomplete-uniqify-list entries))))
+
+(defun pcmpl-cvs-tags (&optional opers)
+  "Return all the tags which could apply to the files related to OPERS."
+  (let ((entries (pcmpl-cvs-entries opers))
+	tags)
+    (with-temp-buffer
+      (apply 'call-process pcmpl-cvs-binary nil t nil
+	     "status" "-v" entries)
+      (goto-char (point-min))
+      (while (re-search-forward "Existing Tags:" nil t)
+	(forward-line)
+	(while (not (looking-at "^$"))
+	  (unless (looking-at "^\\s-+\\(\\S-+\\)\\s-+")
+	    (error "Error in output from `cvs status -v'"))
+	  (setq tags (cons (match-string 1) tags))
+	  (forward-line))))
+    (pcomplete-uniqify-list tags)))
+
+(defun pcmpl-cvs-entries (&optional opers)
+  "Return the Entries for the current directory.
+If OPERS is a list of characters, return entries for which that
+operation character applies, as displayed by 'cvs -n update'."
+  (let* ((arg (pcomplete-arg))
+	 (dir (file-name-as-directory
+	       (or (file-name-directory arg) "")))
+	 (nondir (or (file-name-nondirectory arg) ""))
+	 entries)
+    (if opers
+	(with-temp-buffer
+	  (and dir (cd dir))
+	  (call-process pcmpl-cvs-binary nil t nil
+			"-q" "-n" "-f" "update"); "-l")
+	  (goto-char (point-min))
+	  (while (re-search-forward "^\\(.\\) \\(.+\\)$" nil t)
+	    (if (memq (string-to-char (match-string 1)) opers)
+		(setq entries (cons (match-string 2) entries)))))
+      (with-temp-buffer
+	(insert-file-contents (concat dir "CVS/Entries"))
+	(goto-char (point-min))
+	(while (not (eobp))
+	  (let* ((line (buffer-substring (line-beginning-position)
+					 (line-end-position)))
+		 (fields (split-string line "/"))
+		 text)
+	    (if (eq (aref line 0) ?/)
+		(setq fields (cons "" fields)))
+	    (setq text (nth 1 fields))
+	    (when text
+	      (if (string= (nth 0 fields) "D")
+		  (setq text (file-name-as-directory text)))
+	      (setq entries (cons text entries))))
+	  (forward-line))))
+    (setq pcomplete-stub nondir)
+    (pcomplete-uniqify-list entries)))
+
+;;; pcmpl-cvs.el ends here
+;;; pcmpl-gnu --- completions for GNU project tools
+
+;; Copyright (C) 1999, 2000 Free Software Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(provide 'pcmpl-gnu)
+
+(require 'pcomplete)
+(require 'pcmpl-unix)
+
+(defgroup pcmpl-gnu nil
+  "Completions for GNU project tools."
+  :group 'pcomplete)
+
+;; User Variables:
+
+(defcustom pcmpl-gnu-makefile-regexps
+  '("\\`GNUmakefile" "\\`Makefile" "\\.mak\\'")
+  "*A list of regexps that will match Makefile names."
+  :type '(repeat regexp)
+  :group 'pcmpl-gnu)
+
+;; Functions:
+
+;;;###autoload
+(defun pcomplete/gzip ()
+  "Completion for `gzip'."
+  (let ((pcomplete-help "(gzip)"))
+    (pcomplete-opt "cdfhlLnNqrStvV123456789")
+    (while (pcomplete-here
+	    (pcmpl-gnu-zipped-files
+	     (catch 'has-d-flag
+	       (let ((args pcomplete-args))
+		 (while args
+		   (if (string-match "\\`-.*[dt]" (car args))
+		       (throw 'has-d-flag t))
+		   (setq args (cdr args))))))))))
+
+(defun pcmpl-gnu-zipped-files (unzip-p)
+  "Find all zipped or unzipped files: the inverse of UNZIP-P."
+  (pcomplete-entries
+   nil
+   (function
+    (lambda (entry)
+      (when (and (file-readable-p entry)
+		 (file-regular-p entry))
+	(let ((zipped (string-match "\\.\\(t?gz\\|\\(ta\\)?Z\\)\\'"
+				    entry)))
+	  (or (and unzip-p zipped)
+	      (and (not unzip-p) (not zipped)))))))))
+
+;;;###autoload
+(defun pcomplete/bzip2 ()
+  "Completion for `bzip2'."
+  (pcomplete-opt "hdzkftcqvLVs123456789")
+  (while (pcomplete-here
+	  (pcmpl-gnu-bzipped-files
+	   (catch 'has-d-flag
+	     (let ((args pcomplete-args))
+	       (while args
+		 (if (string-match "\\`-.*[dt]" (car args))
+		     (throw 'has-d-flag t))
+		 (setq args (cdr args)))))))))
+
+(defun pcmpl-gnu-bzipped-files (unzip-p)
+  "Find all zipped or unzipped files: the inverse of UNZIP-P."
+  (pcomplete-entries
+   nil
+   (function
+    (lambda (entry)
+      (when (and (file-readable-p entry)
+		 (file-regular-p entry))
+	(let ((zipped (string-match "\\.\\(t?z2\\|bz2\\)\\'" entry)))
+	  (or (and unzip-p zipped)
+	      (and (not unzip-p) (not zipped)))))))))
+
+;;;###autoload
+(defun pcomplete/make ()
+  "Completion for GNU `make'."
+  (let ((pcomplete-help "(make)Top"))
+    (pcomplete-opt "bmC/def(pcmpl-gnu-makefile-names)hiI/j?kl?no.pqrsStvwW.")
+    (while (pcomplete-here (pcmpl-gnu-make-rule-names) nil 'identity))))
+
+(defun pcmpl-gnu-makefile-names ()
+  "Return a list of possible makefile names."
+  (let ((names (list t))
+	(reg pcmpl-gnu-makefile-regexps))
+    (while reg
+      (nconc names (pcomplete-entries (car reg)))
+      (setq reg (cdr reg)))
+    (cdr names)))
+
+(defun pcmpl-gnu-make-rule-names ()
+  "Return a list of possible make rule names in MAKEFILE."
+  (let* ((minus-f (member "-f" pcomplete-args))
+	 (makefile (or (cadr minus-f)
+		       (if (file-exists-p "GNUmakefile")
+			   "GNUmakefile"
+			 "Makefile")))
+	 rules)
+    (if (not (file-readable-p makefile))
+	(unless minus-f (list "-f"))
+      (with-temp-buffer
+	(insert-file-contents-literally makefile)
+	(while (re-search-forward
+		(concat "^\\s-*\\([^\n#%.$][^:=\n]*\\)\\s-*:[^=]") nil t)
+	  (setq rules (append (split-string (match-string 1)) rules))))
+      (pcomplete-uniqify-list rules))))
+
+(defcustom pcmpl-gnu-tarfile-regexp
+  "\\.t\\(ar\\(\\.\\(gz\\|bz2\\|Z\\)\\)?\\|gz\\|a[zZ]\\|z2\\)\\'"
+  "*A regexp which matches any tar archive."
+  :type 'regexp
+  :group 'pcmpl-gnu)
+
+(defvar pcmpl-gnu-tar-buffer nil)
+
+;;;###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))
+    (while (pcomplete-match "^-" 0)
+      (setq saw-option t)
+      (if (pcomplete-match "^--" 0)
+	  (if (pcomplete-match "^--\\([^= \t\n\f]*\\)\\'" 0)
+	      (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 "\\`--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)))))
+    (setq pcomplete-suffix-list (cdr pcomplete-suffix-list))
+    (unless saw-option
+      (pcomplete-here
+       (mapcar 'char-to-string
+	       (string-to-list
+		"01234567ABCFGIKLMNOPRSTUVWXZbcdfghiklmoprstuvwxz")))
+      (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 (cdr entry))))
+		   tar-parse-info))
+	      (pcomplete-entries))
+	    nil 'identity))))
+
+;;;###autoload
+(defalias 'pcomplete/gdb 'pcomplete/xargs)
+
+;;; pcmpl-gnu.el ends here
+;;; pcmpl-linux --- functions for dealing with cvs completions
+
+;; Copyright (C) 1999, 2000 Free Software Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; These functions are for use with GNU/Linux.  Since they depend on a
+;; certain knowledge of the layout of such systems, they probably
+;; won't work very well on other operating systems.
+
+;;; Code:
+
+(provide 'pcmpl-linux)
+
+(require 'pcomplete)
+
+(defgroup pcmpl-linux nil
+  "Functions for dealing with GNU/Linux completions."
+  :group 'pcomplete)
+
+;; Functions:
+
+;;;###autoload
+(defun pcomplete/kill ()
+  "Completion for GNU/Linux `kill', using /proc filesystem."
+  (if (pcomplete-match "^-\\(.*\\)" 0)
+      (pcomplete-here
+       (pcomplete-uniqify-list
+	(split-string
+	 (pcomplete-process-result "kill" "-l")))
+       (pcomplete-match-string 1 0)))
+  (while (pcomplete-here
+	  (if (file-directory-p "/proc")
+	      (let ((default-directory "/proc/"))
+		(mapcar 'directory-file-name
+			(pcomplete-entries "[0-9]+/$"))))
+	  nil 'identity)))
+
+;;;###autoload
+(defun pcomplete/umount ()
+  "Completion for GNU/Linux `umount'."
+  (pcomplete-opt "hVafrnvt(pcmpl-linux-fs-types)")
+  (while (pcomplete-here (pcmpl-linux-mounted-directories)
+			 nil 'identity)))
+
+;;;###autoload
+(defun pcomplete/mount ()
+  "Completion for GNU/Linux `mount'."
+  (pcomplete-opt "hVanfFrsvwt(pcmpl-linux-fs-types)o?L?U?")
+  (while (pcomplete-here (pcomplete-entries) nil 'identity)))
+
+(defun pcmpl-linux-fs-types ()
+  "Return a list of available fs modules on GNU/Linux systems."
+  (let ((kernel-ver (pcomplete-process-result "uname" "-r")))
+    (mapcar
+     (function
+      (lambda (fsobj)
+	(substring fsobj 0 (- (length fsobj) 2))))
+     (let ((default-directory
+	     (concat "/lib/modules/" kernel-ver "/fs/")))
+       (pcomplete-entries "\\.o$")))))
+
+(defun pcmpl-linux-mounted-directories ()
+  "Return a list of mounted directory names."
+  (let (points)
+    (when (file-readable-p "/etc/mtab")
+      (with-temp-buffer
+	(insert-file-contents-literally "/etc/mtab")
+	(while (not (eobp))
+	  (let* ((line (buffer-substring (point) (line-end-position)))
+		 (args (split-string line " ")))
+	    (setq points (cons (nth 1 args) points)))
+	  (forward-line)))
+      (pcomplete-uniqify-list points))))
+
+(defun pcmpl-linux-mountable-directories ()
+  "Return a list of mountable directory names."
+  (let (points)
+    (when (file-readable-p "/etc/fstab")
+      (with-temp-buffer
+	(insert-file-contents-literally "/etc/fstab")
+	(while (not (eobp))
+	  (let* ((line (buffer-substring (point) (line-end-position)))
+		 (args (split-string line "\\s-+")))
+	    (setq points (cons (nth 1 args) points)))
+	  (forward-line)))
+      (pcomplete-pare-list
+       (pcomplete-uniqify-list points)
+       (cons "swap" (pcmpl-linux-mounted-directories))))))
+
+;;; pcmpl-linux.el ends here
+;;; pcmpl-maint --- init code for building pcomplete
+
+;; Copyright (C) 1999, 2000 Free Sofware Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(setq load-path (cons "." load-path))
+
+(require 'pcomplete)
+
+(defun pcomplete-generate-autoloads ()
+  (interactive)
+  (require 'autoload)
+  (setq generated-autoload-file
+	(expand-file-name (car command-line-args-left)))
+  (setq command-line-args-left (cdr command-line-args-left))
+  (batch-update-autoloads))
+
+;;; pcmpl-maint.el ends here
+;;; pcmpl-rpm --- functions for dealing with rpm completions
+
+;; Copyright (C) 1999, 2000 Free Software Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; These functions provide completion rules for RedHat's `rpm' tool.
+
+;;; Code:
+
+(provide 'pcmpl-rpm)
+
+(require 'pcomplete)
+
+(defgroup pcmpl-rpm nil
+  "Functions for dealing with CVS completions"
+  :group 'pcomplete)
+
+;; Functions:
+
+(defsubst pcmpl-rpm-packages ()
+  (split-string (pcomplete-process-result "rpm" "-q" "-a")))
+
+(defun pcmpl-rpm-all-query (flag)
+  (message "Querying all packages with `%s'..." flag)
+  (let ((pkgs (pcmpl-rpm-packages))
+	(provs (list t)))
+    (while pkgs
+      (nconc provs (split-string
+		    (pcomplete-process-result
+		     "rpm" "-q" (car pkgs) flag)))
+      (setq pkgs (cdr pkgs)))
+    (pcomplete-uniqify-list (cdr provs))))
+
+(defsubst pcmpl-rpm-files ()
+  (pcomplete-dirs-or-entries "\\.rpm\\'"))
+
+;;;###autoload
+(defun pcomplete/rpm ()
+  "Completion for RedHat's `rpm' command.
+These rules were taken from the output of `rpm --help' on a RedHat 6.1
+system.  They follow my interpretation of what followed, but since I'm
+not a major rpm user/builder, please send me any corrections you find.
+You can use \\[eshell-report-bug] to do so."
+  (let (mode)
+    (while (<= pcomplete-index pcomplete-last)
+      (unless mode
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (pcomplete-here*
+	     '("--addsign"
+	       "--checksig"
+	       "--erase"
+	       "--help"
+	       "--initdb"
+	       "--install"
+	       "--pipe"
+	       "--querytags"
+	       "--rebuild"
+	       "--rebuilddb"
+	       "--recompile"
+	       "--resign"
+	       "--rmsource"
+	       "--setperms"
+	       "--setugids"
+	       "--upgrade"
+	       "--verify"
+	       "--version"))
+	  (pcomplete-opt "vqVyiUebtK")))
+;     -b<stage> <spec>
+;     -t<stage> <tarball>    - build package, where <stage> is one of:
+;	  p                - prep (unpack sources and apply patches)
+;	  l                - list check (do some cursory checks on %files)
+;	  c                - compile (prep and compile)
+;	  i                - install (prep, compile, install)
+;	  b                - binary package (prep, compile, install, package)
+;	  a                - bin/src package (prep, compile, install, package)
+      (cond
+       ((or (eq mode 'query)
+	    (pcomplete-match "-[^-]*q"))
+	(setq mode 'query)
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       '("--changelog"
+		 "--dbpath"
+		 "--dump"
+		 "--ftpport"            ;nyi for the next four
+		 "--ftpproxy"
+		 "--httpport"
+		 "--httpproxy"
+		 "--provides"
+		 "--queryformat"
+		 "--rcfile"
+		 "--requires"
+		 "--root"
+		 "--scripts"
+		 "--triggeredby"
+		 "--whatprovides"
+		 "--whatrequires"))
+	      (cond
+	       ((pcomplete-test "--dbpath")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--queryformat")
+		(pcomplete-here*))
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))
+	       ((pcomplete-test "--root")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--scripts")
+		(if (pcomplete-match "^--\\(.*\\)" 0)
+		    (pcomplete-here* '("--triggers"))))
+	       ((pcomplete-test "--triggeredby")
+		(pcomplete-here* (pcmpl-rpm-packages)))
+	       ((pcomplete-test "--whatprovides")
+		(pcomplete-here*
+		 (pcmpl-rpm-all-query "--provides")))
+	       ((pcomplete-test "--whatrequires")
+		(pcomplete-here*
+		 (pcmpl-rpm-all-query "--requires")))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "af.p(pcmpl-rpm-files)ilsdcvR")
+	    (pcomplete-here (pcmpl-rpm-packages)))))
+       ((pcomplete-test "--pipe")
+	(pcomplete-here* (funcall pcomplete-command-completion-function)))
+       ((pcomplete-test "--rmsource")
+	(pcomplete-here* (pcomplete-entries))
+	(throw 'pcomplete-completions nil))
+       ((pcomplete-match "\\`--re\\(build\\|compile\\)\\'")
+	(pcomplete-here (pcmpl-rpm-files))
+	(throw 'pcomplete-completions nil))
+       ((pcomplete-match "\\`--\\(resign\\|addsign\\)\\'")
+	(while (pcomplete-here (pcmpl-rpm-files))))
+       ((or (eq mode 'checksig)
+	    (pcomplete-test "--checksig"))
+	(setq mode 'checksig)
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       '("--nopgp"
+		 "--nogpg"
+		 "--nomd5"
+		 "--rcfile"))
+	      (cond
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "v")
+	    (pcomplete-here (pcmpl-rpm-files)))))
+       ((or (eq mode 'rebuilddb)
+	    (pcomplete-test "--rebuilddb"))
+	(setq mode 'rebuilddb)
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       '("--dbpath"
+		 "--root"
+		 "--rcfile"))
+	      (cond
+	       ((pcomplete-test "--dbpath")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--root")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "v")
+	    (pcomplete-here))))
+       ((memq mode '(install upgrade))
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       (append
+		'("--allfiles"
+		  "--badreloc"
+		  "--dbpath"
+		  "--excludedocs"
+		  "--excludepath"
+		  "--force"
+		  "--hash"
+		  "--ignorearch"
+		  "--ignoreos"
+		  "--ignoresize"
+		  "--includedocs"
+		  "--justdb"
+		  "--nodeps"
+		  "--noorder"
+		  "--noscripts"
+		  "--notriggers")
+		(if (eq mode 'upgrade)
+		    '("--oldpackage"))
+		'("--percent"
+		  "--prefix"
+		  "--rcfile"
+		  "--relocate"
+		  "--replacefiles"
+		  "--replacepkgs"
+		  "--root")))
+	      (cond
+	       ((pcomplete-test "--dbpath")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--relocate")
+		(pcomplete-here*))
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))
+	       ((pcomplete-test "--excludepath")
+		(pcomplete-here* (pcomplete-entries)))
+	       ((pcomplete-test "--root")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--prefix")
+		(pcomplete-here* (pcomplete-dirs)))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "vh")
+	    (pcomplete-here (pcmpl-rpm-files)))))
+       ((or (pcomplete-test "--install")
+	    (pcomplete-match "-[^-]*i"))
+	(setq mode 'install))
+       ((or (pcomplete-test "--upgrade")
+	    (pcomplete-match "-[^-]*U"))
+	(setq mode 'upgrade))
+       ((or (eq mode 'erase)
+	    (pcomplete-test "--erase")
+	    (pcomplete-match "-[^-]*e"))
+	(setq mode 'erase)
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       '("--allmatches"
+		 "--dbpath"
+		 "--justdb"
+		 "--nodeps"
+		 "--noorder"
+		 "--noscripts"
+		 "--notriggers"
+		 "--rcfile"
+		 "--root"))
+	      (cond
+	       ((pcomplete-test "--dbpath")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))
+	       ((pcomplete-test "--root")
+		(pcomplete-here* (pcomplete-dirs)))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "v")
+	    (pcomplete-here (pcmpl-rpm-packages)))))
+       ((or (eq mode 'verify)
+	    (pcomplete-test "--verify"))
+	(setq mode 'verify)
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       '("--dbpath"
+		 "--nodeps"
+		 "--nofiles"
+		 "--nomd5"
+		 "--rcfile"
+		 "--root"
+		 "--triggeredby"
+		 "--whatprovides"
+		 "--whatrequires"))
+	      (cond
+	       ((pcomplete-test "--dbpath")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))
+	       ((pcomplete-test "--root")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--triggeredby")
+		(pcomplete-here* (pcmpl-rpm-packages)))
+	       ((pcomplete-test "--whatprovides")
+		(pcomplete-here*
+		 (pcmpl-rpm-all-query "--provides")))
+	       ((pcomplete-test "--whatrequires")
+		(pcomplete-here*
+		 (pcmpl-rpm-all-query "--requires")))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "af.p(pcmpl-rpm-files)v")
+	    (pcomplete-here (pcmpl-rpm-packages)))))
+       ((or (memq mode '(build test))
+	    (pcomplete-match "\\`-[bt]"))
+	(setq mode (if (pcomplete-match "\\`-b")
+		       'build
+		     'test))
+	(if (pcomplete-match "^--\\(.*\\)" 0)
+	    (progn
+	      (pcomplete-here*
+	       '("--buildroot"
+		 "--clean"
+		 "--nobuild"
+		 "--rcfile"
+		 "--rmsource"
+		 "--short-circuit"
+		 "--sign"
+		 "--target"
+		 "--timecheck"))
+	      (cond
+	       ((pcomplete-test "--buildroot")
+		(pcomplete-here* (pcomplete-dirs)))
+	       ((pcomplete-test "--rcfile")
+		(pcomplete-here* (pcomplete-entries)))
+	       ((pcomplete-test "--timecheck")
+		(pcomplete-here*))))
+	  (if (pcomplete-match "^-" 0)
+	      (pcomplete-opt "v")
+	    (pcomplete-here
+	     (if (eq mode 'test)
+		 (pcomplete-dirs-or-entries "\\.tar\\'")
+	       (pcomplete-dirs-or-entries "\\.spec\\'"))))))
+       (t
+	(error "You must select a mode: -q, -i, -U, --verify, etc."))))))
+
+;;; pcmpl-rpm.el ends here
+;;; pcmpl-unix --- standard UNIX completions
+
+;; Copyright (C) 1999, 2000 Free Software Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(provide 'pcmpl-unix)
+
+(require 'pcomplete)
+
+;; User Variables:
+
+(defcustom pcmpl-unix-group-file "/etc/group"
+  "*If non-nil, a string naming the group file on your system."
+  :type 'file
+  :group 'pcmpl-unix)
+
+(defcustom pcmpl-unix-passwd-file "/etc/passwd"
+  "*If non-nil, a string naming the passwd file on your system."
+  :type 'file
+  :group 'pcmpl-unix)
+
+;; Functions:
+
+;;;###autoload
+(defun pcomplete/cd ()
+  "Completion for `cd'."
+  (pcomplete-here (pcomplete-dirs)))
+
+;;;###autoload
+(defalias 'pcomplete/pushd 'pcomplete/cd)
+
+;;;###autoload
+(defun pcomplete/rmdir ()
+  "Completion for `rmdir'."
+  (while (pcomplete-here (pcomplete-dirs))))
+
+;;;###autoload
+(defun pcomplete/rm ()
+  "Completion for `rm'."
+  (let ((pcomplete-help "(fileutils)rm invocation"))
+    (pcomplete-opt "dfirRv")
+    (while (pcomplete-here (pcomplete-all-entries) nil
+			   'expand-file-name))))
+
+;;;###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)))
+
+;;;###autoload
+(defalias 'pcomplete/time 'pcomplete/xargs)
+
+;;;###autoload
+(defun pcomplete/which ()
+  "Completion for `which'."
+  (while (pcomplete-here (funcall pcomplete-command-completion-function))))
+
+(defun pcmpl-unix-read-passwd-file (file)
+  "Return an alist correlating gids to group names in FILE."
+  (let (names)
+    (when (file-readable-p file)
+      (with-temp-buffer
+	(insert-file-contents file)
+	(goto-char (point-min))
+	(while (not (eobp))
+	  (let* ((fields
+		  (split-string (buffer-substring
+				 (point) (progn (end-of-line)
+						(point))) ":")))
+	    (setq names (cons (nth 0 fields) names)))
+	  (forward-line))))
+    (pcomplete-uniqify-list names)))
+
+(defsubst pcmpl-unix-group-names ()
+  "Read the contents of /etc/group for group names."
+  (if pcmpl-unix-group-file
+      (pcmpl-unix-read-passwd-file pcmpl-unix-group-file)))
+
+(defsubst pcmpl-unix-user-names ()
+  "Read the contents of /etc/passwd for user names."
+  (if pcmpl-unix-passwd-file
+      (pcmpl-unix-read-passwd-file pcmpl-unix-passwd-file)))
+
+;;;###autoload
+(defun pcomplete/chown ()
+  "Completion for the `chown' command."
+  (unless (pcomplete-match "\\`-")
+    (if (pcomplete-match "\\`[^.]*\\'" 0)
+	(pcomplete-here* (pcmpl-unix-user-names))
+      (if (pcomplete-match "\\.\\([^.]*\\)\\'" 0)
+	  (pcomplete-here* (pcmpl-unix-group-names)
+			   (pcomplete-match-string 1 0))
+	(pcomplete-here*))))
+  (while (pcomplete-here (pcomplete-entries))))
+
+;;;###autoload
+(defun pcomplete/chgrp ()
+  "Completion for the `chgrp' command."
+  (unless (pcomplete-match "\\`-")
+    (pcomplete-here* (pcmpl-unix-group-names)))
+  (while (pcomplete-here (pcomplete-entries))))
+
+;;; pcmpl-unix.el ends here
+;;; pcomplete --- programmable completion
+
+;; Copyright (C) 1999, 2000 Free Sofware Foundation
+
+;; Author: John Wiegley <johnw@gnu.org>
+;; Keywords: processes
+;; X-URL: http://www.emacs.org/~johnw/emacs.html
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This module provides a programmable completion facility using
+;; "completion functions".  Each completion function is responsible
+;; for producing a list of possible completions relevant to the current
+;; argument position.
+;;
+;; To use pcomplete with shell-mode, for example, you will need the
+;; following in your .emacs file:
+;;
+;;   (load "pcmpl-auto")
+;;   (add-hook 'shell-mode-hook 'pcomplete-shell-setup)
+;;
+;; Most of the code below simply provides support mechanisms for
+;; writing completion functions.  Completion functions themselves are
+;; very easy to write.  They have few requirements beyond those of
+;; regular Lisp functions.
+;;
+;; Consider the following example, which will complete against
+;; filenames for the first two arguments, and directories for all
+;; remaining arguments:
+;;
+;;   (defun pcomplete/my-command ()
+;;     (pcomplete-here (pcomplete-entries))
+;;     (pcomplete-here (pcomplete-entries))
+;;     (while (pcomplete-here (pcomplete-dirs))))
+;;
+;; Here are the requirements for completion functions:
+;;
+;; @ They must be called "pcomplete/MAJOR-MODE/NAME", or
+;;   "pcomplete/NAME".  This is how they are looked up, using the NAME
+;;   specified in the command argument (the argument in first
+;;   position).
+;;
+;; @ They must be callable with no arguments.
+;;
+;; @ Their return value is ignored.  If they actually return normally,
+;;   it means no completions were available.
+;;
+;; @ In order to provide completions, they must throw the tag
+;;   `pcomplete-completions'.  The value must be the list of possible
+;;   completions for the final argument.
+;;
+;; @ To simplify completion function logic, the tag `pcompleted' may
+;;   be thrown with a value of nil in order to abort the function.  It
+;;   means that there were no completions available.
+;;
+;; When a completion function is called, the variable `pcomplete-args'
+;; is in scope, and contains all of the arguments specified on the
+;; command line.  The variable `pcomplete-last' is the index of the
+;; last argument in that list.
+;;
+;; The variable `pcomplete-index' is used by the completion code to
+;; know which argument the completion function is currently examining.
+;; It always begins at 1, meaning the first argument after the command
+;; name.
+;;
+;; To facilitate writing completion logic, a special macro,
+;; `pcomplete-here', has been provided which does several things:
+;;
+;;  1. It will throw `pcompleted' (with a value of nil) whenever
+;;     `pcomplete-index' exceeds `pcomplete-last'.
+;;
+;;  2. It will increment `pcomplete-index' if the final argument has
+;;     not been reached yet.
+;;
+;;  3. It will evaluate the form passed to it, and throw the result
+;;     using the `pcomplete-completions' tag, if it is called when
+;;     `pcomplete-index' is pointing to the final argument.
+;;
+;; Sometimes a completion function will want to vary the possible
+;; completions for an argument based on the previous one.  To
+;; facilitate tests like this, the function `pcomplete-test' and
+;; `pcomplete-match' are provided.  Called with one argument, they
+;; test the value of the previous command argument.  Otherwise, a
+;; relative index may be given as an optional second argument, where 0
+;; refers to the current argument, 1 the previous, 2 the one before
+;; that, etc.  The symbols `first' and `last' specify absolute
+;; offsets.
+;;
+;; Here is an example which will only complete against directories for
+;; the second argument if the first argument is also a directory:
+;;
+;;   (defun pcomplete/example ()
+;;      (pcomplete-here (pcomplete-entries))
+;;      (if (pcomplete-test 'file-directory-p)
+;;          (pcomplete-here (pcomplete-dirs))
+;;        (pcomplete-here (pcomplete-entries))))
+;;
+;; For generating completion lists based on directory contents, see
+;; the functions `pcomplete-entries', `pcomplete-dirs',
+;; `pcomplete-executables' and `pcomplete-all-entries'.
+;;
+;; Consult the documentation for `pcomplete-here' for information
+;; about its other arguments.
+
+;;; Code:
+
+(provide 'pcomplete)
+
+(defgroup pcomplete nil
+  "Programmable completion."
+  :group 'processes)
+
+;;; User Variables:
+
+(defcustom pcomplete-file-ignore nil
+  "*A regexp of filenames to be disregarded during file completion."
+  :type 'regexp
+  :group 'pcomplete)
+
+(defcustom pcomplete-dir-ignore nil
+  "*A regexp of names to be disregarded during directory completion."
+  :type 'regexp
+  :group 'pcomplete)
+
+(defcustom pcomplete-ignore-case (memq system-type '(ms-dos windows-nt))
+  "*If non-nil, ignore case when doing filename completion."
+  :type 'boolean
+  :group 'pcomplete)
+
+(defcustom pcomplete-autolist nil
+  "*If non-nil, automatically list possibilities on partial completion.
+This mirrors the optional behavior of tcsh."
+  :type 'boolean
+  :group 'pcomplete)
+
+(defcustom pcomplete-suffix-list (list directory-sep-char ?:)
+  "*A list of characters which constitute a proper suffix."
+  :type '(repeat character)
+  :group 'pcomplete)
+
+(defcustom pcomplete-recexact nil
+  "*If non-nil, use shortest completion if characters cannot be added.
+This mirrors the optional behavior of tcsh.
+
+A non-nil value is useful if `pcomplete-autolist' is non-nil too."
+  :type 'boolean
+  :group 'pcomplete)
+
+(defcustom pcomplete-arg-quote-list nil
+  "*List of characters to quote when completing an argument."
+  :type '(choice (repeat character)
+		 (const :tag "Don't quote" nil))
+  :group 'pcomplete)
+
+(defcustom pcomplete-quote-arg-hook nil
+  "*A hook which is run to quote a character within a filename.
+Each function is passed both the filename to be quoted, and the index
+to be considered.  If the function wishes to provide an alternate
+quoted form, it need only return the replacement string.  If no
+function provides a replacement, quoting shall proceed as normal,
+using a backslash to quote any character which is a member of
+`pcomplete-arg-quote-list'."
+  :type 'hook
+  :group 'pcomplete)
+
+(defcustom pcomplete-man-function 'man
+  "*A function to that will be called to display a manual page.
+It will be passed the name of the command to document."
+  :type 'function
+  :group 'pcomplete)
+
+(defcustom pcomplete-compare-entry-function 'string-lessp
+  "*This function is used to order file entries for completion.
+The behavior of most all shells is to sort alphabetically."
+  :type '(radio (function-item string-lessp)
+		(function-item file-newer-than-file-p)
+		(function :tag "Other"))
+  :group 'pcomplete)
+
+(defcustom pcomplete-help nil
+  "*A string or function (or nil) used for context-sensitive help.
+If a string, it should name an Info node that will be jumped to.
+If non-nil, it must a sexp that will be evaluated, and whose
+result will be shown in the minibuffer.
+If nil, the function `pcomplete-man-function' will be called with the
+current command argument."
+  :type '(choice string sexp (const :tag "Use man page" nil))
+  :group 'pcomplete)
+
+(defcustom pcomplete-expand-before-complete nil
+  "*If non-nil, expand the current argument before completing it.
+This means that typing something such as '$HOME/bi' followed by
+\\[pcomplete-argument] will cause the variable reference to be
+resolved first, and the resultant value that will be completed against
+to be inserted in the buffer.  Note that exactly what gets expanded
+and how is entirely up to the behavior of the
+`pcomplete-parse-arguments-function'."
+  :type 'boolean
+  :group 'pcomplete)
+
+(defcustom pcomplete-parse-arguments-function
+  'pcomplete-parse-buffer-arguments
+  "*A function to call to parse the current line's arguments.
+It should be called with no parameters, and with point at the position
+of the argument that is to be completed.
+
+It must either return nil, or a cons cell of the form:
+
+  ((ARG...) (BEG-POS...))
+
+The two lists must be identical in length.  The first gives the final
+value of each command line argument (which need not match the textual
+representation of that argument), and BEG-POS gives the beginning
+position of each argument, as it is seen by the user.  The establishes
+a relationship between the fully resolved value of the argument, and
+the textual representation of the argument."
+  :type 'function
+  :group 'pcomplete)
+
+(defcustom pcomplete-cycle-completions t
+  "*If non-nil, hitting the TAB key cycles through the completion list.
+Typical Emacs behavior is to complete as much as possible, then pause
+waiting for further input.  Then if TAB is hit again, show a list of
+possible completions.  When `pcomplete-cycle-completions' is non-nil,
+it acts more like zsh or 4nt, showing the first maximal match first,
+followed by any further matches on each subsequent pressing of the TAB
+key.  \\[pcomplete-list] is the key to press if the user wants to see
+the list of possible completions."
+  :type 'boolean
+  :group 'pcomplete)
+
+(defcustom pcomplete-cycle-cutoff-length 5
+  "*If the number of completions is greater than this, don't cycle.
+This variable is a compromise between the traditional Emacs style of
+completion, and the \"cycling\" style.  Basically, if there are more
+than this number of completions possible, don't automatically pick the
+first one and then expect the user to press TAB to cycle through them.
+Typically, when there are a large number of completion possibilities,
+the user wants to see them in a list buffer so that they can know what
+options are available.  But if the list is small, it means the user
+has already entered enough input to disambiguate most of the
+possibilities, and therefore they are probably most interested in
+cycling through the candidates.  Set this value to nil if you want
+cycling to always be enabled."
+  :type '(choice integer (const :tag "Always cycle" nil))
+  :group 'pcomplete)
+
+(defcustom pcomplete-restore-window-delay 1
+  "*The number of seconds to wait before restoring completion windows.
+Once the completion window has been displayed, if the user then goes
+on to type something else, that completion window will be removed from
+the display (actually, the original window configuration before it was
+displayed will be restored), after this many seconds of idle time.  If
+set to nil, completion windows will be left on second until the user
+removes them manually.  If set to 0, they will disappear immediately
+after the user enters a key other than TAB."
+  :type '(choice integer (const :tag "Never restore" nil))
+  :group 'pcomplete)
+
+(defcustom pcomplete-try-first-hook nil
+  "*A list of functions which are called before completing an argument.
+This can be used, for example, for completing things which might apply
+to all arguments, such as variable names after a $."
+  :type 'hook
+  :group 'pcomplete)
+
+(defcustom pcomplete-command-completion-function
+  (function
+   (lambda ()
+     (pcomplete-here (pcomplete-executables))))
+  "*Function called for completing the initial command argument."
+  :type 'function
+  :group 'pcomplete)
+
+(defcustom pcomplete-command-name-function 'pcomplete-command-name
+  "*Function called for determining the current command name."
+  :type 'function
+  :group 'pcomplete)
+
+(defcustom pcomplete-default-completion-function
+  (function
+   (lambda ()
+     (while (pcomplete-here (pcomplete-entries)))))
+  "*Function called when no completion rule can be found.
+This function is used to generate completions for every argument."
+  :type 'function
+  :group 'pcomplete)
+
+(defcustom pcomplete-use-paring t
+  "*If t, pare alternatives that have already been used.
+If nil, you will always see the completion set of possible options, no
+matter which of those options have already been used in previous
+command arguments."
+  :type 'boolean
+  :group 'pcomplete)
+
+;;; Internal Variables:
+
+;; for cycling completion support
+(defvar pcomplete-current-completions nil)
+(defvar pcomplete-last-completion-length)
+(defvar pcomplete-last-completion-stub)
+(defvar pcomplete-last-completion-raw)
+(defvar pcomplete-last-window-config nil)
+(defvar pcomplete-window-restore-timer nil)
+
+(make-variable-buffer-local 'pcomplete-current-completions)
+(make-variable-buffer-local 'pcomplete-last-completion-length)
+(make-variable-buffer-local 'pcomplete-last-completion-stub)
+(make-variable-buffer-local 'pcomplete-last-completion-raw)
+(make-variable-buffer-local 'pcomplete-last-window-config)
+(make-variable-buffer-local 'pcomplete-window-restore-timer)
+
+;; used for altering pcomplete's behavior.  These global variables
+;; should always be nil.
+(defvar pcomplete-show-help nil)
+(defvar pcomplete-show-list nil)
+(defvar pcomplete-expand-only-p nil)
+
+;;; User Functions:
+
+;;;###autoload
+(defun pcomplete ()
+  "Support extensible programmable completion.
+To use this function, just bind the TAB key to it, or add it to your
+completion functions list (it should occur fairly early in the list)."
+  (interactive)
+  (if (and (interactive-p)
+	   pcomplete-cycle-completions
+	   pcomplete-current-completions
+	   (memq last-command '(pcomplete
+				pcomplete-expand-and-complete
+				pcomplete-reverse)))
+      (progn
+	(delete-backward-char pcomplete-last-completion-length)
+	(if (eq this-command 'pcomplete-reverse)
+	    (progn
+	      (setq pcomplete-current-completions
+		    (cons (car (last pcomplete-current-completions))
+			  pcomplete-current-completions))
+	      (setcdr (last pcomplete-current-completions 2) nil))
+	  (nconc pcomplete-current-completions
+		 (list (car pcomplete-current-completions)))
+	  (setq pcomplete-current-completions
+		(cdr pcomplete-current-completions)))
+	(pcomplete-insert-entry pcomplete-last-completion-stub
+				(car pcomplete-current-completions)
+				nil pcomplete-last-completion-raw))
+    (setq pcomplete-current-completions nil
+	  pcomplete-last-completion-raw nil)
+    (catch 'pcompleted
+      (let* ((pcomplete-stub)
+	     pcomplete-seen pcomplete-norm-func
+	     pcomplete-args pcomplete-last pcomplete-index
+	     (pcomplete-autolist pcomplete-autolist)
+	     (pcomplete-suffix-list pcomplete-suffix-list)
+	     (completions (pcomplete-completions))
+	     (result (pcomplete-do-complete pcomplete-stub completions)))
+	(and result
+	     (not (eq (car result) 'listed))
+	     (cdr result)
+	     (pcomplete-insert-entry pcomplete-stub (cdr result)
+				     (memq (car result)
+					   '(sole shortest))
+				     pcomplete-last-completion-raw))))))
+
+;;;###autoload
+(defun pcomplete-reverse ()
+  "If cycling completion is in use, cycle backwards."
+  (interactive)
+  (call-interactively 'pcomplete))
+
+;;;###autoload
+(defun pcomplete-expand-and-complete ()
+  "Expand the textual value of the current argument.
+This will modify the current buffer."
+  (interactive)
+  (let ((pcomplete-expand-before-complete t))
+    (pcomplete)))
+
+;;;###autoload
+(defun pcomplete-continue ()
+  "Complete without reference to any cycling completions."
+  (interactive)
+  (setq pcomplete-current-completions nil
+	pcomplete-last-completion-raw nil)
+  (call-interactively 'pcomplete))
+
+;;;###autoload
+(defun pcomplete-expand ()
+  "Expand the textual value of the current argument.
+This will modify the current buffer."
+  (interactive)
+  (let ((pcomplete-expand-before-complete t)
+	(pcomplete-expand-only-p t))
+    (pcomplete)
+    (when (and pcomplete-current-completions
+	       (> (length pcomplete-current-completions) 0))
+      (delete-backward-char pcomplete-last-completion-length)
+      (while pcomplete-current-completions
+	(unless (pcomplete-insert-entry
+		 "" (car pcomplete-current-completions) t
+		 pcomplete-last-completion-raw)
+	  (insert-and-inherit " "))
+	(setq pcomplete-current-completions
+	      (cdr pcomplete-current-completions))))))
+
+;;;###autoload
+(defun pcomplete-help ()
+  "Display any help information relative to the current argument."
+  (interactive)
+  (let ((pcomplete-show-help t))
+    (pcomplete)))
+
+;;;###autoload
+(defun pcomplete-list ()
+  "Show the list of possible completions for the current argument."
+  (interactive)
+  (when (and pcomplete-cycle-completions
+	     pcomplete-current-completions
+	     (eq last-command 'pcomplete-argument))
+    (delete-backward-char pcomplete-last-completion-length)
+    (setq pcomplete-current-completions nil
+	  pcomplete-last-completion-raw nil))
+  (let ((pcomplete-show-list t))
+    (pcomplete)))
+
+;;; Internal Functions:
+
+;; argument handling
+
+;; for the sake of the bye-compiler, when compiling other files that
+;; contain completion functions
+(defvar pcomplete-args nil)
+(defvar pcomplete-begins nil)
+(defvar pcomplete-last nil)
+(defvar pcomplete-index nil)
+(defvar pcomplete-stub nil)
+(defvar pcomplete-seen nil)
+(defvar pcomplete-norm-func nil)
+
+(defun pcomplete-arg (&optional index offset)
+  "Return the textual content of the INDEXth argument.
+INDEX is based from the current processing position.  If INDEX is
+positive, values returned are closer to the command argument; if
+negative, they are closer to the last argument.  If the INDEX is
+outside of the argument list, nil is returned.  The default value for
+INDEX is 0, meaning the current argument being examined.
+
+The special indices `first' and `last' may be used to access those
+parts of the list.
+
+The OFFSET argument is added to/taken away from the index that will be
+used.  This is really only useful with `first' and `last', for
+accessing absolute argument positions."
+  (setq index
+	(if (eq index 'first)
+	    0
+	  (if (eq index 'last)
+	      pcomplete-last
+	    (- pcomplete-index (or index 0)))))
+  (if offset
+      (setq index (+ index offset)))
+  (nth index pcomplete-args))
+
+(defun pcomplete-begin (&optional index offset)
+  "Return the beginning position of the INDEXth argument.
+See the documentation for `pcomplete-arg'."
+  (setq index
+	(if (eq index 'first)
+	    0
+	  (if (eq index 'last)
+	      pcomplete-last
+	    (- pcomplete-index (or index 0)))))
+  (if offset
+      (setq index (+ index offset)))
+  (nth index pcomplete-begins))
+
+(defsubst pcomplete-actual-arg (&optional index offset)
+  "Return the actual text representation of the last argument.
+This different from `pcomplete-arg', which returns the textual value
+that the last argument evaluated to.  This function returns what the
+user actually typed in."
+  (buffer-substring (pcomplete-begin index offset) (point)))
+
+(defsubst pcomplete-next-arg ()
+  "Move the various pointers to the next argument."
+  (setq pcomplete-index (1+ pcomplete-index)
+	pcomplete-stub (pcomplete-arg))
+  (if (> pcomplete-index pcomplete-last)
+      (progn
+	(message "No completions")
+	(throw 'pcompleted nil))))
+
+(defun pcomplete-command-name ()
+  "Return the command name of the first argument."
+  (file-name-nondirectory (pcomplete-arg 'first)))
+
+(defun pcomplete-match (regexp &optional index offset start)
+  "Like `string-match', but on the current completion argument."
+  (let ((arg (pcomplete-arg (or index 1) offset)))
+    (if arg
+	(string-match regexp arg start)
+      (throw 'pcompleted nil))))
+
+(defun pcomplete-match-string (which &optional index offset)
+  "Like `string-match', but on the current completion argument."
+  (let ((arg (pcomplete-arg (or index 1) offset)))
+    (if arg
+	(match-string which arg)
+      (throw 'pcompleted nil))))
+
+(defalias 'pcomplete-match-beginning 'match-beginning)
+(defalias 'pcomplete-match-end 'match-end)
+
+(defsubst pcomplete--test (pred arg)
+  "Perform a programmable completion predicate match."
+  (and pred
+       (cond ((eq pred t) t)
+	     ((functionp pred)
+	      (funcall pred arg))
+	     ((stringp pred)
+	      (string-match (concat "^" pred "$") arg)))
+       pred))
+
+(defun pcomplete-test (predicates &optional index offset)
+  "Predicates to test the current programmable argument with."
+  (let ((arg (pcomplete-arg (or index 1) offset)))
+    (unless (null predicates)
+      (if (not (listp predicates))
+	  (pcomplete--test predicates arg)
+	(let ((pred predicates)
+	      found)
+	  (while (and pred (not found))
+	    (setq found (pcomplete--test (car pred) arg)
+		  pred (cdr pred)))
+	  found)))))
+
+(defun pcomplete-parse-buffer-arguments ()
+  "Parse whitespace separated arguments in the current region."
+  (let ((begin (point-min))
+	(end (point-max))
+	begins args)
+    (save-excursion
+      (goto-char begin)
+      (while (< (point) end)
+	(skip-chars-forward " \t\n")
+	(setq begins (cons (point) begins))
+	(skip-chars-forward "^ \t\n")
+	(setq args (cons (buffer-substring-no-properties
+			  (car begins) (point))
+			 args)))
+      (cons (reverse args) (reverse begins)))))
+
+;;;###autoload
+(defun pcomplete-comint-setup (completef-sym)
+  "Setup a comint buffer to use pcomplete.
+COMPLETEF-SYM should be the symbol where the
+dynamic-complete-functions are kept.  For comint mode itself, this is
+`comint-dynamic-complete-functions'."
+  (set (make-local-variable 'pcomplete-parse-arguments-function)
+       'pcomplete-parse-comint-arguments)
+  (make-local-variable completef-sym)
+  (let ((elem (memq 'comint-dynamic-complete-filename
+		    (symbol-value completef-sym))))
+    (if elem
+	(setcar elem 'pcomplete)
+      (nconc (symbol-value completef-sym)
+	     (list 'pcomplete)))))
+
+;;;###autoload
+(defun pcomplete-shell-setup ()
+  "Setup shell-mode to use pcomplete."
+  (pcomplete-comint-setup 'shell-dynamic-complete-functions))
+
+(defun pcomplete-parse-comint-arguments ()
+  "Parse whitespace separated arguments in the current region."
+  (let ((begin (save-excursion (comint-bol nil) (point)))
+	(end (point))
+	begins args)
+    (save-excursion
+      (goto-char begin)
+      (while (< (point) end)
+	(skip-chars-forward " \t\n")
+	(setq begins (cons (point) begins))
+	(let ((skip t))
+	  (while skip
+	    (skip-chars-forward "^ \t\n")
+	    (if (eq (char-before) ?\\)
+		(skip-chars-forward " \t\n")
+	      (setq skip nil))))
+	(setq args (cons (buffer-substring-no-properties
+			  (car begins) (point))
+			 args)))
+      (cons (reverse args) (reverse begins)))))
+
+(defun pcomplete-parse-arguments (&optional expand-p)
+  "Parse the command line arguments.  Most completions need this info."
+  (let ((results (funcall pcomplete-parse-arguments-function)))
+    (when results
+      (setq pcomplete-args (or (car results) (list ""))
+	    pcomplete-begins (or (cdr results) (list (point)))
+	    pcomplete-last (1- (length pcomplete-args))
+	    pcomplete-index 0
+	    pcomplete-stub (pcomplete-arg 'last))
+      (let ((begin (pcomplete-begin 'last)))
+	(if (and pcomplete-cycle-completions
+		 (listp pcomplete-stub)
+		 (not pcomplete-expand-only-p))
+	    (let* ((completions pcomplete-stub)
+		   (common-stub (car completions))
+		   (c completions)
+		   (len (length common-stub)))
+	      (while (and c (> len 0))
+		(while (and (> len 0)
+			    (not (string=
+				  (substring common-stub 0 len)
+				  (substring (car c) 0
+					     (min (length (car c))
+						  len)))))
+		  (setq len (1- len)))
+		(setq c (cdr c)))
+	      (setq pcomplete-stub (substring common-stub 0 len)
+		    pcomplete-autolist t)
+	      (when (and begin (not pcomplete-show-list))
+		(delete-region begin (point))
+		(pcomplete-insert-entry "" pcomplete-stub))
+	      (throw 'pcomplete-completions completions))
+	  (when expand-p
+	    (if (stringp pcomplete-stub)
+		(when begin
+		  (delete-region begin (point))
+		  (insert-and-inherit pcomplete-stub))
+	      (if (and (listp pcomplete-stub)
+		       pcomplete-expand-only-p)
+		  ;; this is for the benefit of `pcomplete-expand'
+		  (setq pcomplete-last-completion-length (- (point) begin)
+			pcomplete-current-completions pcomplete-stub)
+		(error "Cannot expand argument"))))
+	  (if pcomplete-expand-only-p
+	      (throw 'pcompleted t)
+	    pcomplete-args))))))
+
+(defun pcomplete-quote-argument (filename)
+  "Return FILENAME with magic characters quoted.
+Magic characters are those in `pcomplete-arg-quote-list'."
+  (if (null pcomplete-arg-quote-list)
+      filename
+    (let ((len (length filename))
+	  (index 0)
+	  (result "")
+	  replacement char)
+      (while (< index len)
+	(setq replacement (run-hook-with-args-until-success
+			   'pcomplete-quote-arg-hook filename index))
+	(cond
+	 (replacement
+	  (setq result (concat result replacement)))
+	 ((and (setq char (aref filename index))
+	       (memq char pcomplete-arg-quote-list))
+	  (setq result (concat result "\\" (char-to-string char))))
+	 (t
+	  (setq result (concat result (char-to-string char)))))
+	(setq index (1+ index)))
+      result)))
+
+;; file-system completion lists
+
+(defsubst pcomplete-dirs-or-entries (&optional regexp predicate)
+  "Return either directories, or qualified entries."
+  (append (let ((pcomplete-stub pcomplete-stub))
+	    (pcomplete-entries regexp predicate))
+	  (pcomplete-entries nil 'file-directory-p)))
+
+(defun pcomplete-entries (&optional regexp predicate)
+  "Complete against a list of directory candidates.
+This function always uses the last argument as the basis for
+completion.
+If REGEXP is non-nil, it is a regular expression used to refine the
+match (files not matching the REGEXP will be excluded).
+If PREDICATE is non-nil, it will also be used to refine the match
+\(files for which the PREDICATE returns nil will be excluded).
+If PATH is non-nil, it will be used for completion instead of
+consulting the last argument."
+  (let* ((name pcomplete-stub)
+	 (default-directory (expand-file-name
+			     (or (file-name-directory name)
+				 default-directory)))
+	 above-cutoff)
+    (setq name (file-name-nondirectory name)
+	  pcomplete-stub name)
+    (let ((completions
+	   (file-name-all-completions name default-directory)))
+      (if regexp
+	  (setq completions
+		(pcomplete-pare-list
+		 completions nil
+		 (function
+		  (lambda (file)
+		    (not (string-match regexp file)))))))
+      (if predicate
+	  (setq completions
+		(pcomplete-pare-list
+		 completions nil
+		 (function
+		  (lambda (file)
+		    (not (funcall predicate file)))))))
+      (if (or pcomplete-file-ignore pcomplete-dir-ignore)
+	  (setq completions
+		(pcomplete-pare-list
+		 completions nil
+		 (function
+		  (lambda (file)
+		    (if (eq (aref file (1- (length file)))
+			    directory-sep-char)
+			(and pcomplete-dir-ignore
+			     (string-match pcomplete-dir-ignore file))
+		      (and pcomplete-file-ignore
+			   (string-match pcomplete-file-ignore file))))))))
+      (setq above-cutoff (> (length completions)
+			    pcomplete-cycle-cutoff-length))
+      (sort completions
+	    (function
+	     (lambda (l r)
+	       ;; for the purposes of comparison, remove the
+	       ;; trailing slash from directory names.
+	       ;; Otherwise, "foo.old/" will come before "foo/",
+	       ;; since . is earlier in the ASCII alphabet than
+	       ;; /
+	       (let ((left (if (eq (aref l (1- (length l)))
+				   directory-sep-char)
+			       (substring l 0 (1- (length l)))
+			     l))
+		     (right (if (eq (aref r (1- (length r)))
+				    directory-sep-char)
+				(substring r 0 (1- (length r)))
+			      r)))
+		 (if above-cutoff
+		     (string-lessp left right)
+		   (funcall pcomplete-compare-entry-function
+			    left right)))))))))
+
+(defsubst pcomplete-all-entries (&optional regexp predicate)
+  "Like `pcomplete-entries', but doesn't ignore any entries."
+  (let (pcomplete-file-ignore
+	pcomplete-dir-ignore)
+    (pcomplete-entries regexp predicate)))
+
+(defsubst pcomplete-dirs (&optional regexp)
+  "Complete amongst a list of directories."
+  (pcomplete-entries regexp 'file-directory-p))
+
+(defsubst pcomplete-executables (&optional regexp)
+  "Complete amongst a list of directories and executables."
+  (pcomplete-entries regexp 'file-executable-p))
+
+;; generation of completion lists
+
+(defun pcomplete-find-completion-function (command)
+  "Find the completion function to call for the given COMMAND."
+  (let ((sym (intern-soft
+	      (concat "pcomplete/" (symbol-name major-mode) "/" command))))
+    (unless sym
+      (setq sym (intern-soft (concat "pcomplete/" command))))
+    (and sym (fboundp sym) sym)))
+
+(defun pcomplete-completions ()
+  "Return a list of completions for the current argument position."
+  (catch 'pcomplete-completions
+    (when (pcomplete-parse-arguments pcomplete-expand-before-complete)
+      (if (= pcomplete-index pcomplete-last)
+	  (funcall pcomplete-command-completion-function)
+	(let ((sym (or (pcomplete-find-completion-function
+			(funcall pcomplete-command-name-function))
+		       pcomplete-default-completion-function)))
+	  (ignore
+	   (pcomplete-next-arg)
+	   (funcall sym)))))))
+
+(defun pcomplete-opt (options &optional prefix no-ganging args-follow)
+  "Complete a set of OPTIONS, each beginning with PREFIX (?- by default).
+PREFIX may be t, in which case no PREFIX character is necessary.
+If REQUIRED is non-nil, the options must be present.
+If NO-GANGING is non-nil, each option is separate.  -xy is not allowed.
+If ARGS-FOLLOW is non-nil, then options which arguments which take may
+have the argument appear after a ganged set of options.  This is how
+tar behaves, for example."
+  (if (and (= pcomplete-index pcomplete-last)
+	   (string= (pcomplete-arg) "-"))
+      (let ((len (length options))
+	    (index 0)
+	    char choices)
+	(while (< index len)
+	  (setq char (aref options index))
+	  (if (eq char ?\()
+	      (let ((result (read-from-string options index)))
+		(setq index (cdr result)))
+	    (unless (memq char '(?/ ?* ?? ?.))
+	      (setq choices (cons (char-to-string char) choices)))
+	    (setq index (1+ index))))
+	(throw 'pcomplete-completions
+	       (mapcar
+		(function
+		 (lambda (opt)
+		   (concat "-" opt)))
+		(pcomplete-uniqify-list choices))))
+    (let ((arg (pcomplete-arg)))
+      (when (and (> (length arg) 1)
+		 (stringp arg)
+		 (eq (aref arg 0) (or prefix ?-)))
+	(pcomplete-next-arg)
+	(let ((char (aref arg 1))
+	      (len (length options))
+	      (index 0)
+	      opt-char arg-char result)
+	  (while (< (1+ index) len)
+	    (setq opt-char (aref options index)
+		  arg-char (aref options (1+ index)))
+	    (if (eq arg-char ?\()
+		(setq result
+		      (read-from-string options (1+ index))
+		      index (cdr result)
+		      result (car result))
+	      (setq result nil))
+	    (when (and (eq char opt-char)
+		       (memq arg-char '(?\( ?/ ?* ?? ?.)))
+	      (if (< pcomplete-index pcomplete-last)
+		  (pcomplete-next-arg)
+		(throw 'pcomplete-completions
+		       (cond ((eq arg-char ?/) (pcomplete-dirs))
+			     ((eq arg-char ?*) (pcomplete-executables))
+			     ((eq arg-char ??) nil)
+			     ((eq arg-char ?.) (pcomplete-entries))
+			     ((eq arg-char ?\() (eval result))))))
+	    (setq index (1+ index))))))))
+
+(defun pcomplete--here (&optional form stub paring form-only)
+  "Complete aganst the current argument, if at the end.
+See the documentation for `pcomplete-here'."
+  (if (< pcomplete-index pcomplete-last)
+      (progn
+	(if (eq paring 0)
+	    (setq pcomplete-seen nil)
+	  (unless (eq paring t)
+	    (let ((arg (pcomplete-arg)))
+	      (unless (not (stringp arg))
+		(setq pcomplete-seen
+		      (cons (if paring
+				(funcall paring arg)
+			      (file-truename arg))
+			    pcomplete-seen))))))
+	(pcomplete-next-arg)
+	t)
+    (when pcomplete-show-help
+      (pcomplete--help)
+      (throw 'pcompleted t))
+    (if stub
+	(setq pcomplete-stub stub))
+    (if (or (eq paring t) (eq paring 0))
+	(setq pcomplete-seen nil)
+      (setq pcomplete-norm-func (or paring 'file-truename)))
+    (unless form-only
+      (run-hooks 'pcomplete-try-first-hook))
+    (throw 'pcomplete-completions (eval form))))
+
+(defmacro pcomplete-here (&optional form stub paring form-only)
+  "Complete aganst the current argument, if at the end.
+If completion is to be done here, evaluate FORM to generate the list
+of strings which will be used for completion purposes.  If STUB is a
+string, use it as the completion stub instead of the default (which is
+the entire text of the current argument).
+
+For an example of when you might want to use STUB: if the current
+argument text is 'long-path-name/', you don't want the completions
+list display to be cluttered by 'long-path-name/' appearing at the
+beginning of every alternative.  Not only does this make things less
+intelligle, but it is also inefficient.  Yet, if the completion list
+does not begin with this string for every entry, the current argument
+won't complete correctly.
+
+The solution is to specify a relative stub.  It allows you to
+substitute a different argument from the current argument, almost
+always for the sake of efficiency.
+
+If PARING is nil, this argument will be pared against previous
+arguments using the function `file-truename' to normalize them.
+PARING may be a function, in which case that function is for
+normalization.  If PARING is the value t, the argument dealt with by
+this call will not participate in argument paring.  If it the integer
+0, all previous arguments that have been seen will be cleared.
+
+If FORM-ONLY is non-nil, only the result of FORM will be used to
+generate the completions list.  This means that the hook
+`pcomplete-try-first-hook' will not be run."
+  `(pcomplete--here (quote ,form) ,stub ,paring ,form-only))
+
+(defmacro pcomplete-here* (&optional form stub form-only)
+  "An alternate form which does not participate in argument paring."
+  `(pcomplete-here ,form ,stub t ,form-only))
+
+;; display support
+
+(defun pcomplete-restore-windows ()
+  "If the only window change was due to Completions, restore things."
+  (if pcomplete-last-window-config
+      (let* ((cbuf (get-buffer "*Completions*"))
+	     (cwin (and cbuf (get-buffer-window cbuf))))
+	(when (and cwin (window-live-p cwin))
+	  (bury-buffer cbuf)
+	  (set-window-configuration pcomplete-last-window-config))))
+  (setq pcomplete-last-window-config nil
+	pcomplete-window-restore-timer nil))
+
+;; Abstractions so that the code below will work for both Emacs 20 and
+;; XEmacs 21
+
+(unless (fboundp 'event-matches-key-specifier-p)
+  (defalias 'event-matches-key-specifier-p 'eq))
+
+(unless (fboundp 'read-event)
+  (defsubst read-event (&optional prompt)
+    (aref (read-key-sequence prompt) 0)))
+
+(unless (fboundp 'event-basic-type)
+  (defalias 'event-basic-type 'event-key))
+
+(defun pcomplete-show-completions (completions)
+  "List in help buffer sorted COMPLETIONS.
+Typing SPC flushes the help buffer."
+  (let* ((curbuf (current-buffer)))
+    (when pcomplete-window-restore-timer
+      (cancel-timer pcomplete-window-restore-timer)
+      (setq pcomplete-window-restore-timer nil))
+    (unless pcomplete-last-window-config
+      (setq pcomplete-last-window-config (current-window-configuration)))
+    (with-output-to-temp-buffer "*Completions*"
+      (display-completion-list completions))
+    (message "Hit space to flush")
+    (let (event)
+      (prog1