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