annotate lisp/replace.el @ 814:a634e3b7acc8

[xemacs-hg @ 2002-04-14 12:41:59 by ben] latest changes TODO.ben-mule-21-5: Update. make-docfile.c: Add basic support for handling ISO 2022 doc strings -- we parse the basic charset designation sequences so we know whether we're in ASCII and have to pay attention to end quotes and such. Reformat code according to coding standards. abbrev.el: Add `global-abbrev-mode', which turns on or off abbrev-mode in all buffers. Added `defining-abbrev-turns-on-abbrev-mode' -- if non-nil, defining an abbrev through an interactive function will automatically turn on abbrev-mode, either globally or locally depending on the command. This is the "what you'd expect" behavior. indent.el: general function for indenting a balanced expression in a mode-correct way. Works similar to indent-region in that a mode can specify a specific command to do the whole operation; if not, figure out the region using forward-sexp and indent each line using indent-according-to-mode. keydefs.el: Removed. Modify M-C-backslash to do indent-region-or-balanced-expression. Make S-Tab just insert a TAB char, like it's meant to do. make-docfile.el: Now that we're using the call-process-in-lisp, we need to load an extra file win32-native.el because we're running a bare temacs. menubar-items.el: Totally redo the Cmds menu so that most used commands appear directly on the menu and less used commands appear in submenus. The old way may have been very pretty, but rather impractical. process.el: Under Windows, don't ever use old-call-process-internal, even in batch mode. We can do processes in batch mode. subr.el: Someone recoded truncate-string-to-width, saying "the FSF version is too complicated and does lots of hard-to-understand stuff" but the resulting recoded version was *totally* wrong! it misunderstood the basic point of this function, which is work in *columns* not chars. i dumped ours and copied the version from FSF 21.1. Also added truncate-string-with-continuation-dots, since this idiom is used often. config.inc.samp, xemacs.mak: Separate out debug and optimize flags. Remove all vestiges of USE_MINIMAL_TAGBITS, USE_INDEXED_LRECORD_IMPLEMENTATION, and GUNG_HO, since those ifdefs have long been removed. Make error-checking support actually work. Some rearrangement of config.inc.samp to make it more logical. Remove callproc.c and ntproc.c from xemacs.mak, no longer used. Make pdump the default. lisp.h: Add support for strong type-checking of Bytecount, Bytebpos, Charcount, Charbpos, and others, by making them classes, overloading the operators to provide integer-like operation and carefully controlling what operations are allowed. Not currently enabled in C++ builds because there are still a number of compile errors, and it won't really work till we merge in my "8-bit-Mule" workspace, in which I make use of the new types Charxpos, Bytexpos, Memxpos, representing a "position" either in a buffer or a string. (This is especially important in the extent code.) abbrev.c, alloc.c, eval.c, buffer.c, buffer.h, editfns.c, fns.c, text.h: Warning fixes, some of them related to new C++ strict type checking of Bytecount, Charbpos, etc. dired.c: Caught an actual error due to strong type checking -- char len being passed when should be byte len. alloc.c, backtrace.h, bytecode.c, bytecode.h, eval.c, sysdep.c: Further optimize Ffuncall: -- process arg list at compiled-function creation time, converting into an array for extra-quick access at funcall time. -- rewrite funcall_compiled_function to use it, and inline this function. -- change the order of check for magic stuff in SPECBIND_FAST_UNSAFE to be faster. -- move the check for need to garbage collect into the allocation code, so only a single flag needs to be checked in funcall. buffer.c, symbols.c: add debug funs to check on mule optimization info in buffers and strings. eval.c, emacs.c, text.c, regex.c, scrollbar-msw.c, search.c: Fix evil crashes due to eistrings not properly reinitialized under pdump. Redo a bit some of the init routines; convert some complex_vars_of() into simple vars_of(), because they didn't need complex processing. callproc.c, emacs.c, event-stream.c, nt.c, process.c, process.h, sysdep.c, sysdep.h, syssignal.h, syswindows.h, ntproc.c: Delete. Hallelujah, praise the Lord, there is no god but Allah!!! fix so that processes can be invoked in bare temacs -- thereby eliminating any need for callproc.c. (currently only eliminated under NT.) remove all crufty and unnecessary old process code in ntproc.c and elsewhere. move non-callproc-specific stuff (mostly environment) into process.c, so callproc.c can be left out under NT. console-tty.c, doc.c, file-coding.c, file-coding.h, lstream.c, lstream.h: fix doc string handling so it works with Japanese, etc docs. change handling of "character mode" so callers don't have to manually set it (quite error-prone). event-msw.c: spacing fixes. lread.c: eliminate unused crufty vintage-19 "FSF defun hack" code. lrecord.h: improve pdump description docs. buffer.c, ntheap.c, unexnt.c, win32.c, emacs.c: Mule-ize some unexec and startup code. It was pseudo-Mule-ized before by simply always calling the ...A versions of functions, but that won't cut it -- eventually we want to be able to run properly even if XEmacs has been installed in a Japanese directory. (The current problem is the timing of the loading of the Unicode tables; this will eventually be fixed.) Go through and fix various other places where the code was not Mule-clean. Provide a function mswindows_get_module_file_name() to get our own name without resort to PATH_MAX and such. Add a big comment in main() about the problem with Unicode table load timing that I just alluded to. emacs.c: When error-checking is enabled (interpreted as "user is developing XEmacs"), don't ask user to "pause to read messages" when a fatal error has occurred, because it will wedge if we are in an inner modal loop (typically when a menu is popped up) and make us unable to get a useful stack trace in the debugger. text.c: Correct update_entirely_ascii_p_flag to actually work. lisp.h, symsinit.h: declarations for above changes.
author ben
date Sun, 14 Apr 2002 12:43:31 +0000
parents e7ef97881643
children 13daf40fb997
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; replace.el --- search and replace commands for XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (C) 1985-7, 1992, 1994, 1997 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 ;; Maintainer: XEmacs Development Team
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Keywords: dumped, matching
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;;; Synched up with: FSF 19.34 [Partially].
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 ;; This package supplies the string and regular-expression replace functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; documented in the XEmacs Reference Manual.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;; All the gettext calls are for XEmacs I18N3 message catalog support.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;; (This is hopelessly broken and we should remove it. -sb)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 (defvar case-replace t "\
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 *Non-nil means `query-replace' should preserve case in replacements.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 What this means is that `query-replace' will change the case of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 replacement text so that it matches the text that was replaced.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 If this variable is nil, the replacement text will be inserted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 exactly as it was specified by the user, irrespective of the case
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 of the text that was replaced.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 Note that this flag has no effect if `case-fold-search' is nil,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 or if the replacement text has any uppercase letters in it.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 (defvar query-replace-history nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 (defvar query-replace-interactive nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 "Non-nil means `query-replace' uses the last search string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 That becomes the \"string to replace\".")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 (defvar replace-search-function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 (lambda (str limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 (search-forward str limit t))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
59 "Function used by perform-replace to search forward for a string. It will be
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 called with two arguments: the string to search for and a limit bounding the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 search.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 (defvar replace-re-search-function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 (lambda (regexp limit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 (re-search-forward regexp limit t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 "Function used by perform-replace to search forward for a regular
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 expression. It will be called with two arguments: the regexp to search for and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 a limit bounding the search.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 (defun query-replace-read-args (string regexp-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 (let (from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 (if query-replace-interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (setq from (car (if regexp-flag regexp-search-ring search-ring)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 (setq from (read-from-minibuffer (format "%s: " (gettext string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 nil nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 'query-replace-history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 (setq to (read-from-minibuffer (format "%s %s with: " (gettext string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 nil nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 'query-replace-history))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 (list from to current-prefix-arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 ;; As per suggestion from Per Abrahamsen, limit replacement to the region
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ;; if the region is active.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 (defun query-replace (from-string to-string &optional delimited)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 "Replace some occurrences of FROM-STRING with TO-STRING.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 As each match is found, the user must type a character saying
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 what to do with it. For directions, type \\[help-command] at that time.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 If `query-replace-interactive' is non-nil, the last incremental search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 string is used as FROM-STRING--you don't have to specify it with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 Preserves case in each replacement if `case-replace' and `case-fold-search'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 are non-nil and FROM-STRING has no uppercase letters.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 \(Preserving case means that if the string matched is all caps, or capitalized,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 then its replacement is upcased or capitalized.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 only matches surrounded by word boundaries.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 To customize possible responses, change the \"bindings\" in `query-replace-map'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 (interactive (query-replace-read-args "Query replace" nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (perform-replace from-string to-string t nil delimited))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (defun query-replace-regexp (regexp to-string &optional delimited)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 "Replace some things after point matching REGEXP with TO-STRING.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 As each match is found, the user must type a character saying
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 what to do with it. For directions, type \\[help-command] at that time.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 If `query-replace-interactive' is non-nil, the last incremental search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 regexp is used as REGEXP--you don't have to specify it with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 Preserves case in each replacement if `case-replace' and `case-fold-search'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 are non-nil and REGEXP has no uppercase letters.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 only matches surrounded by word boundaries.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 and `\\=\\N' (where N is a digit) stands for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 whatever what matched the Nth `\\(...\\)' in REGEXP."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 (interactive (query-replace-read-args "Query replace regexp" t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 (perform-replace regexp to-string t t delimited))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 ;;#### Not patently useful
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 (defun map-query-replace-regexp (regexp to-strings &optional arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 "Replace some matches for REGEXP with various strings, in rotation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 The second argument TO-STRINGS contains the replacement strings, separated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 by spaces. This command works like `query-replace-regexp' except
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 that each successive replacement uses the next successive replacement string,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 wrapping around from the last such string to the first.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 Non-interactively, TO-STRINGS may be a list of replacement strings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 If `query-replace-interactive' is non-nil, the last incremental search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 regexp is used as REGEXP--you don't have to specify it with the minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 A prefix argument N says to use each replacement string N times
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 before rotating to the next."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 (let (from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 (setq from (if query-replace-interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 (car regexp-search-ring)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 (read-from-minibuffer "Map query replace (regexp): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 nil nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 'query-replace-history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 (setq to (read-from-minibuffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 (format "Query replace %s with (space-separated strings): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 nil nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 'query-replace-history))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 (list from to current-prefix-arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (let (replacements)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 (if (listp to-strings)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 (setq replacements to-strings)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (while (/= (length to-strings) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (if (string-match " " to-strings)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (setq replacements
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (append replacements
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (list (substring to-strings 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (string-match " " to-strings))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 to-strings (substring to-strings
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 (1+ (string-match " " to-strings))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (setq replacements (append replacements (list to-strings))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 to-strings ""))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 (perform-replace regexp replacements t t nil arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (defun replace-string (from-string to-string &optional delimited)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 "Replace occurrences of FROM-STRING with TO-STRING.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 Preserve case in each match if `case-replace' and `case-fold-search'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 are non-nil and FROM-STRING has no uppercase letters.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 \(Preserving case means that if the string matched is all caps, or capitalized,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 then its replacement is upcased or capitalized.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 only matches surrounded by word boundaries.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 If `query-replace-interactive' is non-nil, the last incremental search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 string is used as FROM-STRING--you don't have to specify it with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 This function is usually the wrong thing to use in a Lisp program.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 What you probably want is a loop like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 (while (search-forward FROM-STRING nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 (replace-match TO-STRING nil t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 which will run faster and will not set the mark or print anything."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 (interactive (query-replace-read-args "Replace string" nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 (perform-replace from-string to-string nil nil delimited))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (defun replace-regexp (regexp to-string &optional delimited)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 "Replace things after point matching REGEXP with TO-STRING.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 Preserve case in each match if `case-replace' and `case-fold-search'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 are non-nil and REGEXP has no uppercase letters.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 \(Preserving case means that if the string matched is all caps, or capitalized,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 then its replacement is upcased or capitalized.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 only matches surrounded by word boundaries.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 and `\\=\\N' (where N is a digit) stands for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 whatever what matched the Nth `\\(...\\)' in REGEXP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 If `query-replace-interactive' is non-nil, the last incremental search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 regexp is used as REGEXP--you don't have to specify it with the minibuffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 This function is usually the wrong thing to use in a Lisp program.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 What you probably want is a loop like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 (while (re-search-forward REGEXP nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 (replace-match TO-STRING nil nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 which will run faster and will not set the mark or print anything."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 (interactive (query-replace-read-args "Replace regexp" t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (perform-replace regexp to-string nil t delimited))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (defvar regexp-history nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 "History list for some commands that read regular expressions.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 (define-function 'keep-lines 'delete-non-matching-lines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 (defun delete-non-matching-lines (regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 "Delete all lines except those containing matches for REGEXP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 A match split across lines preserves all the lines it lies in.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 Applies to all lines after point."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 (interactive (list (read-from-minibuffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 "Keep lines (containing match for regexp): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 nil nil nil 'regexp-history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 (with-interactive-search-caps-disable-folding regexp t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 (or (bolp) (forward-line 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 (let ((start (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 (while (not (eobp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 ;; Start is first char not preserved by previous match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 (if (not (re-search-forward regexp nil 'move))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 (delete-region start (point-max))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 (let ((end (save-excursion (goto-char (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 ;; Now end is first char preserved by the new match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 (if (< start end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (delete-region start end))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 (setq start (save-excursion (forward-line 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 ;; If the match was empty, avoid matching again at same place.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 (and (not (eobp)) (= (match-beginning 0) (match-end 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 (forward-char 1)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 (define-function 'flush-lines 'delete-matching-lines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (defun delete-matching-lines (regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 "Delete lines containing matches for REGEXP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 If a match is split across lines, all the lines it lies in are deleted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 Applies to lines after point."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 (interactive (list (read-from-minibuffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 "Flush lines (containing match for regexp): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 nil nil nil 'regexp-history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 (with-interactive-search-caps-disable-folding regexp t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 (while (and (not (eobp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 (re-search-forward regexp nil t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 (delete-region (save-excursion (goto-char (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 (progn (forward-line 1) (point)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 (define-function 'how-many 'count-matches)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (defun count-matches (regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 "Print number of matches for REGEXP following point."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 (interactive (list (read-from-minibuffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 "How many matches for (regexp): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 nil nil nil 'regexp-history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 (with-interactive-search-caps-disable-folding regexp t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 (let ((count 0) opoint)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (while (and (not (eobp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 (progn (setq opoint (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (re-search-forward regexp nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 (if (= opoint (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 (forward-char 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 (setq count (1+ count))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (message "%d occurrences" count)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 (defvar occur-mode-map ())
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 (if occur-mode-map
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 (setq occur-mode-map (make-sparse-keymap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 (set-keymap-name occur-mode-map 'occur-mode-map) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 (define-key occur-mode-map 'button2 'occur-mode-mouse-goto) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 (define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (defvar occur-buffer nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 (defvar occur-nlines nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (defvar occur-pos-list nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 (defun occur-mode ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 "Major mode for output from \\[occur].
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 \\<occur-mode-map>Move point to one of the items in this buffer, then use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 \\[occur-mode-goto-occurrence] to go to the occurrence that the item refers to.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 \\{occur-mode-map}"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (kill-all-local-variables)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 (use-local-map occur-mode-map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (setq major-mode 'occur-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (setq mode-name (gettext "Occur")) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 (make-local-variable 'occur-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 (make-local-variable 'occur-nlines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 (make-local-variable 'occur-pos-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 (require 'mode-motion) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (setq mode-motion-hook 'mode-motion-highlight-line) ; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 (run-hooks 'occur-mode-hook))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 ;; FSF Version of next function:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 ; (let (buffer pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 ; (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 ; (set-buffer (window-buffer (posn-window (event-end event))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 ; (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 ; (goto-char (posn-point (event-end event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 ; (setq pos (occur-mode-find-occurrence))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 ; (setq buffer occur-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 ; (pop-to-buffer buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 ; (goto-char (marker-position pos))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 (defun occur-mode-mouse-goto (event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 "Go to the occurrence highlighted by mouse.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
325 This function should be bound to a mouse key in the `*Occur*' buffer."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 (interactive "e")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 (let ((window-save (selected-window))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 (frame-save (selected-frame)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 ;; preserve the window/frame setup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 (mouse-set-point event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 (occur-mode-goto-occurrence))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (select-frame frame-save)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 (select-window window-save))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 ;; Called occur-mode-find-occurrence in FSF
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 (defun occur-mode-goto-occurrence ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 "Go to the occurrence the current line describes."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 (interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 (if (or (null occur-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 (null (buffer-name occur-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 (setq occur-buffer nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 occur-pos-list nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 (error "Buffer in which occurrences were found is deleted")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 (let* ((line-count
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 (count-lines (point-min)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 (occur-number (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 (/ (1- line-count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (cond ((< occur-nlines 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (- 2 occur-nlines))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 ((> occur-nlines 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (+ 2 (* 2 occur-nlines)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 (t 1)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 (pos (nth occur-number occur-pos-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 ;; removed t arg from Bob Weiner, 10/6/95
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 (window (get-buffer-window occur-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 (occur-source-buffer occur-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 (if (< line-count 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 (error "No occurrence on this line"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 (or pos
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 (error "No occurrence on this line"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 ;; XEmacs: don't raise window unless it isn't visible
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 ;; allow for the possibility that the occur buffer is on another frame
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 (or (and window
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 (window-live-p window)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 (frame-visible-p (window-frame window))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 (set-buffer occur-source-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 (and (pop-to-buffer occur-source-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 (setq window (get-buffer-window occur-source-buffer))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (goto-char pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (set-window-point window pos)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 (defvar list-matching-lines-default-context-lines 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 "*Default number of context lines to include around a `list-matching-lines'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 match. A negative number means to include that many lines before the match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 A positive number means to include that many lines both before and after.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 ;; XEmacs addition
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 ;;; Damn you Jamie, this is utter trash.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (defvar list-matching-lines-whole-buffer t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 "If t, occur operates on whole buffer, otherwise occur starts from point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 default is t.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (define-function 'occur 'list-matching-lines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (defun list-matching-lines (regexp &optional nlines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 "Show all lines in the current buffer containing a match for REGEXP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 If a match spreads across multiple lines, all those lines are shown.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 444
diff changeset
397 If variable `list-matching-lines-whole-buffer' is non-nil, the entire
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 444
diff changeset
398 buffer is searched, otherwise search begins at point.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 Each line is displayed with NLINES lines before and after, or -NLINES
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 before if NLINES is negative.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 NLINES defaults to `list-matching-lines-default-context-lines'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 Interactively it is the prefix arg.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 The lines are shown in a buffer named `*Occur*'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 It serves as a menu to find any of the occurrences in this buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 \\[describe-mode] in that buffer will explain how."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 ;; XEmacs change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 (list (let* ((default (or (symbol-near-point)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 (and regexp-history
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 (car regexp-history))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 (minibuffer-history-minimum-string-length 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 (input
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 (if default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 ;; rewritten for I18N3 snarfing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 (read-from-minibuffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 (format "List lines matching regexp (default `%s'): "
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 448
diff changeset
419 default) nil nil nil 'regexp-history nil
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 448
diff changeset
420 default)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 (read-from-minibuffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 "List lines matching regexp: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 nil nil nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 'regexp-history))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 (if (and (equal input "") default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 (setq input default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 (setcar regexp-history default)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 ;; clear extra entries
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 (setcdr regexp-history (delete (car regexp-history)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 (cdr regexp-history)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 input)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 current-prefix-arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 (if (equal regexp "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 (error "Must pass non-empty regexp to `list-matching-lines'"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 (setq nlines (if nlines (prefix-numeric-value nlines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 list-matching-lines-default-context-lines))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 (let ((first t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 (dir default-directory)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 (buffer (current-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 (linenum 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 (prevpos (point-min))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 ;; The rest of this function is very different from FSF.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 ;; Presumably that's due to Jamie's misfeature
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 (final-context-start (make-marker)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 (if (not list-matching-lines-whole-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 (setq linenum (1+ (count-lines (point-min) (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 (setq prevpos (point))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 (with-output-to-temp-buffer "*Occur*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 (set-buffer standard-output)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 (setq default-directory dir)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 ;; We will insert the number of lines, and "lines", later.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 ;; #### Needs fixing for I18N3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 (let ((print-escape-newlines t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 (insert (format " matching %s in buffer %s.\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 regexp (buffer-name buffer))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 (occur-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 (setq occur-buffer buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 (setq occur-nlines nlines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 (setq occur-pos-list ()))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 (if (eq buffer standard-output)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 (goto-char (point-max)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 (with-interactive-search-caps-disable-folding regexp t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 (if list-matching-lines-whole-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 (beginning-of-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 (message "Searching for %s ..." regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 ;; Find next match, but give up if prev match was at end of buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 (while (and (not (= prevpos (point-max)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 (re-search-forward regexp nil t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 (goto-char (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 (save-match-data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 (setq linenum (+ linenum (count-lines prevpos (point)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (setq prevpos (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 (goto-char (match-end 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 (let* ((start (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 (goto-char (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 (forward-line (if (< nlines 0) nlines (- nlines)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (end (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (goto-char (match-end 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 (if (> nlines 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 (forward-line (1+ nlines))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 (forward-line 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 (tag (format "%5d" linenum))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 (empty (make-string (length tag) ?\ ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 tem)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 (setq tem (make-marker))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (set-marker tem (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 (set-buffer standard-output)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 (setq occur-pos-list (cons tem occur-pos-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 (or first (zerop nlines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (insert "--------\n"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 (setq first nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 (insert-buffer-substring buffer start end)
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
502 (set-marker final-context-start
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (- (point) (- end (match-end 0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 (backward-char (- end start))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 (setq tem (if (< nlines 0) (- nlines) nlines))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 (while (> tem 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 (insert empty ?:)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 (forward-line 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 (setq tem (1- tem)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (let ((this-linenum linenum))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 (while (< (point) final-context-start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 (if (null tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 (setq tag (format "%5d" this-linenum)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 (insert tag ?:)
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
515 ;; FSFmacs --
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 ;; we handle this using mode-motion-highlight-line, above.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 ;; (put-text-property (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 ;; (beginning-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 ;; (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 ;; (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 ;; (end-of-line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 ;; (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 ;; 'mouse-face 'highlight)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 (forward-line 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 (setq tag nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 (setq this-linenum (1+ this-linenum)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 (while (<= (point) final-context-start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 (insert empty ?:)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 (forward-line 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 (setq this-linenum (1+ this-linenum))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 (while (< tem nlines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 (insert empty ?:)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 (forward-line 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 (setq tem (1+ tem)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 (goto-char (point-max)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 (forward-line 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 (set-buffer standard-output)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 ;; Put positions in increasing order to go with buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 (setq occur-pos-list (nreverse occur-pos-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 (goto-char (point-min))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 (if (= (length occur-pos-list) 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 (insert "1 line")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 (insert (format "%d lines" (length occur-pos-list))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 (if (interactive-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 (message "%d matching lines." (length occur-pos-list))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 ;; It would be nice to use \\[...], but there is no reasonable way
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 ;; to make that display both SPC and Y.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 (defconst query-replace-help
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
550 "Type Space or `y' to replace one match, Delete or `n' to skip to next,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 RET or `q' to exit, Period to replace one match and exit,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 Comma to replace but not move point immediately,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 C-r to enter recursive edit (\\[exit-recursive-edit] to get out again),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 C-w to delete match and recursive edit,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 C-l to clear the frame, redisplay, and offer same replacement again,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 ! to replace all remaining matches with no more questions,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 ^ to move point back to previous match."
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
558
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 "Help message while in query-replace")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 (defvar query-replace-map nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 "Keymap that defines the responses to questions in `query-replace'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 The \"bindings\" in this map are not commands; they are answers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 The valid answers include `act', `skip', `act-and-show',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 `exit', `act-and-exit', `edit', `delete-and-edit', `recenter',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 `automatic', `backup', `exit-prefix', and `help'.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 ;; Why does it seem that ever file has a different method of doing this?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 (if query-replace-map
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 (let ((map (make-sparse-keymap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 (set-keymap-name map 'query-replace-map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 (define-key map " " 'act)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 (define-key map "\d" 'skip)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 (define-key map [delete] 'skip)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 (define-key map [backspace] 'skip)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 (define-key map "y" 'act)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 (define-key map "n" 'skip)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 (define-key map "Y" 'act)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 (define-key map "N" 'skip)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 (define-key map "," 'act-and-show)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 (define-key map [escape] 'exit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 (define-key map "q" 'exit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 (define-key map [return] 'exit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 (define-key map "." 'act-and-exit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 (define-key map "\C-r" 'edit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 (define-key map "\C-w" 'delete-and-edit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 (define-key map "\C-l" 'recenter)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 (define-key map "!" 'automatic)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 (define-key map "^" 'backup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 (define-key map [(control h)] 'help) ;; XEmacs change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 (define-key map [f1] 'help)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 (define-key map [help] 'help)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 (define-key map "?" 'help)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 (define-key map "\C-g" 'quit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 (define-key map "\C-]" 'quit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 ;FSFmacs (define-key map "\e" 'exit-prefix)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 (define-key map [escape] 'exit-prefix)
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
599
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 (setq query-replace-map map)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 ;; isearch-mode is dumped, so don't autoload.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 ;(autoload 'isearch-highlight "isearch")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 ;; XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 (defun perform-replace-next-event (event)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
607 (if search-highlight
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 (let ((aborted t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 (if (match-beginning 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 (isearch-highlight (match-beginning 0) (match-end 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 (next-command-event event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 (setq aborted nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 (isearch-dehighlight aborted)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 (next-command-event event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 (defun perform-replace (from-string replacements
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 query-flag regexp-flag delimited-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 &optional repeat-count map)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 "Subroutine of `query-replace'. Its complexity handles interactive queries.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 Don't use this in your own program unless you want to query and set the mark
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 just as `query-replace' does. Instead, write a simple loop like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 (while (re-search-forward \"foo[ \t]+bar\" nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 (replace-match \"foobar\" nil nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 which will run faster and probably do exactly what you want.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
627 When searching for a match, this function uses
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
628 `replace-search-function' and `replace-re-search-function'."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 (or map (setq map query-replace-map))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 (let* ((event (make-event))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 (nocasify (not (and case-fold-search case-replace
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 (string-equal from-string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 (downcase from-string)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 (literal (not regexp-flag))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
635 (search-function (if regexp-flag
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
636 replace-re-search-function
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 replace-search-function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 (search-string from-string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 (real-match-data nil) ; the match data for the current match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 (next-replacement nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 (replacement-index 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 (keep-going t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 (stack nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 (next-rotate-count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 (replace-count 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 (lastrepl nil) ;Position after last match considered.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 ;; If non-nil, it is marker saying where in the buffer to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 ;; stop.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 (limit nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 (match-again t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 ;; XEmacs addition
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 (qr-case-fold-search
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 (if (and case-fold-search search-caps-disable-folding)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 (no-upper-case-p search-string regexp-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 case-fold-search))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 (message
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 (if query-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 (substitute-command-keys
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 "Query replacing %s with %s: (\\<query-replace-map>\\[help] for help) "))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 ;; If the region is active, operate on region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 (when (region-active-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 ;; Original Per Abrahamsen's code simply narrowed the region,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 ;; thus providing a visual indication of the search boundary.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 ;; Stallman, on the other hand, handles it like this.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 (setq limit (copy-marker (region-end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 (goto-char (region-beginning))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 (zmacs-deactivate-region))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 (if (stringp replacements)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 (setq next-replacement replacements)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 (or repeat-count (setq repeat-count 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 (if delimited-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 (setq search-function replace-re-search-function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 search-string (concat "\\b"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 (if regexp-flag from-string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 (regexp-quote from-string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 "\\b")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 (push-mark)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 (undo-boundary)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 ;; Loop finding occurrences that perhaps should be replaced.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 (while (and keep-going
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 (not (eobp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 (or (null limit) (< (point) limit))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 (let ((case-fold-search qr-case-fold-search))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 (funcall search-function search-string limit))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 ;; If the search string matches immediately after
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 ;; the previous match, but it did not match there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 ;; before the replacement was done, ignore the match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 (if (or (eq lastrepl (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 (and regexp-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 (eq lastrepl (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 (not match-again)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 (if (or (eobp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 (and limit (>= (point) limit)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 nil
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
696 ;; Don't replace the null string
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 ;; right after end of previous replacement.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 (forward-char 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 (let ((case-fold-search qr-case-fold-search))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 (funcall search-function search-string limit)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 ;; Save the data associated with the real match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 (setq real-match-data (match-data))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 ;; Before we make the replacement, decide whether the search string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 ;; can match again just after this match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 (if regexp-flag
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
709 (progn
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 (setq match-again (looking-at search-string))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 ;; XEmacs addition
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 (store-match-data real-match-data)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 ;; If time for a change, advance to next replacement string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 (if (and (listp replacements)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 (= next-rotate-count replace-count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 (setq next-rotate-count
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 (+ next-rotate-count repeat-count))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 (setq next-replacement (nth replacement-index replacements))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 (setq replacement-index (% (1+ replacement-index) (length replacements)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 (if (not query-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 (store-match-data real-match-data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724 (replace-match next-replacement nocasify literal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 (setq replace-count (1+ replace-count)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 (undo-boundary)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 (let ((help-form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728 '(concat (format "Query replacing %s%s with %s.\n\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 (if regexp-flag (gettext "regexp ") "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 from-string next-replacement)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 (substitute-command-keys query-replace-help)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 done replaced def)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 ;; Loop reading commands until one of them sets done,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734 ;; which means it has finished handling this occurrence.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 (while (not done)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 ;; Don't fill up the message log
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 ;; with a bunch of identical messages.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 ;; XEmacs change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 (display-message 'prompt
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 (format message from-string next-replacement))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 (perform-replace-next-event event)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 (setq def (lookup-key map (vector event)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 ;; Restore the match data while we process the command.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 (store-match-data real-match-data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745 (cond ((eq def 'help)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 (with-output-to-temp-buffer (gettext "*Help*")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 (princ (concat
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 (format "Query replacing %s%s with %s.\n\n"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 (if regexp-flag "regexp " "")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 from-string next-replacement)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 (substitute-command-keys
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 query-replace-help)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 (set-buffer standard-output)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 (help-mode))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 ((eq def 'exit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 (setq keep-going nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 (setq done t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 ((eq def 'backup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760 (if stack
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 (let ((elt (car stack)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 (goto-char (car elt))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 (setq replaced (eq t (cdr elt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 (or replaced
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 (store-match-data (cdr elt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 (setq stack (cdr stack)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 (message "No previous match")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 (ding 'no-terminate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 (sit-for 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 ((eq def 'act)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 (or replaced
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 (replace-match next-replacement nocasify literal))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 (setq done t replaced t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 ((eq def 'act-and-exit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 (or replaced
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 (replace-match next-replacement nocasify literal))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 (setq keep-going nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 (setq done t replaced t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 ((eq def 'act-and-show)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 (if (not replaced)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 (replace-match next-replacement nocasify literal)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 (store-match-data nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 (setq replaced t))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 ((eq def 'automatic)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 (or replaced
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 (replace-match next-replacement nocasify literal))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 (setq done t query-flag nil replaced t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 ((eq def 'skip)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 (setq done t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 ((eq def 'recenter)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 (recenter nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 ((eq def 'edit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 (store-match-data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 (prog1 (match-data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 (save-excursion (recursive-edit))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 ;; Before we make the replacement,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 ;; decide whether the search string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 ;; can match again just after this match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 (if regexp-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 (setq match-again (looking-at search-string))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 ((eq def 'delete-and-edit)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 (delete-region (match-beginning 0) (match-end 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 (store-match-data (prog1 (match-data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
805 (save-excursion (recursive-edit))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 (setq replaced t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 ;; Note: we do not need to treat `exit-prefix'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 ;; specially here, since we reread
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 ;; any unrecognized character.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 (setq this-command 'mode-exited)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 (setq keep-going nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813 (setq unread-command-events
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 (cons event unread-command-events))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 (setq done t))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 ;; Record previous position for ^ when we move on.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 ;; Change markers to numbers in the match data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818 ;; since lots of markers slow down editing.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 (setq stack
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 (cons (cons (point)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 (or replaced
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 (match-data t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 stack))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 (if replaced (setq replace-count (1+ replace-count)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 (setq lastrepl (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 ;; Useless in XEmacs. We handle (de)highlighting through
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 ;; perform-replace-next-event.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 ;(replace-dehighlight)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 (or unread-command-events
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 (message "Replaced %d occurrence%s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 replace-count
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833 (if (= replace-count 1) "" "s")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 (and keep-going stack)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 ;; FSFmacs code: someone should port it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
838 ;(defvar query-replace-highlight nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839 ; "*Non-nil means to highlight words during query replacement.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 ;(defvar replace-overlay nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 ;(defun replace-dehighlight ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 ; (and replace-overlay
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 ; (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 ; (delete-overlay replace-overlay)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847 ; (setq replace-overlay nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849 ;(defun replace-highlight (start end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 ; (and query-replace-highlight
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 ; (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 ; (or replace-overlay
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 ; (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 ; (setq replace-overlay (make-overlay start end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 ; (overlay-put replace-overlay 'face
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 ; (if (internal-find-face 'query-replace)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857 ; 'query-replace 'region))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 ; (move-overlay replace-overlay start end (current-buffer)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860 (defun match-string (num &optional string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 "Return string of text matched by last search.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 NUM specifies which parenthesized expression in the last regexp.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 Zero means the entire text matched by the whole regexp or whole string.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 STRING should be given if the last search was by `string-match' on STRING."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 (if (match-beginning num)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 (if string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 (substring string (match-beginning num) (match-end num))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 (buffer-substring (match-beginning num) (match-end num)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871 (defmacro save-match-data (&rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872 "Execute BODY forms, restoring the global value of the match data."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873 (let ((original (make-symbol "match-data")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 (list 'let (list (list original '(match-data)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
875 (list 'unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
876 (cons 'progn body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877 (list 'store-match-data original)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 ;;; replace.el ends here