implement egrep.el
[emacs-egrep.git] / egrep.el
1 (defun egrep-regexps-1 (result-buffer regexp predicate args)
2   (let ((file-name (buffer-file-name)))
3     (save-excursion
4       (goto-char (point-min))
5       (while (re-search-forward regexp nil t)
6         (if (or (not predicate) (apply predicate args))
7             (let ((line (count-lines (point-min) (point)))
8                   (column (current-column))
9                   (text (buffer-substring (save-excursion (beginning-of-line) (point))
10                                           (save-excursion (end-of-line) (point)))))
11             (with-current-buffer result-buffer
12               (let ((inhibit-read-only t))
13                 (insert (format "%s:%d:%d: %s\n"
14                                 (dired-make-relative file-name default-directory)
15                                 line column text))))))))))
16
17 (defun egrep-prepare-result-buffer ()
18   (let ((result-buffer (get-buffer-create "*search*")))
19     (with-current-buffer result-buffer
20       (let ((inhibit-read-only t))
21         (grep-mode)
22         (erase-buffer)
23         (insert (format "; Searching for '%s' ...\n" regexp))))
24     result-buffer))
25
26 (defun egrep-finalize-result-buffer (result-buffer)
27   (pop-to-buffer result-buffer)
28   (goto-char (point-min)))
29
30 (defun egrep-regexps (regexp &optional predicate &rest args)
31   (interactive "sRegexp: ")
32   (let ((result-buffer (egrep-prepare-result-buffer)))
33     (egrep-regexps-1 result-buffer regexp predicate args)
34     (egrep-finalize-result-buffer result-buffer)))
35
36 (defun egrep-font-face-predicate (face-symbol)
37   (eq (get-text-property (point) 'face) face-symbol))
38
39 (defun egrep-regexps-with-face (regexp face-symbol)
40   (interactive (list (read-string "Regexp: ")
41                      (intern (completing-read "Face symbol: "
42                                               (mapcar (lambda (face) (symbol-name face)) (face-list))
43                                               nil t))))
44   (egrep-regexps regexp 'egrep-font-face-predicate face-symbol))
45
46 (defun egrep-regexps-dired-marked-files (regexp &optional prepare predicate &rest args)
47   (interactive "sRegexp: ")
48   (let ((result-buffer (egrep-prepare-result-buffer)))
49     (loop for file-name in (dired-get-marked-files nil current-prefix-arg)
50           do (let ((buffer (find-file-noselect file-name)))
51                (with-current-buffer buffer
52                  (if prepare (funcall prepare))
53                  (egrep-regexps-1 result-buffer regexp predicate args))))
54     (egrep-finalize-result-buffer result-buffer)))
55
56 (defun egrep-string-startswith (string start)
57   (and (> (length string) (length start))
58        (string= (substring string 0 (length start)) start)))
59
60 (defun egrep-grep-list (func list)
61   (let (r)
62     (while list
63       (if (funcall func (car list))
64           (setq r (cons (car list) r)))
65       (setq list (cdr list)))
66     (nreverse r)))
67
68 (defun egrep-read-font-lock-face (prompt &optional predicate initial hist default inherit-input-method)
69   (intern (completing-read prompt
70                            (egrep-grep-list (lambda (font) (egrep-string-startswith font "font-lock-"))
71                                             (mapcar (lambda (face) (symbol-name face)) (face-list)))
72                            predicate  t (or initial "font-lock-") hist default inherit-input-method)))
73
74 (defun egrep-regexps-with-face-dired-marked-files (regexp face-symbol)
75   (interactive (list (read-string "Regexp: ")
76                      (egrep-read-font-lock-face "Font symbol: ")))
77   (egrep-regexps-dired-marked-files regexp
78                                     (lambda ()
79                                       (font-lock-fontify-buffer)
80                                       (htmlize-ensure-fontified))
81                                     'egrep-font-face-predicate
82                                     face-symbol))