1 ;;; pcmpl-cvs.el --- functions for dealing with cvs completions
3 ;; Copyright (C) 1999-2011 Free Software Foundation, Inc.
5 ;; Author: John Wiegley <johnw@gnu.org>
8 ;; This file is part of GNU Emacs.
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 3 of the License, or
13 ;; (at your option) any later version.
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.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25 ;; These functions provide completion rules for the `cvs' tool.
34 (defgroup pcmpl-cvs nil
35 "Functions for dealing with CVS completions."
40 (defcustom pcmpl-cvs-binary
(or (executable-find "cvs") "cvs")
41 "The full path of the 'cvs' binary."
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")
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")
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
)
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")
102 (while (pcomplete-here (pcmpl-cvs-entries '(?M ?R ?A
)))))
103 ((pcomplete-test "update")
104 (setq pcomplete-help
"(cvs)update")
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
)))))
111 (while (pcomplete-here (pcmpl-cvs-entries)))))))
113 (defun pcmpl-cvs-commands ()
114 "Return a list of available CVS commands."
116 (call-process pcmpl-cvs-binary nil t nil
"--help-commands")
117 (goto-char (point-min))
119 (while (re-search-forward "^\\s-+\\([a-z]+\\)" nil t
)
120 (setq cmds
(cons (match-string 1) cmds
)))
121 (pcomplete-uniqify-list cmds
))))
123 (defun pcmpl-cvs-modules ()
124 "Return a list of available modules under CVS."
126 (call-process pcmpl-cvs-binary nil t nil
"checkout" "-c")
127 (goto-char (point-min))
129 (while (re-search-forward "\\(\\S-+\\)$" nil t
)
130 (setq entries
(cons (match-string 1) entries
)))
131 (pcomplete-uniqify-list entries
))))
133 (defun pcmpl-cvs-tags (&optional opers
)
134 "Return all the tags which could apply to the files related to OPERS."
135 (let ((entries (pcmpl-cvs-entries opers
))
138 (apply 'call-process pcmpl-cvs-binary nil t nil
139 "status" "-v" entries
)
140 (goto-char (point-min))
141 (while (re-search-forward "Existing Tags:" nil t
)
143 (while (not (looking-at "^$"))
144 (unless (looking-at "^\\s-+\\(\\S-+\\)\\s-+")
145 (error "Error in output from `cvs status -v'"))
146 (setq tags
(cons (match-string 1) tags
))
148 (pcomplete-uniqify-list tags
)))
150 (defun pcmpl-cvs-entries (&optional opers
)
151 "Return the Entries for the current directory.
152 If OPERS is a list of characters, return entries for which that
153 operation character applies, as displayed by 'cvs -n update'."
154 (let* ((arg (pcomplete-arg))
155 (dir (file-name-as-directory
156 (or (file-name-directory arg
) "")))
157 (nondir (or (file-name-nondirectory arg
) ""))
162 (call-process pcmpl-cvs-binary nil t nil
163 "-q" "-n" "-f" "update"); "-l")
164 (goto-char (point-min))
165 (while (re-search-forward "^\\(.\\) \\(.+\\)$" nil t
)
166 (if (memq (string-to-char (match-string 1)) opers
)
167 (setq entries
(cons (match-string 2) entries
)))))
169 (insert-file-contents (concat dir
"CVS/Entries"))
170 (goto-char (point-min))
172 (let* ((line (buffer-substring (line-beginning-position)
173 (line-end-position)))
174 (fields (split-string line
"/"))
176 (if (eq (aref line
0) ?
/)
177 (setq fields
(cons "" fields
)))
178 (setq text
(nth 1 fields
))
180 (if (string= (nth 0 fields
) "D")
181 (setq text
(file-name-as-directory text
)))
182 (setq entries
(cons text entries
))))
184 (setq pcomplete-stub nondir
)
185 (pcomplete-uniqify-list entries
)))
187 ;;; pcmpl-cvs.el ends here