Mercurial > hg > xemacs-beta
comparison lisp/replace.el @ 1069:13daf40fb997
[xemacs-hg @ 2002-10-24 14:59:22 by youngs]
2002-10-25 Scott Evans <gse@antisleep.com>
* replace.el (operate-on-non-matching-lines)
(operate-on-non-matching-lines): Generalized from
delete-non-matching-lines and delete-matching-lines. The
"operate" versions work with regions, can copy to the kill ring,
and return the number of lines copied/deleted.
(delete-non-matching-lines): Use operate-on-non-matching-lines.
(delete-matching-lines): Use operate-on-matching-lines.
(kill-non-matching-lines): New.
(copy-non-matching-lines): New.
(kill-matching-lines): New.
(copy-matching-lines): New.
author | youngs |
---|---|
date | Thu, 24 Oct 2002 14:59:27 +0000 |
parents | e7ef97881643 |
children | 1b0339b048ce |
comparison
equal
deleted
inserted
replaced
1068:9d75b4fe084c | 1069:13daf40fb997 |
---|---|
210 which will run faster and will not set the mark or print anything." | 210 which will run faster and will not set the mark or print anything." |
211 (interactive (query-replace-read-args "Replace regexp" t)) | 211 (interactive (query-replace-read-args "Replace regexp" t)) |
212 (perform-replace regexp to-string nil t delimited)) | 212 (perform-replace regexp to-string nil t delimited)) |
213 | 213 |
214 | 214 |
215 | |
216 ;; gse wonders: Is there a better place for this to go? Might other packages | |
217 ;; want to use it? | |
215 (defvar regexp-history nil | 218 (defvar regexp-history nil |
216 "History list for some commands that read regular expressions.") | 219 "History list for some commands that read regular expressions.") |
217 | 220 |
221 (defun operate-on-non-matching-lines (regexp delete kill &optional beg end) | |
222 "Internal function used by delete-non-matching-lines, | |
223 kill-non-matching-lines, and copy-matching-lines. | |
224 | |
225 REGEXP is a regular expression to *not* match when performing | |
226 operations. | |
227 | |
228 If DELETE is non-nil, the lines of text are deleted. It doesn't make | |
229 sense to set this to nil if KILL is nil -- nothing will happen. | |
230 | |
231 If KILL is non-nil, the lines of text are stored in the kill ring (as | |
232 one block of text). | |
233 | |
234 BEG and END, if non-nil, specify the start and end locations to work | |
235 within. If these are nil, point and point-max are used. | |
236 | |
237 A match split across lines preserves all the lines it lies in. | |
238 Applies to all lines after point. | |
239 | |
240 Returns the number of lines matched." | |
241 (with-search-caps-disable-folding regexp t | |
242 (save-excursion | |
243 ;; Move to a beginning point if specified. | |
244 (when beg (goto-char beg)) | |
245 ;; Always start on the beginning of a line. | |
246 (or (bolp) (forward-line 1)) | |
247 | |
248 (let ((matched-text nil) | |
249 (curmatch-start (point)) | |
250 (limit (copy-marker (point-max)))) | |
251 ;; Limit search if limits were specified. | |
252 (when end (setq limit (copy-marker end))) | |
253 | |
254 ;; Search. Stop if we are at end of buffer or outside the | |
255 ;; limit. | |
256 (while (not (or | |
257 (eobp) | |
258 (and limit (>= (point) limit)))) | |
259 ;; curmatch-start is first char not preserved by previous match. | |
260 (if (not (re-search-forward regexp limit 'move)) | |
261 (let ((curmatch-end limit)) | |
262 (setq matched-text (concat matched-text (buffer-substring curmatch-start curmatch-end))) | |
263 (if delete (delete-region curmatch-start curmatch-end))) | |
264 (let ((curmatch-end (save-excursion (goto-char (match-beginning 0)) | |
265 (beginning-of-line) | |
266 (point)))) | |
267 ;; Now curmatch-end is first char preserved by the new match. | |
268 (if (< curmatch-start curmatch-end) | |
269 (progn | |
270 (setq matched-text (concat matched-text (buffer-substring curmatch-start curmatch-end))) | |
271 (if delete (delete-region curmatch-start curmatch-end)))))) | |
272 (setq curmatch-start (save-excursion (forward-line 1) | |
273 (point))) | |
274 ;; If the match was empty, avoid matching again at same place. | |
275 (and (not (eobp)) (= (match-beginning 0) (match-end 0)) | |
276 (forward-char 1))) | |
277 | |
278 ;; If any lines were matched and KILL is non-nil, insert the | |
279 ;; matched lines into the kill ring. | |
280 (if (and matched-text kill) (kill-new matched-text)) | |
281 | |
282 ;; Return the number of matched lines. | |
283 (with-temp-buffer | |
284 ;; Use concat to make a string even if matched-text is nil. | |
285 (insert (concat matched-text)) | |
286 (count-lines (point-min) (point-max))) | |
287 )))) | |
288 | |
218 (define-function 'keep-lines 'delete-non-matching-lines) | 289 (define-function 'keep-lines 'delete-non-matching-lines) |
219 (defun delete-non-matching-lines (regexp) | 290 (defun delete-non-matching-lines (regexp) |
220 "Delete all lines except those containing matches for REGEXP. | 291 "Delete lines that do not match REGEXP, from point to the end of the |
221 A match split across lines preserves all the lines it lies in. | 292 buffer (or within the region, if it is active)." |
222 Applies to all lines after point." | |
223 (interactive (list (read-from-minibuffer | 293 (interactive (list (read-from-minibuffer |
224 "Keep lines (containing match for regexp): " | 294 "Keep lines (containing match for regexp): " |
225 nil nil nil 'regexp-history))) | 295 nil nil nil 'regexp-history))) |
226 (with-interactive-search-caps-disable-folding regexp t | 296 (let ((beg nil) |
297 (end nil) | |
298 (count nil)) | |
299 (when (region-active-p) | |
300 (setq beg (region-beginning)) | |
301 (setq end (region-end))) | |
302 (setq count (operate-on-non-matching-lines regexp t nil beg end)) | |
303 (message "%i lines deleted" count))) | |
304 | |
305 (defun kill-non-matching-lines (regexp) | |
306 "Delete the lines that do not match REGEXP, from point to the end of | |
307 the buffer (or within the region, if it is active). The deleted lines | |
308 are placed in the kill ring as one block of text." | |
309 (interactive (list (read-from-minibuffer | |
310 "Kill non-matching lines (regexp): " | |
311 nil nil nil 'regexp-history))) | |
312 (let ((beg nil) | |
313 (end nil) | |
314 (count nil)) | |
315 (when (region-active-p) | |
316 (setq beg (region-beginning)) | |
317 (setq end (region-end))) | |
318 (setq count (operate-on-non-matching-lines regexp t t beg end)) | |
319 (message "%i lines killed" count))) | |
320 | |
321 (defun copy-non-matching-lines (regexp) | |
322 "Find all lines that do not match REGEXP from point to the end of the | |
323 buffer (or within the region, if it is active), and place them in the | |
324 kill ring as one block of text." | |
325 (interactive (list (read-from-minibuffer | |
326 "Copy non-matching lines (regexp): " | |
327 nil nil nil 'regexp-history))) | |
328 (let ((beg nil) | |
329 (end nil) | |
330 (count nil)) | |
331 (when (region-active-p) | |
332 (setq beg (region-beginning)) | |
333 (setq end (region-end))) | |
334 (setq count (operate-on-non-matching-lines regexp nil t beg end)) | |
335 (message "%i lines copied" count))) | |
336 | |
337 (defun operate-on-matching-lines (regexp delete kill &optional beg end) | |
338 "Internal function used by delete-matching-lines, kill-matching-lines, | |
339 and copy-matching-lines. | |
340 | |
341 If DELETE is non-nil, the lines of text are deleted. It doesn't make | |
342 sense to set this to nil if KILL is nil -- nothing will happen. | |
343 | |
344 If KILL is non-nil, the lines of text are stored in the kill ring (as | |
345 one block of text). | |
346 | |
347 BEG and END, if non-nil, specify the start and end locations to work | |
348 within. If these are nil, point and point-max are used. | |
349 | |
350 If a match is split across lines, all the lines it lies in are deleted. | |
351 Applies to lines after point. | |
352 Returns the number of lines matched." | |
353 (with-search-caps-disable-folding regexp t | |
227 (save-excursion | 354 (save-excursion |
228 (or (bolp) (forward-line 1)) | 355 (let ((matched-text nil) |
229 (let ((start (point))) | 356 (curmatch-start nil) |
230 (while (not (eobp)) | 357 (curmatch-end nil) |
231 ;; Start is first char not preserved by previous match. | 358 (limit nil)) |
232 (if (not (re-search-forward regexp nil 'move)) | 359 |
233 (delete-region start (point-max)) | 360 ;; Limit search if limits were specified. |
234 (let ((end (save-excursion (goto-char (match-beginning 0)) | 361 (when beg (goto-char beg)) |
235 (beginning-of-line) | 362 (when end (setq limit (copy-marker end))) |
236 (point)))) | 363 |
237 ;; Now end is first char preserved by the new match. | 364 (while (and (not (eobp)) |
238 (if (< start end) | 365 (re-search-forward regexp limit t)) |
239 (delete-region start end)))) | 366 (setq curmatch-start (save-excursion (goto-char (match-beginning 0)) |
240 (setq start (save-excursion (forward-line 1) | 367 (beginning-of-line) |
241 (point))) | 368 (point))) |
242 ;; If the match was empty, avoid matching again at same place. | 369 (setq curmatch-end (progn (forward-line 1) (point))) |
243 (and (not (eobp)) (= (match-beginning 0) (match-end 0)) | 370 (setq matched-text (concat matched-text (buffer-substring curmatch-start curmatch-end))) |
244 (forward-char 1))))))) | 371 (if delete (delete-region curmatch-start curmatch-end))) |
372 | |
373 (if (and matched-text kill) (kill-new matched-text)) | |
374 | |
375 ;; Return the number of matched lines. | |
376 (with-temp-buffer | |
377 ;; Use concat to make a string even if matched-text is nil. | |
378 (insert (concat matched-text)) | |
379 (count-lines (point-min) (point-max))) | |
380 )))) | |
245 | 381 |
246 (define-function 'flush-lines 'delete-matching-lines) | 382 (define-function 'flush-lines 'delete-matching-lines) |
247 (defun delete-matching-lines (regexp) | 383 (defun delete-matching-lines (regexp) |
248 "Delete lines containing matches for REGEXP. | 384 "Delete the lines that match REGEXP, from point to the end of the |
249 If a match is split across lines, all the lines it lies in are deleted. | 385 buffer (or within the region, if it is active)." |
250 Applies to lines after point." | |
251 (interactive (list (read-from-minibuffer | 386 (interactive (list (read-from-minibuffer |
252 "Flush lines (containing match for regexp): " | 387 "Flush lines (containing match for regexp): " |
253 nil nil nil 'regexp-history))) | 388 nil nil nil 'regexp-history))) |
254 (with-interactive-search-caps-disable-folding regexp t | 389 (let ((beg nil) |
255 (save-excursion | 390 (end nil) |
256 (while (and (not (eobp)) | 391 (count nil)) |
257 (re-search-forward regexp nil t)) | 392 (when (region-active-p) |
258 (delete-region (save-excursion (goto-char (match-beginning 0)) | 393 (setq beg (region-beginning)) |
259 (beginning-of-line) | 394 (setq end (region-end))) |
260 (point)) | 395 (setq count (operate-on-matching-lines regexp t nil beg end)) |
261 (progn (forward-line 1) (point))))))) | 396 (message "%i lines deleted" count))) |
397 | |
398 (defun kill-matching-lines (regexp) | |
399 "Delete the lines that match REGEXP, from point to the end of the | |
400 buffer (or within the region, if it is active). The deleted lines are | |
401 placed in the kill ring as one block of text." | |
402 (interactive (list (read-from-minibuffer | |
403 "Kill lines (containing match for regexp): " | |
404 nil nil nil 'regexp-history))) | |
405 (let ((beg nil) | |
406 (end nil) | |
407 (count nil)) | |
408 (when (region-active-p) | |
409 (setq beg (region-beginning)) | |
410 (setq end (region-end))) | |
411 (setq count (operate-on-matching-lines regexp t t beg end)) | |
412 (message "%i lines killed" count))) | |
413 | |
414 (defun copy-matching-lines (regexp) | |
415 "Find all lines that match REGEXP from point to the end of the | |
416 buffer (or within the region, if it is active), and place them in the | |
417 kill ring as one block of text." | |
418 (interactive (list (read-from-minibuffer | |
419 "Copy lines (containing match for regexp): " | |
420 nil nil nil 'regexp-history))) | |
421 (let ((beg nil) | |
422 (end nil) | |
423 (count nil)) | |
424 (when (region-active-p) | |
425 (setq beg (region-beginning)) | |
426 (setq end (region-end))) | |
427 (setq count (operate-on-matching-lines regexp nil t beg end)) | |
428 (message "%i lines copied" count))) | |
262 | 429 |
263 (define-function 'how-many 'count-matches) | 430 (define-function 'how-many 'count-matches) |
264 (defun count-matches (regexp) | 431 (defun count-matches (regexp) |
265 "Print number of matches for REGEXP following point." | 432 "Print number of matches for REGEXP following point." |
266 (interactive (list (read-from-minibuffer | 433 (interactive (list (read-from-minibuffer |