pcmpl-x.el 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. ;;; pcmpl-x.el --- completion for miscellaneous tools -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2013-2015 Free Software Foundation, Inc.
  3. ;; Author: Leo Liu <sdl.web@gmail.com>
  4. ;; Keywords: processes, tools, convenience
  5. ;; Package: pcomplete
  6. ;; This file is part of GNU Emacs.
  7. ;; GNU Emacs is free software: you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; GNU Emacs is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Code:
  18. (eval-when-compile (require 'cl-lib))
  19. (require 'pcomplete)
  20. ;;;; tlmgr - http://www.tug.org/texlive/tlmgr.html
  21. (defcustom pcmpl-x-tlmgr-program "tlmgr"
  22. "Name of the tlmgr program."
  23. :version "24.4"
  24. :type 'file
  25. :group 'pcomplete)
  26. (defvar pcmpl-x-tlmgr-common-options
  27. '("--repository"
  28. "--gui"
  29. "--gui-lang"
  30. "--machine-readable"
  31. "--package-logfile"
  32. "--pause"
  33. "--persistent-downloads"
  34. "--no-persistent-downloads"
  35. "--no-execute-actions"
  36. "--debug-translation"
  37. "--help"
  38. "--version"))
  39. (defvar pcmpl-x-tlmgr-actions
  40. '(("help")
  41. ("version")
  42. ("gui")
  43. ("install")
  44. ("update")
  45. ("backup")
  46. ("restore")
  47. ("remove")
  48. ("repository" ("list" "add" "remove" "set"))
  49. ("candidates")
  50. ("option" ("show"
  51. "showall"
  52. "repository"
  53. "formats"
  54. "postcode"
  55. "docfiles"
  56. "srcfiles"
  57. "backupdir"
  58. "autobackup"
  59. "sys_bin"
  60. "sys_man"
  61. "sys_info"
  62. "desktop_integration"
  63. "fileassocs"
  64. "multiuser"))
  65. ("conf" ("texmf" "tlmgr"))
  66. ("paper"
  67. ("a4" "letter" "xdvi" "pdftex" "dvips" "dvipdfmx" "dvipdfm" "context")
  68. (lambda ()
  69. (unless (member (pcomplete-arg 1) '("a4" "letter"))
  70. (pcomplete-here* '("paper"))
  71. (pcomplete-here* '("a4" "letter")))))
  72. ("platform" ("list" "add" "remove"))
  73. ("print-platform" ("collections" "schemes"))
  74. ("arch" ("list" "add" "remove"))
  75. ("print-arch" ("collections" "schemes"))
  76. ("info" ("collections" "schemes"))
  77. ("search")
  78. ("dump-tlpdb")
  79. ("check" ("files" "depends" "executes" "runfiles" "all"))
  80. ("path" ("add" "remove"))
  81. ("postaction" ("install" "remove") ("shortcut" "fileassoc" "script"))
  82. ("uninstall")
  83. ("generate" ("language"
  84. "language.dat"
  85. "language.def"
  86. "language.dat.lua"
  87. "fmtutil"))))
  88. (defvar pcmpl-x-tlmgr-options-cache (make-hash-table :size 31 :test 'equal))
  89. (defun pcmpl-x-tlmgr-action-options (action)
  90. "Get the list of long options for ACTION."
  91. (if (eq (gethash action pcmpl-x-tlmgr-options-cache 'missing) 'missing)
  92. (with-temp-buffer
  93. (when (zerop
  94. (call-process pcmpl-x-tlmgr-program nil t nil action "-h"))
  95. (goto-char (point-min))
  96. (puthash action
  97. (cons "--help"
  98. (cl-loop while (re-search-forward
  99. "^[ \t]+\\(--[[:alnum:]-]+=?\\)"
  100. nil t)
  101. collect (match-string 1)))
  102. pcmpl-x-tlmgr-options-cache)
  103. (pcmpl-x-tlmgr-action-options action)))
  104. (gethash action pcmpl-x-tlmgr-options-cache)))
  105. ;;;###autoload
  106. (defun pcomplete/tlmgr ()
  107. "Completion for the `tlmgr' command."
  108. (while (pcomplete-match "^--" 0)
  109. (pcomplete-here* pcmpl-x-tlmgr-common-options)
  110. (unless (or (pcomplete-match "^--" 0)
  111. (all-completions (pcomplete-arg 0) pcmpl-x-tlmgr-actions))
  112. (pcomplete-here* (pcomplete-dirs-or-entries))))
  113. (pcomplete-here* pcmpl-x-tlmgr-actions)
  114. (let ((action (substring-no-properties (pcomplete-arg 1))))
  115. (while t
  116. (if (pcomplete-match "^--" 0)
  117. (pcomplete-here* (pcmpl-x-tlmgr-action-options action))
  118. (dolist (completions (cdr (assoc action pcmpl-x-tlmgr-actions)))
  119. (cond ((functionp completions)
  120. (funcall completions))
  121. ((all-completions (pcomplete-arg 0) completions)
  122. (pcomplete-here* completions))
  123. (t (pcomplete-here* (pcomplete-dirs-or-entries)))))
  124. (unless (pcomplete-match "^--" 0)
  125. (pcomplete-here* (pcomplete-dirs-or-entries)))))))
  126. ;;;; ack - http://betterthangrep.com
  127. ;; Usage:
  128. ;; - To complete short options type '-' first
  129. ;; - To complete long options type '--' first
  130. ;; - Color name completion is supported following
  131. ;; --color-filename=, --color-match= and --color-lineno=
  132. ;; - Type completion is supported following --type=
  133. (defcustom pcmpl-x-ack-program
  134. (file-name-nondirectory (or (executable-find "ack-grep")
  135. (executable-find "ack")
  136. "ack"))
  137. "Name of the ack program."
  138. :version "24.4"
  139. :type 'file
  140. :group 'pcomplete)
  141. (defvar pcmpl-x-ack-color-options
  142. '("clear"
  143. "reset"
  144. "dark"
  145. "bold"
  146. "underline"
  147. "underscore"
  148. "blink"
  149. "reverse"
  150. "concealed"
  151. "black"
  152. "red"
  153. "green"
  154. "yellow"
  155. "blue"
  156. "magenta"
  157. "on_black"
  158. "on_red"
  159. "on_green"
  160. "on_yellow"
  161. "on_blue"
  162. "on_magenta"
  163. "on_cyan"
  164. "on_white")
  165. "Color names for the `ack' command.")
  166. (defun pcmpl-x-ack-run (buffer &rest args)
  167. "Run ack with ARGS and send the output to BUFFER."
  168. (condition-case nil
  169. (apply 'call-process (or pcmpl-x-ack-program "ack") nil buffer nil args)
  170. (file-error -1)))
  171. (defun pcmpl-x-ack-short-options ()
  172. "Short options for the `ack' command."
  173. (with-temp-buffer
  174. (let (options)
  175. (when (zerop (pcmpl-x-ack-run t "--help"))
  176. (goto-char (point-min))
  177. (while (re-search-forward "^ -\\([^-]\\)" nil t)
  178. (push (match-string 1) options))
  179. (mapconcat 'identity (nreverse options) "")))))
  180. (defun pcmpl-x-ack-long-options (&optional arg)
  181. "Long options for the `ack' command."
  182. (with-temp-buffer
  183. (let (options)
  184. (when (zerop (pcmpl-x-ack-run t (or arg "--help")))
  185. (goto-char (point-min))
  186. (while (re-search-forward
  187. "\\(?: ?\\|, \\)\\(--\\(\\[no\\]\\)?\\([[:alnum:]-]+=?\\)\\)"
  188. nil t)
  189. (if (not (match-string 2))
  190. (push (match-string 1) options)
  191. (push (concat "--" (match-string 3)) options)
  192. (push (concat "--no" (match-string 3)) options)))
  193. (nreverse options)))))
  194. (defun pcmpl-x-ack-type-options ()
  195. "A list of types for the `ack' command."
  196. (pcmpl-x-ack-long-options "--help-types"))
  197. ;;;###autoload
  198. (defun pcomplete/ack ()
  199. "Completion for the `ack' command.
  200. Start an argument with `-' to complete short options and `--' for
  201. long options."
  202. ;; No space after =
  203. (while t
  204. (if (pcomplete-match "^-" 0)
  205. (cond
  206. ((pcomplete-match "^--color-\\w+=\\(\\S-*\\)" 0)
  207. (pcomplete-here* pcmpl-x-ack-color-options
  208. (pcomplete-match-string 1 0) t))
  209. ((pcomplete-match "^--\\(?:no\\)?ignore-dir=\\(\\S-*\\)" 0)
  210. (pcomplete-here* (pcomplete-dirs)
  211. (pcomplete-match-string 1 0) t))
  212. ((pcomplete-match "^--type=\\(\\S-*\\)" 0)
  213. (pcomplete-here* (mapcar (lambda (type-option)
  214. (substring type-option 2))
  215. (pcmpl-x-ack-type-options))
  216. (pcomplete-match-string 1 0) t))
  217. ((pcomplete-match "^--" 0)
  218. (pcomplete-here* (append (pcmpl-x-ack-long-options)
  219. (pcmpl-x-ack-type-options))))
  220. (t (pcomplete-opt (pcmpl-x-ack-short-options))))
  221. (pcomplete-here* (pcomplete-dirs-or-entries)))))
  222. ;;;###autoload
  223. (defalias 'pcomplete/ack-grep 'pcomplete/ack)
  224. ;;;; the_silver_search - https://github.com/ggreer/the_silver_searcher
  225. (defvar pcmpl-x-ag-options nil)
  226. (defun pcmpl-x-ag-options ()
  227. (or pcmpl-x-ag-options
  228. (setq pcmpl-x-ag-options
  229. (with-temp-buffer
  230. (when (zerop (call-process "ag" nil t nil "--help"))
  231. (let (short long)
  232. (goto-char (point-min))
  233. (while (re-search-forward "^ +\\(-[a-zA-Z]\\) " nil t)
  234. (push (match-string 1) short))
  235. (goto-char (point-min))
  236. (while (re-search-forward
  237. "^ +\\(?:-[a-zA-Z] \\)?\\(--\\(\\[no\\]\\)?[^ \t\n]+\\) "
  238. nil t)
  239. (if (match-string 2)
  240. (progn
  241. (replace-match "" nil nil nil 2)
  242. (push (match-string 1) long)
  243. (replace-match "no" nil nil nil 2)
  244. (push (match-string 1) long))
  245. (push (match-string 1) long)))
  246. (list (cons 'short (nreverse short))
  247. (cons 'long (nreverse long)))))))))
  248. ;;;###autoload
  249. (defun pcomplete/ag ()
  250. "Completion for the `ag' command."
  251. (while t
  252. (if (pcomplete-match "^-" 0)
  253. (pcomplete-here* (cdr (assq (if (pcomplete-match "^--" 0) 'long 'short)
  254. (pcmpl-x-ag-options))))
  255. (pcomplete-here* (pcomplete-dirs-or-entries)))))
  256. (provide 'pcmpl-x)
  257. ;;; pcmpl-x.el ends here