changelog shortlog tags changeset files revisions annotate raw

regex-tool.el

changeset 66: 5b737eefe5ea
author: kim.vanwyk
date: Wed Nov 10 15:19:03 2010 +0200 (18 months ago)
permissions: -rw-r--r--
description: Adding CSharp Mode and Google Weather
1;;; regex-tool --- A regular expression evaluation tool for programmers
2
3;; Copyright (C) 2007 John Wiegley
4
5;; Author: John Wiegley <johnw@newartisans.com>
6;; Created: 29 Oct 2007
7;; Modified: 17 Nov 2007
8;; Version: 1.2
9;; Keywords: regex languages programming development
10;; X-URL: http://www.newartisans.com/
11
12;; This program is free software; you can redistribute it and/or
13;; modify it under the terms of the GNU General Public License as
14;; published by the Free Software Foundation; either version 2, or (at
15;; your option) any later version.
16
17;; This program is distributed in the hope that it will be useful, but
18;; WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20;; General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;; This program currently uses frames only.
30;;
31;; After you type M-x regex-tool, you will see three buffers: *Regex*, *Text*
32;; and *Groups*. The *Regex* buffer contains your regular expression. By
33;; default, this tool uses Emacs regular expressions. If you customize the
34;; variable `regex-tool-backend', you can switch to using full Perl regular
35;; expressions.
36;;
37;; The *Text* buffer contains the sample text you want to match against.
38;; Change this however you like.
39;;
40;; The *Groups* buffer will list out any regular expression groups that match.
41;; Your regular expression is searched for as many times as it appears in the
42;; buffer, and any groups that match will be repeated.
43;;
44;; The results are updated as you type in either the *Regex* or *Text* buffer.
45;; Use C-c C-c to force an update. Use C-c C-k to quit all the regex-tool
46;; buffers and remove the frame.
47
48;;; Version History:
49
50;; 1.1 - Don't die horribly if the user simply types '^' or '$'
51;; 1.2 - Include cl.el at compile time
52
53(eval-when-compile
54 (require 'cl))
55
56(defgroup regex-tool nil
57 "Outline-based notes management and organizer."
58 :tag "Org"
59 :group 'programming)
60
61(defvar regex-tool-mode-map (make-sparse-keymap))
62(defvar regex-tool-mode-abbrev-table)
63
64(define-derived-mode regex-tool-mode text-mode "Regex Tool"
65 "This is regex-tool mode."
66 (define-key regex-tool-mode-map [(control ?c) (control ?c)]
67 'regex-tool-markup-text)
68 (define-key regex-tool-mode-map [(control ?c) (control ?k)]
69 'regex-tool-quit)
70 (add-hook 'after-change-functions 'regex-tool-markup-text nil t))
71
72(defface regex-tool-matched-face
73 '((((background light)) (:foreground "Red" :bold t))
74 (((background dark)) (:foreground "Orange" :bold t)))
75 ""
76 :group 'regex-tool)
77
78(defcustom regex-tool-backend 'emacs
79 "The backend used to process regular expressions.
80The `emacs' backend handles regular expressions directly.
81The `perl' backend talks to a perl subprocess to do the handling.\"
82"
83 :type '(choice
84 (const :tag "Emacs" emacs)
85 (const :tag "Perl" perl))
86 :group 'regex-tool)
87
88(defun regex-render-perl (regex sample)
89 (with-temp-buffer
90 (insert (format "@lines = <DATA>;
91$line = join(\" \", @lines);
92print \"(\";
93while ($line =~ m/%s/mg) {
94 print \"(\", length($`), \" \", length($&), \" \";
95 for $i (1 .. 20) {
96 if ($$i) {
97 print \"(\", $i, \" . \\\"\", $$i, \"\\\") \";
98 }
99 }
100 print \")\";
101}
102print \")\";
103__DATA__
104%s" regex sample))
105 (call-process-region (point-min) (point-max) "perl" t t)
106 (goto-char (point-min))
107 (read (current-buffer))))
108
109(defvar regex-expr-buffer nil)
110(defvar regex-text-buffer nil)
111(defvar regex-group-buffer nil)
112
113(defun regex-tool ()
114 (interactive)
115 (select-frame (make-frame-command))
116 (split-window-vertically)
117 (split-window-vertically)
118 (balance-windows)
119 (setq regex-expr-buffer (get-buffer-create "*Regex*"))
120 (switch-to-buffer regex-expr-buffer)
121 (regex-tool-mode)
122 (other-window 1)
123 (setq regex-text-buffer (get-buffer-create "*Text*"))
124 (switch-to-buffer regex-text-buffer)
125 (goto-char (point-min))
126 (if (eolp)
127 (insert "Hello, this is text your regular expression will match against."))
128 (regex-tool-mode)
129 (other-window 1)
130 (setq regex-group-buffer (get-buffer-create "*Groups*"))
131 (switch-to-buffer regex-group-buffer)
132 (other-window 1))
133
134(defun regex-tool-markup-text (&optional beg end len)
135 (interactive)
136 (let ((regex (with-current-buffer regex-expr-buffer
137 (buffer-string)))
138 previous-point)
139 (when (> (length regex) 0)
140 (with-current-buffer regex-group-buffer
141 (erase-buffer))
142 (with-current-buffer regex-text-buffer
143 (remove-overlays)
144 (save-excursion
145 (ignore-errors
146 (goto-char (point-min))
147 (if (eq regex-tool-backend 'emacs)
148 (while (and (setq previous-point (point))
149 (re-search-forward regex nil t))
150 (if (= (point) previous-point)
151 (forward-char 1)
152 (overlay-put (make-overlay (match-beginning 0)
153 (match-end 0))
154 'face 'regex-tool-matched-face)
155 (dotimes (i 10)
156 (let ((text (match-string i)))
157 (if text
158 (save-match-data
159 (with-current-buffer regex-group-buffer
160 (goto-char (point-max))
161 (insert (format "Group %d: '%s'\n" i text)))))))
162 (with-current-buffer regex-group-buffer
163 (insert ?\n))))
164 (let ((results (regex-render-perl regex (buffer-string))))
165 (dolist (result results)
166 (let ((offset (nth 0 result))
167 (length (nth 1 result))
168 (matches (nthcdr 2 result)))
169 (overlay-put (make-overlay (1+ offset) (+ offset length 1))
170 'face 'regex-tool-matched-face)
171 (let ((match-zero (buffer-substring (1+ offset)
172 (+ offset length 1))))
173 (with-current-buffer regex-group-buffer
174 (insert (format "Group 0: '%s'\n" match-zero))))
175 (dolist (match matches)
176 (with-current-buffer regex-group-buffer
177 (goto-char (point-max))
178 (insert (format "Group %d: '%s'\n" (car match)
179 (cdr match)))))
180 (with-current-buffer regex-group-buffer
181 (insert ?\n)))))))))
182 (with-current-buffer regex-group-buffer
183 (goto-char (point-min))))))
184
185(defun regex-tool-quit ()
186 (interactive)
187 (kill-buffer regex-expr-buffer)
188 (kill-buffer regex-text-buffer)
189 (kill-buffer regex-group-buffer)
190 (delete-frame))
191
192(provide 'regex-tool)
193
194;; regex-tool.el ends here