Mercurial > emacs
comparison lisp/emacs-lisp/re-builder.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 0d8b17d428b5 |
children |
comparison
equal
deleted
inserted
replaced
88154:8ce476d3ba36 | 88155:d7ddb3e565de |
---|---|
1 ;;; re-builder.el --- building Regexps with visual feedback | 1 ;;; re-builder.el --- building Regexps with visual feedback |
2 | 2 |
3 ;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, |
4 ;; 2005 Free Software Foundation, Inc. | |
4 | 5 |
5 ;; Author: Detlev Zundel <dzu@gnu.org> | 6 ;; Author: Detlev Zundel <dzu@gnu.org> |
6 ;; Keywords: matching, lisp, tools | 7 ;; Keywords: matching, lisp, tools |
7 | 8 |
8 ;; This file is part of GNU Emacs. | 9 ;; This file is part of GNU Emacs. |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 ;; GNU General Public License for more details. | 19 ;; GNU General Public License for more details. |
19 | 20 |
20 ;; You should have received a copy of the GNU General Public License | 21 ;; You should have received a copy of the GNU General Public License |
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 22 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
23 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02110-1301, USA. |
24 | 25 |
25 ;;; Commentary: | 26 ;;; Commentary: |
26 | 27 |
27 ;; When I have to come up with regular expressions that are more | 28 ;; When I have to come up with regular expressions that are more |
28 ;; complex than simple string matchers, especially if they contain sub | 29 ;; complex than simple string matchers, especially if they contain sub |
43 ;; shown only in the modeline without throwing the errors at you. If | 44 ;; shown only in the modeline without throwing the errors at you. If |
44 ;; you want to know the reason why RE Builder considers it as invalid | 45 ;; you want to know the reason why RE Builder considers it as invalid |
45 ;; call `reb-force-update' ("\C-c\C-u") which should reveal the error. | 46 ;; call `reb-force-update' ("\C-c\C-u") which should reveal the error. |
46 | 47 |
47 ;; The target buffer can be changed with `reb-change-target-buffer' | 48 ;; The target buffer can be changed with `reb-change-target-buffer' |
48 ;; ("\C-c\C-b"). Changing the target buffer automatically removes | 49 ;; ("\C-c\C-b"). Changing the target buffer automatically removes |
49 ;; the overlays from the old buffer and displays the new one in the | 50 ;; the overlays from the old buffer and displays the new one in the |
50 ;; target window. | 51 ;; target window. |
51 | 52 |
52 ;; The `re-builder' keeps the focus while updating the matches in the | 53 ;; The `re-builder' keeps the focus while updating the matches in the |
53 ;; target buffer so corrections are easy to incorporate. If you are | 54 ;; target buffer so corrections are easy to incorporate. If you are |
59 ;; can be limited by `reb-auto-match-limit' so that they should not | 60 ;; can be limited by `reb-auto-match-limit' so that they should not |
60 ;; have a negative impact on the editing. Setting it to nil makes | 61 ;; have a negative impact on the editing. Setting it to nil makes |
61 ;; even the auto updates go all the way. Forcing an update overrides | 62 ;; even the auto updates go all the way. Forcing an update overrides |
62 ;; this limit allowing an easy way to see all matches. | 63 ;; this limit allowing an easy way to see all matches. |
63 | 64 |
64 ;; Currently `re-builder' understands four different forms of input, | 65 ;; Currently `re-builder' understands five different forms of input, |
65 ;; namely `read', `string', `sregex' and `lisp-re' syntax. Read | 66 ;; namely `read', `string', `rx', `sregex' and `lisp-re' syntax. Read |
66 ;; syntax and string syntax are both delimited by `"'s and behave | 67 ;; syntax and string syntax are both delimited by `"'s and behave |
67 ;; according to their name. With the `string' syntax there's no need | 68 ;; according to their name. With the `string' syntax there's no need |
68 ;; to escape the backslashes and double quotes simplifying the editing | 69 ;; to escape the backslashes and double quotes simplifying the editing |
69 ;; somewhat. The other two allow editing of symbolic regular | 70 ;; somewhat. The other three allow editing of symbolic regular |
70 ;; expressions supported by the packages of the same name. (`lisp-re' | 71 ;; expressions supported by the packages of the same name. (`lisp-re' |
71 ;; is a package by me and its support may go away as it is nearly the | 72 ;; is a package by me and its support may go away as it is nearly the |
72 ;; same as the `sregex' package in Emacs) | 73 ;; same as the `sregex' package in Emacs) |
73 | 74 |
74 ;; Editing symbolic expressions is done through a major mode derived | 75 ;; Editing symbolic expressions is done through a major mode derived |
133 :group 're-builder | 134 :group 're-builder |
134 :type '(choice (const :tag "Read syntax" read) | 135 :type '(choice (const :tag "Read syntax" read) |
135 (const :tag "String syntax" string) | 136 (const :tag "String syntax" string) |
136 (const :tag "`sregex' syntax" sregex) | 137 (const :tag "`sregex' syntax" sregex) |
137 (const :tag "`lisp-re' syntax" lisp-re) | 138 (const :tag "`lisp-re' syntax" lisp-re) |
139 (const :tag "`rx' syntax" rx) | |
138 (value: string))) | 140 (value: string))) |
139 | 141 |
140 (defcustom reb-auto-match-limit 200 | 142 (defcustom reb-auto-match-limit 200 |
141 "*Positive integer limiting the matches for RE Builder auto updates. | 143 "*Positive integer limiting the matches for RE Builder auto updates. |
142 Set it to nil if you don't want limits here." | 144 Set it to nil if you don't want limits here." |
174 :inverse-video t)) | 176 :inverse-video t)) |
175 "Used for displaying the second matching subexpression." | 177 "Used for displaying the second matching subexpression." |
176 :group 're-builder) | 178 :group 're-builder) |
177 | 179 |
178 (defface reb-match-3 | 180 (defface reb-match-3 |
179 '((((class color) (background light)) | 181 '((((min-colors 88) (class color) (background light)) |
182 :background "yellow1") | |
183 (((class color) (background light)) | |
180 :background "yellow") | 184 :background "yellow") |
181 (((class color) (background dark)) | 185 (((class color) (background dark)) |
182 :background "sienna4") | 186 :background "sienna4") |
183 (t | 187 (t |
184 :inverse-video t)) | 188 :inverse-video t)) |
226 | 230 |
227 (defconst reb-buffer "*RE-Builder*" | 231 (defconst reb-buffer "*RE-Builder*" |
228 "Buffer to use for the RE Builder.") | 232 "Buffer to use for the RE Builder.") |
229 | 233 |
230 ;; Define the local "\C-c" keymap | 234 ;; Define the local "\C-c" keymap |
231 (defvar reb-mode-map nil | 235 (defvar reb-mode-map |
236 (let ((map (make-sparse-keymap))) | |
237 (define-key map "\C-c\C-c" 'reb-toggle-case) | |
238 (define-key map "\C-c\C-q" 'reb-quit) | |
239 (define-key map "\C-c\C-w" 'reb-copy) | |
240 (define-key map "\C-c\C-s" 'reb-next-match) | |
241 (define-key map "\C-c\C-r" 'reb-prev-match) | |
242 (define-key map "\C-c\C-i" 'reb-change-syntax) | |
243 (define-key map "\C-c\C-e" 'reb-enter-subexp-mode) | |
244 (define-key map "\C-c\C-b" 'reb-change-target-buffer) | |
245 (define-key map "\C-c\C-u" 'reb-force-update) | |
246 map) | |
232 "Keymap used by the RE Builder.") | 247 "Keymap used by the RE Builder.") |
233 | |
234 (if (not reb-mode-map) | |
235 (progn | |
236 (setq reb-mode-map (make-sparse-keymap)) | |
237 (define-key reb-mode-map "\C-c\C-c" 'reb-toggle-case) | |
238 (define-key reb-mode-map "\C-c\C-q" 'reb-quit) | |
239 (define-key reb-mode-map "\C-c\C-w" 'reb-copy) | |
240 (define-key reb-mode-map "\C-c\C-s" 'reb-next-match) | |
241 (define-key reb-mode-map "\C-c\C-r" 'reb-prev-match) | |
242 (define-key reb-mode-map "\C-c\C-i" 'reb-change-syntax) | |
243 (define-key reb-mode-map "\C-c\C-e" 'reb-enter-subexp-mode) | |
244 (define-key reb-mode-map "\C-c\C-b" 'reb-change-target-buffer) | |
245 (define-key reb-mode-map "\C-c\C-u" 'reb-force-update))) | |
246 | 248 |
247 (defun reb-mode () | 249 (defun reb-mode () |
248 "Major mode for interactively building Regular Expressions. | 250 "Major mode for interactively building Regular Expressions. |
249 \\{reb-mode-map}" | 251 \\{reb-mode-map}" |
250 (interactive) | 252 (interactive) |
251 (kill-all-local-variables) | 253 (kill-all-local-variables) |
252 (setq major-mode 'reb-mode | 254 (setq major-mode 'reb-mode |
253 mode-name "RE Builder") | 255 mode-name "RE Builder") |
254 (use-local-map reb-mode-map) | 256 (use-local-map reb-mode-map) |
255 (reb-mode-common) | 257 (reb-mode-common) |
256 (run-hooks 'reb-mode-hook)) | 258 (run-mode-hooks 'reb-mode-hook)) |
257 | 259 |
258 (define-derived-mode reb-lisp-mode | 260 (define-derived-mode reb-lisp-mode |
259 emacs-lisp-mode "RE Builder Lisp" | 261 emacs-lisp-mode "RE Builder Lisp" |
260 "Major mode for interactively building symbolic Regular Expressions." | 262 "Major mode for interactively building symbolic Regular Expressions." |
261 (cond ((eq reb-re-syntax 'lisp-re) ; Pull in packages | 263 (cond ((eq reb-re-syntax 'lisp-re) ; Pull in packages |
262 (require 'lisp-re)) ; as needed | 264 (require 'lisp-re)) ; as needed |
263 ((eq reb-re-syntax 'sregex) ; sregex is not autoloaded | 265 ((eq reb-re-syntax 'sregex) ; sregex is not autoloaded |
264 (require 'sregex))) ; right now.. | 266 (require 'sregex)) ; right now.. |
267 ((eq reb-re-syntax 'rx) ; rx-to-string is autoloaded | |
268 (require 'rx))) ; require rx anyway | |
265 (reb-mode-common)) | 269 (reb-mode-common)) |
266 | 270 |
267 ;; Use the same "\C-c" keymap as `reb-mode' and use font-locking from | 271 ;; Use the same "\C-c" keymap as `reb-mode' and use font-locking from |
268 ;; `emacs-lisp-mode' | 272 ;; `emacs-lisp-mode' |
269 (define-key reb-lisp-mode-map "\C-c" | 273 (define-key reb-lisp-mode-map "\C-c" |
294 ;; At least make the overlays go away if the buffer is killed | 298 ;; At least make the overlays go away if the buffer is killed |
295 (make-local-variable 'reb-kill-buffer) | 299 (make-local-variable 'reb-kill-buffer) |
296 (add-hook 'kill-buffer-hook 'reb-kill-buffer) | 300 (add-hook 'kill-buffer-hook 'reb-kill-buffer) |
297 (reb-auto-update nil nil nil)) | 301 (reb-auto-update nil nil nil)) |
298 | 302 |
299 | |
300 ;; Handy macro for doing things in other windows | |
301 (defmacro reb-with-current-window (window &rest body) | |
302 "With WINDOW selected evaluate BODY forms and reselect previous window." | |
303 | |
304 (let ((oldwindow (make-symbol "*oldwindow*"))) | |
305 `(let ((,oldwindow (selected-window))) | |
306 (select-window ,window) | |
307 (unwind-protect | |
308 (progn | |
309 ,@body) | |
310 (select-window ,oldwindow))))) | |
311 (put 'reb-with-current-window 'lisp-indent-function 0) | |
312 | |
313 (defun reb-color-display-p () | 303 (defun reb-color-display-p () |
314 "Return t if display is capable of displaying colors." | 304 "Return t if display is capable of displaying colors." |
315 (eq 'color | 305 (eq 'color |
316 ;; emacs/xemacs compatibility | 306 ;; emacs/xemacs compatibility |
317 (if (fboundp 'frame-parameter) | 307 (if (fboundp 'frame-parameter) |
318 (frame-parameter (selected-frame) 'display-type) | 308 (frame-parameter (selected-frame) 'display-type) |
319 (frame-property (selected-frame) 'display-type)))) | 309 (if (fboundp 'frame-property) |
310 (frame-property (selected-frame) 'display-type))))) | |
320 | 311 |
321 (defsubst reb-lisp-syntax-p () | 312 (defsubst reb-lisp-syntax-p () |
322 "Return non-nil if RE Builder uses a Lisp syntax." | 313 "Return non-nil if RE Builder uses a Lisp syntax." |
323 (memq reb-re-syntax '(lisp-re sregex))) | 314 (memq reb-re-syntax '(lisp-re sregex rx))) |
324 | 315 |
325 (defmacro reb-target-binding (symbol) | 316 (defmacro reb-target-binding (symbol) |
326 "Return binding for SYMBOL in the RE Builder target buffer." | 317 "Return binding for SYMBOL in the RE Builder target buffer." |
327 `(with-current-buffer reb-target-buffer ,symbol)) | 318 `(with-current-buffer reb-target-buffer ,symbol)) |
328 | 319 |
320 (defun reb-initialize-buffer () | |
321 "Initialize the current buffer as a RE Builder buffer." | |
322 (erase-buffer) | |
323 (reb-insert-regexp) | |
324 (goto-char (+ 2 (point-min))) | |
325 (cond ((reb-lisp-syntax-p) | |
326 (reb-lisp-mode)) | |
327 (t (reb-mode)))) | |
328 | |
329 ;;; This is to help people find this in Apropos. | |
330 ;;;###autoload | |
331 (defalias 'regexp-builder 're-builder) | |
329 | 332 |
330 ;;;###autoload | 333 ;;;###autoload |
331 (defun re-builder () | 334 (defun re-builder () |
332 "Call up the RE Builder for the current window." | 335 "Construct a regexp interactively." |
333 (interactive) | 336 (interactive) |
334 | 337 |
335 (if (and (string= (buffer-name) reb-buffer) | 338 (if (and (string= (buffer-name) reb-buffer) |
336 (memq major-mode '(reb-mode reb-lisp-mode))) | 339 (memq major-mode '(reb-mode reb-lisp-mode))) |
337 (message "Already in the RE Builder") | 340 (message "Already in the RE Builder") |
340 (setq reb-target-buffer (current-buffer) | 343 (setq reb-target-buffer (current-buffer) |
341 reb-target-window (selected-window) | 344 reb-target-window (selected-window) |
342 reb-window-config (current-window-configuration)) | 345 reb-window-config (current-window-configuration)) |
343 (select-window (split-window (selected-window) (- (window-height) 4))) | 346 (select-window (split-window (selected-window) (- (window-height) 4))) |
344 (switch-to-buffer (get-buffer-create reb-buffer)) | 347 (switch-to-buffer (get-buffer-create reb-buffer)) |
345 (erase-buffer) | 348 (reb-initialize-buffer))) |
346 (reb-insert-regexp) | |
347 (goto-char (+ 2 (point-min))) | |
348 (cond | |
349 ((reb-lisp-syntax-p) | |
350 (reb-lisp-mode)) | |
351 (t (reb-mode))))) | |
352 | 349 |
353 (defun reb-change-target-buffer (buf) | 350 (defun reb-change-target-buffer (buf) |
354 "Change the target buffer and display it in the target window." | 351 "Change the target buffer and display it in the target window." |
355 (interactive "bSet target buffer to: ") | 352 (interactive "bSet target buffer to: ") |
356 | 353 |
362 (reb-do-update | 359 (reb-do-update |
363 (if reb-subexp-mode reb-subexp-displayed nil)) | 360 (if reb-subexp-mode reb-subexp-displayed nil)) |
364 (reb-update-modestring)))) | 361 (reb-update-modestring)))) |
365 | 362 |
366 (defun reb-force-update () | 363 (defun reb-force-update () |
367 "Forces an update in the RE Builder target window without a match limit." | 364 "Force an update in the RE Builder target window without a match limit." |
368 (interactive) | 365 (interactive) |
369 | 366 |
370 (let ((reb-auto-match-limit nil)) | 367 (let ((reb-auto-match-limit nil)) |
371 (reb-update-overlays | 368 (reb-update-overlays |
372 (if reb-subexp-mode reb-subexp-displayed nil)))) | 369 (if reb-subexp-mode reb-subexp-displayed nil)))) |
384 (defun reb-next-match () | 381 (defun reb-next-match () |
385 "Go to next match in the RE Builder target window." | 382 "Go to next match in the RE Builder target window." |
386 (interactive) | 383 (interactive) |
387 | 384 |
388 (reb-assert-buffer-in-window) | 385 (reb-assert-buffer-in-window) |
389 (reb-with-current-window | 386 (with-selected-window reb-target-window |
390 reb-target-window | |
391 (if (not (re-search-forward reb-regexp (point-max) t)) | 387 (if (not (re-search-forward reb-regexp (point-max) t)) |
392 (message "No more matches.") | 388 (message "No more matches.") |
393 (reb-show-subexp | 389 (reb-show-subexp |
394 (or (and reb-subexp-mode reb-subexp-displayed) 0) | 390 (or (and reb-subexp-mode reb-subexp-displayed) 0) |
395 t)))) | 391 t)))) |
397 (defun reb-prev-match () | 393 (defun reb-prev-match () |
398 "Go to previous match in the RE Builder target window." | 394 "Go to previous match in the RE Builder target window." |
399 (interactive) | 395 (interactive) |
400 | 396 |
401 (reb-assert-buffer-in-window) | 397 (reb-assert-buffer-in-window) |
402 (reb-with-current-window reb-target-window | 398 (with-selected-window reb-target-window |
403 (goto-char (1- (point))) | 399 (let ((p (point))) |
404 (if (not (re-search-backward reb-regexp (point-min) t)) | 400 (goto-char (1- p)) |
405 (message "No more matches.") | 401 (if (re-search-backward reb-regexp (point-min) t) |
406 (reb-show-subexp | 402 (reb-show-subexp |
407 (or (and reb-subexp-mode reb-subexp-displayed) 0) | 403 (or (and reb-subexp-mode reb-subexp-displayed) 0) |
408 t)))) | 404 t) |
405 (goto-char p) | |
406 (message "No more matches."))))) | |
409 | 407 |
410 (defun reb-toggle-case () | 408 (defun reb-toggle-case () |
411 "Toggle case sensitivity of searches for RE Builder target buffer." | 409 "Toggle case sensitivity of searches for RE Builder target buffer." |
412 (interactive) | 410 (interactive) |
413 | 411 |
440 "Visually show limit of subexpression SUBEXP of recent search. | 438 "Visually show limit of subexpression SUBEXP of recent search. |
441 On color displays this just puts point to the end of the expression as | 439 On color displays this just puts point to the end of the expression as |
442 the match should already be marked by an overlay. | 440 the match should already be marked by an overlay. |
443 On other displays jump to the beginning and the end of it. | 441 On other displays jump to the beginning and the end of it. |
444 If the optional PAUSE is non-nil then pause at the end in any case." | 442 If the optional PAUSE is non-nil then pause at the end in any case." |
445 (reb-with-current-window reb-target-window | 443 (with-selected-window reb-target-window |
446 (if (not (reb-color-display-p)) | 444 (if (not (reb-color-display-p)) |
447 (progn (goto-char (match-beginning subexp)) | 445 (progn (goto-char (match-beginning subexp)) |
448 (sit-for reb-blink-delay))) | 446 (sit-for reb-blink-delay))) |
449 (goto-char (match-end subexp)) | 447 (goto-char (match-end subexp)) |
450 (if (or (not (reb-color-display-p)) pause) | 448 (if (or (not (reb-color-display-p)) pause) |
464 Optional argument SYNTAX must be specified if called non-interactively." | 462 Optional argument SYNTAX must be specified if called non-interactively." |
465 (interactive | 463 (interactive |
466 (list (intern | 464 (list (intern |
467 (completing-read "Select syntax: " | 465 (completing-read "Select syntax: " |
468 (mapcar (lambda (el) (cons (symbol-name el) 1)) | 466 (mapcar (lambda (el) (cons (symbol-name el) 1)) |
469 '(read string lisp-re sregex)) | 467 '(read string lisp-re sregex rx)) |
470 nil t (symbol-name reb-re-syntax))))) | 468 nil t (symbol-name reb-re-syntax))))) |
471 | 469 |
472 (if (memq syntax '(read string lisp-re sregex)) | 470 (if (memq syntax '(read string lisp-re sregex rx)) |
473 (let ((buffer (get-buffer reb-buffer))) | 471 (let ((buffer (get-buffer reb-buffer))) |
474 (setq reb-re-syntax syntax) | 472 (setq reb-re-syntax syntax) |
475 (if buffer | 473 (when buffer |
476 (with-current-buffer buffer | 474 (with-current-buffer buffer |
477 (erase-buffer) | 475 (reb-initialize-buffer)))) |
478 (reb-insert-regexp) | |
479 (goto-char (+ 2 (point-min))) | |
480 (cond ((reb-lisp-syntax-p) | |
481 (reb-lisp-mode)) | |
482 (t (reb-mode)))))) | |
483 (error "Invalid syntax: %s" syntax))) | 476 (error "Invalid syntax: %s" syntax))) |
484 | 477 |
485 | 478 |
486 ;; Non-interactive functions below | 479 ;; Non-interactive functions below |
487 (defun reb-do-update (&optional subexp) | 480 (defun reb-do-update (&optional subexp) |
492 (reb-update-regexp) | 485 (reb-update-regexp) |
493 (reb-update-overlays subexp)) | 486 (reb-update-overlays subexp)) |
494 | 487 |
495 (defun reb-auto-update (beg end lenold &optional force) | 488 (defun reb-auto-update (beg end lenold &optional force) |
496 "Called from `after-update-functions' to update the display. | 489 "Called from `after-update-functions' to update the display. |
497 BEG END and LENOLD are passed in from the hook. | 490 BEG, END and LENOLD are passed in from the hook. |
498 An actual update is only done if the regexp has changed or if the | 491 An actual update is only done if the regexp has changed or if the |
499 optional fourth argument FORCE is non-nil." | 492 optional fourth argument FORCE is non-nil." |
500 (let ((prev-valid reb-valid-string) | 493 (let ((prev-valid reb-valid-string) |
501 (new-valid | 494 (new-valid |
502 (condition-case nil | 495 (condition-case nil |
546 (defun reb-display-subexp (&optional subexp) | 539 (defun reb-display-subexp (&optional subexp) |
547 "Highlight only subexpression SUBEXP in the RE Builder." | 540 "Highlight only subexpression SUBEXP in the RE Builder." |
548 (interactive) | 541 (interactive) |
549 | 542 |
550 (setq reb-subexp-displayed | 543 (setq reb-subexp-displayed |
551 (or subexp (string-to-int (format "%c" last-command-char)))) | 544 (or subexp (string-to-number (format "%c" last-command-char)))) |
552 (reb-update-modestring) | 545 (reb-update-modestring) |
553 (reb-do-update reb-subexp-displayed)) | 546 (reb-do-update reb-subexp-displayed)) |
554 | 547 |
555 (defun reb-kill-buffer () | 548 (defun reb-kill-buffer () |
556 "When the RE Builder buffer is killed make sure no overlays stay around." | 549 "When the RE Builder buffer is killed make sure no overlays stay around." |
599 (reb-empty-regexp))))))) | 592 (reb-empty-regexp))))))) |
600 | 593 |
601 (defun reb-cook-regexp (re) | 594 (defun reb-cook-regexp (re) |
602 "Return RE after processing it according to `reb-re-syntax'." | 595 "Return RE after processing it according to `reb-re-syntax'." |
603 (cond ((eq reb-re-syntax 'lisp-re) | 596 (cond ((eq reb-re-syntax 'lisp-re) |
604 (lre-compile-string (eval (car (read-from-string re))))) | 597 (if (fboundp 'lre-compile-string) |
598 (lre-compile-string (eval (car (read-from-string re)))))) | |
605 ((eq reb-re-syntax 'sregex) | 599 ((eq reb-re-syntax 'sregex) |
606 (apply 'sregex (eval (car (read-from-string re))))) | 600 (apply 'sregex (eval (car (read-from-string re))))) |
601 ((eq reb-re-syntax 'rx) | |
602 (rx-to-string (eval (car (read-from-string re))))) | |
607 (t re))) | 603 (t re))) |
608 | 604 |
609 (defun reb-update-regexp () | 605 (defun reb-update-regexp () |
610 "Update the regexp for the target buffer. | 606 "Update the regexp for the target buffer. |
611 Return t if the (cooked) expression changed." | 607 Return t if the (cooked) expression changed." |
668 (error "Too many subexpressions - face `%s' not defined" | 664 (error "Too many subexpressions - face `%s' not defined" |
669 face-name ))) | 665 face-name ))) |
670 (overlay-put overlay 'priority i))) | 666 (overlay-put overlay 'priority i))) |
671 (setq i (1+ i)))))) | 667 (setq i (1+ i)))))) |
672 (let ((count (if subexp submatches matches))) | 668 (let ((count (if subexp submatches matches))) |
673 (message"%s %smatch(es)%s" | 669 (message "%s %smatch%s%s" |
674 (if (= 0 count) "No" (int-to-string count)) | 670 (if (= 0 count) "No" (int-to-string count)) |
675 (if subexp "subexpression " "") | 671 (if subexp "subexpression " "") |
672 (if (= 1 count) "" "es") | |
676 (if (and reb-auto-match-limit | 673 (if (and reb-auto-match-limit |
677 (= reb-auto-match-limit count)) | 674 (= reb-auto-match-limit count)) |
678 " (limit reached)" ""))) | 675 " (limit reached)" ""))) |
679 (if firstmatch | 676 (if firstmatch |
680 (progn (store-match-data firstmatch) | 677 (progn (store-match-data firstmatch) |
681 (reb-show-subexp (or subexp 0)))))) | 678 (reb-show-subexp (or subexp 0)))))) |
682 | 679 |
683 (provide 're-builder) | 680 (provide 're-builder) |
684 | 681 |
682 ;;; arch-tag: 5c5515ac-4085-4524-a421-033f44f032e7 | |
685 ;;; re-builder.el ends here | 683 ;;; re-builder.el ends here |