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