;;; pcomplete.el --- programmable completion
-;; Copyright (C) 1999, 2000,01,02,03,04 Free Sofware Foundation
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;; 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; Keywords: processes abbrev
;; 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)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; 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.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; 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
:type 'boolean
:group 'pcomplete)
-(defcustom pcomplete-suffix-list (list directory-sep-char ?:)
+(defcustom pcomplete-suffix-list (list ?/ ?:)
"*A list of characters which constitute a proper suffix."
:type '(repeat character)
:group 'pcomplete)
:type 'hook
:group 'pcomplete)
+(defsubst pcomplete-executables (&optional regexp)
+ "Complete amongst a list of directories and executables."
+ (pcomplete-entries regexp 'file-executable-p))
+
(defcustom pcomplete-command-completion-function
(function
(lambda ()
;;; User Functions:
;;;###autoload
-(defun pcomplete ()
+(defun pcomplete (&optional interactively)
"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)
+ (interactive "p")
+ (if (and interactively
pcomplete-cycle-completions
pcomplete-current-completions
(memq last-command '(pcomplete
"Setup shell-mode to use pcomplete."
(pcomplete-comint-setup 'shell-dynamic-complete-functions))
+(declare-function comint-bol "comint" (&optional arg))
+
(defun pcomplete-parse-comint-arguments ()
"Parse whitespace separated arguments in the current region."
(let ((begin (save-excursion (comint-bol nil) (point)))
If no directory information can be extracted from the completed
component, `default-directory' is used as the basis for completion."
(let* ((name (substitute-env-vars pcomplete-stub))
+ (completion-ignore-case pcomplete-ignore-case)
(default-directory (expand-file-name
(or (file-name-directory name)
default-directory)))
(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
;; 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
"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)
(if pcomplete-last-window-config
(let* ((cbuf (get-buffer "*Completions*"))
(cwin (and cbuf (get-buffer-window cbuf))))
- (when (and cwin (window-live-p cwin))
+ (when (window-live-p cwin)
(bury-buffer cbuf)
(set-window-configuration pcomplete-last-window-config))))
(setq pcomplete-last-window-config 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))
+(defalias 'pcomplete-event-matches-key-specifier-p
+ (if (featurep 'xemacs)
+ 'event-matches-key-specifier-p
+ 'eq))
-(unless (fboundp 'read-event)
- (defsubst read-event (&optional prompt)
+(defun pcomplete-read-event (&optional prompt)
+ (if (fboundp 'read-event)
+ (read-event 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."
(prog1
(catch 'done
(while (with-current-buffer (get-buffer "*Completions*")
- (setq event (read-event)))
+ (setq event (pcomplete-read-event)))
(cond
- ((event-matches-key-specifier-p event ? )
+ ((pcomplete-event-matches-key-specifier-p event ?\s)
(set-window-configuration pcomplete-last-window-config)
(setq pcomplete-last-window-config nil)
(throw 'done nil))
- ((event-matches-key-specifier-p event 'tab)
- (save-selected-window
- (select-window (get-buffer-window "*Completions*"))
- (if (pos-visible-in-window-p (point-max))
- (goto-char (point-min))
- (scroll-up)))
+ ((or (pcomplete-event-matches-key-specifier-p event 'tab)
+ ;; Needed on a terminal
+ (pcomplete-event-matches-key-specifier-p event 9))
+ (let ((win (or (get-buffer-window "*Completions*" 0)
+ (display-buffer "*Completions*"
+ 'not-this-window))))
+ (with-selected-window win
+ (if (pos-visible-in-window-p (point-max))
+ (goto-char (point-min))
+ (scroll-up))))
(message ""))
(t
(setq unread-command-events (list event))
(fboundp 'Info-goto-node))
(listp pcomplete-help)))
(if (listp pcomplete-help)
- (message (eval pcomplete-help))
+ (message "%s" (eval pcomplete-help))
(save-window-excursion (info))
(switch-to-buffer-other-window "*info*")
(funcall (symbol-function 'Info-goto-node) pcomplete-help))
;; general utilities
-(defsubst pcomplete-time-less-p (t1 t2)
- "Say whether time T1 is less than time T2."
- (or (< (car t1) (car t2))
- (and (= (car t1) (car t2))
- (< (nth 1 t1) (nth 1 t2)))))
-
(defun pcomplete-pare-list (l r &optional pred)
"Destructively remove from list L all elements matching any in list R.
Test is done using `equal'.