Mercurial > emacs
changeset 107476:dc9e20df2b90
Implement Occur multi-line matches.
http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg01044.html
* replace.el (occur): Doc fix.
(occur-engine): Set `begpt' to the beginning of the first line.
Set `endpt' to the end of the last match line. At first, count
line numbers between `origpt' and `begpt'. Split out code from
`out-line' variable to new let-bindings `match-prefix' and
`match-str'. In `out-line' add non-numeric prefix to all
non-first lines of multi-line matches. Finally, count lines
between `begpt' and `endpt' and add to `lines'.
author | Juri Linkov <juri@jurta.org> |
---|---|
date | Tue, 23 Mar 2010 18:09:45 +0200 |
parents | 7913a8c227bd |
children | 1039cde2a81b |
files | etc/TODO lisp/ChangeLog lisp/replace.el |
diffstat | 3 files changed, 52 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/TODO Tue Mar 23 17:48:09 2010 +0200 +++ b/etc/TODO Tue Mar 23 18:09:45 2010 +0200 @@ -105,9 +105,6 @@ ** erase-buffer should perhaps disregard read-only properties of text. -** Make occur correctly handle matches that span more than one line, - as well as overlapping matches. - ** Fix the kill/yank treatment of invisible text. At the moment, invisible text is placed in the kill-ring, so that the contents of the ring may not correspond to the text as displayed to the user.
--- a/lisp/ChangeLog Tue Mar 23 17:48:09 2010 +0200 +++ b/lisp/ChangeLog Tue Mar 23 18:09:45 2010 +0200 @@ -1,3 +1,17 @@ +2010-03-23 Juri Linkov <juri@jurta.org> + + Implement Occur multi-line matches. + http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg01044.html + + * replace.el (occur): Doc fix. + (occur-engine): Set `begpt' to the beginning of the first line. + Set `endpt' to the end of the last match line. At first, count + line numbers between `origpt' and `begpt'. Split out code from + `out-line' variable to new let-bindings `match-prefix' and + `match-str'. In `out-line' add non-numeric prefix to all + non-first lines of multi-line matches. Finally, count lines + between `begpt' and `endpt' and add to `lines'. + 2010-03-23 Juri Linkov <juri@jurta.org> * replace.el (occur-accumulate-lines, occur-engine):
--- a/lisp/replace.el Tue Mar 23 17:48:09 2010 +0200 +++ b/lisp/replace.el Tue Mar 23 18:09:45 2010 +0200 @@ -1045,7 +1045,7 @@ (defun occur (regexp &optional nlines) "Show all lines in the current buffer containing a match for REGEXP. -This function can not handle matches that span more than one line. +If a match spreads across multiple lines, all those lines are shown. Each line is displayed with NLINES lines before and after, or -NLINES before if NLINES is negative. @@ -1210,11 +1210,14 @@ (when (setq endpt (re-search-forward regexp nil t)) (setq matches (1+ matches)) ;; increment match count (setq matchbeg (match-beginning 0)) - (setq lines (+ lines (1- (count-lines origpt endpt)))) + ;; Get beginning of first match line and end of the last. (save-excursion (goto-char matchbeg) - (setq begpt (line-beginning-position) - endpt (line-end-position))) + (setq begpt (line-beginning-position)) + (goto-char endpt) + (setq endpt (line-end-position))) + ;; Sum line numbers up to the first match line. + (setq lines (+ lines (count-lines origpt begpt))) (setq marker (make-marker)) (set-marker marker matchbeg) (setq curstring (occur-engine-line begpt endpt keep-props)) @@ -1234,24 +1237,33 @@ curstring) (setq start (match-end 0)))) ;; Generate the string to insert for this match - (let* ((out-line + (let* ((match-prefix + ;; Using 7 digits aligns tabs properly. + (apply #'propertize (format "%7d:" lines) + (append + (when prefix-face + `(font-lock-face prefix-face)) + `(occur-prefix t mouse-face (highlight) + occur-target ,marker follow-link t + help-echo "mouse-2: go to this occurrence")))) + (match-str + ;; We don't put `mouse-face' on the newline, + ;; because that loses. And don't put it + ;; on context lines to reduce flicker. + (propertize curstring 'mouse-face (list 'highlight) + 'occur-target marker + 'follow-link t + 'help-echo + "mouse-2: go to this occurrence")) + (out-line (concat - ;; Using 7 digits aligns tabs properly. - (apply #'propertize (format "%7d:" lines) - (append - (when prefix-face - `(font-lock-face prefix-face)) - `(occur-prefix t mouse-face (highlight) - occur-target ,marker follow-link t - help-echo "mouse-2: go to this occurrence"))) - ;; We don't put `mouse-face' on the newline, - ;; because that loses. And don't put it - ;; on context lines to reduce flicker. - (propertize curstring 'mouse-face (list 'highlight) - 'occur-target marker - 'follow-link t - 'help-echo - "mouse-2: go to this occurrence") + match-prefix + ;; Add non-numeric prefix to all non-first lines + ;; of multi-line matches. + (replace-regexp-in-string + "\n" + "\n :" + match-str) ;; Add marker at eol, but no mouse props. (propertize "\n" 'occur-target marker))) (data @@ -1270,7 +1282,11 @@ (goto-char endpt)) (if endpt (progn - (setq lines (1+ lines)) + ;; Sum line numbers between first and last match lines. + (setq lines (+ lines (count-lines begpt endpt) + ;; Add 1 for empty last match line since + ;; count-lines returns 1 line less. + (if (and (bolp) (eolp)) 1 0))) ;; On to the next match... (forward-line 1)) (goto-char (point-max))))))