1 ;;; pcmpl-x.el --- completion for miscellaneous tools -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2013 Free Software Foundation, Inc.
5 ;; Author: Leo Liu <sdl.web@gmail.com>
6 ;; Keywords: processes, tools, convenience
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/>.
26 (eval-when-compile (require 'cl-lib
))
30 ;;;; tlmgr - http://www.tug.org/texlive/tlmgr.html
32 (defcustom pcmpl-x-tlmgr-program
"tlmgr"
33 "Name of the tlmgr program."
37 (defvar pcmpl-x-tlmgr-common-options
44 "--persistent-downloads"
45 "--no-persistent-downloads"
46 "--no-execute-actions"
51 (defvar pcmpl-x-tlmgr-actions
60 ("repository" ("list" "add" "remove" "set"))
77 ("conf" ("texmf" "tlmgr"))
79 ("a4" "letter" "xdvi" "pdftex" "dvips" "dvipdfmx" "dvipdfm" "context")
81 (unless (member (pcomplete-arg 1) '("a4" "letter"))
82 (pcomplete-here* '("paper"))
83 (pcomplete-here* '("a4" "letter")))))
84 ("platform" ("list" "add" "remove"))
85 ("print-platform" ("collections" "schemes"))
86 ("arch" ("list" "add" "remove"))
87 ("print-arch" ("collections" "schemes"))
88 ("info" ("collections" "schemes"))
91 ("check" ("files" "depends" "executes" "runfiles" "all"))
92 ("path" ("add" "remove"))
93 ("postaction" ("install" "remove") ("shortcut" "fileassoc" "script"))
95 ("generate" ("language"
101 (defvar pcmpl-x-tlmgr-options-cache
(make-hash-table :size
31 :test
'equal
))
103 (defun pcmpl-x-tlmgr-action-options (action)
104 "Get the list of long options for ACTION."
105 (if (eq (gethash action pcmpl-x-tlmgr-options-cache
'missing
) 'missing
)
108 (call-process pcmpl-x-tlmgr-program nil t nil action
"-h"))
109 (goto-char (point-min))
112 (cl-loop while
(re-search-forward
113 "^[ \t]+\\(--[[:alnum:]-]+=?\\)"
115 collect
(match-string 1)))
116 pcmpl-x-tlmgr-options-cache
)
117 (pcmpl-x-tlmgr-action-options action
)))
118 (gethash action pcmpl-x-tlmgr-options-cache
)))
121 (defun pcomplete/tlmgr
()
122 "Completion for the `tlmgr' command."
123 (while (pcomplete-match "^--" 0)
124 (pcomplete-here* pcmpl-x-tlmgr-common-options
)
125 (unless (or (pcomplete-match "^--" 0)
126 (all-completions (pcomplete-arg 0) pcmpl-x-tlmgr-actions
))
127 (pcomplete-here* (pcomplete-dirs-or-entries))))
128 (pcomplete-here* pcmpl-x-tlmgr-actions
)
129 (let ((action (substring-no-properties (pcomplete-arg 1))))
131 (if (pcomplete-match "^--" 0)
132 (pcomplete-here* (pcmpl-x-tlmgr-action-options action
))
133 (dolist (completions (cdr (assoc action pcmpl-x-tlmgr-actions
)))
134 (cond ((functionp completions
)
135 (funcall completions
))
136 ((all-completions (pcomplete-arg 0) completions
)
137 (pcomplete-here* completions
))
138 (t (pcomplete-here* (pcomplete-dirs-or-entries)))))
139 (unless (pcomplete-match "^--" 0)
140 (pcomplete-here* (pcomplete-dirs-or-entries)))))))
143 ;;;; ack - http://betterthangrep.com
146 ;; - To complete short options type '-' first
147 ;; - To complete long options type '--' first
148 ;; - Color name completion is supported following
149 ;; --color-filename=, --color-match= and --color-lineno=
150 ;; - Type completion is supported following --type=
152 (defcustom pcmpl-x-ack-program
153 (file-name-nondirectory (or (executable-find "ack-grep")
154 (executable-find "ack")
156 "Name of the ack program."
160 (defvar pcmpl-x-ack-color-options
184 "Color names for the `ack' command.")
186 (defun pcmpl-x-ack-run (buffer &rest args
)
187 "Run ack with ARGS and send the output to BUFFER."
189 (apply 'call-process
(or pcmpl-x-ack-program
"ack") nil buffer nil args
)
192 (defun pcmpl-x-ack-short-options ()
193 "Short options for the `ack' command."
196 (when (zerop (pcmpl-x-ack-run t
"--help"))
197 (goto-char (point-min))
198 (while (re-search-forward "^ -\\([^-]\\)" nil t
)
199 (push (match-string 1) options
))
200 (mapconcat 'identity
(nreverse options
) "")))))
202 (defun pcmpl-x-ack-long-options (&optional arg
)
203 "Long options for the `ack' command."
206 (when (zerop (pcmpl-x-ack-run t
(or arg
"--help")))
207 (goto-char (point-min))
208 (while (re-search-forward
209 "\\(?: ?\\|, \\)\\(--\\(\\[no\\]\\)?\\([[:alnum:]-]+=?\\)\\)"
211 (if (not (match-string 2))
212 (push (match-string 1) options
)
213 (push (concat "--" (match-string 3)) options
)
214 (push (concat "--no" (match-string 3)) options
)))
215 (nreverse options
)))))
217 (defun pcmpl-x-ack-type-options ()
218 "A list of types for the `ack' command."
219 (pcmpl-x-ack-long-options "--help-types"))
222 (defun pcomplete/ack
()
223 "Completion for the `ack' command.
224 Start an argument with '-' to complete short options and '--' for
228 (if (pcomplete-match "^-" 0)
230 ((pcomplete-match "^--color-\\w+=\\(\\S-*\\)" 0)
231 (pcomplete-here* pcmpl-x-ack-color-options
232 (pcomplete-match-string 1 0) t
))
233 ((pcomplete-match "^--\\(?:no\\)?ignore-dir=\\(\\S-*\\)" 0)
234 (pcomplete-here* (pcomplete-dirs)
235 (pcomplete-match-string 1 0) t
))
236 ((pcomplete-match "^--type=\\(\\S-*\\)" 0)
237 (pcomplete-here* (mapcar (lambda (type-option)
238 (substring type-option
2))
239 (pcmpl-x-ack-type-options))
240 (pcomplete-match-string 1 0) t
))
241 ((pcomplete-match "^--" 0)
242 (pcomplete-here* (append (pcmpl-x-ack-long-options)
243 (pcmpl-x-ack-type-options))))
244 (t (pcomplete-opt (pcmpl-x-ack-short-options))))
245 (pcomplete-here* (pcomplete-dirs-or-entries)))))
248 (defalias 'pcomplete
/ack-grep
'pcomplete
/ack
)
251 ;;;; the_silver_search - https://github.com/ggreer/the_silver_searcher
253 (defvar pcmpl-x-ag-options nil
)
255 (defun pcmpl-x-ag-options ()
256 (or pcmpl-x-ag-options
257 (setq pcmpl-x-ag-options
259 (when (zerop (call-process "ag" nil t nil
"--help"))
261 (goto-char (point-min))
262 (while (re-search-forward "^ +\\(-[a-zA-Z]\\) " nil t
)
263 (push (match-string 1) short
))
264 (goto-char (point-min))
265 (while (re-search-forward
266 "^ +\\(?:-[a-zA-Z] \\)?\\(--\\(\\[no\\]\\)?[^ \t\n]+\\) "
270 (replace-match "" nil nil nil
2)
271 (push (match-string 1) long
)
272 (replace-match "no" nil nil nil
2)
273 (push (match-string 1) long
))
274 (push (match-string 1) long
)))
275 (list (cons 'short
(nreverse short
))
276 (cons 'long
(nreverse long
)))))))))
279 (defun pcomplete/ag
()
280 "Completion for the `ag' command."
282 (if (pcomplete-match "^-" 0)
283 (pcomplete-here* (cdr (assq (if (pcomplete-match "^--" 0) 'long
'short
)
284 (pcmpl-x-ag-options))))
285 (pcomplete-here* (pcomplete-dirs-or-entries)))))
288 ;;; pcmpl-x.el ends here