]> code.delx.au - gnu-emacs-elpa/blob - packages/ack/pcmpl-ack.el
Fix some quoting problems in doc strings
[gnu-emacs-elpa] / packages / ack / pcmpl-ack.el
1 ;;; pcmpl-ack.el --- completion for ack and ag -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
4
5 ;; Author: Leo Liu <sdl.web@gmail.com>
6 ;; Keywords: tools, processes, convenience
7 ;; Created: 2012-09-26
8 ;; URL: https://github.com/leoliu/ack-el
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23 ;;; Commentary:
24
25 ;; Provide pcompletion support for the cli tool `ack' which can be
26 ;; downloaded from http://beyondgrep.com.
27 ;;
28 ;; Install:
29 ;; (autoload 'pcomplete/ack "pcmpl-ack")
30 ;; (autoload 'pcomplete/ag "pcmpl-ack")
31 ;;
32 ;; Usage:
33 ;; - To complete short options type '-' first
34 ;; - To complete long options type '--' first
35 ;; - Color name completion is supported following
36 ;; --color-filename=, --color-match= and --color-lineno=
37 ;; - Type completion is supported following --type=
38
39 ;;; Code:
40
41 (require 'pcomplete)
42
43 (defcustom pcmpl-ack-program
44 (file-name-nondirectory (or (executable-find "ack-grep")
45 (executable-find "ack")
46 "ack"))
47 "Name of the ack program."
48 :type 'file
49 :group 'pcomplete)
50
51 (defvar pcmpl-ack-color-options
52 '("clear"
53 "reset"
54 "dark"
55 "bold"
56 "underline"
57 "underscore"
58 "blink"
59 "reverse"
60 "concealed"
61 "black"
62 "red"
63 "green"
64 "yellow"
65 "blue"
66 "magenta"
67 "on_black"
68 "on_red"
69 "on_green"
70 "on_yellow"
71 "on_blue"
72 "on_magenta"
73 "on_cyan"
74 "on_white")
75 "Color names for the `ack' command.")
76
77 (defun pcmpl-ack-run (buffer &rest args)
78 "Run ack with ARGS and send the output to BUFFER."
79 (condition-case nil
80 (apply 'call-process (or pcmpl-ack-program "ack") nil buffer nil args)
81 (file-error -1)))
82
83 (defun pcmpl-ack-short-options ()
84 "Short options for the `ack' command."
85 (with-temp-buffer
86 (let (options)
87 (when (zerop (pcmpl-ack-run t "--help"))
88 (goto-char (point-min))
89 (while (re-search-forward "^ -\\([^-]\\)" nil t)
90 (push (match-string 1) options))
91 (mapconcat 'identity (nreverse options) "")))))
92
93 (defun pcmpl-ack-long-options (&optional arg)
94 "Long options for the `ack' command."
95 (with-temp-buffer
96 (let (options)
97 (when (zerop (pcmpl-ack-run t (or arg "--help")))
98 (goto-char (point-min))
99 (while (re-search-forward
100 "\\(?: ?\\|, \\)\\(--\\(\\[no\\]\\)?\\([[:alnum:]-]+=?\\)\\)"
101 nil t)
102 (if (not (match-string 2))
103 (push (match-string 1) options)
104 (push (concat "--" (match-string 3)) options)
105 (push (concat "--no" (match-string 3)) options)))
106 (nreverse options)))))
107
108 (defun pcmpl-ack-type-options ()
109 "A list of types for the `ack' command."
110 (pcmpl-ack-long-options "--help-types"))
111
112 ;;;###autoload
113 (defun pcomplete/ack ()
114 "Completion for the `ack' command.
115 Start an argument with `-' to complete short options and `--' for
116 long options."
117 ;; No space after =
118 (while t
119 (if (pcomplete-match "^-" 0)
120 (cond
121 ((pcomplete-match "^--color-\\w+=\\(\\S-*\\)" 0)
122 (pcomplete-here* pcmpl-ack-color-options
123 (pcomplete-match-string 1 0) t))
124 ((pcomplete-match "^--\\(?:no\\)?ignore-dir=\\(\\S-*\\)" 0)
125 (pcomplete-here* (pcomplete-dirs)
126 (pcomplete-match-string 1 0) t))
127 ((pcomplete-match "^--type=\\(\\S-*\\)" 0)
128 (pcomplete-here* (mapcar (lambda (type-option)
129 (substring type-option 2))
130 (pcmpl-ack-type-options))
131 (pcomplete-match-string 1 0) t))
132 ((pcomplete-match "^--" 0)
133 (pcomplete-here* (append (pcmpl-ack-long-options)
134 (pcmpl-ack-type-options))))
135 (t (pcomplete-opt (pcmpl-ack-short-options))))
136 (pcomplete-here* (pcomplete-dirs-or-entries)))))
137
138 ;;;###autoload
139 (defalias 'pcomplete/ack-grep 'pcomplete/ack)
140
141 (defvar pcmpl-ack-ag-options nil)
142
143 (defun pcmpl-ack-ag-options ()
144 (or pcmpl-ack-ag-options
145 (setq pcmpl-ack-ag-options
146 (with-temp-buffer
147 (when (zerop (call-process "ag" nil t nil "--help"))
148 (let (short long)
149 (goto-char (point-min))
150 (while (re-search-forward "^ +\\(-[a-zA-Z]\\) " nil t)
151 (push (match-string 1) short))
152 (goto-char (point-min))
153 (while (re-search-forward
154 "^ +\\(?:-[a-zA-Z] \\)?\\(--\\(\\[no\\]\\)?[^ \t\n]+\\) "
155 nil t)
156 (if (match-string 2)
157 (progn
158 (replace-match "" nil nil nil 2)
159 (push (match-string 1) long)
160 (replace-match "no" nil nil nil 2)
161 (push (match-string 1) long))
162 (push (match-string 1) long)))
163 (list (cons 'short (nreverse short))
164 (cons 'long (nreverse long)))))))))
165
166 ;;;###autoload
167 (defun pcomplete/ag ()
168 "Completion for the `ag' command."
169 (while t
170 (if (pcomplete-match "^-" 0)
171 (pcomplete-here* (cdr (assq (if (pcomplete-match "^--" 0) 'long 'short)
172 (pcmpl-ack-ag-options))))
173 (pcomplete-here* (pcomplete-dirs-or-entries)))))
174
175 (provide 'pcmpl-ack)
176 ;;; pcmpl-ack.el ends here