aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2010-03-23 18:09:45 +0200
committerJuri Linkov2010-03-23 18:09:45 +0200
commit774642e5492984eceb237d6fc4de129fd3996ed5 (patch)
treed0d6c434335db2b462e836bf2fe6f95073615a8a
parent53e87c57beb29757236032939c9333cb2e56d024 (diff)
downloademacs-774642e5492984eceb237d6fc4de129fd3996ed5.tar.gz
emacs-774642e5492984eceb237d6fc4de129fd3996ed5.zip
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'.
-rw-r--r--etc/TODO3
-rw-r--r--lisp/ChangeLog14
-rw-r--r--lisp/replace.el60
3 files changed, 52 insertions, 25 deletions
diff --git a/etc/TODO b/etc/TODO
index a20ffdaa0d3..6ce2947bd93 100644
--- a/etc/TODO
+++ b/etc/TODO
@@ -105,9 +105,6 @@ for users to customize.
105 105
106** erase-buffer should perhaps disregard read-only properties of text. 106** erase-buffer should perhaps disregard read-only properties of text.
107 107
108** Make occur correctly handle matches that span more than one line,
109 as well as overlapping matches.
110
111** Fix the kill/yank treatment of invisible text. At the moment, 108** Fix the kill/yank treatment of invisible text. At the moment,
112 invisible text is placed in the kill-ring, so that the contents of 109 invisible text is placed in the kill-ring, so that the contents of
113 the ring may not correspond to the text as displayed to the user. 110 the ring may not correspond to the text as displayed to the user.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b84b8436993..c417eb7246e 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,19 @@
12010-03-23 Juri Linkov <juri@jurta.org> 12010-03-23 Juri Linkov <juri@jurta.org>
2 2
3 Implement Occur multi-line matches.
4 http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg01044.html
5
6 * replace.el (occur): Doc fix.
7 (occur-engine): Set `begpt' to the beginning of the first line.
8 Set `endpt' to the end of the last match line. At first, count
9 line numbers between `origpt' and `begpt'. Split out code from
10 `out-line' variable to new let-bindings `match-prefix' and
11 `match-str'. In `out-line' add non-numeric prefix to all
12 non-first lines of multi-line matches. Finally, count lines
13 between `begpt' and `endpt' and add to `lines'.
14
152010-03-23 Juri Linkov <juri@jurta.org>
16
3 * replace.el (occur-accumulate-lines, occur-engine): 17 * replace.el (occur-accumulate-lines, occur-engine):
4 Use `occur-engine-line' instead of duplicate code. 18 Use `occur-engine-line' instead of duplicate code.
5 (occur-engine-line): New function created from duplicate code 19 (occur-engine-line): New function created from duplicate code
diff --git a/lisp/replace.el b/lisp/replace.el
index f2d49b4de1c..4a8b39dbca7 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1045,7 +1045,7 @@ invoke `occur'."
1045 1045
1046(defun occur (regexp &optional nlines) 1046(defun occur (regexp &optional nlines)
1047 "Show all lines in the current buffer containing a match for REGEXP. 1047 "Show all lines in the current buffer containing a match for REGEXP.
1048This function can not handle matches that span more than one line. 1048If a match spreads across multiple lines, all those lines are shown.
1049 1049
1050Each line is displayed with NLINES lines before and after, or -NLINES 1050Each line is displayed with NLINES lines before and after, or -NLINES
1051before if NLINES is negative. 1051before if NLINES is negative.
@@ -1210,11 +1210,14 @@ See also `multi-occur'."
1210 (when (setq endpt (re-search-forward regexp nil t)) 1210 (when (setq endpt (re-search-forward regexp nil t))
1211 (setq matches (1+ matches)) ;; increment match count 1211 (setq matches (1+ matches)) ;; increment match count
1212 (setq matchbeg (match-beginning 0)) 1212 (setq matchbeg (match-beginning 0))
1213 (setq lines (+ lines (1- (count-lines origpt endpt)))) 1213 ;; Get beginning of first match line and end of the last.
1214 (save-excursion 1214 (save-excursion
1215 (goto-char matchbeg) 1215 (goto-char matchbeg)
1216 (setq begpt (line-beginning-position) 1216 (setq begpt (line-beginning-position))
1217 endpt (line-end-position))) 1217 (goto-char endpt)
1218 (setq endpt (line-end-position)))
1219 ;; Sum line numbers up to the first match line.
1220 (setq lines (+ lines (count-lines origpt begpt)))
1218 (setq marker (make-marker)) 1221 (setq marker (make-marker))
1219 (set-marker marker matchbeg) 1222 (set-marker marker matchbeg)
1220 (setq curstring (occur-engine-line begpt endpt keep-props)) 1223 (setq curstring (occur-engine-line begpt endpt keep-props))
@@ -1234,24 +1237,33 @@ See also `multi-occur'."
1234 curstring) 1237 curstring)
1235 (setq start (match-end 0)))) 1238 (setq start (match-end 0))))
1236 ;; Generate the string to insert for this match 1239 ;; Generate the string to insert for this match
1237 (let* ((out-line 1240 (let* ((match-prefix
1241 ;; Using 7 digits aligns tabs properly.
1242 (apply #'propertize (format "%7d:" lines)
1243 (append
1244 (when prefix-face
1245 `(font-lock-face prefix-face))
1246 `(occur-prefix t mouse-face (highlight)
1247 occur-target ,marker follow-link t
1248 help-echo "mouse-2: go to this occurrence"))))
1249 (match-str
1250 ;; We don't put `mouse-face' on the newline,
1251 ;; because that loses. And don't put it
1252 ;; on context lines to reduce flicker.
1253 (propertize curstring 'mouse-face (list 'highlight)
1254 'occur-target marker
1255 'follow-link t
1256 'help-echo
1257 "mouse-2: go to this occurrence"))
1258 (out-line
1238 (concat 1259 (concat
1239 ;; Using 7 digits aligns tabs properly. 1260 match-prefix
1240 (apply #'propertize (format "%7d:" lines) 1261 ;; Add non-numeric prefix to all non-first lines
1241 (append 1262 ;; of multi-line matches.
1242 (when prefix-face 1263 (replace-regexp-in-string
1243 `(font-lock-face prefix-face)) 1264 "\n"
1244 `(occur-prefix t mouse-face (highlight) 1265 "\n :"
1245 occur-target ,marker follow-link t 1266 match-str)
1246 help-echo "mouse-2: go to this occurrence")))
1247 ;; We don't put `mouse-face' on the newline,
1248 ;; because that loses. And don't put it
1249 ;; on context lines to reduce flicker.
1250 (propertize curstring 'mouse-face (list 'highlight)
1251 'occur-target marker
1252 'follow-link t
1253 'help-echo
1254 "mouse-2: go to this occurrence")
1255 ;; Add marker at eol, but no mouse props. 1267 ;; Add marker at eol, but no mouse props.
1256 (propertize "\n" 'occur-target marker))) 1268 (propertize "\n" 'occur-target marker)))
1257 (data 1269 (data
@@ -1270,7 +1282,11 @@ See also `multi-occur'."
1270 (goto-char endpt)) 1282 (goto-char endpt))
1271 (if endpt 1283 (if endpt
1272 (progn 1284 (progn
1273 (setq lines (1+ lines)) 1285 ;; Sum line numbers between first and last match lines.
1286 (setq lines (+ lines (count-lines begpt endpt)
1287 ;; Add 1 for empty last match line since
1288 ;; count-lines returns 1 line less.
1289 (if (and (bolp) (eolp)) 1 0)))
1274 ;; On to the next match... 1290 ;; On to the next match...
1275 (forward-line 1)) 1291 (forward-line 1))
1276 (goto-char (point-max)))))) 1292 (goto-char (point-max))))))