pcmpl-cvs.el 6.5 KB

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