mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-02 11:21:42 +00:00
*** empty log message ***
This commit is contained in:
parent
1853aa6bc9
commit
d1221ea91d
@ -1,5 +1,7 @@
|
||||
2000-03-09 Gerd Moellmann <gerd@gnu.org>
|
||||
|
||||
* emacs-lisp/re-builder.el: New file.
|
||||
|
||||
* mouse.el (mouse-drag-region): Don't run up-event handler
|
||||
if hscroll has changed.
|
||||
|
||||
|
@ -410,7 +410,7 @@
|
||||
(put 'shadow 'custom-loads '("shadowfile" "shadow"))
|
||||
(put 'hl-line 'custom-loads '("hl-line"))
|
||||
(put 'internal 'custom-loads '("startup" "cus-edit"))
|
||||
(put 'lisp 'custom-loads '("simple" "lisp" "lisp-mode" "cmuscheme" "ielm" "xscheme" "advice" "bytecomp" "checkdoc" "cl-indent" "cust-print" "edebug" "elp" "find-func" "pp" "shadow" "trace" "scheme"))
|
||||
(put 'lisp 'custom-loads '("simple" "lisp" "lisp-mode" "cmuscheme" "ielm" "xscheme" "advice" "bytecomp" "checkdoc" "cl-indent" "cust-print" "edebug" "elp" "find-func" "pp" "re-builder" "shadow" "trace" "scheme"))
|
||||
(put 'local 'custom-loads '("calendar"))
|
||||
(put 'rlogin 'custom-loads '("rlogin"))
|
||||
(put 'debugger 'custom-loads '("debug"))
|
||||
@ -516,6 +516,7 @@
|
||||
(put 'ielm 'custom-loads '("ielm"))
|
||||
(put 'find-dired 'custom-loads '("find-dired"))
|
||||
(put 'delphi 'custom-loads '("delphi"))
|
||||
(put 're-builder 'custom-loads '("re-builder"))
|
||||
(put 'killing 'custom-loads '("simple"))
|
||||
(put 'gnus-group-various 'custom-loads '("gnus-group" "gnus"))
|
||||
;;; These are for handling :version. We need to have a minimum of
|
||||
|
683
lisp/emacs-lisp/re-builder.el
Normal file
683
lisp/emacs-lisp/re-builder.el
Normal file
@ -0,0 +1,683 @@
|
||||
;;; re-builder.el --- Building Regexps with visual feedback
|
||||
|
||||
;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Detlev Zundel <dzu@gnu.org>
|
||||
;; Keywords: matching, lisp, tools
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; $Id: re-builder.el,v 1.3 2000/01/25 23:42:24 dzu Exp $
|
||||
|
||||
;; When I have to come up with regular expressions that are more
|
||||
;; complex than simple string matchers, especially if they contain sub
|
||||
;; expressions, I find myself spending quite some time in the
|
||||
;; `development cycle'. `re-builder' aims to shorten this time span
|
||||
;; so I can get on with the more interesting bits.
|
||||
|
||||
;; With it you can have immediate visual feedback about how well the
|
||||
;; regexp behaves to your expectations on the intended data.
|
||||
|
||||
;; When called up `re-builder' attaches itself to the current buffer
|
||||
;; which becomes its target buffer, where all the matching is done.
|
||||
;; The active window is split so you have a view on the data while
|
||||
;; authoring the RE. If the edited expression is valid the matches in
|
||||
;; the target buffer are marked automatically with colored overlays
|
||||
;; (for non-color displays see below) giving you feedback over the
|
||||
;; extents of the matched (sub) expressions. The (non-)validity is
|
||||
;; shown only in the modeline without throwing the errors at you. If
|
||||
;; you want to know the reason why RE Builder considers it as invalid
|
||||
;; call `reb-force-update' ("\C-c\C-u") which should reveal the error.
|
||||
|
||||
;; The `re-builder' keeps the focus while updating the matches in the
|
||||
;; target buffer so corrections are easy to incorporate. If you are
|
||||
;; satisfied with the result you can paste the RE to the kill-ring
|
||||
;; with `reb-copy' ("\C-c\C-w"), quit the `re-builder' ("\C-c\C-q")
|
||||
;; and use it wherever you need it.
|
||||
|
||||
;; As the automatic updates can take some time on large buffers, they
|
||||
;; can be limited by `reb-auto-match-limit' so that they should not
|
||||
;; have a negative impact on the editing. Setting it to nil makes
|
||||
;; even the auto updates go all the way. Forcing an update overrides
|
||||
;; this limit allowing an easy way to see all matches.
|
||||
|
||||
;; Currently `re-builder' understands four different forms of input,
|
||||
;; namely `read', `string', `sregex' and `lisp-re' syntax. Read
|
||||
;; syntax and string syntax are both delimited by `"'s and behave
|
||||
;; according to their name. With the `string' syntax there's no need
|
||||
;; to escape the backslashes and double quotes simplifying the editing
|
||||
;; somewhat. The other two allow editing of symbolic regular
|
||||
;; expressions supported by the packages of the same name. (`lisp-re'
|
||||
;; is a package by me and its support may go away as it is nearly the
|
||||
;; same as the `sregex' package in Emacs)
|
||||
|
||||
;; Editing symbolic expressions is done through a major mode derived
|
||||
;; from `emacs-lisp-mode' so you'll get all the good stuff like
|
||||
;; automatic indentation and font-locking etc.
|
||||
|
||||
;; When editing a symbolic regular expression, only the first
|
||||
;; expression in the RE Builder buffer is considered, which helps
|
||||
;; limiting the extent of the expression like the `"'s do for the text
|
||||
;; modes. For the `sregex' syntax the function `sregex' is applied to
|
||||
;; the evaluated expression read. So you can use quoted arguments
|
||||
;; with something like '("findme") or you can construct arguments to
|
||||
;; your hearts delight with a valid ELisp expression. (The compiled
|
||||
;; string form will be copied by `reb-copy') If you want to take
|
||||
;; a glance at the corresponding string you can temporarily change the
|
||||
;; input syntax.
|
||||
|
||||
;; Changing the input syntax is transparent (for the obvious exception
|
||||
;; non-symbolic -> symbolic) so you can change your mind as often as
|
||||
;; you like.
|
||||
|
||||
;; There is also a shortcut function for toggling the
|
||||
;; `case-fold-search' variable in the target buffer with an immediate
|
||||
;; update.
|
||||
|
||||
|
||||
;; Q: But what if my display cannot show colored overlays?
|
||||
;; A: Then the cursor will flash around the matched text making it stand
|
||||
;; out.
|
||||
|
||||
;; Q: But how can I then make out the sub-expressions?
|
||||
;; A: Thats where the `sub-expression mode' comes in. In it only the
|
||||
;; digit keys are assigned to perform an update that will flash the
|
||||
;; corresponding subexp only.
|
||||
|
||||
|
||||
;;; History:
|
||||
;;
|
||||
;; Changes from Version 1.2:
|
||||
;; - Fixed a bug preventing normal startup after killing the (previous)
|
||||
;; target-buffer
|
||||
;; - Fixed XEmacs support
|
||||
;;
|
||||
;; Changes from Version 1.1:
|
||||
;; - The editing is now done through two major-modes rather than
|
||||
;; having one minor-mode that behaves exactly like a major-mode
|
||||
;; - Automatic updates for valid re's simplify the user interface
|
||||
;; - Easy interface for changing the input syntax and case
|
||||
;; sensitivity of the target buffer
|
||||
;; - As nobody reported the bugs that were fixed you probably don't
|
||||
;; want to know about them...
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; On XEmacs, load the overlay compatibility library
|
||||
(if (not (fboundp 'make-overlay))
|
||||
(require 'overlay))
|
||||
|
||||
;; User costomizable variables
|
||||
(defgroup re-builder nil
|
||||
"Options for the RE Builder."
|
||||
:group 'lisp
|
||||
:prefix "reb-")
|
||||
|
||||
(defcustom reb-blink-delay 0.5
|
||||
"*Seconds to blink cursor for next/previous match in RE Builder."
|
||||
:group 're-builder
|
||||
:type 'number)
|
||||
|
||||
(defcustom reb-mode-hook nil
|
||||
"*Hooks to run on entering RE Builder mode."
|
||||
:group 're-builder
|
||||
:type 'hook)
|
||||
|
||||
(defcustom reb-re-syntax 'read
|
||||
"*Syntax for the REs in the RE Builder.
|
||||
Can either be `read', `string' or `lisp-re'."
|
||||
:group 're-builder
|
||||
:type '(choice (const :tag "Read syntax" read)
|
||||
(const :tag "String syntax" string)
|
||||
(const :tag "`sregex' syntax" sregex)
|
||||
(const :tag "`lisp-re' syntax" lisp-re)
|
||||
(value: sring)))
|
||||
|
||||
(defcustom reb-auto-match-limit 200
|
||||
"*Positive integer limiting the matches for RE Builder auto updates.
|
||||
Set it to nil if you don't want limits here."
|
||||
:group 're-builder
|
||||
:type '(restricted-sexp :match-alternatives
|
||||
(integerp 'nil)))
|
||||
|
||||
|
||||
(defface reb-match-0
|
||||
'((((class color))
|
||||
(:background "lightblue"))
|
||||
(t (:inverse-video t)))
|
||||
"Used for displaying the whole match."
|
||||
:group 're-builder)
|
||||
|
||||
(defface reb-match-1
|
||||
'((((class color))
|
||||
(:background "aquamarine"))
|
||||
(t (:inverse-video t)))
|
||||
"Used for displaying the first matching subexpression."
|
||||
:group 're-builder)
|
||||
|
||||
(defface reb-match-2
|
||||
'((((class color))
|
||||
(:background "springgreen"))
|
||||
(t (:inverse-video t)))
|
||||
"Used for displaying the second matching subexpression."
|
||||
:group 're-builder)
|
||||
|
||||
(defface reb-match-3
|
||||
'((((class color))
|
||||
(:background "yellow"))
|
||||
(t (:inverse-video t)))
|
||||
"Used for displaying the third matching subexpression."
|
||||
:group 're-builder)
|
||||
|
||||
;; Internal variables below
|
||||
(defvar reb-mode nil
|
||||
"Enables the RE Builder minor mode.")
|
||||
|
||||
(defvar reb-target-buffer nil
|
||||
"Buffer to which the RE is applied to.")
|
||||
|
||||
(defvar reb-target-window nil
|
||||
"Window to which the RE is applied to.")
|
||||
|
||||
(defvar reb-regexp nil
|
||||
"Last regexp used by RE Builder.")
|
||||
|
||||
(defvar reb-regexp-src nil
|
||||
"Last regexp used by RE Builder before processing it.
|
||||
Except for Lisp syntax this is the same as `reb-regexp'.")
|
||||
|
||||
(defvar reb-overlays nil
|
||||
"List of overlays of the RE Builder.")
|
||||
|
||||
(defvar reb-window-config nil
|
||||
"Old window configuration.")
|
||||
|
||||
(defvar reb-subexp-mode nil
|
||||
"Indicates whether sub-exp mode is active.")
|
||||
|
||||
(defvar reb-subexp-displayed nil
|
||||
"Indicates which sub-exp is active.")
|
||||
|
||||
(defvar reb-mode-string ""
|
||||
"String in mode line for additional info.")
|
||||
|
||||
(defvar reb-valid-string ""
|
||||
"String in mode line showing validity of RE.")
|
||||
|
||||
(make-variable-buffer-local 'reb-overlays)
|
||||
(make-variable-buffer-local 'reb-regexp)
|
||||
(make-variable-buffer-local 'reb-regexp-src)
|
||||
|
||||
(defconst reb-buffer "*RE-Builder*"
|
||||
"Buffer to use for the RE Builder.")
|
||||
|
||||
;; Define the local "\C-c" keymap
|
||||
(defvar reb-mode-map nil
|
||||
"Keymap used by the RE Builder.")
|
||||
|
||||
(if (not reb-mode-map)
|
||||
(progn
|
||||
(setq reb-mode-map (make-sparse-keymap))
|
||||
(define-key reb-mode-map "\C-c\C-c" 'reb-toggle-case)
|
||||
(define-key reb-mode-map "\C-c\C-q" 'reb-quit)
|
||||
(define-key reb-mode-map "\C-c\C-w" 'reb-copy)
|
||||
(define-key reb-mode-map "\C-c\C-s" 'reb-next-match)
|
||||
(define-key reb-mode-map "\C-c\C-r" 'reb-prev-match)
|
||||
(define-key reb-mode-map "\C-c\C-i" 'reb-change-syntax)
|
||||
(define-key reb-mode-map "\C-c\C-e" 'reb-enter-subexp-mode)
|
||||
(define-key reb-mode-map "\C-c\C-u" 'reb-force-update)))
|
||||
|
||||
(defun reb-mode ()
|
||||
"Major mode for interactively building Regular Expressions.
|
||||
\\{reb-mode-map}"
|
||||
(interactive)
|
||||
|
||||
(setq major-mode 'reb-mode
|
||||
mode-name "RE Builder")
|
||||
(use-local-map reb-mode-map)
|
||||
(reb-mode-common)
|
||||
(run-hooks reb-mode-hook))
|
||||
|
||||
(define-derived-mode reb-lisp-mode
|
||||
emacs-lisp-mode "RE Builder Lisp"
|
||||
"Major mode for interactively building symbolic Regular Expressions.
|
||||
\\{reb-lisp-mode-map}"
|
||||
(cond ((eq reb-re-syntax 'lisp-re) ; Pull in packages
|
||||
(require 'lisp-re)) ; as needed
|
||||
((eq reb-re-syntax 'sregex) ; sregex is not autoloaded
|
||||
(require 'sregex))) ; right now..
|
||||
(reb-mode-common))
|
||||
|
||||
;; Use the same "\C-c" keymap as `reb-mode' and use font-locking from
|
||||
;; `emacs-lisp-mode'
|
||||
(define-key reb-lisp-mode-map "\C-c"
|
||||
(lookup-key reb-mode-map "\C-c"))
|
||||
|
||||
(if (boundp 'font-lock-defaults-alist)
|
||||
(setq font-lock-defaults-alist
|
||||
(cons (cons 'reb-lisp-mode
|
||||
(cdr (assoc 'emacs-lisp-mode
|
||||
font-lock-defaults-alist)))
|
||||
font-lock-defaults-alist)))
|
||||
|
||||
(defvar reb-subexp-mode-map nil
|
||||
"Keymap used by the RE Builder for the subexpression mode.")
|
||||
|
||||
(if (not reb-subexp-mode-map)
|
||||
(progn
|
||||
(setq reb-subexp-mode-map (make-sparse-keymap))
|
||||
(suppress-keymap reb-subexp-mode-map)
|
||||
;; Again share the "\C-c" keymap for the commands
|
||||
(define-key reb-subexp-mode-map "\C-c"
|
||||
(lookup-key reb-mode-map "\C-c"))
|
||||
(define-key reb-subexp-mode-map "q" 'reb-quit-subexp-mode)
|
||||
(mapcar (lambda (digit)
|
||||
(define-key reb-subexp-mode-map (int-to-string digit)
|
||||
'reb-display-subexp))
|
||||
'(0 1 2 3 4 5 6 7 8 9))))
|
||||
|
||||
(defun reb-mode-common ()
|
||||
"Setup functions common to functions `reb-mode' and `reb-mode-lisp'."
|
||||
|
||||
(setq reb-mode-string ""
|
||||
reb-valid-string ""
|
||||
mode-line-buffer-identification
|
||||
'(25 . ("%b" reb-mode-string reb-valid-string)))
|
||||
(reb-update-modestring)
|
||||
(make-local-variable 'after-change-functions)
|
||||
(add-hook 'after-change-functions
|
||||
'reb-auto-update)
|
||||
;; At least make the overlays go away if the buffer is killed
|
||||
(make-local-variable 'reb-kill-buffer)
|
||||
(add-hook 'kill-buffer-hook 'reb-kill-buffer)
|
||||
(reb-auto-update nil nil nil))
|
||||
|
||||
|
||||
;; Handy macro for doing things in other windows
|
||||
(defmacro reb-with-current-window (window &rest body)
|
||||
"With WINDOW selected evaluate BODY forms and reselect previous window."
|
||||
|
||||
(let ((oldwindow (make-symbol "*oldwindow*")))
|
||||
`(let ((,oldwindow (selected-window)))
|
||||
(select-window ,window)
|
||||
(unwind-protect
|
||||
(progn
|
||||
,@body)
|
||||
(select-window ,oldwindow)))))
|
||||
(put 'reb-with-current-window 'lisp-indent-function 0)
|
||||
|
||||
(defun reb-color-display-p ()
|
||||
"Return t if display is capable of displaying colors."
|
||||
(eq 'color
|
||||
;; emacs/xemacs compatibility
|
||||
(if (fboundp 'frame-parameter)
|
||||
(frame-parameter (selected-frame) 'display-type)
|
||||
(frame-property (selected-frame) 'display-type))))
|
||||
|
||||
(defsubst reb-lisp-syntax-p ()
|
||||
"Return non-nil if RE Builder uses a Lisp syntax."
|
||||
(memq reb-re-syntax '(lisp-re sregex)))
|
||||
|
||||
(defmacro reb-target-binding (symbol)
|
||||
"Return binding for SYMBOL in the RE Builder target buffer."
|
||||
`(with-current-buffer reb-target-buffer ,symbol))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun re-builder ()
|
||||
"Call up the RE Builder for the current window."
|
||||
(interactive)
|
||||
|
||||
(if reb-target-buffer
|
||||
(reb-delete-overlays))
|
||||
(setq reb-target-buffer (current-buffer)
|
||||
reb-target-window (selected-window)
|
||||
reb-window-config (current-window-configuration))
|
||||
(select-window (split-window (selected-window) (- (window-height) 4)))
|
||||
(switch-to-buffer (get-buffer-create reb-buffer))
|
||||
(erase-buffer)
|
||||
(reb-insert-regexp)
|
||||
(goto-char (+ 2 (point-min)))
|
||||
(cond
|
||||
((reb-lisp-syntax-p)
|
||||
(reb-lisp-mode))
|
||||
(t (reb-mode))))
|
||||
|
||||
|
||||
(defun reb-force-update ()
|
||||
"Forces an update in the RE Builder target window without a match limit."
|
||||
(interactive)
|
||||
|
||||
(let ((reb-auto-match-limit nil))
|
||||
(reb-update-overlays
|
||||
(if reb-subexp-mode reb-subexp-displayed nil))))
|
||||
|
||||
(defun reb-quit ()
|
||||
"Quit the RE Builder mode."
|
||||
(interactive)
|
||||
|
||||
(setq reb-subexp-mode nil
|
||||
reb-subexp-displayed nil)
|
||||
(reb-delete-overlays)
|
||||
(bury-buffer)
|
||||
(set-window-configuration reb-window-config))
|
||||
|
||||
(defun reb-next-match ()
|
||||
"Go to next match in the RE Builder target window."
|
||||
(interactive)
|
||||
|
||||
(reb-assert-buffer-in-window)
|
||||
(reb-with-current-window
|
||||
reb-target-window
|
||||
(if (not (re-search-forward reb-regexp (point-max) t))
|
||||
(message "No more matches.")
|
||||
(reb-show-subexp
|
||||
(or (and reb-subexp-mode reb-subexp-displayed) 0)
|
||||
t))))
|
||||
|
||||
(defun reb-prev-match ()
|
||||
"Go to previous match in the RE Builder target window."
|
||||
(interactive)
|
||||
|
||||
(reb-assert-buffer-in-window)
|
||||
(reb-with-current-window reb-target-window
|
||||
(goto-char (1- (point)))
|
||||
(if (not (re-search-backward reb-regexp (point-min) t))
|
||||
(message "No more matches.")
|
||||
(reb-show-subexp
|
||||
(or (and reb-subexp-mode reb-subexp-displayed) 0)
|
||||
t))))
|
||||
|
||||
(defun reb-toggle-case ()
|
||||
"Toggle case sensitivity of searches for RE Builder target buffer."
|
||||
(interactive)
|
||||
|
||||
(with-current-buffer reb-target-buffer
|
||||
(setq case-fold-search (not case-fold-search)))
|
||||
(reb-update-modestring)
|
||||
(reb-auto-update nil nil nil t))
|
||||
|
||||
(defun reb-copy ()
|
||||
"Copy current RE into the kill ring for later insertion."
|
||||
(interactive)
|
||||
|
||||
(reb-update-regexp)
|
||||
(let ((re (with-output-to-string
|
||||
(print (reb-target-binding reb-regexp)))))
|
||||
(kill-new (substring re 1 (1- (length re))))
|
||||
(message "Regexp copied to kill-ring")))
|
||||
|
||||
;; The subexpression mode is not electric because the number of
|
||||
;; matches should be seen rather than a prompt.
|
||||
(defun reb-enter-subexp-mode ()
|
||||
"Enter the subexpression mode in the RE Builder."
|
||||
(interactive)
|
||||
|
||||
(setq reb-subexp-mode t)
|
||||
(reb-update-modestring)
|
||||
(use-local-map reb-subexp-mode-map)
|
||||
(message "`0'-`9' to display subexpressions `q' to quit subexp mode."))
|
||||
|
||||
(defun reb-show-subexp (subexp &optional pause)
|
||||
"Visually show limit of subexpression SUBEXP of recent search.
|
||||
On color displays this just puts point to the end of the expression as
|
||||
the match should already be marked by an overlay.
|
||||
On other displays jump to the beginning and the end of it.
|
||||
If the optional PAUSE is non-nil then pause at the end in any case."
|
||||
(reb-with-current-window reb-target-window
|
||||
(if (not (reb-color-display-p))
|
||||
(progn (goto-char (match-beginning subexp))
|
||||
(sit-for reb-blink-delay)))
|
||||
(goto-char (match-end subexp))
|
||||
(if (or (not (reb-color-display-p)) pause)
|
||||
(sit-for reb-blink-delay))))
|
||||
|
||||
(defun reb-quit-subexp-mode ()
|
||||
"Quit the subexpression mode in the RE Builder."
|
||||
(interactive)
|
||||
|
||||
(setq reb-subexp-mode nil
|
||||
reb-subexp-displayed nil)
|
||||
(reb-update-modestring)
|
||||
(use-local-map reb-mode-map)
|
||||
(reb-do-update))
|
||||
|
||||
(defun reb-change-syntax (&optional syntax)
|
||||
"Change the syntax used by the RE Builder.
|
||||
Optional argument SYNTAX must be specified if called non-interactively."
|
||||
(interactive
|
||||
(list (intern
|
||||
(completing-read "Select syntax: "
|
||||
(mapcar (lambda (el) (cons (symbol-name el) 1))
|
||||
'(read string lisp-re sregex))
|
||||
nil t (symbol-name reb-re-syntax)))))
|
||||
|
||||
(if (memq syntax '(read string lisp-re sregex))
|
||||
(let ((buffer (get-buffer reb-buffer)))
|
||||
(setq reb-re-syntax syntax)
|
||||
(if buffer
|
||||
(with-current-buffer buffer
|
||||
(erase-buffer)
|
||||
(reb-insert-regexp)
|
||||
(goto-char (+ 2 (point-min)))
|
||||
(cond ((reb-lisp-syntax-p)
|
||||
(reb-lisp-mode))
|
||||
(t (reb-mode))))))
|
||||
(error "Invalid syntax: %s" syntax)))
|
||||
|
||||
|
||||
;; Non-interactive functions below
|
||||
(defun reb-do-update (&optional subexp)
|
||||
"Update matches in the RE Builder target window.
|
||||
If SUBEXP is non-nil mark only the corresponding sub-expressions."
|
||||
|
||||
(reb-assert-buffer-in-window)
|
||||
(reb-update-regexp)
|
||||
(reb-update-overlays subexp))
|
||||
|
||||
(defun reb-auto-update (beg end lenold &optional force)
|
||||
"Called from `after-update-functions' to update the display.
|
||||
BEG END and LENOLD are passed in from the hook.
|
||||
An actual update is only done if the regexp has changed or if the
|
||||
optional fourth argument FORCE is non-nil."
|
||||
(let ((prev-valid reb-valid-string)
|
||||
(new-valid
|
||||
(condition-case nil
|
||||
(progn
|
||||
(if (or (reb-update-regexp) force)
|
||||
(progn
|
||||
(reb-assert-buffer-in-window)
|
||||
(reb-do-update)))
|
||||
"")
|
||||
(error " *invalid*"))))
|
||||
(setq reb-valid-string new-valid)
|
||||
(force-mode-line-update)
|
||||
|
||||
;; Through the caching of the re a change invalidating the syntax
|
||||
;; for symbolic expressions will not delete the overlays so we
|
||||
;; catch it here
|
||||
(if (and (reb-lisp-syntax-p)
|
||||
(not (string= prev-valid new-valid))
|
||||
(string= prev-valid ""))
|
||||
(reb-delete-overlays))))
|
||||
|
||||
(defun reb-delete-overlays ()
|
||||
"Delete all RE Builder overlays in the `reb-target-buffer' buffer."
|
||||
(if (buffer-live-p reb-target-buffer)
|
||||
(with-current-buffer reb-target-buffer
|
||||
(mapcar 'delete-overlay reb-overlays)
|
||||
(setq reb-overlays nil))))
|
||||
|
||||
(defun reb-assert-buffer-in-window ()
|
||||
"Assert that `reb-target-buffer' is displayed in `reb-target-window'."
|
||||
|
||||
(if (not (eq reb-target-buffer (window-buffer reb-target-window)))
|
||||
(set-window-buffer reb-target-window reb-target-buffer)))
|
||||
|
||||
(defun reb-update-modestring ()
|
||||
"Update the variable `reb-mode-string' displayed in the mode line."
|
||||
(setq reb-mode-string
|
||||
(concat
|
||||
(if reb-subexp-mode
|
||||
(concat " (subexp " (or reb-subexp-displayed "-") ")")
|
||||
"")
|
||||
(if (not (reb-target-binding case-fold-search))
|
||||
" Case"
|
||||
"")))
|
||||
(force-mode-line-update))
|
||||
|
||||
(defun reb-display-subexp (&optional subexp)
|
||||
"Highlight only subexpression SUBEXP in the RE Builder."
|
||||
(interactive)
|
||||
|
||||
(setq reb-subexp-displayed
|
||||
(or subexp (string-to-int (format "%c" last-command-char))))
|
||||
(reb-update-modestring)
|
||||
(reb-do-update reb-subexp-displayed))
|
||||
|
||||
(defun reb-kill-buffer ()
|
||||
"When the RE Builder buffer is killed make sure no overlays stay around."
|
||||
|
||||
(if (member major-mode '(reb-mode reb-lisp-mode))
|
||||
(reb-delete-overlays)))
|
||||
|
||||
|
||||
;; The next functions are the interface between the regexp and
|
||||
;; its textual representation in the RE Builder buffer.
|
||||
;; They are the only functions concerned with the actual syntax
|
||||
;; being used.
|
||||
(defun reb-read-regexp ()
|
||||
"Read current RE."
|
||||
(save-excursion
|
||||
(cond ((eq reb-re-syntax 'read)
|
||||
(goto-char (point-min))
|
||||
(read (current-buffer)))
|
||||
((eq reb-re-syntax 'string)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "\"")
|
||||
(let ((beg (point)))
|
||||
(goto-char (point-max))
|
||||
(re-search-backward "\"")
|
||||
(buffer-substring-no-properties beg (point))))
|
||||
((reb-lisp-syntax-p)
|
||||
(buffer-string)))))
|
||||
|
||||
(defun reb-empty-regexp ()
|
||||
"Return empty RE for current syntax."
|
||||
(cond ((reb-lisp-syntax-p) "'()")
|
||||
(t "")))
|
||||
|
||||
(defun reb-insert-regexp ()
|
||||
"Insert current RE."
|
||||
|
||||
(let ((re (or (reb-target-binding reb-regexp)
|
||||
(reb-empty-regexp))))
|
||||
(cond ((eq reb-re-syntax 'read)
|
||||
(print re (current-buffer)))
|
||||
((eq reb-re-syntax 'string)
|
||||
(insert "\n\"" re "\""))
|
||||
;; For the Lisp syntax we need the "source" of the regexp
|
||||
((reb-lisp-syntax-p)
|
||||
(insert (or (reb-target-binding reb-regexp-src)
|
||||
(reb-empty-regexp)))))))
|
||||
|
||||
(defun reb-cook-regexp (re)
|
||||
"Return RE after processing it according to `reb-re-syntax'."
|
||||
(cond ((eq reb-re-syntax 'lisp-re)
|
||||
(lre-compile-string (eval (car (read-from-string re)))))
|
||||
((eq reb-re-syntax 'sregex)
|
||||
(apply 'sregex (eval (car (read-from-string re)))))
|
||||
(t re)))
|
||||
|
||||
(defun reb-update-regexp ()
|
||||
"Update the regexp for the target buffer.
|
||||
Return t if the (cooked) expression changed."
|
||||
(let* ((re-src (reb-read-regexp))
|
||||
(re (reb-cook-regexp re-src)))
|
||||
(with-current-buffer reb-target-buffer
|
||||
(let ((oldre reb-regexp))
|
||||
(prog1
|
||||
(not (string= oldre re))
|
||||
(setq reb-regexp re)
|
||||
;; Only update the source re for the lisp formats
|
||||
(if (reb-lisp-syntax-p)
|
||||
(setq reb-regexp-src re-src)))))))
|
||||
|
||||
|
||||
;; And now the real core of the whole thing
|
||||
(defun reb-count-subexps (re)
|
||||
"Return number of sub-expressions in the regexp RE."
|
||||
|
||||
(let ((i 0) (beg 0))
|
||||
(while (string-match "\\\\(" re beg)
|
||||
(setq i (1+ i)
|
||||
beg (match-end 0)))
|
||||
i))
|
||||
|
||||
|
||||
(defun reb-update-overlays (&optional subexp)
|
||||
"Switch to `reb-target-buffer' and mark all matches of `reb-regexp'.
|
||||
If SUBEXP is non-nil mark only the corresponding sub-expressions."
|
||||
|
||||
(let* ((re (reb-target-binding reb-regexp))
|
||||
(subexps (reb-count-subexps re))
|
||||
(matches 0)
|
||||
(submatches 0)
|
||||
firstmatch)
|
||||
(save-excursion
|
||||
(set-buffer reb-target-buffer)
|
||||
(reb-delete-overlays)
|
||||
(goto-char (point-min))
|
||||
(while (and (re-search-forward re (point-max) t)
|
||||
(or (not reb-auto-match-limit)
|
||||
(< matches reb-auto-match-limit)))
|
||||
(if (= 0 (length (match-string 0)))
|
||||
(error "Empty regular expression!"))
|
||||
(let ((i 0))
|
||||
(setq matches (1+ matches))
|
||||
(while (<= i subexps)
|
||||
(if (and (or (not subexp) (= subexp i))
|
||||
(match-beginning i))
|
||||
(let ((overlay (make-overlay (match-beginning i)
|
||||
(match-end i)))
|
||||
(face-name (format "reb-match-%d" i)))
|
||||
(if (not firstmatch)
|
||||
(setq firstmatch (match-data)))
|
||||
(setq reb-overlays (cons overlay reb-overlays)
|
||||
submatches (1+ submatches))
|
||||
(overlay-put
|
||||
overlay 'face
|
||||
(or (intern-soft face-name)
|
||||
(error "Too many subexpressions - face `%s' not defined"
|
||||
face-name )))
|
||||
(overlay-put overlay 'priority i)))
|
||||
(setq i (1+ i))))))
|
||||
(let ((count (if subexp submatches matches)))
|
||||
(message"%s %smatch(es)%s"
|
||||
(if (= 0 count) "No" (int-to-string count))
|
||||
(if subexp "subexpression " "")
|
||||
(if (and reb-auto-match-limit
|
||||
(= reb-auto-match-limit count))
|
||||
" (limit reached)" "")))
|
||||
(if firstmatch
|
||||
(progn (store-match-data firstmatch)
|
||||
(reb-show-subexp (or subexp 0))))))
|
||||
|
||||
;;; re-builder.el ends here
|
@ -629,6 +629,15 @@ Obsolete.")
|
||||
(autoload (quote auto-show-mode) "auto-show" "\
|
||||
This command is obsolete." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (autoconf-mode) "autoconf" "progmodes/autoconf.el"
|
||||
;;;;;; (14532 61420))
|
||||
;;; Generated autoloads from progmodes/autoconf.el
|
||||
|
||||
(autoload (quote autoconf-mode) "autoconf" "\
|
||||
Major mode for editing Autoconf configure.in files." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (auto-insert-mode define-auto-insert auto-insert)
|
||||
@ -1031,7 +1040,7 @@ a reflection." t nil)
|
||||
;;;;;; bookmark-load bookmark-save bookmark-write bookmark-delete
|
||||
;;;;;; bookmark-insert bookmark-rename bookmark-insert-location
|
||||
;;;;;; bookmark-relocate bookmark-jump bookmark-set) "bookmark"
|
||||
;;;;;; "bookmark.el" (14419 37278))
|
||||
;;;;;; "bookmark.el" (14531 42950))
|
||||
;;; Generated autoloads from bookmark.el
|
||||
(define-key ctl-x-map "rb" 'bookmark-jump)
|
||||
(define-key ctl-x-map "rm" 'bookmark-set)
|
||||
@ -1527,7 +1536,7 @@ name of buffer configuration." t nil)
|
||||
;;;### (autoloads (batch-byte-recompile-directory batch-byte-compile
|
||||
;;;;;; display-call-tree byte-compile compile-defun byte-compile-file
|
||||
;;;;;; byte-recompile-directory byte-force-recompile) "bytecomp"
|
||||
;;;;;; "emacs-lisp/bytecomp.el" (14516 150))
|
||||
;;;;;; "emacs-lisp/bytecomp.el" (14534 23874))
|
||||
;;; Generated autoloads from emacs-lisp/bytecomp.el
|
||||
|
||||
(autoload (quote byte-force-recompile) "bytecomp" "\
|
||||
@ -2526,7 +2535,7 @@ and runs the normal hook `command-history-hook'." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "cl" "emacs-lisp/cl.el" (14495 18013))
|
||||
;;;### (autoloads nil "cl" "emacs-lisp/cl.el" (14533 31536))
|
||||
;;; Generated autoloads from emacs-lisp/cl.el
|
||||
|
||||
(defvar custom-print-functions nil "\
|
||||
@ -2567,8 +2576,8 @@ For use inside Lisp programs, see also `c-macro-expansion'." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (run-scheme) "cmuscheme" "cmuscheme.el" (13569
|
||||
;;;;;; 34340))
|
||||
;;;### (autoloads (run-scheme) "cmuscheme" "cmuscheme.el" (14535
|
||||
;;;;;; 44845))
|
||||
;;; Generated autoloads from cmuscheme.el
|
||||
|
||||
(autoload (quote run-scheme) "cmuscheme" "\
|
||||
@ -2630,7 +2639,7 @@ read/written by MS-DOS software, or for display on the MS-DOS terminal." t nil)
|
||||
|
||||
;;;### (autoloads (comint-redirect-results-list-from-process comint-redirect-results-list
|
||||
;;;;;; comint-redirect-send-command-to-process comint-redirect-send-command
|
||||
;;;;;; comint-run make-comint) "comint" "comint.el" (14411 60193))
|
||||
;;;;;; comint-run make-comint) "comint" "comint.el" (14535 44845))
|
||||
;;; Generated autoloads from comint.el
|
||||
|
||||
(autoload (quote make-comint) "comint" "\
|
||||
@ -6010,7 +6019,7 @@ with no args, if that value is non-nil." t nil)
|
||||
;;;;;; facemenu-remove-special facemenu-remove-all facemenu-remove-face-props
|
||||
;;;;;; facemenu-set-read-only facemenu-set-intangible facemenu-set-invisible
|
||||
;;;;;; facemenu-set-face-from-menu facemenu-set-background facemenu-set-foreground
|
||||
;;;;;; facemenu-set-face) "facemenu" "facemenu.el" (14508 6392))
|
||||
;;;;;; facemenu-set-face) "facemenu" "facemenu.el" (14529 14394))
|
||||
;;; Generated autoloads from facemenu.el
|
||||
(define-key global-map "\M-g" 'facemenu-keymap)
|
||||
(autoload 'facemenu-keymap "facemenu" "Keymap for face-changing commands." t 'keymap)
|
||||
@ -6604,7 +6613,7 @@ in your `~/.emacs' file, replacing [f7] by your favourite key:
|
||||
;;;### (autoloads (font-lock-fontify-buffer global-font-lock-mode
|
||||
;;;;;; global-font-lock-mode font-lock-remove-keywords font-lock-add-keywords
|
||||
;;;;;; turn-on-font-lock font-lock-mode) "font-lock" "font-lock.el"
|
||||
;;;;;; (14522 33623))
|
||||
;;;;;; (14535 40196))
|
||||
;;; Generated autoloads from font-lock.el
|
||||
|
||||
(defvar font-lock-mode-hook nil "\
|
||||
@ -9751,8 +9760,8 @@ This command runs the normal hooks `text-mode-hook' and `mh-letter-mode-hook'."
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (mh-version mh-rmail) "mh-e" "mail/mh-e.el" (14376
|
||||
;;;;;; 9267))
|
||||
;;;### (autoloads (mh-version mh-rmail) "mh-e" "mail/mh-e.el" (14532
|
||||
;;;;;; 63447))
|
||||
;;; Generated autoloads from mail/mh-e.el
|
||||
|
||||
(autoload (quote mh-rmail) "mh-e" "\
|
||||
@ -9921,7 +9930,7 @@ different buffer menu using the function `msb'." t nil)
|
||||
;;;;;; list-fontsets describe-fontset describe-font list-coding-categories
|
||||
;;;;;; list-coding-systems describe-current-coding-system describe-current-coding-system-briefly
|
||||
;;;;;; describe-coding-system list-charset-chars read-charset list-character-sets)
|
||||
;;;;;; "mule-diag" "international/mule-diag.el" (14524 58690))
|
||||
;;;;;; "mule-diag" "international/mule-diag.el" (14529 14422))
|
||||
;;; Generated autoloads from international/mule-diag.el
|
||||
|
||||
(autoload (quote list-character-sets) "mule-diag" "\
|
||||
@ -10329,7 +10338,7 @@ startup file, `~/.emacs-octave'." t nil)
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (octave-mode) "octave-mod" "progmodes/octave-mod.el"
|
||||
;;;;;; (14358 1330))
|
||||
;;;;;; (14535 42068))
|
||||
;;; Generated autoloads from progmodes/octave-mod.el
|
||||
|
||||
(autoload (quote octave-mode) "octave-mod" "\
|
||||
@ -11331,11 +11340,20 @@ Display `quickurl-list' as a formatted list using `quickurl-list-mode'." t nil)
|
||||
Compile the the current buffer's directory on HOST. Log in as USER.
|
||||
See \\[compile]." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (re-builder) "re-builder" "emacs-lisp/re-builder.el"
|
||||
;;;;;; (14536 1936))
|
||||
;;; Generated autoloads from emacs-lisp/re-builder.el
|
||||
|
||||
(autoload (quote re-builder) "re-builder" "\
|
||||
Call up the RE Builder for the current window." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (recentf-open-more-files recentf-cleanup recentf-edit-list
|
||||
;;;;;; recentf-save-list recentf-mode) "recentf" "recentf.el" (14522
|
||||
;;;;;; 39506))
|
||||
;;;;;; recentf-save-list recentf-mode) "recentf" "recentf.el" (14533
|
||||
;;;;;; 31505))
|
||||
;;; Generated autoloads from recentf.el
|
||||
|
||||
(autoload (quote recentf-mode) "recentf" "\
|
||||
@ -11552,7 +11570,7 @@ Here are all local bindings.
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (regexp-opt-depth regexp-opt) "regexp-opt" "emacs-lisp/regexp-opt.el"
|
||||
;;;;;; (14495 18015))
|
||||
;;;;;; (14535 45202))
|
||||
;;; Generated autoloads from emacs-lisp/regexp-opt.el
|
||||
|
||||
(autoload (quote regexp-opt) "regexp-opt" "\
|
||||
@ -11563,10 +11581,7 @@ is enclosed by at least one regexp grouping construct.
|
||||
The returned regexp is typically more efficient than the equivalent regexp:
|
||||
|
||||
(let ((open-paren (if PAREN \"\\\\(\" \"\")) (close-paren (if PAREN \"\\\\)\" \"\")))
|
||||
(concat open-paren (mapconcat 'regexp-quote STRINGS \"\\\\|\") close-paren))
|
||||
|
||||
but typically contains more regexp grouping constructs.
|
||||
Use `regexp-opt-depth' to count them." nil nil)
|
||||
(concat open-paren (mapconcat 'regexp-quote STRINGS \"\\\\|\") close-paren))" nil nil)
|
||||
|
||||
(autoload (quote regexp-opt-depth) "regexp-opt" "\
|
||||
Return the depth of REGEXP.
|
||||
@ -12212,7 +12227,7 @@ scribe-electric-parenthesis
|
||||
;;;;;; mail-signature mail-personal-alias-file mail-alias-file mail-default-reply-to
|
||||
;;;;;; mail-archive-file-name mail-header-separator mail-yank-ignored-headers
|
||||
;;;;;; mail-interactive mail-self-blind mail-specify-envelope-from
|
||||
;;;;;; mail-from-style) "sendmail" "mail/sendmail.el" (14495 18026))
|
||||
;;;;;; mail-from-style) "sendmail" "mail/sendmail.el" (14532 62968))
|
||||
;;; Generated autoloads from mail/sendmail.el
|
||||
|
||||
(defvar mail-from-style (quote angles) "\
|
||||
@ -13250,7 +13265,7 @@ Try to set `comint-output-filter-functions' like this:
|
||||
;;;### (autoloads (strokes-mode strokes-load-user-strokes strokes-help
|
||||
;;;;;; strokes-describe-stroke strokes-do-complex-stroke strokes-do-stroke
|
||||
;;;;;; strokes-read-complex-stroke strokes-read-stroke strokes-global-set-stroke)
|
||||
;;;;;; "strokes" "strokes.el" (13337 50462))
|
||||
;;;;;; "strokes" "strokes.el" (14527 50024))
|
||||
;;; Generated autoloads from strokes.el
|
||||
|
||||
(defvar strokes-mode nil "\
|
||||
@ -14095,7 +14110,7 @@ This function performs no refilling of the changed text." t nil)
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (display-time-mode display-time display-time-day-and-date
|
||||
;;;;;; display-time-mode) "time" "time.el" (14495 17997))
|
||||
;;;;;; display-time-mode) "time" "time.el" (14526 14916))
|
||||
;;; Generated autoloads from time.el
|
||||
|
||||
(defvar display-time-mode nil "\
|
||||
@ -15542,6 +15557,25 @@ If no window is at the desired location, an error is signaled." t nil)
|
||||
(autoload (quote windmove-default-keybindings) "windmove" "\
|
||||
Set up default keybindings for `windmove'." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (winner-mode winner-mode) "winner" "winner.el"
|
||||
;;;;;; (14535 44846))
|
||||
;;; Generated autoloads from winner.el
|
||||
|
||||
(defvar winner-mode nil "\
|
||||
Toggle winner-mode.
|
||||
Setting this variable directly does not take effect;
|
||||
use either \\[customize] or the function `winner-mode'.")
|
||||
|
||||
(custom-add-to-group (quote winner) (quote winner-mode) (quote custom-variable))
|
||||
|
||||
(custom-add-load (quote winner-mode) (quote winner))
|
||||
|
||||
(autoload (quote winner-mode) "winner" "\
|
||||
Toggle Winner mode.
|
||||
With arg, turn Winner mode on if and only if arg is positive." t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads (wordstar-mode) "ws-mode" "emulation/ws-mode.el"
|
||||
|
Loading…
Reference in New Issue
Block a user