aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/replace.el
diff options
context:
space:
mode:
authorRichard M. Stallman1997-07-23 02:52:57 +0000
committerRichard M. Stallman1997-07-23 02:52:57 +0000
commit8d15583ff560b23e7482e588351300d9fdcc5720 (patch)
tree780518bc4321579218530808dc99b4c86bbce917 /lisp/replace.el
parentc8225cbef31d718d9a65b420faaf0bc387573acb (diff)
downloademacs-8d15583ff560b23e7482e588351300d9fdcc5720.tar.gz
emacs-8d15583ff560b23e7482e588351300d9fdcc5720.zip
(occur): Use text property `occur' to store the
marker for the occurrence in the source buffer. This replaces the list `occur-pos-list', and fixes the bug for multi-line matches. Set up `occur-point' text property for occur-next and occur-prev. (occur): occur-num-matches stores the number of matches found. (occur-mode-find-occurrence): Use `occur' text property to find marker for locus of the occurrence. (occur-next, occur-prev): New commands. (occur): Fixed bug preventing line number being displayed if line number is less than the number of lines of context.
Diffstat (limited to 'lisp/replace.el')
-rw-r--r--lisp/replace.el132
1 files changed, 81 insertions, 51 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index f0dc0fc1cea..a13916bf280 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -246,11 +246,12 @@ Applies to lines after point."
246 (define-key occur-mode-map [mouse-2] 'occur-mode-mouse-goto) 246 (define-key occur-mode-map [mouse-2] 'occur-mode-mouse-goto)
247 (define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence) 247 (define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence)
248 (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence) 248 (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence)
249 (define-key occur-mode-map "\M-n" 'occur-next)
250 (define-key occur-mode-map "\M-p" 'occur-prev)
249 (define-key occur-mode-map "g" 'revert-buffer)) 251 (define-key occur-mode-map "g" 'revert-buffer))
250 252
251(defvar occur-buffer nil) 253(defvar occur-buffer nil)
252(defvar occur-nlines nil) 254(defvar occur-nlines nil)
253(defvar occur-pos-list nil)
254(defvar occur-command-arguments nil 255(defvar occur-command-arguments nil
255 "Arguments that were given to `occur' when it made this buffer.") 256 "Arguments that were given to `occur' when it made this buffer.")
256 257
@@ -271,7 +272,6 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
271 (setq revert-buffer-function 'occur-revert-function) 272 (setq revert-buffer-function 'occur-revert-function)
272 (make-local-variable 'occur-buffer) 273 (make-local-variable 'occur-buffer)
273 (make-local-variable 'occur-nlines) 274 (make-local-variable 'occur-nlines)
274 (make-local-variable 'occur-pos-list)
275 (make-local-variable 'occur-command-arguments) 275 (make-local-variable 'occur-command-arguments)
276 (run-hooks 'occur-mode-hook)) 276 (run-hooks 'occur-mode-hook))
277 277
@@ -299,28 +299,12 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
299 (if (or (null occur-buffer) 299 (if (or (null occur-buffer)
300 (null (buffer-name occur-buffer))) 300 (null (buffer-name occur-buffer)))
301 (progn 301 (progn
302 (setq occur-buffer nil 302 (setq occur-buffer nil)
303 occur-pos-list nil)
304 (error "Buffer in which occurrences were found is deleted"))) 303 (error "Buffer in which occurrences were found is deleted")))
305 (let* ((line-count 304 (let ((pos (get-text-property (point) 'occur)))
306 (count-lines (point-min) 305 (if (null pos)
307 (save-excursion 306 (error "No occurrence on this line")
308 (beginning-of-line) 307 pos)))
309 (point))))
310 (occur-number (save-excursion
311 (beginning-of-line)
312 (/ (1- line-count)
313 (cond ((< occur-nlines 0)
314 (- 2 occur-nlines))
315 ((> occur-nlines 0)
316 (+ 2 (* 2 occur-nlines)))
317 (t 1)))))
318 (pos (nth occur-number occur-pos-list)))
319 (if (< line-count 1)
320 (error "No occurrence on this line"))
321 (or pos
322 (error "No occurrence on this line"))
323 pos))
324 308
325(defun occur-mode-goto-occurrence () 309(defun occur-mode-goto-occurrence ()
326 "Go to the occurrence the current line describes." 310 "Go to the occurrence the current line describes."
@@ -328,6 +312,39 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
328 (let ((pos (occur-mode-find-occurrence))) 312 (let ((pos (occur-mode-find-occurrence)))
329 (pop-to-buffer occur-buffer) 313 (pop-to-buffer occur-buffer)
330 (goto-char (marker-position pos)))) 314 (goto-char (marker-position pos))))
315
316(defun occur-next (&optional n)
317 "Move to the Nth (default 1) next match in the *Occur* buffer."
318 (interactive "p")
319 (if (not n) (setq n 1))
320 (let ((r))
321 (while (> n 0)
322 (if (get-text-property (point) 'occur-point)
323 (forward-char 1))
324 (setq r (next-single-property-change (point) 'occur-point))
325 (if r
326 (goto-char r)
327 (error "no more matches"))
328 (setq n (1- n)))))
329
330
331
332(defun occur-prev (&optional n)
333 "Move to the Nth (default 1) previous match in the *Occur* buffer."
334 (interactive "p")
335 (if (not n) (setq n 1))
336 (let ((r))
337 (while (> n 0)
338
339 (setq r (get-text-property (point) 'occur-point))
340 (if r (forward-char -1))
341
342 (setq r (previous-single-property-change (point) 'occur-point))
343 (if r
344 (goto-char (- r 1))
345 (error "no earlier matches"))
346
347 (setq n (1- n)))))
331 348
332(defcustom list-matching-lines-default-context-lines 0 349(defcustom list-matching-lines-default-context-lines 0
333 "*Default number of context lines to include around a `list-matching-lines' 350 "*Default number of context lines to include around a `list-matching-lines'
@@ -376,6 +393,7 @@ the matching is case-sensitive."
376 (prefix-numeric-value nlines) 393 (prefix-numeric-value nlines)
377 list-matching-lines-default-context-lines)) 394 list-matching-lines-default-context-lines))
378 (first t) 395 (first t)
396 (occur-num-matches 0)
379 (buffer (current-buffer)) 397 (buffer (current-buffer))
380 (dir default-directory) 398 (dir default-directory)
381 (linenum 1) 399 (linenum 1)
@@ -406,7 +424,6 @@ the matching is case-sensitive."
406 (occur-mode) 424 (occur-mode)
407 (setq occur-buffer buffer) 425 (setq occur-buffer buffer)
408 (setq occur-nlines nlines) 426 (setq occur-nlines nlines)
409 (setq occur-pos-list ())
410 (setq occur-command-arguments 427 (setq occur-command-arguments
411 (list regexp nlines))) 428 (list regexp nlines)))
412 (if (eq buffer standard-output) 429 (if (eq buffer standard-output)
@@ -431,30 +448,45 @@ the matching is case-sensitive."
431 (forward-line (1+ nlines)) 448 (forward-line (1+ nlines))
432 (forward-line 1)) 449 (forward-line 1))
433 (point))) 450 (point)))
434 ;; Record where the actual match 451 (match-beg (- (match-beginning 0) start))
435 (match-offset
436 (save-excursion
437 (goto-char (match-beginning 0))
438 (beginning-of-line)
439 ;; +6 to skip over line number
440 (+ 6 (- (match-beginning 0) (point)))))
441 (match-len (- (match-end 0) (match-beginning 0))) 452 (match-len (- (match-end 0) (match-beginning 0)))
442 (tag (format "%5d" linenum)) 453 (tag (format "%5d" linenum))
443 (empty (make-string (length tag) ?\ )) 454 (empty (make-string (length tag) ?\ ))
444 tem) 455 tem
456 occur-marker
457 (text-beg (make-marker))
458 (text-end (make-marker))
459 )
445 (save-excursion 460 (save-excursion
446 (setq tem (make-marker)) 461 (setq occur-marker (make-marker))
447 (set-marker tem (point)) 462 (set-marker occur-marker (point))
448 (set-buffer standard-output) 463 (set-buffer standard-output)
449 (setq occur-pos-list (cons tem occur-pos-list)) 464 (setq occur-num-matches (1+ occur-num-matches))
450 (or first (zerop nlines) 465 (or first (zerop nlines)
451 (insert "--------\n")) 466 (insert "--------\n"))
452 (setq first nil) 467 (setq first nil)
468 (set-marker text-beg (point))
453 (insert-buffer-substring buffer start end) 469 (insert-buffer-substring buffer start end)
470 (set-marker text-end (point))
471 (if list-matching-lines-face
472 (put-text-property
473 (+ (marker-position text-beg) match-beg)
474 (+ (marker-position text-beg) match-beg match-len)
475 'face list-matching-lines-face))
476
477 ;; Identify a place for occur-next and occur-prev
478 ;; to move to.
479 (put-text-property
480 (+ (marker-position text-beg) match-beg match-len)
481 (+ (marker-position text-beg) match-beg match-len 1)
482 'occur-point t)
454 (set-marker final-context-start 483 (set-marker final-context-start
455 (- (point) (- end (match-end 0)))) 484 (- (point) (- end (match-end 0))))
456 (goto-char (- (point) (- end start))) 485 (goto-char (- (point) (- end start)))
457 (setq tem nlines) 486 ;;(setq tem nlines)
487 (setq tem (if (< linenum nlines)
488 (- nlines linenum)
489 nlines))
458 (while (> tem 0) 490 (while (> tem 0)
459 (insert empty ?:) 491 (insert empty ?:)
460 (forward-line 1) 492 (forward-line 1)
@@ -469,16 +501,6 @@ the matching is case-sensitive."
469 (save-excursion 501 (save-excursion
470 (beginning-of-line) 502 (beginning-of-line)
471 (point))) 503 (point)))
472 (put-text-property line-start
473 (save-excursion
474 (end-of-line)
475 (point))
476 'mouse-face 'highlight)
477 (if list-matching-lines-face
478 (put-text-property
479 (+ line-start match-offset)
480 (+ line-start match-offset match-len)
481 'face list-matching-lines-face))
482 (forward-line 1) 504 (forward-line 1)
483 (setq tag nil) 505 (setq tag nil)
484 (setq this-linenum (1+ this-linenum))) 506 (setq this-linenum (1+ this-linenum)))
@@ -486,20 +508,28 @@ the matching is case-sensitive."
486 (insert empty ?:) 508 (insert empty ?:)
487 (forward-line 1) 509 (forward-line 1)
488 (setq this-linenum (1+ this-linenum)))) 510 (setq this-linenum (1+ this-linenum))))
489 (while (< tem nlines) 511 (while (and (< (point) (point-max)) (< tem nlines))
490 (insert empty ?:) 512 (insert empty ?:)
491 (forward-line 1) 513 (forward-line 1)
492 (setq tem (1+ tem))) 514 (setq tem (1+ tem)))
515
516 ;; Add text properties. The `occur' prop is used to
517 ;; store the marker of the matching text in the
518 ;; source buffer.
519 (put-text-property (marker-position text-beg)
520 (- (marker-position text-end) 1)
521 'mouse-face 'highlight)
522 (put-text-property (marker-position text-beg)
523 (- (marker-position text-end) 1)
524 'occur occur-marker)
493 (goto-char (point-max))) 525 (goto-char (point-max)))
494 (forward-line 1))) 526 (forward-line 1)))
495 (set-buffer standard-output) 527 (set-buffer standard-output)
496 ;; Put positions in increasing order to go with buffer.
497 (setq occur-pos-list (nreverse occur-pos-list))
498 (goto-char (point-min)) 528 (goto-char (point-min))
499 (let ((message-string 529 (let ((message-string
500 (if (= (length occur-pos-list) 1) 530 (if (= occur-num-matches 1)
501 "1 line" 531 "1 line"
502 (format "%d lines" (length occur-pos-list))))) 532 (format "%d lines" occur-num-matches))))
503 (insert message-string) 533 (insert message-string)
504 (if (interactive-p) 534 (if (interactive-p)
505 (message "%s matched" message-string))))))))) 535 (message "%s matched" message-string)))))))))