1 ;;; pcmpl-x.el --- completion for miscellaneous tools -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2013-2018 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 <https://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."
38 (defvar pcmpl-x-tlmgr-common-options
45 "--persistent-downloads"
46 "--no-persistent-downloads"
47 "--no-execute-actions"
52 (defvar pcmpl-x-tlmgr-actions
61 ("repository" ("list" "add" "remove" "set"))
78 ("conf" ("texmf" "tlmgr"))
80 ("a4" "letter" "xdvi" "pdftex" "dvips" "dvipdfmx" "dvipdfm" "context")
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"))
92 ("check" ("files" "depends" "executes" "runfiles" "all"))
93 ("path" ("add" "remove"))
94 ("postaction" ("install" "remove") ("shortcut" "fileassoc" "script"))
96 ("generate" ("language"
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
)
109 (call-process pcmpl-x-tlmgr-program nil t nil action
"-h"))
110 (goto-char (point-min))
113 (cl-loop while
(re-search-forward
114 "^[ \t]+\\(--[[:alnum:]-]+=?\\)"
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
)))
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))))
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
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")
157 "Name of the ack program."
162 (defvar pcmpl-x-ack-color-options
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."
191 (apply 'call-process
(or pcmpl-x-ack-program
"ack") nil buffer nil args
)
194 (defun pcmpl-x-ack-short-options ()
195 "Short options for the `ack' command."
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."
208 (when (zerop (pcmpl-x-ack-run t
(or arg
"--help")))
209 (goto-char (point-min))
210 (while (re-search-forward
211 "\\(?: ?\\|, \\)\\(--\\(\\[no\\]\\)?\\([[:alnum:]-]+=?\\)\\)"
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"))
224 (defun pcomplete/ack
()
225 "Completion for the `ack' command.
226 Start an argument with `-' to complete short options and `--' for
230 (if (pcomplete-match "^-" 0)
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)))))
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
261 (when (zerop (call-process "ag" nil t nil
"--help"))
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]+\\) "
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
)))))))))
281 (defun pcomplete/ag
()
282 "Completion for the `ag' command."
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)))))
290 ;;; pcmpl-x.el ends here