;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
To customize possible responses, change the \"bindings\" in `query-replace-map'."
(interactive (let ((common
- (query-replace-read-args
+ (query-replace-read-args
(if (and transient-mark-mode mark-active)
"Query replace in region"
"Query replace")
Use \\[repeat-complex-command] after this command for details."
(interactive
(let ((common
- (query-replace-read-args
+ (query-replace-read-args
(if (and transient-mark-mode mark-active)
"Query replace regexp in region"
"Query replace regexp")
and TO-STRING is also null.)"
(interactive
(let ((common
- (query-replace-read-args
+ (query-replace-read-args
(if (and transient-mark-mode mark-active)
"Replace string in region"
"Replace string")
which will run faster and will not set the mark or print anything."
(interactive
(let ((common
- (query-replace-read-args
+ (query-replace-read-args
(if (and transient-mark-mode mark-active)
- "Replace regexp in region"
- "Replace regexp")
+ "Replace regexp in region"
+ "Replace regexp")
t)))
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (and transient-mark-mode mark-active)
Prompt for a regexp with PROMPT.
Value is a list, (REGEXP)."
(list (read-from-minibuffer prompt nil nil nil
- 'regexp-history nil t)))
+ 'regexp-history nil t)
+ nil nil t))
-(defun keep-lines (regexp &optional rstart rend)
+(defun keep-lines (regexp &optional rstart rend interactive)
"Delete all lines except those containing matches for REGEXP.
A match split across lines preserves all the lines it lies in.
-Applies to all lines after point.
+When called from Lisp (and usually interactively as well, see below)
+applies to all lines starting after point.
If REGEXP contains upper case characters (excluding those preceded by `\\'),
the matching is case-sensitive.
Second and third arg RSTART and REND specify the region to operate on.
+This command operates on (the accessible part of) all lines whose
+accessible part is entirely contained in the region determined by RSTART
+and REND. (A newline ending a line counts as part of that line.)
Interactively, in Transient Mark mode when the mark is active, operate
-on the contents of the region. Otherwise, operate from point to the
-end of the buffer."
+on all lines whose accessible part is entirely contained in the region.
+Otherwise, the command applies to all lines starting after point.
+When calling this function from Lisp, you can pretend that it was
+called interactively by passing a non-nil INTERACTIVE argument.
+
+This function starts looking for the next match from the end of
+the previous match. Hence, it ignores matches that overlap
+a previously found match."
(interactive
(progn
(if rstart
(progn
(goto-char (min rstart rend))
- (setq rend (copy-marker (max rstart rend))))
- (if (and transient-mark-mode mark-active)
+ (setq rend
+ (progn
+ (save-excursion
+ (goto-char (max rstart rend))
+ (unless (or (bolp) (eobp))
+ (forward-line 0))
+ (point-marker)))))
+ (if (and interactive transient-mark-mode mark-active)
(setq rstart (region-beginning)
- rend (copy-marker (region-end)))
+ rend (progn
+ (goto-char (region-end))
+ (unless (or (bolp) (eobp))
+ (forward-line 0))
+ (point-marker)))
(setq rstart (point)
rend (point-max-marker)))
(goto-char rstart))
(if (not (re-search-forward regexp rend 'move))
(delete-region start rend)
(let ((end (save-excursion (goto-char (match-beginning 0))
- (beginning-of-line)
+ (forward-line 0)
(point))))
;; Now end is first char preserved by the new match.
(if (< start end)
;; If the match was empty, avoid matching again at same place.
(and (< (point) rend)
(= (match-beginning 0) (match-end 0))
- (forward-char 1))))))
+ (forward-char 1)))))
+ (set-marker rend nil)
+ nil)
-(defun flush-lines (regexp &optional rstart rend)
- "Delete lines containing matches for REGEXP.
-If a match is split across lines, all the lines it lies in are deleted.
-Applies to lines after point.
+(defun flush-lines (regexp &optional rstart rend interactive)
+ "Delete lines containing matches for REGEXP.
+When called from Lisp (and usually when called interactively as
+well, see below), applies to the part of the buffer after point.
+The line point is in is deleted if and only if it contains a
+match for regexp starting after point.
If REGEXP contains upper case characters (excluding those preceded by `\\'),
the matching is case-sensitive.
Second and third arg RSTART and REND specify the region to operate on.
+Lines partially contained in this region are deleted if and only if
+they contain a match entirely contained in it.
Interactively, in Transient Mark mode when the mark is active, operate
on the contents of the region. Otherwise, operate from point to the
-end of the buffer."
+end of (the accessible portion of) the buffer. When calling this function
+from Lisp, you can pretend that it was called interactively by passing
+a non-nil INTERACTIVE argument.
+
+If a match is split across lines, all the lines it lies in are deleted.
+They are deleted _before_ looking for the next match. Hence, a match
+starting on the same line at which another match ended is ignored."
(interactive
(progn
(progn
(goto-char (min rstart rend))
(setq rend (copy-marker (max rstart rend))))
- (if (and transient-mark-mode mark-active)
+ (if (and interactive transient-mark-mode mark-active)
(setq rstart (region-beginning)
rend (copy-marker (region-end)))
(setq rstart (point)
(while (and (< (point) rend)
(re-search-forward regexp rend t))
(delete-region (save-excursion (goto-char (match-beginning 0))
- (beginning-of-line)
+ (forward-line 0)
(point))
- (progn (forward-line 1) (point)))))))
+ (progn (forward-line 1) (point))))))
+ (set-marker rend nil)
+ nil)
-(defun how-many (regexp &optional rstart rend)
- "Print number of matches for REGEXP following point.
+(defun how-many (regexp &optional rstart rend interactive)
+ "Print and return number of matches for REGEXP following point.
+When called from Lisp and INTERACTIVE is omitted or nil, just return
+the number, do not print it; if INTERACTIVE is t, the function behaves
+in all respects has if it had been called interactively.
If REGEXP contains upper case characters (excluding those preceded by `\\'),
the matching is case-sensitive.
Interactively, in Transient Mark mode when the mark is active, operate
on the contents of the region. Otherwise, operate from point to the
-end of the buffer."
+end of (the accessible portion of) the buffer.
+
+This function starts looking for the next match from the end of
+the previous match. Hence, it ignores matches that overlap
+a previously found match."
(interactive
(keep-lines-read-args "How many matches for (regexp): "))
(save-excursion
(if rstart
- (goto-char (min rstart rend))
- (if (and transient-mark-mode mark-active)
+ (progn
+ (goto-char (min rstart rend))
+ (setq rend (max rstart rend)))
+ (if (and interactive transient-mark-mode mark-active)
(setq rstart (region-beginning)
- rend (copy-marker (region-end)))
+ rend (region-end))
(setq rstart (point)
- rend (point-max-marker)))
+ rend (point-max)))
(goto-char rstart))
(let ((count 0)
opoint
(if (= opoint (point))
(forward-char 1)
(setq count (1+ count))))
- (message "%d occurrences" count))))
+ (when interactive (message "%d occurrence%s"
+ count
+ (if (= count 1) "" "s")))
+ count)))
\f
(defvar occur-mode-map
:group 'matching)
(defcustom occur-hook nil
- "Hook run when `occur' is called."
+ "Hook run by Occur when there are any matches."
:type 'hook
:group 'matching)
(make-local-variable 'occur-revert-arguments)
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
(setq next-error-function 'occur-next-error)
- (run-hooks 'occur-mode-hook))
+ (run-mode-hooks 'occur-mode-hook))
(defun occur-revert-function (ignore1 ignore2)
"Handle `revert-buffer' for Occur mode buffers."
'((((class color) (min-colors 88) (background light))
:background "Tan")
(((class color) (min-colors 88) (background dark))
- :background "RoyalBlue4")
+ :background "RoyalBlue3")
(((class color) (min-colors 8))
:background "blue" :foreground "white")
(((type tty) (class mono))
(when current-prefix-arg
(prefix-numeric-value current-prefix-arg))))
-(defun occur-rename-buffer (&optional unique-p)
+(defun occur-rename-buffer (&optional unique-p interactive-p)
"Rename the current *Occur* buffer to *Occur: original-buffer-name*.
-Here `original-buffer-name' is the buffer name were occur was originally run.
-When given the prefix argument, the renaming will not clobber the existing
-buffer(s) of that name, but use `generate-new-buffer-name' instead.
-You can add this to `occur-hook' if you always want a separate *Occur*
-buffer for each buffer where you invoke `occur'."
- (interactive "P")
+Here `original-buffer-name' is the buffer name were Occur was originally run.
+When given the prefix argument, or called non-interactively, the renaming
+will not clobber the existing buffer(s) of that name, but use
+`generate-new-buffer-name' instead. You can add this to `occur-hook'
+if you always want a separate *Occur* buffer for each buffer where you
+invoke `occur'."
+ (interactive "P\np")
(with-current-buffer
(if (eq major-mode 'occur-mode) (current-buffer) (get-buffer "*Occur*"))
(rename-buffer (concat "*Occur: "
(mapconcat #'buffer-name
(car (cddr occur-revert-arguments)) "/")
"*")
- unique-p)))
+ (or unique-p (not interactive-p)))))
(defun occur (regexp &optional nlines)
"Show all lines in the current buffer containing a match for REGEXP.
-
-If a match spreads across multiple lines, all those lines are shown.
+This function can not handle matches that span more than one line.
Each line is displayed with NLINES lines before and after, or -NLINES
before if NLINES is negative.
(if (= count 1) "" "es")
regexp))
(setq occur-revert-arguments (list regexp nlines bufs))
- (if (> count 0)
- (progn
- (display-buffer occur-buf)
- (setq next-error-last-buffer occur-buf))
- (kill-buffer occur-buf)))
- (run-hooks 'occur-hook))
- (setq buffer-read-only t)
- (set-buffer-modified-p nil))))
+ (if (= count 0)
+ (kill-buffer occur-buf)
+ (display-buffer occur-buf)
+ (setq next-error-last-buffer occur-buf)
+ (setq buffer-read-only t)
+ (set-buffer-modified-p nil)
+ (run-hooks 'occur-hook)))))))
(defun occur-engine-add-prefix (lines)
(mapcar
(and (eq new reuse)
(eq (null integers) (markerp (car reuse)))
new)))
- (match-data integers
- (prog1 reuse
- (while reuse
- (if (markerp (car reuse))
- (set-marker (car reuse) nil))
- (setq reuse (cdr reuse)))))))
+ (match-data integers reuse t)))
(defun replace-match-maybe-edit (newtext fixedcase literal noedit match-data)
"Make a replacement with `replace-match', editing `\\?'.
(while (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\\\?\\)"
newtext)
(setq newtext
- (read-input "Edit replacement string: "
- (prog1
- (cons
- (replace-match "" t t newtext 3)
- (1+ (match-beginning 3)))
- (setq match-data
- (replace-match-data
- nil match-data match-data))))
+ (read-string "Edit replacement string: "
+ (prog1
+ (cons
+ (replace-match "" t t newtext 3)
+ (1+ (match-beginning 3)))
+ (setq match-data
+ (replace-match-data
+ nil match-data match-data))))
noedit nil)))
(set-match-data match-data)
(replace-match newtext fixedcase literal)
nil real-match-data
real-match-data)
next-replacement
- (read-input "Edit replacement string: "
- next-replacement)
+ (read-string "Edit replacement string: "
+ next-replacement)
noedit nil)
(if replaced
(set-match-data real-match-data)
;; Change markers to numbers in the match data
;; since lots of markers slow down editing.
(push (list (point) replaced
-;;; If the replacement has already happened, all we need is the
-;;; current match start and end. We could get this with a trivial
-;;; match like
-;;; (save-excursion (goto-char (match-beginning 0))
-;;; (search-forward (match-string 0))
-;;; (match-data t))
-;;; if we really wanted to avoid manually constructing match data.
-;;; Adding current-buffer is necessary so that match-data calls can
-;;; return markers which are appropriate for editing.
+;;; If the replacement has already happened, all we need is the
+;;; current match start and end. We could get this with a trivial
+;;; match like
+;;; (save-excursion (goto-char (match-beginning 0))
+;;; (search-forward (match-string 0))
+;;; (match-data t))
+;;; if we really wanted to avoid manually constructing match data.
+;;; Adding current-buffer is necessary so that match-data calls can
+;;; return markers which are appropriate for editing.
(if replaced
(list
(match-beginning 0)