pcmpl-rpm.el 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. ;;; pcmpl-rpm.el --- functions for dealing with rpm completions
  2. ;; Copyright (C) 1999-2015 Free Software Foundation, Inc.
  3. ;; Package: pcomplete
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; These functions provide completion rules for the `rpm' command.
  17. ;;; Code:
  18. (require 'pcomplete)
  19. (defgroup pcmpl-rpm nil
  20. "Options for rpm completion."
  21. :group 'pcomplete
  22. :prefix "pcmpl-rpm-")
  23. ;; rpm -qa can be slow. Adding --nodigest --nosignature is MUCH faster.
  24. (defcustom pcmpl-rpm-query-options
  25. (let (opts)
  26. (with-temp-buffer
  27. (when (ignore-errors (call-process "rpm" nil t nil "--help"))
  28. (if (search-backward "--nodigest " nil 'move)
  29. (setq opts '("--nodigest")))
  30. (goto-char (point-min))
  31. (if (search-forward "--nosignature " nil t)
  32. (push "--nosignature" opts))))
  33. opts)
  34. "String, or list of strings, with extra options for an rpm query command."
  35. :version "24.3"
  36. :type '(choice (const :tag "No options" nil)
  37. (string :tag "Single option")
  38. (repeat :tag "List of options" string))
  39. :group 'pcmpl-rpm)
  40. (defcustom pcmpl-rpm-cache t
  41. "Whether to cache the list of installed packages."
  42. :version "24.3"
  43. :type 'boolean
  44. :group 'pcmpl-rpm)
  45. (defconst pcmpl-rpm-cache-stamp-file "/var/lib/rpm/Packages"
  46. "File used to check that the list of installed packages is up-to-date.")
  47. (defvar pcmpl-rpm-cache-time nil
  48. "Time at which the list of installed packages was updated.")
  49. (defvar pcmpl-rpm-packages nil
  50. "List of installed packages.")
  51. ;; Functions:
  52. (defun pcmpl-rpm-packages ()
  53. "Return a list of all installed rpm packages."
  54. (if (and pcmpl-rpm-cache
  55. pcmpl-rpm-cache-time
  56. (let ((mtime (nth 5 (file-attributes pcmpl-rpm-cache-stamp-file))))
  57. (and mtime (not (time-less-p pcmpl-rpm-cache-time mtime)))))
  58. pcmpl-rpm-packages
  59. (message "Getting list of installed rpms...")
  60. (setq pcmpl-rpm-cache-time (current-time)
  61. pcmpl-rpm-packages
  62. (split-string (apply 'pcomplete-process-result "rpm"
  63. (append '("-q" "-a")
  64. (if (stringp pcmpl-rpm-query-options)
  65. (list pcmpl-rpm-query-options)
  66. pcmpl-rpm-query-options)))))
  67. (message "Getting list of installed rpms...done")
  68. pcmpl-rpm-packages))
  69. ;; Should this use pcmpl-rpm-query-options?
  70. ;; I don't think it would speed it up at all (?).
  71. (defun pcmpl-rpm-all-query (flag)
  72. (message "Querying all packages with `%s'..." flag)
  73. (let ((pkgs (pcmpl-rpm-packages))
  74. (provs (list t)))
  75. (while pkgs
  76. (nconc provs (split-string
  77. (pcomplete-process-result
  78. "rpm" "-q" (car pkgs) flag)))
  79. (setq pkgs (cdr pkgs)))
  80. (pcomplete-uniqify-list (cdr provs))))
  81. (defsubst pcmpl-rpm-files ()
  82. (pcomplete-dirs-or-entries "\\.rpm\\'"))
  83. ;;;###autoload
  84. (defun pcomplete/rpm ()
  85. "Completion for the `rpm' command."
  86. ;; Originally taken from the output of `rpm --help' on a Red Hat 6.1 system.
  87. (let (mode)
  88. (while (<= pcomplete-index pcomplete-last)
  89. (unless mode
  90. (if (pcomplete-match "^--\\(.*\\)" 0)
  91. (pcomplete-here*
  92. '("--addsign"
  93. "--checksig"
  94. "--erase"
  95. "--help"
  96. "--initdb"
  97. "--install"
  98. "--pipe"
  99. "--querytags"
  100. "--rebuild"
  101. "--rebuilddb"
  102. "--recompile"
  103. "--resign"
  104. "--rmsource"
  105. "--setperms"
  106. "--setugids"
  107. "--upgrade"
  108. "--verify"
  109. "--version"))
  110. (pcomplete-opt "vqVyiUebtK")))
  111. ; -b<stage> <spec>
  112. ; -t<stage> <tarball> - build package, where <stage> is one of:
  113. ; p - prep (unpack sources and apply patches)
  114. ; l - list check (do some cursory checks on %files)
  115. ; c - compile (prep and compile)
  116. ; i - install (prep, compile, install)
  117. ; b - binary package (prep, compile, install, package)
  118. ; a - bin/src package (prep, compile, install, package)
  119. (cond
  120. ((or (eq mode 'query)
  121. (pcomplete-match "-[^-]*q"))
  122. (setq mode 'query)
  123. (if (pcomplete-match "^--\\(.*\\)" 0)
  124. (progn
  125. (pcomplete-here*
  126. '("--changelog"
  127. "--dbpath"
  128. "--dump"
  129. "--file"
  130. "--ftpport" ;nyi for the next four
  131. "--ftpproxy"
  132. "--httpport"
  133. "--httpproxy"
  134. "--provides"
  135. "--queryformat"
  136. "--rcfile"
  137. "--requires"
  138. "--root"
  139. "--scripts"
  140. "--triggeredby"
  141. "--whatprovides"
  142. "--whatrequires"))
  143. (cond
  144. ((pcomplete-test "--dbpath")
  145. (pcomplete-here* (pcomplete-dirs)))
  146. ((pcomplete-test "--queryformat")
  147. (pcomplete-here*))
  148. ((pcomplete-test "--rcfile")
  149. (pcomplete-here* (pcomplete-entries)))
  150. ((pcomplete-test "--file")
  151. (pcomplete-here* (pcomplete-entries)))
  152. ((pcomplete-test "--root")
  153. (pcomplete-here* (pcomplete-dirs)))
  154. ((pcomplete-test "--scripts")
  155. (if (pcomplete-match "^--\\(.*\\)" 0)
  156. (pcomplete-here* '("--triggers"))))
  157. ((pcomplete-test "--triggeredby")
  158. (pcomplete-here* (pcmpl-rpm-packages)))
  159. ((pcomplete-test "--whatprovides")
  160. (pcomplete-here*
  161. (pcmpl-rpm-all-query "--provides")))
  162. ((pcomplete-test "--whatrequires")
  163. (pcomplete-here*
  164. (pcmpl-rpm-all-query "--requires")))))
  165. (if (pcomplete-match "^-" 0)
  166. (pcomplete-opt "af.p(pcmpl-rpm-files)ilsdcvR")
  167. (if (pcomplete-test "-[^-]*p" 'first 1)
  168. (pcomplete-here (pcmpl-rpm-files))
  169. (if (pcomplete-test "-[^-]*f" 'first 1)
  170. (pcomplete-here* (pcomplete-entries))
  171. (pcomplete-here (pcmpl-rpm-packages)))))))
  172. ((pcomplete-test "--pipe")
  173. (pcomplete-here* (funcall pcomplete-command-completion-function)))
  174. ((pcomplete-test "--rmsource")
  175. (pcomplete-here* (pcomplete-entries))
  176. (throw 'pcomplete-completions nil))
  177. ((pcomplete-match "\\`--re\\(build\\|compile\\)\\'")
  178. (pcomplete-here (pcmpl-rpm-files))
  179. (throw 'pcomplete-completions nil))
  180. ((pcomplete-match "\\`--\\(resign\\|addsign\\)\\'")
  181. (while (pcomplete-here (pcmpl-rpm-files))))
  182. ((or (eq mode 'checksig)
  183. (pcomplete-test "--checksig"))
  184. (setq mode 'checksig)
  185. (if (pcomplete-match "^--\\(.*\\)" 0)
  186. (progn
  187. (pcomplete-here*
  188. '("--nopgp"
  189. "--nogpg"
  190. "--nomd5"
  191. "--rcfile"))
  192. (cond
  193. ((pcomplete-test "--rcfile")
  194. (pcomplete-here* (pcomplete-entries)))))
  195. (if (pcomplete-match "^-" 0)
  196. (pcomplete-opt "v")
  197. (pcomplete-here (pcmpl-rpm-files)))))
  198. ((or (eq mode 'rebuilddb)
  199. (pcomplete-test "--rebuilddb"))
  200. (setq mode 'rebuilddb)
  201. (if (pcomplete-match "^--\\(.*\\)" 0)
  202. (progn
  203. (pcomplete-here*
  204. '("--dbpath"
  205. "--root"
  206. "--rcfile"))
  207. (cond
  208. ((pcomplete-test "--dbpath")
  209. (pcomplete-here* (pcomplete-dirs)))
  210. ((pcomplete-test "--root")
  211. (pcomplete-here* (pcomplete-dirs)))
  212. ((pcomplete-test "--rcfile")
  213. (pcomplete-here* (pcomplete-entries)))))
  214. (if (pcomplete-match "^-" 0)
  215. (pcomplete-opt "v")
  216. (pcomplete-here))))
  217. ((memq mode '(install upgrade))
  218. (if (pcomplete-match "^--\\(.*\\)" 0)
  219. (progn
  220. (pcomplete-here*
  221. (append
  222. '("--allfiles"
  223. "--badreloc"
  224. "--dbpath"
  225. "--excludedocs"
  226. "--excludepath"
  227. "--force"
  228. "--hash"
  229. "--ignorearch"
  230. "--ignoreos"
  231. "--ignoresize"
  232. "--includedocs"
  233. "--justdb"
  234. "--nodeps"
  235. "--noorder"
  236. "--noscripts"
  237. "--notriggers")
  238. (if (eq mode 'upgrade)
  239. '("--oldpackage"))
  240. '("--percent"
  241. "--prefix"
  242. "--rcfile"
  243. "--relocate"
  244. "--replacefiles"
  245. "--replacepkgs"
  246. "--root")))
  247. (cond
  248. ((pcomplete-test "--dbpath")
  249. (pcomplete-here* (pcomplete-dirs)))
  250. ((pcomplete-test "--relocate")
  251. (pcomplete-here*))
  252. ((pcomplete-test "--rcfile")
  253. (pcomplete-here* (pcomplete-entries)))
  254. ((pcomplete-test "--excludepath")
  255. (pcomplete-here* (pcomplete-entries)))
  256. ((pcomplete-test "--root")
  257. (pcomplete-here* (pcomplete-dirs)))
  258. ((pcomplete-test "--prefix")
  259. (pcomplete-here* (pcomplete-dirs)))))
  260. (if (pcomplete-match "^-" 0)
  261. (pcomplete-opt "vh")
  262. (pcomplete-here (pcmpl-rpm-files)))))
  263. ((or (pcomplete-test "--install")
  264. (pcomplete-match "-[^-]*i"))
  265. (setq mode 'install))
  266. ((or (pcomplete-test "--upgrade")
  267. (pcomplete-match "-[^-]*U"))
  268. (setq mode 'upgrade))
  269. ((or (eq mode 'erase)
  270. (pcomplete-test "--erase")
  271. (pcomplete-match "-[^-]*e"))
  272. (setq mode 'erase)
  273. (if (pcomplete-match "^--\\(.*\\)" 0)
  274. (progn
  275. (pcomplete-here*
  276. '("--allmatches"
  277. "--dbpath"
  278. "--justdb"
  279. "--nodeps"
  280. "--noorder"
  281. "--noscripts"
  282. "--notriggers"
  283. "--rcfile"
  284. "--root"))
  285. (cond
  286. ((pcomplete-test "--dbpath")
  287. (pcomplete-here* (pcomplete-dirs)))
  288. ((pcomplete-test "--rcfile")
  289. (pcomplete-here* (pcomplete-entries)))
  290. ((pcomplete-test "--root")
  291. (pcomplete-here* (pcomplete-dirs)))))
  292. (if (pcomplete-match "^-" 0)
  293. (pcomplete-opt "v")
  294. (pcomplete-here (pcmpl-rpm-packages)))))
  295. ((or (eq mode 'verify)
  296. (pcomplete-test "--verify"))
  297. (setq mode 'verify)
  298. (if (pcomplete-match "^--\\(.*\\)" 0)
  299. (progn
  300. (pcomplete-here*
  301. '("--dbpath"
  302. "--nodeps"
  303. "--nofiles"
  304. "--nomd5"
  305. "--rcfile"
  306. "--root"
  307. "--triggeredby"
  308. "--whatprovides"
  309. "--whatrequires"))
  310. (cond
  311. ((pcomplete-test "--dbpath")
  312. (pcomplete-here* (pcomplete-dirs)))
  313. ((pcomplete-test "--rcfile")
  314. (pcomplete-here* (pcomplete-entries)))
  315. ((pcomplete-test "--root")
  316. (pcomplete-here* (pcomplete-dirs)))
  317. ((pcomplete-test "--triggeredby")
  318. (pcomplete-here* (pcmpl-rpm-packages)))
  319. ((pcomplete-test "--whatprovides")
  320. (pcomplete-here*
  321. (pcmpl-rpm-all-query "--provides")))
  322. ((pcomplete-test "--whatrequires")
  323. (pcomplete-here*
  324. (pcmpl-rpm-all-query "--requires")))))
  325. (if (pcomplete-match "^-" 0)
  326. (pcomplete-opt "af.p(pcmpl-rpm-files)v")
  327. (pcomplete-here (pcmpl-rpm-packages)))))
  328. ((or (memq mode '(build test))
  329. (pcomplete-match "\\`-[bt]"))
  330. (setq mode (if (pcomplete-match "\\`-b")
  331. 'build
  332. 'test))
  333. (if (pcomplete-match "^--\\(.*\\)" 0)
  334. (progn
  335. (pcomplete-here*
  336. '("--buildroot"
  337. "--clean"
  338. "--nobuild"
  339. "--rcfile"
  340. "--rmsource"
  341. "--short-circuit"
  342. "--sign"
  343. "--target"
  344. "--timecheck"))
  345. (cond
  346. ((pcomplete-test "--buildroot")
  347. (pcomplete-here* (pcomplete-dirs)))
  348. ((pcomplete-test "--rcfile")
  349. (pcomplete-here* (pcomplete-entries)))
  350. ((pcomplete-test "--timecheck")
  351. (pcomplete-here*))))
  352. (if (pcomplete-match "^-" 0)
  353. (pcomplete-opt "v")
  354. (pcomplete-here
  355. (pcomplete-dirs-or-entries (if (eq mode 'test)
  356. "\\.tar\\'"
  357. "\\.spec\\'"))))))
  358. (t
  359. (error "You must select a mode: -q, -i, -U, --verify, etc"))))))
  360. (provide 'pcmpl-rpm)
  361. ;;; pcmpl-rpm.el ends here