pcmpl-gnu.el 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. ;;; pcmpl-gnu.el --- completions for GNU project tools -*- lexical-binding: t -*-
  2. ;; Copyright (C) 1999-2017 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. ;;; Code:
  17. (provide 'pcmpl-gnu)
  18. (require 'pcomplete)
  19. (require 'pcmpl-unix)
  20. (defgroup pcmpl-gnu nil
  21. "Completions for GNU project tools."
  22. :group 'pcomplete)
  23. ;; User Variables:
  24. (defcustom pcmpl-gnu-makefile-regexps
  25. '("\\`GNUmakefile" "\\`[Mm]akefile" "\\.ma?k\\'")
  26. "A list of regexps that will match Makefile names."
  27. :type '(repeat regexp)
  28. :group 'pcmpl-gnu)
  29. ;; Functions:
  30. ;;;###autoload
  31. (defun pcomplete/gzip ()
  32. "Completion for `gzip'."
  33. (let ((pcomplete-help "(gzip)"))
  34. (pcomplete-opt "cdfhlLnNqrStvV123456789")
  35. (while (pcomplete-here
  36. (pcmpl-gnu-zipped-files
  37. (catch 'has-d-flag
  38. (let ((args pcomplete-args))
  39. (while args
  40. (if (string-match "\\`-.*[dt]" (car args))
  41. (throw 'has-d-flag t))
  42. (setq args (cdr args))))))))))
  43. (defun pcmpl-gnu-zipped-files (unzip-p)
  44. "Find all zipped or unzipped files: the inverse of UNZIP-P."
  45. (pcomplete-entries
  46. nil
  47. (function
  48. (lambda (entry)
  49. (when (and (file-readable-p entry)
  50. (file-regular-p entry))
  51. (let ((zipped (string-match "\\.\\(t?gz\\|\\(ta\\)?Z\\)\\'"
  52. entry)))
  53. (or (and unzip-p zipped)
  54. (and (not unzip-p) (not zipped)))))))))
  55. ;;;###autoload
  56. (defun pcomplete/bzip2 ()
  57. "Completion for `bzip2'."
  58. (pcomplete-opt "hdzkftcqvLVs123456789")
  59. (while (pcomplete-here
  60. (pcmpl-gnu-bzipped-files
  61. (catch 'has-d-flag
  62. (let ((args pcomplete-args))
  63. (while args
  64. (if (string-match "\\`-.*[dt]" (car args))
  65. (throw 'has-d-flag t))
  66. (setq args (cdr args)))))))))
  67. (defun pcmpl-gnu-bzipped-files (unzip-p)
  68. "Find all zipped or unzipped files: the inverse of UNZIP-P."
  69. (pcomplete-entries
  70. nil
  71. (function
  72. (lambda (entry)
  73. (when (and (file-readable-p entry)
  74. (file-regular-p entry))
  75. (let ((zipped (string-match "\\.\\(t?z2\\|bz2\\)\\'" entry)))
  76. (or (and unzip-p zipped)
  77. (and (not unzip-p) (not zipped)))))))))
  78. ;;;###autoload
  79. (defun pcomplete/make ()
  80. "Completion for GNU `make'."
  81. (let ((pcomplete-help "(make)Top"))
  82. (pcomplete-opt "bmC/def(pcmpl-gnu-makefile-names)hiI/j?kl?no.pqrsStvwW.")
  83. (while (pcomplete-here (completion-table-in-turn
  84. (pcmpl-gnu-make-rule-names)
  85. (pcomplete-entries))
  86. nil 'identity))))
  87. (defun pcmpl-gnu-makefile-names ()
  88. "Return a list of possible makefile names."
  89. (pcomplete-entries (mapconcat 'identity pcmpl-gnu-makefile-regexps "\\|")))
  90. (defun pcmpl-gnu-make-rule-names ()
  91. "Return a list of possible make rule names in MAKEFILE."
  92. (let* ((minus-f (member "-f" pcomplete-args))
  93. (makefile (or (cadr minus-f)
  94. (cond
  95. ((file-exists-p "GNUmakefile") "GNUmakefile")
  96. ((file-exists-p "makefile") "makefile")
  97. (t "Makefile"))))
  98. rules)
  99. (if (not (file-readable-p makefile))
  100. (unless minus-f (list "-f"))
  101. (with-temp-buffer
  102. (ignore-errors ;Could be a directory or something.
  103. (insert-file-contents makefile))
  104. (while (re-search-forward
  105. (concat "^\\s-*\\([^\n#%.$][^:=\n]*\\)\\s-*:[^=]") nil t)
  106. (setq rules (append (split-string (match-string 1)) rules))))
  107. (pcomplete-uniqify-list rules))))
  108. (defcustom pcmpl-gnu-tarfile-regexp
  109. "\\.t\\(ar\\(\\.\\(gz\\|bz2\\|Z\\|xz\\)\\)?\\|gz\\|a[zZ]\\|z2\\)\\'"
  110. "A regexp which matches any tar archive."
  111. :version "24.3" ; added xz
  112. :type 'regexp
  113. :group 'pcmpl-gnu)
  114. ;; Only used in tar-mode buffers.
  115. (defvar tar-parse-info)
  116. (declare-function tar-header-name "tar-mode" t t)
  117. (defmacro pcmpl-gnu-with-file-buffer (file &rest body)
  118. "Run BODY inside a buffer visiting FILE."
  119. (declare (debug t) (indent 1))
  120. (let ((exist (make-symbol "exist"))
  121. (filesym (make-symbol "file"))
  122. (buf (make-symbol "buf")))
  123. `(let* ((,filesym ,file)
  124. (,exist (find-buffer-visiting ,filesym))
  125. (,buf (or ,exist (find-file-noselect ,filesym))))
  126. (unwind-protect
  127. (with-current-buffer ,buf
  128. ,@body)
  129. (when (and (not ,exist) (buffer-live-p ,buf))
  130. (kill-buffer ,buf))))))
  131. ;;;###autoload
  132. (defun pcomplete/tar ()
  133. "Completion for the GNU tar utility."
  134. ;; options that end in an equal sign will want further completion...
  135. (let (saw-option complete-within)
  136. (let ((pcomplete-suffix-list (if (boundp 'pcomplete-suffix-list)
  137. (cons ?= pcomplete-suffix-list))))
  138. (while (pcomplete-match "^-" 0)
  139. (setq saw-option t)
  140. (if (pcomplete-match "^--" 0)
  141. (if (pcomplete-match "^--\\([^= \t\n\f]*\\)\\'" 0)
  142. ;; FIXME: Extract this list from "tar --help".
  143. (pcomplete-here*
  144. '("--absolute-names"
  145. "--after-date="
  146. "--append"
  147. "--atime-preserve"
  148. "--backup"
  149. "--block-number"
  150. "--blocking-factor="
  151. "--catenate"
  152. "--checkpoint"
  153. "--compare"
  154. "--compress"
  155. "--concatenate"
  156. "--confirmation"
  157. "--create"
  158. "--delete"
  159. "--dereference"
  160. "--diff"
  161. "--directory="
  162. "--exclude="
  163. "--exclude-from="
  164. "--extract"
  165. "--file="
  166. "--files-from="
  167. "--force-local"
  168. "--get"
  169. "--group="
  170. "--gzip"
  171. "--help"
  172. "--ignore-failed-read"
  173. "--ignore-zeros"
  174. "--incremental"
  175. "--info-script="
  176. "--interactive"
  177. "--keep-old-files"
  178. "--label="
  179. "--list"
  180. "--listed-incremental"
  181. "--mode="
  182. "--modification-time"
  183. "--multi-volume"
  184. "--new-volume-script="
  185. "--newer="
  186. "--newer-mtime"
  187. "--no-recursion"
  188. "--null"
  189. "--numeric-owner"
  190. "--old-archive"
  191. "--one-file-system"
  192. "--owner="
  193. "--portability"
  194. "--posix"
  195. "--preserve"
  196. "--preserve-order"
  197. "--preserve-permissions"
  198. "--read-full-records"
  199. "--record-size="
  200. "--recursive-unlink"
  201. "--remove-files"
  202. "--rsh-command="
  203. "--same-order"
  204. "--same-owner"
  205. "--same-permissions"
  206. "--sparse"
  207. "--starting-file="
  208. "--suffix="
  209. "--tape-length="
  210. "--to-stdout"
  211. "--totals"
  212. "--uncompress"
  213. "--ungzip"
  214. "--unlink-first"
  215. "--update"
  216. "--use-compress-program="
  217. "--verbose"
  218. "--verify"
  219. "--version"
  220. "--volno-file=")))
  221. (pcomplete-opt "01234567ABCFGKLMNOPRSTUVWXZbcdfghiklmoprstuvwxz"))
  222. (cond
  223. ((pcomplete-match "\\`-\\'" 0)
  224. (pcomplete-here*))
  225. ((pcomplete-match "\\`--after-date=" 0)
  226. (pcomplete-here*))
  227. ((pcomplete-match "\\`--backup=" 0)
  228. (pcomplete-here*))
  229. ((pcomplete-match "\\`--blocking-factor=" 0)
  230. (pcomplete-here*))
  231. ((pcomplete-match "\\`--directory=\\(.*\\)" 0)
  232. (pcomplete-here* (pcomplete-dirs)
  233. (pcomplete-match-string 1 0)))
  234. ((pcomplete-match "\\`--exclude-from=\\(.*\\)" 0)
  235. (pcomplete-here* (pcomplete-entries)
  236. (pcomplete-match-string 1 0)))
  237. ((pcomplete-match "\\`--exclude=" 0)
  238. (pcomplete-here*))
  239. ((pcomplete-match "\\`--\\(extract\\|list\\)\\'" 0)
  240. (setq complete-within t))
  241. ((pcomplete-match "\\`--file=\\(.*\\)" 0)
  242. (pcomplete-here* (pcomplete-dirs-or-entries pcmpl-gnu-tarfile-regexp)
  243. (pcomplete-match-string 1 0)))
  244. ((pcomplete-match "\\`--files-from=\\(.*\\)" 0)
  245. (pcomplete-here* (pcomplete-entries)
  246. (pcomplete-match-string 1 0)))
  247. ((pcomplete-match "\\`--group=\\(.*\\)" 0)
  248. (pcomplete-here* (pcmpl-unix-group-names)
  249. (pcomplete-match-string 1 0)))
  250. ((pcomplete-match "\\`--info-script=\\(.*\\)" 0)
  251. (pcomplete-here* (pcomplete-entries)
  252. (pcomplete-match-string 1 0)))
  253. ((pcomplete-match "\\`--label=" 0)
  254. (pcomplete-here*))
  255. ((pcomplete-match "\\`--mode=" 0)
  256. (pcomplete-here*))
  257. ((pcomplete-match "\\`--new-volume-script=\\(.*\\)" 0)
  258. (pcomplete-here* (pcomplete-entries)
  259. (pcomplete-match-string 1 0)))
  260. ((pcomplete-match "\\`--newer=" 0)
  261. (pcomplete-here*))
  262. ((pcomplete-match "\\`--owner=\\(.*\\)" 0)
  263. (pcomplete-here* (pcmpl-unix-user-names)
  264. (pcomplete-match-string 1 0)))
  265. ((pcomplete-match "\\`--record-size=" 0)
  266. (pcomplete-here*))
  267. ((pcomplete-match "\\`--rsh-command=\\(.*\\)" 0)
  268. (pcomplete-here* (funcall pcomplete-command-completion-function)
  269. (pcomplete-match-string 1 0)))
  270. ((pcomplete-match "\\`--starting-file=\\(.*\\)" 0)
  271. (pcomplete-here* (pcomplete-entries)
  272. (pcomplete-match-string 1 0)))
  273. ((pcomplete-match "\\`--suffix=" 0)
  274. (pcomplete-here*))
  275. ((pcomplete-match "\\`--tape-length=" 0)
  276. (pcomplete-here*))
  277. ((pcomplete-match "\\`--use-compress-program=\\(.*\\)" 0)
  278. (pcomplete-here* (funcall pcomplete-command-completion-function)
  279. (pcomplete-match-string 1 0)))
  280. ((pcomplete-match "\\`--volno-file=\\(.*\\)" 0)
  281. (pcomplete-here* (pcomplete-entries)
  282. (pcomplete-match-string 1 0))))))
  283. (unless saw-option
  284. (pcomplete-here
  285. (mapcar 'char-to-string
  286. (string-to-list
  287. "01234567ABCFGIKLMNOPRSTUVWXZbcdfghiklmoprstuvwxz")))
  288. (if (pcomplete-match "[xt]" 'first 1)
  289. (setq complete-within t)))
  290. (pcomplete-here (pcomplete-dirs-or-entries pcmpl-gnu-tarfile-regexp))
  291. (while (pcomplete-here
  292. (if (and complete-within
  293. (let* ((fa (file-attributes (pcomplete-arg 1)))
  294. (size (nth 7 fa)))
  295. (and (numberp size)
  296. (or (null large-file-warning-threshold)
  297. (< size large-file-warning-threshold)))))
  298. (let ((file (pcomplete-arg 1)))
  299. (completion-table-dynamic
  300. (lambda (_string)
  301. (pcmpl-gnu-with-file-buffer
  302. file (mapcar #'tar-header-name tar-parse-info)))))
  303. (pcomplete-entries))
  304. nil 'identity))))
  305. ;;;###autoload
  306. (defun pcomplete/find ()
  307. "Completion for the GNU find utility."
  308. (let ((prec (pcomplete-arg 'last -1)))
  309. (cond ((and (pcomplete-match "^-" 'last)
  310. (string= "find" prec))
  311. (pcomplete-opt "HLPDO"))
  312. ((pcomplete-match "^-" 'last)
  313. (while (pcomplete-here
  314. '("-amin" "-anewer" "-atime" "-cmin" "-cnewer" "-context"
  315. "-ctime" "-daystart" "-delete" "-depth" "-empty" "-exec"
  316. "-execdir" "-executable" "-false" "-fls" "-follow"
  317. "-fprint" "-fprint0" "-fprintf" "-fstype" "-gid" "-group"
  318. "-help" "-ignore_readdir_race" "-ilname" "-iname"
  319. "-inum" "-ipath" "-iregex" "-iwholename"
  320. "-links" "-lname" "-ls" "-maxdepth"
  321. "-mindepth" "-mmin" "-mount" "-mtime"
  322. "-name" "-newer" "-nogroup" "-noignore_readdir_race"
  323. "-noleaf" "-nouser" "-nowarn" "-ok"
  324. "-okdir" "-path" "-perm" "-print"
  325. "-print0" "-printf" "-prune" "-quit"
  326. "-readable" "-regex" "-regextype" "-samefile"
  327. "-size" "-true" "-type" "-uid"
  328. "-used" "-user" "-version" "-warn"
  329. "-wholename" "-writable" "-xdev" "-xtype"))))
  330. ((string= "-type" prec)
  331. (while (pcomplete-here (list "b" "c" "d" "p" "f" "l" "s" "D"))))
  332. ((string= "-xtype" prec)
  333. (while (pcomplete-here (list "b" "c" "d" "p" "f" "l" "s"))))
  334. ((or (string= prec "-exec")
  335. (string= prec "-execdir"))
  336. (while (pcomplete-here* (funcall pcomplete-command-completion-function)
  337. (pcomplete-arg 'last) t))))
  338. (while (pcomplete-here (pcomplete-dirs) nil 'identity))))
  339. ;;;###autoload
  340. (defalias 'pcomplete/gdb 'pcomplete/xargs)
  341. ;;; pcmpl-gnu.el ends here