1;;; pcmpl-cvs.el --- functions for dealing with cvs completions 2 3;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 4;; 2005, 2006, 2007 Free Software Foundation, Inc. 5 6;; Author: John Wiegley <johnw@gnu.org> 7 8;; This file is part of GNU Emacs. 9 10;; GNU Emacs is free software; you can redistribute it and/or modify 11;; it under the terms of the GNU General Public License as published by 12;; the Free Software Foundation; either version 2, or (at your option) 13;; any later version. 14 15;; GNU Emacs is distributed in the hope that it will be useful, 16;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18;; GNU General Public License for more details. 19 20;; You should have received a copy of the GNU General Public License 21;; along with GNU Emacs; see the file COPYING. If not, write to the 22;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23;; Boston, MA 02110-1301, USA. 24 25;;; Commentary: 26 27;; These functions provide completion rules for the `cvs' tool. 28 29;;; Code: 30 31(provide 'pcmpl-cvs) 32 33(require 'pcomplete) 34(require 'executable) 35 36(defgroup pcmpl-cvs nil 37 "Functions for dealing with CVS completions." 38 :group 'pcomplete) 39 40;; User Variables: 41 42(defcustom pcmpl-cvs-binary (or (executable-find "cvs") "cvs") 43 "*The full path of the 'cvs' binary." 44 :type 'file 45 :group 'pcmpl-cvs) 46 47;; Functions: 48 49;;;###autoload 50(defun pcomplete/cvs () 51 "Completion rules for the `cvs' command." 52 (let ((pcomplete-help "(cvs)Invoking CVS")) 53 (pcomplete-opt "HQqrwlntvfab/T/e*d/z?s") 54 (pcomplete-here* (pcmpl-cvs-commands)) 55 (cond ((pcomplete-test "add") 56 (setq pcomplete-help "(cvs)Adding files") 57 (pcomplete-opt "k?m?") 58 (while (pcomplete-here (pcmpl-cvs-entries '(??))))) 59 ((pcomplete-test "remove") 60 (setq pcomplete-help "(cvs)Removing files") 61 (pcomplete-opt "flR") 62 (while (pcomplete-here (pcmpl-cvs-entries '(?U))))) 63 ((pcomplete-test "init") 64 (setq pcomplete-help "(cvs)Creating a repository")) 65 ((pcomplete-test '("login" "logout")) 66 (setq pcomplete-help "(cvs)Password authentication client")) 67 ((pcomplete-test "import") 68 (setq pcomplete-help "(cvs)import") 69 (pcomplete-opt "dk?I(pcmpl-cvs-entries '(??))b?m?W?")) 70 ((pcomplete-test "checkout") 71 (setq pcomplete-help "(cvs)checkout") 72 (pcomplete-opt "ANPRcflnpsr?D?d/k?j?") 73 (pcomplete-here (pcmpl-cvs-modules))) 74 ((pcomplete-test "rtag") 75 (setq pcomplete-help "(cvs)Creating a branch") 76 (pcomplete-opt "aflRndbr?DF") 77 (pcomplete-here (pcmpl-cvs-modules))) 78 ((pcomplete-test "release") 79 (setq pcomplete-help "(cvs)release") 80 (pcomplete-opt "d") 81 (while (pcomplete-here (pcomplete-dirs)))) 82 ((pcomplete-test "export") 83 (setq pcomplete-help "(cvs)export") 84 (pcomplete-opt "NflRnr?D?d/k?") 85 (pcomplete-here (pcmpl-cvs-modules))) 86 ((pcomplete-test "commit") 87 (setq pcomplete-help "(cvs)commit files") 88 (pcomplete-opt "nRlfF.m?r(pcmpl-cvs-tags '(?M ?R ?A))") 89 (while (pcomplete-here (pcmpl-cvs-entries '(?M ?R ?A))))) 90 ((pcomplete-test "diff") 91 (setq pcomplete-help "(cvs)Viewing differences") 92 (let ((opt-index pcomplete-index) 93 saw-backdate) 94 (pcomplete-opt "lRD?Nr(pcmpl-cvs-tags)") 95 (while (< opt-index pcomplete-index) 96 (if (pcomplete-match "^-[Dr]" (- pcomplete-index opt-index)) 97 (setq saw-backdate t opt-index pcomplete-index) 98 (setq opt-index (1+ opt-index)))) 99 (while (pcomplete-here 100 (pcmpl-cvs-entries (unless saw-backdate '(?M))))))) 101 ((pcomplete-test "unedit") 102 (setq pcomplete-help "(cvs)Editing files") 103 (pcomplete-opt "lR") 104 (while (pcomplete-here (pcmpl-cvs-entries '(?M ?R ?A))))) 105 ((pcomplete-test "update") 106 (setq pcomplete-help "(cvs)update") 107 (pcomplete-opt 108 (concat "APdflRpk?r(pcmpl-cvs-tags '(?U ?P))D?" 109 "j(pcmpl-cvs-tags '(?U ?P))" 110 "I(pcmpl-cvs-entries '(??))W?")) 111 (while (pcomplete-here (pcmpl-cvs-entries '(?U ?P))))) 112 (t 113 (while (pcomplete-here (pcmpl-cvs-entries))))))) 114 115(defun pcmpl-cvs-commands () 116 "Return a list of available CVS commands." 117 (with-temp-buffer 118 (call-process pcmpl-cvs-binary nil t nil "--help-commands") 119 (goto-char (point-min)) 120 (let (cmds) 121 (while (re-search-forward "^\\s-+\\([a-z]+\\)" nil t) 122 (setq cmds (cons (match-string 1) cmds))) 123 (pcomplete-uniqify-list cmds)))) 124 125(defun pcmpl-cvs-modules () 126 "Return a list of available modules under CVS." 127 (with-temp-buffer 128 (call-process pcmpl-cvs-binary nil t nil "checkout" "-c") 129 (goto-char (point-min)) 130 (let (entries) 131 (while (re-search-forward "\\(\\S-+\\)$" nil t) 132 (setq entries (cons (match-string 1) entries))) 133 (pcomplete-uniqify-list entries)))) 134 135(defun pcmpl-cvs-tags (&optional opers) 136 "Return all the tags which could apply to the files related to OPERS." 137 (let ((entries (pcmpl-cvs-entries opers)) 138 tags) 139 (with-temp-buffer 140 (apply 'call-process pcmpl-cvs-binary nil t nil 141 "status" "-v" entries) 142 (goto-char (point-min)) 143 (while (re-search-forward "Existing Tags:" nil t) 144 (forward-line) 145 (while (not (looking-at "^$")) 146 (unless (looking-at "^\\s-+\\(\\S-+\\)\\s-+") 147 (error "Error in output from `cvs status -v'")) 148 (setq tags (cons (match-string 1) tags)) 149 (forward-line)))) 150 (pcomplete-uniqify-list tags))) 151 152(defun pcmpl-cvs-entries (&optional opers) 153 "Return the Entries for the current directory. 154If OPERS is a list of characters, return entries for which that 155operation character applies, as displayed by 'cvs -n update'." 156 (let* ((arg (pcomplete-arg)) 157 (dir (file-name-as-directory 158 (or (file-name-directory arg) ""))) 159 (nondir (or (file-name-nondirectory arg) "")) 160 entries) 161 (if opers 162 (with-temp-buffer 163 (and dir (cd dir)) 164 (call-process pcmpl-cvs-binary nil t nil 165 "-q" "-n" "-f" "update"); "-l") 166 (goto-char (point-min)) 167 (while (re-search-forward "^\\(.\\) \\(.+\\)$" nil t) 168 (if (memq (string-to-char (match-string 1)) opers) 169 (setq entries (cons (match-string 2) entries))))) 170 (with-temp-buffer 171 (insert-file-contents (concat dir "CVS/Entries")) 172 (goto-char (point-min)) 173 (while (not (eobp)) 174 (let* ((line (buffer-substring (line-beginning-position) 175 (line-end-position))) 176 (fields (split-string line "/")) 177 text) 178 (if (eq (aref line 0) ?/) 179 (setq fields (cons "" fields))) 180 (setq text (nth 1 fields)) 181 (when text 182 (if (string= (nth 0 fields) "D") 183 (setq text (file-name-as-directory text))) 184 (setq entries (cons text entries)))) 185 (forward-line)))) 186 (setq pcomplete-stub nondir) 187 (pcomplete-uniqify-list entries))) 188 189;;; arch-tag: d2aeac43-4bf5-4509-a496-74b863c6642b 190;;; pcmpl-cvs.el ends here 191