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