Mercurial > emacs
comparison lisp/emacs-lisp/re-builder.el @ 93198:eb3d659f5085
(reb-mode-common): Remove reference to bogus variable `reb-kill-buffer';
don't make hooks buffer-local, use the LOCAL arg of `add-hook'.
(reb-blink-delay, reb-mode-hook, reb-re-syntax, reb-auto-match-limit):
Remove spurious * from defcustom docstrings.
(reb-next-match, reb-prev-match, reb-enter-subexp-mode): Fix typos in messages.
(reb-mode-buffer-p): New function.
(re-builder, reb-kill-buffer): Use `reb-mode-buffer-p'. Use `when'.
(top, reb-show-subexp, reb-auto-update, reb-auto-update, reb-delete-overlays,
reb-cook-regexp, reb-update-regexp, reb-update-overlays): Use `unless', `when'.
(re-builder-unload-function): New function.
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Tue, 25 Mar 2008 16:48:19 +0000 |
parents | 107ccd98fa12 |
children | 44fab469d68d |
comparison
equal
deleted
inserted
replaced
93197:212fa666680e | 93198:eb3d659f5085 |
---|---|
107 | 107 |
108 | 108 |
109 ;;; Code: | 109 ;;; Code: |
110 | 110 |
111 ;; On XEmacs, load the overlay compatibility library | 111 ;; On XEmacs, load the overlay compatibility library |
112 (if (not (fboundp 'make-overlay)) | 112 (unless (fboundp 'make-overlay) |
113 (require 'overlay)) | 113 (require 'overlay)) |
114 | 114 |
115 ;; User customizable variables | 115 ;; User customizable variables |
116 (defgroup re-builder nil | 116 (defgroup re-builder nil |
117 "Options for the RE Builder." | 117 "Options for the RE Builder." |
118 :group 'lisp | 118 :group 'lisp |
119 :prefix "reb-") | 119 :prefix "reb-") |
120 | 120 |
121 (defcustom reb-blink-delay 0.5 | 121 (defcustom reb-blink-delay 0.5 |
122 "*Seconds to blink cursor for next/previous match in RE Builder." | 122 "Seconds to blink cursor for next/previous match in RE Builder." |
123 :group 're-builder | 123 :group 're-builder |
124 :type 'number) | 124 :type 'number) |
125 | 125 |
126 (defcustom reb-mode-hook nil | 126 (defcustom reb-mode-hook nil |
127 "*Hooks to run on entering RE Builder mode." | 127 "Hooks to run on entering RE Builder mode." |
128 :group 're-builder | 128 :group 're-builder |
129 :type 'hook) | 129 :type 'hook) |
130 | 130 |
131 (defcustom reb-re-syntax 'read | 131 (defcustom reb-re-syntax 'read |
132 "*Syntax for the REs in the RE Builder. | 132 "Syntax for the REs in the RE Builder. |
133 Can either be `read', `string', `sregex', `lisp-re', `rx'." | 133 Can either be `read', `string', `sregex', `lisp-re', `rx'." |
134 :group 're-builder | 134 :group 're-builder |
135 :type '(choice (const :tag "Read syntax" read) | 135 :type '(choice (const :tag "Read syntax" read) |
136 (const :tag "String syntax" string) | 136 (const :tag "String syntax" string) |
137 (const :tag "`sregex' syntax" sregex) | 137 (const :tag "`sregex' syntax" sregex) |
138 (const :tag "`lisp-re' syntax" lisp-re) | 138 (const :tag "`lisp-re' syntax" lisp-re) |
139 (const :tag "`rx' syntax" rx))) | 139 (const :tag "`rx' syntax" rx))) |
140 | 140 |
141 (defcustom reb-auto-match-limit 200 | 141 (defcustom reb-auto-match-limit 200 |
142 "*Positive integer limiting the matches for RE Builder auto updates. | 142 "Positive integer limiting the matches for RE Builder auto updates. |
143 Set it to nil if you don't want limits here." | 143 Set it to nil if you don't want limits here." |
144 :group 're-builder | 144 :group 're-builder |
145 :type '(restricted-sexp :match-alternatives | 145 :type '(restricted-sexp :match-alternatives |
146 (integerp 'nil))) | 146 (integerp 'nil))) |
147 | 147 |
290 (setq reb-mode-string "" | 290 (setq reb-mode-string "" |
291 reb-valid-string "" | 291 reb-valid-string "" |
292 mode-line-buffer-identification | 292 mode-line-buffer-identification |
293 '(25 . ("%b" reb-mode-string reb-valid-string))) | 293 '(25 . ("%b" reb-mode-string reb-valid-string))) |
294 (reb-update-modestring) | 294 (reb-update-modestring) |
295 (make-local-variable 'after-change-functions) | 295 (add-hook 'after-change-functions 'reb-auto-update nil t) |
296 (add-hook 'after-change-functions | |
297 'reb-auto-update) | |
298 ;; At least make the overlays go away if the buffer is killed | 296 ;; At least make the overlays go away if the buffer is killed |
299 (make-local-variable 'reb-kill-buffer) | 297 (add-hook 'kill-buffer-hook 'reb-kill-buffer nil t) |
300 (add-hook 'kill-buffer-hook 'reb-kill-buffer) | |
301 (reb-auto-update nil nil nil)) | 298 (reb-auto-update nil nil nil)) |
302 | 299 |
303 (defun reb-color-display-p () | 300 (defun reb-color-display-p () |
304 "Return t if display is capable of displaying colors." | 301 "Return t if display is capable of displaying colors." |
305 (eq 'color | 302 (eq 'color |
324 (goto-char (+ 2 (point-min))) | 321 (goto-char (+ 2 (point-min))) |
325 (cond ((reb-lisp-syntax-p) | 322 (cond ((reb-lisp-syntax-p) |
326 (reb-lisp-mode)) | 323 (reb-lisp-mode)) |
327 (t (reb-mode)))) | 324 (t (reb-mode)))) |
328 | 325 |
326 (defun reb-mode-buffer-p () | |
327 "Return non-nil if the current buffer is a RE Builder buffer." | |
328 (memq major-mode '(reb-mode reb-lisp-mode))) | |
329 | |
329 ;;; This is to help people find this in Apropos. | 330 ;;; This is to help people find this in Apropos. |
330 ;;;###autoload | 331 ;;;###autoload |
331 (defalias 'regexp-builder 're-builder) | 332 (defalias 'regexp-builder 're-builder) |
332 | 333 |
333 ;;;###autoload | 334 ;;;###autoload |
334 (defun re-builder () | 335 (defun re-builder () |
335 "Construct a regexp interactively." | 336 "Construct a regexp interactively." |
336 (interactive) | 337 (interactive) |
337 | 338 |
338 (if (and (string= (buffer-name) reb-buffer) | 339 (if (and (string= (buffer-name) reb-buffer) |
339 (memq major-mode '(reb-mode reb-lisp-mode))) | 340 (reb-mode-buffer-p)) |
340 (message "Already in the RE Builder") | 341 (message "Already in the RE Builder") |
341 (if reb-target-buffer | 342 (when reb-target-buffer |
342 (reb-delete-overlays)) | 343 (reb-delete-overlays)) |
343 (setq reb-target-buffer (current-buffer) | 344 (setq reb-target-buffer (current-buffer) |
344 reb-target-window (selected-window) | 345 reb-target-window (selected-window) |
345 reb-window-config (current-window-configuration)) | 346 reb-window-config (current-window-configuration)) |
346 (select-window (split-window (selected-window) (- (window-height) 4))) | 347 (select-window (split-window (selected-window) (- (window-height) 4))) |
347 (switch-to-buffer (get-buffer-create reb-buffer)) | 348 (switch-to-buffer (get-buffer-create reb-buffer)) |
383 (interactive) | 384 (interactive) |
384 | 385 |
385 (reb-assert-buffer-in-window) | 386 (reb-assert-buffer-in-window) |
386 (with-selected-window reb-target-window | 387 (with-selected-window reb-target-window |
387 (if (not (re-search-forward reb-regexp (point-max) t)) | 388 (if (not (re-search-forward reb-regexp (point-max) t)) |
388 (message "No more matches.") | 389 (message "No more matches") |
389 (reb-show-subexp | 390 (reb-show-subexp |
390 (or (and reb-subexp-mode reb-subexp-displayed) 0) | 391 (or (and reb-subexp-mode reb-subexp-displayed) 0) |
391 t)))) | 392 t)))) |
392 | 393 |
393 (defun reb-prev-match () | 394 (defun reb-prev-match () |
401 (if (re-search-backward reb-regexp (point-min) t) | 402 (if (re-search-backward reb-regexp (point-min) t) |
402 (reb-show-subexp | 403 (reb-show-subexp |
403 (or (and reb-subexp-mode reb-subexp-displayed) 0) | 404 (or (and reb-subexp-mode reb-subexp-displayed) 0) |
404 t) | 405 t) |
405 (goto-char p) | 406 (goto-char p) |
406 (message "No more matches."))))) | 407 (message "No more matches"))))) |
407 | 408 |
408 (defun reb-toggle-case () | 409 (defun reb-toggle-case () |
409 "Toggle case sensitivity of searches for RE Builder target buffer." | 410 "Toggle case sensitivity of searches for RE Builder target buffer." |
410 (interactive) | 411 (interactive) |
411 | 412 |
430 "Enter the subexpression mode in the RE Builder." | 431 "Enter the subexpression mode in the RE Builder." |
431 (interactive) | 432 (interactive) |
432 (setq reb-subexp-mode t) | 433 (setq reb-subexp-mode t) |
433 (reb-update-modestring) | 434 (reb-update-modestring) |
434 (use-local-map reb-subexp-mode-map) | 435 (use-local-map reb-subexp-mode-map) |
435 (message "`0'-`9' to display subexpressions `q' to quit subexp mode.")) | 436 (message "`0'-`9' to display subexpressions `q' to quit subexp mode")) |
436 | 437 |
437 (defun reb-show-subexp (subexp &optional pause) | 438 (defun reb-show-subexp (subexp &optional pause) |
438 "Visually show limit of subexpression SUBEXP of recent search. | 439 "Visually show limit of subexpression SUBEXP of recent search. |
439 On color displays this just puts point to the end of the expression as | 440 On color displays this just puts point to the end of the expression as |
440 the match should already be marked by an overlay. | 441 the match should already be marked by an overlay. |
441 On other displays jump to the beginning and the end of it. | 442 On other displays jump to the beginning and the end of it. |
442 If the optional PAUSE is non-nil then pause at the end in any case." | 443 If the optional PAUSE is non-nil then pause at the end in any case." |
443 (with-selected-window reb-target-window | 444 (with-selected-window reb-target-window |
444 (if (not (reb-color-display-p)) | 445 (unless (reb-color-display-p) |
445 (progn (goto-char (match-beginning subexp)) | 446 (goto-char (match-beginning subexp)) |
446 (sit-for reb-blink-delay))) | 447 (sit-for reb-blink-delay)) |
447 (goto-char (match-end subexp)) | 448 (goto-char (match-end subexp)) |
448 (if (or (not (reb-color-display-p)) pause) | 449 (when (or (not (reb-color-display-p)) pause) |
449 (sit-for reb-blink-delay)))) | 450 (sit-for reb-blink-delay)))) |
450 | 451 |
451 (defun reb-quit-subexp-mode () | 452 (defun reb-quit-subexp-mode () |
452 "Quit the subexpression mode in the RE Builder." | 453 "Quit the subexpression mode in the RE Builder." |
453 (interactive) | 454 (interactive) |
454 (setq reb-subexp-mode nil | 455 (setq reb-subexp-mode nil |
492 optional fourth argument FORCE is non-nil." | 493 optional fourth argument FORCE is non-nil." |
493 (let ((prev-valid reb-valid-string) | 494 (let ((prev-valid reb-valid-string) |
494 (new-valid | 495 (new-valid |
495 (condition-case nil | 496 (condition-case nil |
496 (progn | 497 (progn |
497 (if (or (reb-update-regexp) force) | 498 (when (or (reb-update-regexp) force) |
498 (progn | 499 (reb-assert-buffer-in-window) |
499 (reb-assert-buffer-in-window) | 500 (reb-do-update)) |
500 (reb-do-update))) | |
501 "") | 501 "") |
502 (error " *invalid*")))) | 502 (error " *invalid*")))) |
503 (setq reb-valid-string new-valid) | 503 (setq reb-valid-string new-valid) |
504 (force-mode-line-update) | 504 (force-mode-line-update) |
505 | 505 |
506 ;; Through the caching of the re a change invalidating the syntax | 506 ;; Through the caching of the re a change invalidating the syntax |
507 ;; for symbolic expressions will not delete the overlays so we | 507 ;; for symbolic expressions will not delete the overlays so we |
508 ;; catch it here | 508 ;; catch it here |
509 (if (and (reb-lisp-syntax-p) | 509 (when (and (reb-lisp-syntax-p) |
510 (not (string= prev-valid new-valid)) | 510 (not (string= prev-valid new-valid)) |
511 (string= prev-valid "")) | 511 (string= prev-valid "")) |
512 (reb-delete-overlays)))) | 512 (reb-delete-overlays)))) |
513 | 513 |
514 (defun reb-delete-overlays () | 514 (defun reb-delete-overlays () |
515 "Delete all RE Builder overlays in the `reb-target-buffer' buffer." | 515 "Delete all RE Builder overlays in the `reb-target-buffer' buffer." |
516 (if (buffer-live-p reb-target-buffer) | 516 (when (buffer-live-p reb-target-buffer) |
517 (with-current-buffer reb-target-buffer | 517 (with-current-buffer reb-target-buffer |
518 (mapc 'delete-overlay reb-overlays) | 518 (mapc 'delete-overlay reb-overlays) |
519 (setq reb-overlays nil)))) | 519 (setq reb-overlays nil)))) |
520 | 520 |
521 (defun reb-assert-buffer-in-window () | 521 (defun reb-assert-buffer-in-window () |
546 (reb-do-update reb-subexp-displayed)) | 546 (reb-do-update reb-subexp-displayed)) |
547 | 547 |
548 (defun reb-kill-buffer () | 548 (defun reb-kill-buffer () |
549 "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." |
550 | 550 |
551 (if (member major-mode '(reb-mode reb-lisp-mode)) | 551 (when (reb-mode-buffer-p) |
552 (reb-delete-overlays))) | 552 (reb-delete-overlays))) |
553 | 553 |
554 | 554 |
555 ;; The next functions are the interface between the regexp and | 555 ;; The next functions are the interface between the regexp and |
556 ;; its textual representation in the RE Builder buffer. | 556 ;; its textual representation in the RE Builder buffer. |
557 ;; They are the only functions concerned with the actual syntax | 557 ;; They are the only functions concerned with the actual syntax |
592 (reb-empty-regexp))))))) | 592 (reb-empty-regexp))))))) |
593 | 593 |
594 (defun reb-cook-regexp (re) | 594 (defun reb-cook-regexp (re) |
595 "Return RE after processing it according to `reb-re-syntax'." | 595 "Return RE after processing it according to `reb-re-syntax'." |
596 (cond ((eq reb-re-syntax 'lisp-re) | 596 (cond ((eq reb-re-syntax 'lisp-re) |
597 (if (fboundp 'lre-compile-string) | 597 (when (fboundp 'lre-compile-string) |
598 (lre-compile-string (eval (car (read-from-string re)))))) | 598 (lre-compile-string (eval (car (read-from-string re)))))) |
599 ((eq reb-re-syntax 'sregex) | 599 ((eq reb-re-syntax 'sregex) |
600 (apply 'sregex (eval (car (read-from-string re))))) | 600 (apply 'sregex (eval (car (read-from-string re))))) |
601 ((eq reb-re-syntax 'rx) | 601 ((eq reb-re-syntax 'rx) |
602 (rx-to-string (eval (car (read-from-string re))))) | 602 (rx-to-string (eval (car (read-from-string re))))) |
603 (t re))) | 603 (t re))) |
611 (let ((oldre reb-regexp)) | 611 (let ((oldre reb-regexp)) |
612 (prog1 | 612 (prog1 |
613 (not (string= oldre re)) | 613 (not (string= oldre re)) |
614 (setq reb-regexp re) | 614 (setq reb-regexp re) |
615 ;; Only update the source re for the lisp formats | 615 ;; Only update the source re for the lisp formats |
616 (if (reb-lisp-syntax-p) | 616 (when (reb-lisp-syntax-p) |
617 (setq reb-regexp-src re-src))))))) | 617 (setq reb-regexp-src re-src))))))) |
618 | 618 |
619 | 619 |
620 ;; And now the real core of the whole thing | 620 ;; And now the real core of the whole thing |
621 (defun reb-count-subexps (re) | 621 (defun reb-count-subexps (re) |
622 "Return number of sub-expressions in the regexp RE." | 622 "Return number of sub-expressions in the regexp RE." |
641 (goto-char (point-min)) | 641 (goto-char (point-min)) |
642 (while (and (not (eobp)) | 642 (while (and (not (eobp)) |
643 (re-search-forward re (point-max) t) | 643 (re-search-forward re (point-max) t) |
644 (or (not reb-auto-match-limit) | 644 (or (not reb-auto-match-limit) |
645 (< matches reb-auto-match-limit))) | 645 (< matches reb-auto-match-limit))) |
646 (if (= 0 (length (match-string 0))) | 646 (when (and (= 0 (length (match-string 0))) |
647 (unless (eobp) | 647 (not (eobp))) |
648 (forward-char 1))) | 648 (forward-char 1)) |
649 (let ((i 0) | 649 (let ((i 0) |
650 suffix max-suffix) | 650 suffix max-suffix) |
651 (setq matches (1+ matches)) | 651 (setq matches (1+ matches)) |
652 (while (<= i subexps) | 652 (while (<= i subexps) |
653 (if (and (or (not subexp) (= subexp i)) | 653 (when (and (or (not subexp) (= subexp i)) |
654 (match-beginning i)) | 654 (match-beginning i)) |
655 (let ((overlay (make-overlay (match-beginning i) | 655 (let ((overlay (make-overlay (match-beginning i) |
656 (match-end i))) | 656 (match-end i))) |
657 ;; When we have exceeded the number of provided faces, | 657 ;; When we have exceeded the number of provided faces, |
658 ;; cycle thru them where `max-suffix' denotes the maximum | 658 ;; cycle thru them where `max-suffix' denotes the maximum |
659 ;; suffix for `reb-match-*' that has been defined and | 659 ;; suffix for `reb-match-*' that has been defined and |
660 ;; `suffix' the suffix calculated for the current match. | 660 ;; `suffix' the suffix calculated for the current match. |
661 (face | 661 (face |
662 (cond | 662 (cond |
663 (max-suffix | 663 (max-suffix |
664 (if (= suffix max-suffix) | 664 (if (= suffix max-suffix) |
665 (setq suffix 1) | 665 (setq suffix 1) |
666 (setq suffix (1+ suffix))) | 666 (setq suffix (1+ suffix))) |
667 (intern-soft (format "reb-match-%d" suffix))) | 667 (intern-soft (format "reb-match-%d" suffix))) |
668 ((intern-soft (format "reb-match-%d" i))) | 668 ((intern-soft (format "reb-match-%d" i))) |
669 ((setq max-suffix (1- i)) | 669 ((setq max-suffix (1- i)) |
670 (setq suffix 1) | 670 (setq suffix 1) |
671 ;; `reb-match-1' must exist. | 671 ;; `reb-match-1' must exist. |
672 'reb-match-1)))) | 672 'reb-match-1)))) |
673 (unless firstmatch (setq firstmatch (match-data))) | 673 (unless firstmatch (setq firstmatch (match-data))) |
674 (setq reb-overlays (cons overlay reb-overlays) | 674 (setq reb-overlays (cons overlay reb-overlays) |
675 submatches (1+ submatches)) | 675 submatches (1+ submatches)) |
676 (overlay-put overlay 'face face) | 676 (overlay-put overlay 'face face) |
677 (overlay-put overlay 'priority i))) | 677 (overlay-put overlay 'priority i))) |
678 (setq i (1+ i)))))) | 678 (setq i (1+ i)))))) |
679 (let ((count (if subexp submatches matches))) | 679 (let ((count (if subexp submatches matches))) |
680 (message "%s %smatch%s%s" | 680 (message "%s %smatch%s%s" |
681 (if (= 0 count) "No" (int-to-string count)) | 681 (if (= 0 count) "No" (int-to-string count)) |
682 (if subexp "subexpression " "") | 682 (if subexp "subexpression " "") |
683 (if (= 1 count) "" "es") | 683 (if (= 1 count) "" "es") |
684 (if (and reb-auto-match-limit | 684 (if (and reb-auto-match-limit |
685 (= reb-auto-match-limit count)) | 685 (= reb-auto-match-limit count)) |
686 " (limit reached)" ""))) | 686 " (limit reached)" ""))) |
687 (if firstmatch | 687 (when firstmatch |
688 (progn (store-match-data firstmatch) | 688 (store-match-data firstmatch) |
689 (reb-show-subexp (or subexp 0)))))) | 689 (reb-show-subexp (or subexp 0))))) |
690 | |
691 ;; The End | |
692 (defun re-builder-unload-function () | |
693 "Unload the RE Builder library." | |
694 (when (buffer-live-p (get-buffer reb-buffer)) | |
695 (with-current-buffer reb-buffer | |
696 (remove-hook 'after-change-functions 'reb-auto-update t) | |
697 (remove-hook 'kill-buffer-hook 'reb-kill-buffer t) | |
698 (when (reb-mode-buffer-p) | |
699 (reb-delete-overlays) | |
700 (funcall default-major-mode)))) | |
701 ;; continue standard unloading | |
702 nil) | |
690 | 703 |
691 (provide 're-builder) | 704 (provide 're-builder) |
692 | 705 |
693 ;;; arch-tag: 5c5515ac-4085-4524-a421-033f44f032e7 | 706 ;;; arch-tag: 5c5515ac-4085-4524-a421-033f44f032e7 |
694 ;;; re-builder.el ends here | 707 ;;; re-builder.el ends here |