* bug#14017: Highlight prefix line numbers in occur
@ 2013-03-21 22:38 Juri Linkov
2013-03-24 21:54 ` Juri Linkov
0 siblings, 1 reply; 3+ messages in thread
From: Juri Linkov @ 2013-03-21 22:38 UTC (permalink / raw)
To: 14017
Currently the `prefix-face' arg of `occur-engine' is unused.
Its caller `occur-1' just sends nil to `occur-engine'.
This is the reason why a bug in its usage in `occur-engine'
remained undiscovered for a long time. The bug is that this code:
(when prefix-face
`(font-lock-face prefix-face))
should be fixed to:
(when prefix-face
`(font-lock-face ,prefix-face))
To take it into use I propose to add a new face option
`list-matching-lines-prefix-face' to accompany the existing
`list-matching-lines-buffer-name-face' and `list-matching-lines-face'.
Its default value could be `shadow' - the same face as is used to
highlight line numbers in `linum-mode' (their output will look similar).
=== modified file 'lisp/replace.el'
--- lisp/replace.el 2013-03-10 08:44:07 +0000
+++ lisp/replace.el 2013-03-21 22:36:56 +0000
@@ -1125,6 +1125,14 @@ (defcustom list-matching-lines-buffer-name-face
:type 'face
:group 'matching)
+(defcustom list-matching-lines-prefix-face 'shadow
+ "Face used by \\[list-matching-lines] to show the prefix column.
+If the face doesn't differ from the default face,
+don't highlight the prefix with line numbers specially."
+ :type 'face
+ :group 'matching
+ :version "24.4")
+
(defcustom occur-excluded-properties
'(read-only invisible intangible field mouse-face help-echo local-map keymap
yank-handler follow-link)
@@ -1334,7 +1342,9 @@ (defun occur-1 (regexp nlines bufs &opti
(isearch-no-upper-case-p regexp t)
case-fold-search)
list-matching-lines-buffer-name-face
- nil list-matching-lines-face
+ (if (face-differs-from-default-p list-matching-lines-prefix-face)
+ list-matching-lines-prefix-face)
+ list-matching-lines-face
(not (eq occur-excluded-properties t))))))
(let* ((bufcount (length active-bufs))
(diff (- (length bufs) bufcount)))
@@ -1423,7 +1433,7 @@ (defun occur-engine (regexp buffers out-
(apply #'propertize (format "%7d:" lines)
(append
(when prefix-face
- `(font-lock-face prefix-face))
+ `(font-lock-face ,prefix-face))
`(occur-prefix t mouse-face (highlight)
;; Allow insertion of text at
;; the end of the prefix (for
@@ -1447,7 +1457,9 @@ (defun occur-engine (regexp buffers out-
;; of multi-line matches.
(replace-regexp-in-string
"\n"
- "\n :"
+ (if prefix-face
+ (propertize "\n :" 'font-lock-face prefix-face)
+ "\n :")
match-str)
;; Add marker at eol, but no mouse props.
(propertize "\n" 'occur-target marker)))
@@ -1458,7 +1470,8 @@ (defun occur-engine (regexp buffers out-
;; The complex multi-line display style.
(setq ret (occur-context-lines
out-line nlines keep-props begpt endpt
- lines prev-lines prev-after-lines))
+ lines prev-lines prev-after-lines
+ prefix-face))
;; Set first elem of the returned list to `data',
;; and the second elem to `prev-after-lines'.
(setq prev-after-lines (nth 1 ret))
@@ -1482,7 +1495,7 @@ (defun occur-engine (regexp buffers out-
(when prev-after-lines
(with-current-buffer out-buf
(insert (apply #'concat (occur-engine-add-prefix
- prev-after-lines)))))))
+ prev-after-lines prefix-face)))))))
(when (not (zerop matches)) ;; is the count zero?
(setq globalcount (+ globalcount matches))
(with-current-buffer out-buf
@@ -1537,10 +1550,13 @@ (defun occur-engine-line (beg end &optio
str)
(buffer-substring-no-properties beg end)))
-(defun occur-engine-add-prefix (lines)
+(defun occur-engine-add-prefix (lines &optional prefix-face)
(mapcar
#'(lambda (line)
- (concat " :" line "\n"))
+ (concat (if prefix-face
+ (propertize " :" 'font-lock-face prefix-face)
+ " :")
+ line "\n"))
lines))
(defun occur-accumulate-lines (count &optional keep-props pt)
@@ -1569,7 +1585,8 @@ (defun occur-accumulate-lines (count &op
;; Generate a list of lines, add prefixes to all but OUT-LINE,
;; then concatenate them all together.
(defun occur-context-lines (out-line nlines keep-props begpt endpt
- lines prev-lines prev-after-lines)
+ lines prev-lines prev-after-lines
+ &optional prefix-face)
;; Find after- and before-context lines of the current match.
(let ((before-lines
(nreverse (cdr (occur-accumulate-lines
@@ -1609,10 +1626,13 @@ (defun occur-context-lines (out-line nli
;; Return a list where the first element is the output line.
(apply #'concat
(append
- (and prev-after-lines
- (occur-engine-add-prefix prev-after-lines))
- (and separator (list separator))
- (occur-engine-add-prefix before-lines)
+ (if prev-after-lines
+ (occur-engine-add-prefix prev-after-lines prefix-face))
+ (if separator
+ (list (if prefix-face
+ (propertize separator 'font-lock-face prefix-face)
+ separator)))
+ (occur-engine-add-prefix before-lines prefix-face)
(list out-line)))
;; And the second element is the list of context after-lines.
(if (> nlines 0) after-lines))))
^ permalink raw reply [flat|nested] 3+ messages in thread
* bug#14017: Highlight prefix line numbers in occur
2013-03-21 22:38 bug#14017: Highlight prefix line numbers in occur Juri Linkov
@ 2013-03-24 21:54 ` Juri Linkov
2013-05-29 23:47 ` Juri Linkov
0 siblings, 1 reply; 3+ messages in thread
From: Juri Linkov @ 2013-03-24 21:54 UTC (permalink / raw)
To: 14017
> Currently the `prefix-face' arg of `occur-engine' is unused.
> Its caller `occur-1' just sends nil to `occur-engine'.
> This is the reason why a bug in its usage in `occur-engine'
> remained undiscovered for a long time.
>
> To take it into use I propose to add a new face option
> `list-matching-lines-prefix-face' to accompany the existing
> `list-matching-lines-buffer-name-face' and `list-matching-lines-face'.
This is installed now.
Another problem I found with the line numbers in `occur' is that
the number of matches it reports in the header line is wrong.
If there are more than one match on a line, the total number
of matches is more than the total number of matching lines
currently displayed in the header line. So I propose
to change the format of the occur header line from:
2 matches for "is" in buffer: *scratch*
to:
4 matches in 2 lines for "is" in buffer: *scratch*
I found that the exact number of matches (as opposed to
the number of matching lines) often is necessary to know beforehand
how many times it requires to type C-s to visit all matches
or how many times to type y/n to replace all matches in the buffer.
=== modified file 'lisp/replace.el'
--- lisp/replace.el 2013-02-25 20:57:44 +0000
+++ lisp/replace.el 2013-03-24 21:48:28 +0000
@@ -1347,16 +1347,18 @@ (defun occur-1 (regexp nlines bufs &opti
(defun occur-engine (regexp buffers out-buf nlines case-fold
title-face prefix-face match-face keep-props)
(with-current-buffer out-buf
- (let ((globalcount 0)
+ (let ((global-lines 0) ;; total count of matching lines
+ (global-matches 0) ;; total count of matches
(coding nil)
(case-fold-search case-fold))
;; Map over all the buffers
(dolist (buf buffers)
(when (buffer-live-p buf)
- (let ((matches 0) ;; count of matched lines
- (lines 1) ;; line count
- (prev-after-lines nil) ;; context lines of prev match
- (prev-lines nil) ;; line number of prev match endpt
+ (let ((lines 0) ;; count of matching lines
+ (matches 0) ;; count of matches
+ (curr-line 1) ;; line count
+ (prev-line nil) ;; line number of prev match endpt
+ (prev-after-lines nil) ;; context lines of prev match
(matchbeg 0)
(origpt nil)
(begpt nil)
@@ -1376,8 +1378,9 @@ (defun occur-engine (regexp buffers out-
(while (not (eobp))
(setq origpt (point))
(when (setq endpt (re-search-forward regexp nil t))
- (setq matches (1+ matches)) ;; increment match count
+ (setq lines (1+ lines)) ;; increment matching lines count
(setq matchbeg (match-beginning 0))
;; Get beginning of first match line and end of the last.
(save-excursion
@@ -1386,7 +1389,7 @@ (defun occur-engine (regexp buffers out-
(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 curr-line (+ curr-line (count-lines origpt begpt)))
(setq marker (make-marker))
(set-marker marker matchbeg)
(setq curstring (occur-engine-line begpt endpt keep-props))
@@ -1395,6 +1398,7 @@ (defun occur-engine (regexp buffers out-
(start 0))
(while (and (< start len)
(string-match regexp curstring start))
+ (setq matches (1+ matches))
(add-text-properties
(match-beginning 0) (match-end 0)
(append
@@ -1408,7 +1412,7 @@ (defun occur-engine (regexp buffers out-
;; Generate the string to insert for this match
(let* ((match-prefix
;; Using 7 digits aligns tabs properly.
- (apply #'propertize (format "%7d:" lines)
+ (apply #'propertize (format "%7d:" curr-line)
(append
(when prefix-face
`(font-lock-face prefix-face))
@@ -1446,7 +1450,7 @@ (defun occur-engine (regexp buffers out-
;; The complex multi-line display style.
(setq ret (occur-context-lines
out-line nlines keep-props begpt endpt
- lines prev-lines prev-after-lines))
+ curr-line prev-line prev-after-lines))
;; Set first elem of the returned list to `data',
;; and the second elem to `prev-after-lines'.
(setq prev-after-lines (nth 1 ret))
@@ -1458,28 +1462,30 @@ (defun occur-engine (regexp buffers out-
(if endpt
(progn
;; 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)))
+ (setq curr-line (+ curr-line (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)))
- (setq prev-lines (1- lines)))
+ (setq prev-line (1- curr-line)))
;; Flush remaining context after-lines.
(when prev-after-lines
(with-current-buffer out-buf
(insert (apply #'concat (occur-engine-add-prefix
prev-after-lines)))))))
- (when (not (zerop matches)) ;; is the count zero?
- (setq globalcount (+ globalcount matches))
+ (when (not (zerop lines)) ;; is the count zero?
+ (setq global-lines (+ global-lines lines)
+ global-matches (+ global-matches matches))
(with-current-buffer out-buf
(goto-char headerpt)
(let ((beg (point))
end)
(insert (propertize
- (format "%d match%s%s in buffer: %s\n"
+ (format "%d match%s in %d line%s%s in buffer: %s\n"
matches (if (= matches 1) "" "es")
+ lines (if (= lines 1) "" "s")
;; Don't display regexp for multi-buffer.
(if (> (length buffers) 1)
"" (format " for \"%s\""
@@ -1494,12 +1500,13 @@ (defun occur-engine (regexp buffers out-
`(occur-title ,buf))))
(goto-char (point-min)))))))
;; Display total match count and regexp for multi-buffer.
- (when (and (not (zerop globalcount)) (> (length buffers) 1))
+ (when (and (not (zerop global-lines)) (> (length buffers) 1))
(goto-char (point-min))
(let ((beg (point))
end)
- (insert (format "%d match%s total for \"%s\":\n"
- globalcount (if (= globalcount 1) "" "es")
+ (insert (format "%d match%s in %d line%s total for \"%s\":\n"
+ global-matches (if (= global-matches 1) "" "es")
+ global-lines (if (= global-lines 1) "" "s")
(query-replace-descr regexp)))
(setq end (point))
(add-text-properties beg end (when title-face
@@ -1510,8 +1517,8 @@ (defun occur-engine (regexp buffers out-
;; that locally binds it. Let's use it also for the output
;; buffer.
(set-buffer-file-coding-system coding))
- ;; Return the number of matches
- globalcount)))
+ ;; Return the number of matching lines
+ global-lines)))
(defun occur-engine-line (beg end &optional keep-props)
(if (and keep-props (if (boundp 'jit-lock-mode) jit-lock-mode)
@@ -1551,13 +1558,13 @@ (defun occur-accumulate-lines (count &op
;; Generate context display for occur.
;; OUT-LINE is the line where the match is.
;; NLINES and KEEP-PROPS are args to occur-engine.
-;; LINES is line count of the current match,
-;; PREV-LINES is line count of the previous match,
+;; CURR-LINE is line count of the current match,
+;; PREV-LINE is line count of the previous match,
;; PREV-AFTER-LINES is a list of after-context lines of the previous match.
;; Generate a list of lines, add prefixes to all but OUT-LINE,
;; then concatenate them all together.
(defun occur-context-lines (out-line nlines keep-props begpt endpt
- lines prev-lines prev-after-lines)
+ curr-line prev-line prev-after-lines)
;; Find after- and before-context lines of the current match.
(let ((before-lines
(nreverse (cdr (occur-accumulate-lines
@@ -1572,22 +1579,22 @@ (defun occur-context-lines (out-line nli
(when prev-after-lines
;; Don't overlap prev after-lines with current before-lines.
- (if (>= (+ prev-lines (length prev-after-lines))
- (- lines (length before-lines)))
+ (if (>= (+ prev-line (length prev-after-lines))
+ (- curr-line (length before-lines)))
(setq prev-after-lines
(butlast prev-after-lines
(- (length prev-after-lines)
- (- lines prev-lines (length before-lines) 1))))
+ (- curr-line prev-line (length before-lines) 1))))
;; Separate non-overlapping context lines with a dashed line.
(setq separator "-------\n")))
- (when prev-lines
+ (when prev-line
;; Don't overlap current before-lines with previous match line.
- (if (<= (- lines (length before-lines))
- prev-lines)
+ (if (<= (- curr-line (length before-lines))
+ prev-line)
(setq before-lines
(nthcdr (- (length before-lines)
- (- lines prev-lines 1))
+ (- curr-line prev-line 1))
before-lines))
;; Separate non-overlapping before-context lines.
(unless (> nlines 0)
^ permalink raw reply [flat|nested] 3+ messages in thread
* bug#14017: Highlight prefix line numbers in occur
2013-03-24 21:54 ` Juri Linkov
@ 2013-05-29 23:47 ` Juri Linkov
0 siblings, 0 replies; 3+ messages in thread
From: Juri Linkov @ 2013-05-29 23:47 UTC (permalink / raw)
To: 14017
> Another problem I found with the line numbers in `occur' is that
> the number of matches it reports in the header line is wrong.
> If there are more than one match on a line, the total number
> of matches is more than the total number of matching lines
> currently displayed in the header line. So I propose
> to change the format of the occur header line from:
>
> 2 matches for "is" in buffer: *scratch*
>
> to:
>
> 4 matches in 2 lines for "is" in buffer: *scratch*
>
> I found that the exact number of matches (as opposed to
> the number of matching lines) often is necessary to know beforehand
> how many times it requires to type C-s to visit all matches
> or how many times to type y/n to replace all matches in the buffer.
This is installed now.
I propose to use a similar message for grep output as well,
i.e. to change the current format:
Grep finished with no matches found at Tue Jul 19 15:43:12
Grep finished (matches found) at Thu Jul 21 15:02:15
to:
Grep finished with no matches found at Tue Jul 19 15:43:12
Grep finished with 42 matches found at Thu Jul 21 15:02:15
or if grep can count only matching lines then:
Grep finished with 42 matching lines at Thu Jul 21 15:02:15
otherwise:
Grep finished with 42 matches in 5 lines at Thu Jul 21 15:02:15
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-05-29 23:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-21 22:38 bug#14017: Highlight prefix line numbers in occur Juri Linkov
2013-03-24 21:54 ` Juri Linkov
2013-05-29 23:47 ` Juri Linkov
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.