unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [patch] Run occur command restricted to a region
@ 2016-12-29  6:36 Tino Calancha
  2016-12-29 16:10 ` Eli Zaretskii
  2016-12-29 23:31 ` [patch] Run occur command restricted to a region Juri Linkov
  0 siblings, 2 replies; 39+ messages in thread
From: Tino Calancha @ 2016-12-29  6:36 UTC (permalink / raw)
  To: Emacs developers; +Cc: tino.calancha


Hi,

is it worth to have versions of `occur' restricting the
search to lines before (after) the current line?

Maybe there is already a way to do that, and i just ignore it.
I usually just i copy the region into a temporary buffer; then
i run `occur' there.

I just wrote a patch to show my point; it adds the following commands:
1) occur-backward: for lines before the current one.
2) occur-forward: for lines after the current one.
3) occur-in-region: for lines within the active region.

Not sure if we want to bind them to keys.
Tentatively, i have assigned `M-s b' and `M-s f' for
1) and 2) in the `search-map'.  That means, these bindings
are not available in all modes; OTOH command `occur' is in
the `global-map', so it's always available.

Any comment about this proposal?

Thanks,
Tino
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 61097b346737aa1960da568c54fc2b9211e5fe5c Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Thu, 29 Dec 2016 15:02:47 +0900
Subject: [PATCH] New commands: occur-forward, occur-backward, occur-in-region

* lisp/replace.el (occur-matches-threshold): New variable.
(occur-in-region, occur-forward, occur-backward): New commands.
* lisp/bindings.el (search-map): Bind occur-backward to 'M-s b'
and occur-forward to 'M-s f'.
---
 lisp/bindings.el |  2 ++
 lisp/replace.el  | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/lisp/bindings.el b/lisp/bindings.el
index c13f4b156a..4b1c88a3c5 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -928,6 +928,8 @@ search-map
 (define-key esc-map "s" search-map)
 
 (define-key search-map "o"    'occur)
+(define-key search-map "b"    'occur-backward)
+(define-key search-map "f"    'occur-forward)
 (define-key search-map "\M-w" 'eww-search-words)
 (define-key search-map "hr"   'highlight-regexp)
 (define-key search-map "hp"   'highlight-phrase)
diff --git a/lisp/replace.el b/lisp/replace.el
index a172174633..09e0bf1e1f 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1322,11 +1322,12 @@ occur-excluded-properties
   :group 'matching
   :version "22.1")
 
-(defun occur-read-primary-args ()
-  (let* ((perform-collect (consp current-prefix-arg))
+(defun occur-read-primary-args (&optional where)
+  (let* ((str (if where (concat " " where) ""))
+         (perform-collect (consp current-prefix-arg))
          (regexp (read-regexp (if perform-collect
-                                  "Collect strings matching regexp"
-                                "List lines matching regexp")
+                                  (concat "Collect strings matching regexp" str)
+                                (concat "List lines matching regexp" str))
                               'regexp-history-last)))
     (list regexp
 	  (if perform-collect
@@ -1389,6 +1390,42 @@ occur
   (interactive (occur-read-primary-args))
   (occur-1 regexp nlines (list (current-buffer))))
 
+(defun occur-backward (regexp &optional nlines)
+    "Show all lines before current line containing a match for REGEXP.
+Each line is displayed with NLINES lines before and after, or -NLINES
+before if NLINES is negative.
+As `occur' but restricted to lines before the current one."
+  (interactive (occur-read-primary-args "backward"))
+  (narrow-to-region (point-min) (point))
+  (occur regexp nlines)
+  (widen))
+
+(defun occur-forward (regexp &optional nlines)
+  "Show all lines after current line containing a match for REGEXP.
+Each line is displayed with NLINES lines before and after, or -NLINES
+before if NLINES is negative.
+As `occur' but restricted to lines after the current one."
+  (interactive (occur-read-primary-args "forward"))
+  (let ((occur-matches-threshold
+         (line-number-at-pos (point))))
+    (narrow-to-region (point) (point-max))
+    (occur regexp nlines))
+  (widen))
+
+(defun occur-in-region (regexp &optional nlines)
+  "Show all lines in the active region containing a match for REGEXP.
+Each line is displayed with NLINES lines before and after, or -NLINES
+before if NLINES is negative.
+As `occur' but restricted to lines within the active region."
+  (interactive (occur-read-primary-args "in region"))
+  (unless (use-region-p)
+    (error "Region not active"))
+    (let ((occur-matches-threshold
+         (line-number-at-pos (region-beginning))))
+      (narrow-to-region (region-beginning) (region-end))
+      (occur regexp nlines))
+    (widen))
+
 (defvar ido-ignore-item-temp-list)
 
 (defun multi-occur (bufs regexp &optional nlines)
@@ -1539,6 +1576,9 @@ occur-1
             (set-buffer-modified-p nil)
             (run-hooks 'occur-hook)))))))
 
+;; Let binded in `occur-forward' and `occur-in-region'.
+(defvar occur-matches-threshold nil)
+
 (defun occur-engine (regexp buffers out-buf nlines case-fold
 			    title-face prefix-face match-face keep-props)
   (with-current-buffer out-buf
@@ -1551,7 +1591,8 @@ occur-engine
 	(when (buffer-live-p buf)
 	  (let ((lines 0)               ;; count of matching lines
 		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur-matches-threshold 1))
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.5)
 of 2016-12-28
Repository revision: 112460da705c2a6716d7b6bc72501de0a3757259



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-29  6:36 [patch] Run occur command restricted to a region Tino Calancha
@ 2016-12-29 16:10 ` Eli Zaretskii
  2016-12-29 16:54   ` Tino Calancha
  2017-01-03 17:37   ` Region argument (was: [patch] Run occur command restricted to a region) Stefan Monnier
  2016-12-29 23:31 ` [patch] Run occur command restricted to a region Juri Linkov
  1 sibling, 2 replies; 39+ messages in thread
From: Eli Zaretskii @ 2016-12-29 16:10 UTC (permalink / raw)
  To: Tino Calancha; +Cc: emacs-devel

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Thu, 29 Dec 2016 15:36:56 +0900
> Cc: tino.calancha@gmail.com
> 
> Any comment about this proposal?

I have one comment:

> +(defun occur-in-region (regexp &optional nlines)
> +  "Show all lines in the active region containing a match for REGEXP.
> +Each line is displayed with NLINES lines before and after, or -NLINES
> +before if NLINES is negative.
> +As `occur' but restricted to lines within the active region."
> +  (interactive (occur-read-primary-args "in region"))
> +  (unless (use-region-p)
> +    (error "Region not active"))

I think our convention for functions that act on the region is to
accept BEG and END arguments, so that the function could be called
from Lisp.  The 'interactive' form/spec should then provide these
arguments for the interactive use.

Also, this will need a NEWS entry, and possibly also an addition to
the user manual.

Thanks.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-29 16:10 ` Eli Zaretskii
@ 2016-12-29 16:54   ` Tino Calancha
  2016-12-29 18:16     ` Drew Adams
  2017-01-03 17:37   ` Region argument (was: [patch] Run occur command restricted to a region) Stefan Monnier
  1 sibling, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2016-12-29 16:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tino.calancha, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> +(defun occur-in-region (regexp &optional nlines)
>> +  "Show all lines in the active region containing a match for REGEXP.
>> +Each line is displayed with NLINES lines before and after, or -NLINES
>> +before if NLINES is negative.
>> +As `occur' but restricted to lines within the active region."
>> +  (interactive (occur-read-primary-args "in region"))
>> +  (unless (use-region-p)
>> +    (error "Region not active"))
>
> I think our convention for functions that act on the region is to
> accept BEG and END arguments, so that the function could be called
> from Lisp.  The 'interactive' form/spec should then provide these
> arguments for the interactive use.
Right! Thank you.

> Also, this will need a NEWS entry, and possibly also an addition to
> the user manual.
Sure, i have added a NEWS entry for the commands.
I don't see a clear place in the manual where to mention about
these commands: it seems `occur' is just defined in the intro as an
example on how to make keybindings.

Here is the updated patch:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From fbee1d786c35b6148112f32717d30e17836fd4ae Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Fri, 30 Dec 2016 01:42:00 +0900
Subject: [PATCH] New commands: occur-forward, occur-backward, occur-in-region

* lisp/replace.el (occur-matches-threshold): New variable.
(occur-in-region, occur-forward, occur-backward): New commands.
* lisp/bindings.el (search-map): Bind occur-backward to 'M-s b'
and occur-forward to 'M-s f'.
; etc/DEBUG: Add entry for the new commands.
---
 etc/NEWS         |  5 +++++
 lisp/bindings.el |  2 ++
 lisp/replace.el  | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index e2ada7c1be..9cfd5ed340 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -294,6 +294,11 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
 \f
 * Editing Changes in Emacs 26.1
 
+---
+** New commands 'occur-in-region', 'occur-forward' and 'occur-backward'
+run 'occur' restricted to a region of the current buffer; 'occur-backward'
+bound to 'M-s b' and 'occur-forward' bound to 'M-s f'.
+
 +++
 ** New bindings for 'query-replace-map'.
 'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/bindings.el b/lisp/bindings.el
index c13f4b156a..4b1c88a3c5 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -928,6 +928,8 @@ search-map
 (define-key esc-map "s" search-map)
 
 (define-key search-map "o"    'occur)
+(define-key search-map "b"    'occur-backward)
+(define-key search-map "f"    'occur-forward)
 (define-key search-map "\M-w" 'eww-search-words)
 (define-key search-map "hr"   'highlight-regexp)
 (define-key search-map "hp"   'highlight-phrase)
diff --git a/lisp/replace.el b/lisp/replace.el
index a172174633..95af63b108 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1092,6 +1092,9 @@ occur-mode
   (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
   (setq next-error-function 'occur-next-error))
 
+;; Let binded in `occur-forward' and `occur-in-region'.
+(defvar occur-matches-threshold nil)
+
 \f
 ;;; Occur Edit mode
 
@@ -1322,11 +1325,12 @@ occur-excluded-properties
   :group 'matching
   :version "22.1")
 
-(defun occur-read-primary-args ()
-  (let* ((perform-collect (consp current-prefix-arg))
+(defun occur-read-primary-args (&optional where)
+  (let* ((str (if where (concat " " where) ""))
+         (perform-collect (consp current-prefix-arg))
          (regexp (read-regexp (if perform-collect
-                                  "Collect strings matching regexp"
-                                "List lines matching regexp")
+                                  (concat "Collect strings matching regexp" str)
+                                (concat "List lines matching regexp" str))
                               'regexp-history-last)))
     (list regexp
 	  (if perform-collect
@@ -1389,6 +1393,45 @@ occur
   (interactive (occur-read-primary-args))
   (occur-1 regexp nlines (list (current-buffer))))
 
+(defun occur-backward (regexp &optional nlines)
+    "Show all lines before current line containing a match for REGEXP.
+Each line is displayed with NLINES lines before and after, or -NLINES
+before if NLINES is negative.
+As `occur' but restricted to lines before the current one."
+  (interactive (occur-read-primary-args "backward"))
+  (narrow-to-region (point-min) (point))
+  (occur regexp nlines)
+  (widen))
+
+(defun occur-forward (regexp &optional nlines)
+  "Show all lines after current line containing a match for REGEXP.
+Each line is displayed with NLINES lines before and after, or -NLINES
+before if NLINES is negative.
+As `occur' but restricted to lines after the current one."
+  (interactive (occur-read-primary-args "forward"))
+  (let ((occur-matches-threshold
+         (line-number-at-pos (point))))
+    (narrow-to-region (point) (point-max))
+    (occur regexp nlines))
+  (widen))
+
+(defun occur-in-region (regexp beg end &optional nlines)
+  "Show all lines in the active region containing a match for REGEXP.
+BEG and END define the region.
+Each line is displayed with NLINES lines before and after, or -NLINES
+before if NLINES is negative.
+As `occur' but restricted to lines within the active region."
+  (interactive
+   (if (null (use-region-p))
+       (error "Region not active")
+     (let ((args (occur-read-primary-args "in region")))
+       (list (car args) (region-beginning) (region-end) (cadr args)))))
+  (let ((occur-matches-threshold
+         (line-number-at-pos beg)))
+    (narrow-to-region beg end)
+    (occur regexp nlines))
+  (widen))
+
 (defvar ido-ignore-item-temp-list)
 
 (defun multi-occur (bufs regexp &optional nlines)
@@ -1551,7 +1594,8 @@ occur-engine
 	(when (buffer-live-p buf)
 	  (let ((lines 0)               ;; count of matching lines
 		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur-matches-threshold 1))
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.5)
 of 2016-12-30
Repository revision: 11b81a54d538e8deca3cd64521cf85409efb617b



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* RE: [patch] Run occur command restricted to a region
  2016-12-29 16:54   ` Tino Calancha
@ 2016-12-29 18:16     ` Drew Adams
  2016-12-29 18:50       ` Kaushal Modi
  2016-12-30  2:57       ` Tino Calancha
  0 siblings, 2 replies; 39+ messages in thread
From: Drew Adams @ 2016-12-29 18:16 UTC (permalink / raw)
  To: Tino Calancha, Eli Zaretskii; +Cc: emacs-devel

>  (define-key search-map "o"    'occur)
> +(define-key search-map "b"    'occur-backward)
> +(define-key search-map "f"    'occur-forward)

FWIW, I don't think those keys (`M-s b' and `M-s f') should be
bound to those commands.  If we want to bind the new commands
during Isearch then I suggest that the occur commands be grouped
on prefix key `M-s o':

  M-s oo   occur
  M-s ob   occur-backward
  M-s of   occur-backward

`M-s' is a _general_ search prefix key.  There is nothing
particularly mnemonic about `b' or `f' being `occur-backward'
or `occur-forward'.  And we should not sacrifice 3 `M-s' keys
to these commands.

I, and perhaps other users, and perhaps in the future vanilla
Emacs, have other bindings on `M-s'.  And `M-s' bindings can
be anything at all related to the encompassing context of
searching.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-29 18:16     ` Drew Adams
@ 2016-12-29 18:50       ` Kaushal Modi
  2016-12-29 20:52         ` Drew Adams
  2016-12-30  2:57       ` Tino Calancha
  1 sibling, 1 reply; 39+ messages in thread
From: Kaushal Modi @ 2016-12-29 18:50 UTC (permalink / raw)
  To: Drew Adams, Tino Calancha, Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1438 bytes --]

I agree with Drew's reasoning behind not using up the M-s b/f bindings for
occur-backward/forward. But I don't like the idea of having M-s o as a
submap binding. M-s o is super useful as it is now.

Here's a suggestion for bindings that might work out. I am not at a
computer, so cannot verify if M-s M-o is already taken,.. but if not then
how about

M-s M-o f for occur-forward, and
M-s M-o b for occur-backward

??

The above bindings are easy to press and also easy to remember.

On Thu, Dec 29, 2016, 11:47 PM Drew Adams <drew.adams@oracle.com> wrote:

> >  (define-key search-map "o"    'occur)
> > +(define-key search-map "b"    'occur-backward)
> > +(define-key search-map "f"    'occur-forward)
>
> FWIW, I don't think those keys (`M-s b' and `M-s f') should be
> bound to those commands.  If we want to bind the new commands
> during Isearch then I suggest that the occur commands be grouped
> on prefix key `M-s o':
>
>   M-s oo   occur
>   M-s ob   occur-backward
>   M-s of   occur-backward
>
> `M-s' is a _general_ search prefix key.  There is nothing
> particularly mnemonic about `b' or `f' being `occur-backward'
> or `occur-forward'.  And we should not sacrifice 3 `M-s' keys
> to these commands.
>
> I, and perhaps other users, and perhaps in the future vanilla
> Emacs, have other bindings on `M-s'.  And `M-s' bindings can
> be anything at all related to the encompassing context of
> searching.
>
> --

Kaushal Modi

[-- Attachment #2: Type: text/html, Size: 2459 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [patch] Run occur command restricted to a region
  2016-12-29 18:50       ` Kaushal Modi
@ 2016-12-29 20:52         ` Drew Adams
  0 siblings, 0 replies; 39+ messages in thread
From: Drew Adams @ 2016-12-29 20:52 UTC (permalink / raw)
  To: Kaushal Modi, Tino Calancha, Eli Zaretskii; +Cc: emacs-devel

> I agree with Drew's reasoning behind not using up the M-s b/f
> bindings for occur-backward/forward. But I don't like the idea
> of having M-s o as a submap binding.  M-s o is super useful as
> it is now.

It is simple to hit `o o' instead of `o'.  And it has the
advantage of reminding you of the fact that there are also
`o f' and `o b'.  `M-s o o' is no less "super useful" than
`M-s o'.

> Here's a suggestion for bindings that might work out.
> I am not at a computer, so cannot verify if M-s M-o is
> already taken,.. but if not then how about M-s M-o f
> for occur-forward, and M-s M-o b for occur-backward??
>
> The above bindings are easy to press and also easy to remember.

Those are horrible, IMO.  Instead of sacrificing `M-s b'
and `M-s f' you are sacrificing `M-s M-o'.  So you've
saved only one key.  And at the cost of introducing more
complexity.

And inconsistency, unless you also move `occur' to
`M-s M-o o'.  If you do that, then I'm in favor.

The point is to group all of the occur commands wrt
keys: have them use the same prefix.  Prefix `M-s M-o'
is at least as easy to use as prefix `M-s o'.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-29  6:36 [patch] Run occur command restricted to a region Tino Calancha
  2016-12-29 16:10 ` Eli Zaretskii
@ 2016-12-29 23:31 ` Juri Linkov
  2016-12-30  2:47   ` Tino Calancha
  2016-12-30  7:53   ` Eli Zaretskii
  1 sibling, 2 replies; 39+ messages in thread
From: Juri Linkov @ 2016-12-29 23:31 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers

> is it worth to have versions of `occur' restricting the
> search to lines before (after) the current line?
>
> Maybe there is already a way to do that, and i just ignore it.
> I usually just i copy the region into a temporary buffer; then
> i run `occur' there.

(info "(emacs) Other Repeating Search") says what is the recommended way
to do this is:

`M-x occur'
     Prompt for a regexp, and display a list showing each line in the
     buffer that contains a match for it.  The text that matched is
     highlighted using the `match' face.  To limit the search to part
     of the buffer, narrow to that part (*note Narrowing::).

> I just wrote a patch to show my point; it adds the following commands:
> 1) occur-backward: for lines before the current one.

The name occur-backward falsely implies it uses re-search-backward,
and I'm unsure if we need it as a counter part of isearch-backward.

> 2) occur-forward: for lines after the current one.
> 3) occur-in-region: for lines within the active region.

Maybe we should use the same logic of other related commands in replace.el
how-many, keep-lines, flush-lines that limit the affected lines to the
active region, or when the region is not active, take only lines after
the current line.  Then we don't need separate commands, and no keys for them.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-29 23:31 ` [patch] Run occur command restricted to a region Juri Linkov
@ 2016-12-30  2:47   ` Tino Calancha
  2016-12-30 23:20     ` Juri Linkov
  2016-12-30  7:53   ` Eli Zaretskii
  1 sibling, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2016-12-30  2:47 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha



On Fri, 30 Dec 2016, Juri Linkov wrote:

> Maybe we should use the same logic of other related commands in replace.el
> how-many, keep-lines, flush-lines that limit the affected lines to the
> active region, or when the region is not active, take only lines after
> the current line.  Then we don't need separate commands, and no keys for them.
Yeah, that is a source of confusion when using those tools:
1) Commands like `how-many' or `flush-lines' by default apply to the lines
    after point; they accept optional arguments to cover a region as well.
2) OTOH `occur' by default uses the entire buffer; it doesn't accept
    arguments to select a region.

It's a nice thing if all related tools follow similar defaults. 
Command `occur' is also used in `multi-occur', to search in multiple 
buffers: in that case you must search in the entire buffers.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* RE: [patch] Run occur command restricted to a region
  2016-12-29 18:16     ` Drew Adams
  2016-12-29 18:50       ` Kaushal Modi
@ 2016-12-30  2:57       ` Tino Calancha
  1 sibling, 0 replies; 39+ messages in thread
From: Tino Calancha @ 2016-12-30  2:57 UTC (permalink / raw)
  To: Drew Adams
  Cc: kaushal.modi, juri, Eli Zaretskii, Emacs developers,
	Tino Calancha



On Thu, 29 Dec 2016, Drew Adams wrote:

>>  (define-key search-map "o"    'occur)
>> +(define-key search-map "b"    'occur-backward)
>> +(define-key search-map "f"    'occur-forward)
>
> FWIW, I don't think those keys (`M-s b' and `M-s f') should be
> bound to those commands.  If we want to bind the new commands
> during Isearch then I suggest that the occur commands be grouped
> on prefix key `M-s o':
>
>  M-s oo   occur
>  M-s ob   occur-backward
>  M-s of   occur-backward
>
> `M-s' is a _general_ search prefix key.  There is nothing
> particularly mnemonic about `b' or `f' being `occur-backward'
> or `occur-forward'.  And we should not sacrifice 3 `M-s' keys
> to these commands.
>
> I, and perhaps other users, and perhaps in the future vanilla
> Emacs, have other bindings on `M-s'.  And `M-s' bindings can
> be anything at all related to the encompassing context of
> searching.
I agree with you that my suggested keybindings are not a good choice.
To me, grouping related commands under a common prefix sounds like
a good idea.
I am also OK with not providing keybindings to these new commands at all.




^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-29 23:31 ` [patch] Run occur command restricted to a region Juri Linkov
  2016-12-30  2:47   ` Tino Calancha
@ 2016-12-30  7:53   ` Eli Zaretskii
  2016-12-30 23:16     ` Juri Linkov
  1 sibling, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2016-12-30  7:53 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel, tino.calancha

> From: Juri Linkov <juri@linkov.net>
> Date: Fri, 30 Dec 2016 01:31:04 +0200
> Cc: Emacs developers <emacs-devel@gnu.org>
> 
> > 1) occur-backward: for lines before the current one.
> 
> The name occur-backward falsely implies it uses re-search-backward,
> and I'm unsure if we need it as a counter part of isearch-backward.

I can suggest occur-before and occur-after instead.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-30  7:53   ` Eli Zaretskii
@ 2016-12-30 23:16     ` Juri Linkov
  2016-12-31  8:37       ` Eli Zaretskii
       [not found]       ` <87r34ozq20.fsf@gmail.com>
  0 siblings, 2 replies; 39+ messages in thread
From: Juri Linkov @ 2016-12-30 23:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel, tino.calancha

>> > 1) occur-backward: for lines before the current one.
>>
>> The name occur-backward falsely implies it uses re-search-backward,
>> and I'm unsure if we need it as a counter part of isearch-backward.
>
> I can suggest occur-before and occur-after instead.

Or occur-above and occur-below.

What causes the doubt is that there are no other commands like that.
No ‘count-words-before’, no ‘count-words-above’, just ‘count-words-region’
no ‘comment-before’, no ‘comment-above’, just ‘comment-region’,
no ‘delete-before’, no ‘delete-above’, just ‘delete-region’,
and tens of other similar commands.  This means that it's simple enough
to select the region (e.g. ‘M-<’ to the beginning of the buffer) and
use ‘*-region’ commands to operate on the active region.
So it should be enough to handle the active region in ‘occur’
without creating new commands.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-30  2:47   ` Tino Calancha
@ 2016-12-30 23:20     ` Juri Linkov
  0 siblings, 0 replies; 39+ messages in thread
From: Juri Linkov @ 2016-12-30 23:20 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers

>> Maybe we should use the same logic of other related commands in replace.el
>> how-many, keep-lines, flush-lines that limit the affected lines to the
>> active region, or when the region is not active, take only lines after
>> the current line.  Then we don't need separate commands, and no keys for them.
> Yeah, that is a source of confusion when using those tools:
> 1) Commands like `how-many' or `flush-lines' by default apply to the lines
>    after point; they accept optional arguments to cover a region as well.
> 2) OTOH `occur' by default uses the entire buffer; it doesn't accept
>    arguments to select a region.
>
> It's a nice thing if all related tools follow similar defaults. Command
> `occur' is also used in `multi-occur', to search in multiple buffers: in
> that case you must search in the entire buffers.

Like other commands, ‘occur’ could handle the active region,
but please show this fact in the header of the output *Occur* buffer,
so the users will immediately notice the scope of the output.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2016-12-30 23:16     ` Juri Linkov
@ 2016-12-31  8:37       ` Eli Zaretskii
       [not found]       ` <87r34ozq20.fsf@gmail.com>
  1 sibling, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2016-12-31  8:37 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel, tino.calancha

> From: Juri Linkov <juri@linkov.net>
> Cc: tino.calancha@gmail.com,  emacs-devel@gnu.org
> Date: Sat, 31 Dec 2016 01:16:34 +0200
> 
> >> > 1) occur-backward: for lines before the current one.
> >>
> >> The name occur-backward falsely implies it uses re-search-backward,
> >> and I'm unsure if we need it as a counter part of isearch-backward.
> >
> > I can suggest occur-before and occur-after instead.
> 
> Or occur-above and occur-below.
> 
> What causes the doubt is that there are no other commands like that.
> No ‘count-words-before’, no ‘count-words-above’, just ‘count-words-region’
> no ‘comment-before’, no ‘comment-above’, just ‘comment-region’,
> no ‘delete-before’, no ‘delete-above’, just ‘delete-region’,
> and tens of other similar commands.

This command emulates Grep, with its -A and -B options.  That's why I
suggested "after" and "before".  No other command need to show
context, so it's quite understandable why this one is unique in that
sense.

> This means that it's simple enough to select the region (e.g. ‘M-<’
> to the beginning of the buffer) and use ‘*-region’ commands to
> operate on the active region.  So it should be enough to handle the
> active region in ‘occur’ without creating new commands.

The problem is that the meaning of the region here says nothing about
the context lines the user wants displayed in the Occur buffer.  I
agree that an active region should mean "find matches in that region",
but we still need a way for the user to specify non-default number of
context lines to show with the matches, I think.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
       [not found]             ` <87d1g55h8d.fsf@mail.linkov.net>
@ 2017-01-03 10:19               ` Tino Calancha
  2017-01-18 11:04                 ` Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-01-03 10:19 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha


(Re-send with emacs-devel@gnu.org as CC)

On Mon, 2 Jan 2017, Juri Linkov wrote:

>>> If you need to see whether matching lines are before or after
>>> the current line, then what do you think about showing and highlighting
>>> the current line in the output *Occur* buffer?
>> Inserting the current line, which might not match the regexp, in *Occur*;
>> i am not sure about it.
>> Please, try the second part of the patch, and let me know if looks
>> useful for you.
>
> I tried it, and I'm not sure - the problem is that it's not obvious
> that the highlighted line is the current line.  Maybe better to put the cursor
> in *Occur* on the first matching line after the current line? But I doubt whether
> users will like this change in cursor positioning.
See the updated patch.  Play with it and let me know how you see it.
In my case, just the first part of the patch, i.e., to run `occur' 
restricted to the region is all that i need.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From d2334a303db81f69b09dfe09d3332905dab6be68 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Tue, 3 Jan 2017 19:00:08 +0900
Subject: [PATCH 1/3] Allow occur command to operate on the region

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional args START, END; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search: Idem.
; etc/NEWS: Add entry to announce the change.
---
  doc/emacs/search.texi               |  3 +++
  doc/lispintro/emacs-lisp-intro.texi |  8 ++++---
  etc/NEWS                            |  2 ++
  lisp/replace.el                     | 48 +++++++++++++++++++++++++++++++------
  4 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index b728258973..28e25bec43 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1672,6 +1672,9 @@ Other Repeating Search
  no upper-case letters and @code{case-fold-search} is non-@code{nil}.
  Aside from @code{occur} and its variants, all operate on the text from
  point to the end of the buffer, or on the region if it is active.
+The command @code{occur} will operate on the region if
+it is active as well; when the region is not active, @code{occur}
+operates in the whole buffer.

  @findex list-matching-lines
  @findex occur
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 830c072cf5..36d767737d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -17151,9 +17151,11 @@ Keybindings

  @findex occur
  The @code{occur} command shows all the lines in the current buffer
-that contain a match for a regular expression.  Matching lines are
-shown in a buffer called @file{*Occur*}.  That buffer serves as a menu
-to jump to occurrences.
+that contain a match for a regular expression.  When the region is
+active, @code{occur} restricts matches to such region.  Otherwise it
+uses the entire buffer.
+Matching lines are shown in a buffer called @file{*Occur*}.
+That buffer serves as a menu to jump to occurrences.

  @findex global-unset-key
  @cindex Unbinding key
diff --git a/etc/NEWS b/etc/NEWS
index d91204b21b..cb01e03971 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -301,6 +301,8 @@ substituted by a home directory by writing it as "/foo:/:/~/file".

  * Editing Changes in Emacs 26.1

+
+** The 'occur' command can now operate on the region.
  +++
  ** New bindings for 'query-replace-map'.
  'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/replace.el b/lisp/replace.el
index ff91734445..cedf8e0c67 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1360,7 +1360,12 @@ occur-rename-buffer
                             "*")
                     (or unique-p (not interactive-p)))))

-(defun occur (regexp &optional nlines)
+;; Region limits when `occur' applies on a region.
+(defvar occur--region-start nil)
+(defvar occur--region-end nil)
+(defvar occur--matches-threshold nil)
+
+(defun occur (regexp &optional nlines start end)
    "Show all lines in the current buffer containing a match for REGEXP.
  If a match spreads across multiple lines, all those lines are shown.

@@ -1369,6 +1374,13 @@ occur
  NLINES defaults to `list-matching-lines-default-context-lines'.
  Interactively it is the prefix arg.

+Optional args START and END, if non-nil, mean restrict search to the
+specified region.
+ When START is non-nil and END is nil, END defaults to the last
+ accessible position in the current buffer.
+ When END is non-nil and START is nil, START defaults to the first
+ accessible position in the current buffer.
+
  The lines are shown in a buffer named `*Occur*'.
  It serves as a menu to find any of the occurrences in this buffer.
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
@@ -1386,8 +1398,23 @@ occur
  program.  When there is no parenthesized subexpressions in REGEXP
  the entire match is collected.  In any case the searched buffer
  is not modified."
-  (interactive (occur-read-primary-args))
-  (occur-1 regexp nlines (list (current-buffer))))
+  (interactive
+   (nconc (occur-read-primary-args)
+          (list (and (use-region-p) (region-beginning))
+                (and (use-region-p) (region-end)))))
+  (let ((in-region-p (or start end)))
+    (when in-region-p
+      (or start (setq start (point-min)))
+      (or end (setq end (point-max))))
+    (let ((occur--region-start start)
+          (occur--region-end end)
+          (occur--matches-threshold
+           (and in-region-p
+                (line-number-at-pos (min start end)))))
+      (save-excursion ; If no matches `occur-1' doesn't restore the point.
+        (and in-region-p (narrow-to-region start end))
+        (occur-1 regexp nlines (list (current-buffer)))
+        (and in-region-p (widen))))))

  (defvar ido-ignore-item-temp-list)

@@ -1545,13 +1572,15 @@ occur-engine
      (let ((global-lines 0)    ;; total count of matching lines
  	  (global-matches 0)  ;; total count of matches
  	  (coding nil)
-	  (case-fold-search case-fold))
+	  (case-fold-search case-fold)
+          (in-region-p (and occur--region-start occur--region-end)))
        ;; Map over all the buffers
        (dolist (buf buffers)
  	(when (buffer-live-p buf)
  	  (let ((lines 0)               ;; count of matching lines
  		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur--matches-threshold 1))
  		(prev-line nil)         ;; line number of prev match endpt
  		(prev-after-lines nil)  ;; context lines of prev match
  		(matchbeg 0)
@@ -1684,7 +1713,7 @@ occur-engine
  		(let ((beg (point))
  		      end)
  		  (insert (propertize
-			   (format "%d match%s%s%s in buffer: %s\n"
+			   (format "%d match%s%s%s in buffer: %s%s\n"
  				   matches (if (= matches 1) "" "es")
  				   ;; Don't display the same number of lines
  				   ;; and matches in case of 1 match per line.
@@ -1694,7 +1723,12 @@ occur-engine
  				   ;; Don't display regexp for multi-buffer.
  				   (if (> (length buffers) 1)
  				       "" (occur-regexp-descr regexp))
-				   (buffer-name buf))
+				   (buffer-name buf)
+                                   (if in-region-p
+                                       (format " within region: %d-%d"
+                                               occur--region-start
+                                               occur--region-end)
+                                     ""))
  			   'read-only t))
  		  (setq end (point))
  		  (add-text-properties beg end `(occur-title ,buf))
-- 
2.11.0

From 5a27c052cc1469c72a57d624010a2a8d0c0543b9 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Tue, 3 Jan 2017 19:00:29 +0900
Subject: [PATCH 2/3] Show current line highlighted in *Occur* buffer

* lisp/replace.el (occur--orig-line, occur--orig-line-str): New variables.
(occur, occur-engine): Use them.
---
  lisp/replace.el | 25 ++++++++++++++++++++++++-
  1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/lisp/replace.el b/lisp/replace.el
index cedf8e0c67..448ac2cf3c 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1364,6 +1364,8 @@ occur-rename-buffer
  (defvar occur--region-start nil)
  (defvar occur--region-end nil)
  (defvar occur--matches-threshold nil)
+(defvar occur--orig-line nil)
+(defvar occur--orig-line-str nil)

  (defun occur (regexp &optional nlines start end)
    "Show all lines in the current buffer containing a match for REGEXP.
@@ -1410,7 +1412,13 @@ occur
            (occur--region-end end)
            (occur--matches-threshold
             (and in-region-p
-                (line-number-at-pos (min start end)))))
+                (line-number-at-pos (min start end))))
+          (occur--orig-line
+           (line-number-at-pos (point)))
+          (occur--orig-line-str
+           (buffer-substring-no-properties
+            (line-beginning-position)
+            (line-end-position))))
        (save-excursion ; If no matches `occur-1' doesn't restore the point.
          (and in-region-p (narrow-to-region start end))
          (occur-1 regexp nlines (list (current-buffer)))
@@ -1581,6 +1589,9 @@ occur-engine
  		(matches 0)             ;; count of matches
  		(curr-line              ;; line count
                   (or occur--matches-threshold 1))
+                (orig-line occur--orig-line)
+                (orig-line-str occur--orig-line-str)
+                (orig-line-shown-p)
  		(prev-line nil)         ;; line number of prev match endpt
  		(prev-after-lines nil)  ;; context lines of prev match
  		(matchbeg 0)
@@ -1687,6 +1698,12 @@ occur-engine
  			      (nth 0 ret))))
  		      ;; Actually insert the match display data
  		      (with-current-buffer out-buf
+                        (when (and (not orig-line-shown-p)
+                                   (>= curr-line orig-line))
+                          (insert
+                           (concat
+                            (propertize orig-line-str 'face 'query-replace) "\n"))
+                          (setq orig-line-shown-p t))
  			(insert data)))
  		    (goto-char endpt))
  		  (if endpt
@@ -1700,6 +1717,12 @@ occur-engine
  			(forward-line 1))
  		    (goto-char (point-max)))
  		  (setq prev-line (1- curr-line)))
+                ;; Insert original line if haven't done yet.
+                (unless orig-line-shown-p
+                  (with-current-buffer out-buf
+                    (insert
+                     (concat
+                      (propertize orig-line-str 'face 'query-replace) "\n"))))
  		;; Flush remaining context after-lines.
  		(when prev-after-lines
  		  (with-current-buffer out-buf
-- 
2.11.0

From 366d7e5118d1411b7b43925c3a95bcb50a04db90 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Tue, 3 Jan 2017 19:00:47 +0900
Subject: [PATCH 3/3] occur: Set point on the first matching line after the
  current one

* lisp/replace.el (occur-current-line-face): New face.
(occur--final-pos): New variable.
(occur-1): Use it.
(occur-engine): Idem.
Show the current line with 'occur-current-line-face'.
---
  lisp/replace.el | 45 ++++++++++++++++++++++++++++++++++++---------
  1 file changed, 36 insertions(+), 9 deletions(-)

diff --git a/lisp/replace.el b/lisp/replace.el
index 448ac2cf3c..0c67fe3640 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1081,6 +1081,12 @@ occur-mode-find-occurrence-hook
    :type 'hook
    :group 'matching)

+(defface occur-current-line-face
+  '((t (:inherit lazy-highlight)))
+  "Face for highlighting the current line in *Occur* buffer."
+  :group 'matching
+  :version "26.1")
+
  (put 'occur-mode 'mode-class 'special)
  (define-derived-mode occur-mode special-mode "Occur"
    "Major mode for output from \\[occur].
@@ -1366,6 +1372,7 @@ occur--region-end
  (defvar occur--matches-threshold nil)
  (defvar occur--orig-line nil)
  (defvar occur--orig-line-str nil)
+(defvar occur--final-pos nil)

  (defun occur (regexp &optional nlines start end)
    "Show all lines in the current buffer containing a match for REGEXP.
@@ -1517,7 +1524,8 @@ occur-1
  	(occur-mode))
        (let ((inhibit-read-only t)
  	    ;; Don't generate undo entries for creation of the initial contents.
-	    (buffer-undo-list t))
+	    (buffer-undo-list t)
+            (occur--final-pos nil))
  	(erase-buffer)
  	(let ((count
  	       (if (stringp nlines)
@@ -1569,6 +1577,10 @@ occur-1
            (if (= count 0)
                (kill-buffer occur-buf)
              (display-buffer occur-buf)
+            (when occur--final-pos
+              (set-window-point
+               (get-buffer-window occur-buf 'all-frames)
+               occur--final-pos))
              (setq next-error-last-buffer occur-buf)
              (setq buffer-read-only t)
              (set-buffer-modified-p nil)
@@ -1581,7 +1593,8 @@ occur-engine
  	  (global-matches 0)  ;; total count of matches
  	  (coding nil)
  	  (case-fold-search case-fold)
-          (in-region-p (and occur--region-start occur--region-end)))
+          (in-region-p (and occur--region-start occur--region-end))
+          (multi-occur-p (cdr buffers)))
        ;; Map over all the buffers
        (dolist (buf buffers)
  	(when (buffer-live-p buf)
@@ -1598,6 +1611,7 @@ occur-engine
  		(origpt nil)
  		(begpt nil)
  		(endpt nil)
+                (finalpt nil)
  		(marker nil)
  		(curstring "")
  		(ret nil)
@@ -1698,12 +1712,17 @@ occur-engine
  			      (nth 0 ret))))
  		      ;; Actually insert the match display data
  		      (with-current-buffer out-buf
-                        (when (and (not orig-line-shown-p)
+                        (when (and (not multi-occur-p)
+                                   (not orig-line-shown-p)
                                     (>= curr-line orig-line))
                            (insert
                             (concat
-                            (propertize orig-line-str 'face 'query-replace) "\n"))
-                          (setq orig-line-shown-p t))
+                            (propertize
+                             (format "%7d:%s" orig-line orig-line-str)
+                             'face 'occur-current-line-face
+                             'mouse-face 'mode-line-highlight
+                             'help-echo "Current line") "\n"))
+                          (setq orig-line-shown-p t finalpt (point)))
  			(insert data)))
  		    (goto-char endpt))
  		  (if endpt
@@ -1718,11 +1737,16 @@ occur-engine
  		    (goto-char (point-max)))
  		  (setq prev-line (1- curr-line)))
                  ;; Insert original line if haven't done yet.
-                (unless orig-line-shown-p
+                (when (and (not multi-occur-p)
+                           (not orig-line-shown-p))
                    (with-current-buffer out-buf
                      (insert
                       (concat
-                      (propertize orig-line-str 'face 'query-replace) "\n"))))
+                      (propertize
+                       (format "%7d:%s" orig-line orig-line-str)
+                       'face 'occur-current-line-face
+                       'mouse-face 'mode-line-highlight
+                       'help-echo "Current line") "\n"))))
  		;; Flush remaining context after-lines.
  		(when prev-after-lines
  		  (with-current-buffer out-buf
@@ -1756,8 +1780,11 @@ occur-engine
  		  (setq end (point))
  		  (add-text-properties beg end `(occur-title ,buf))
  		  (when title-face
-		    (add-face-text-property beg end title-face)))
-		(goto-char (point-min)))))))
+		    (add-face-text-property beg end title-face))
+                  (goto-char (if finalpt
+                                 (setq occur--final-pos
+                                       (cl-incf finalpt (- end beg)))
+                               (point-min)))))))))
        ;; Display total match count and regexp for multi-buffer.
        (when (and (not (zerop global-lines)) (> (length buffers) 1))
  	(goto-char (point-min))
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.5)
  of 2017-01-03
Repository revision: 975b2acfe6a4e246631c372063d7bdef0f832d3d



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Region argument (was: [patch] Run occur command restricted to a region)
  2016-12-29 16:10 ` Eli Zaretskii
  2016-12-29 16:54   ` Tino Calancha
@ 2017-01-03 17:37   ` Stefan Monnier
  2017-01-03 18:34     ` Eli Zaretskii
  1 sibling, 1 reply; 39+ messages in thread
From: Stefan Monnier @ 2017-01-03 17:37 UTC (permalink / raw)
  To: emacs-devel

> I think our convention for functions that act on the region is to
> accept BEG and END arguments, so that the function could be called
> from Lisp.

Indeed.

Note also that in order to support rectangular regions (which are
currently poorly supported, but which we'd like to see supported more
generally), we should change/tweak this convention.


        Stefan




^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: Region argument (was: [patch] Run occur command restricted to a region)
  2017-01-03 17:37   ` Region argument (was: [patch] Run occur command restricted to a region) Stefan Monnier
@ 2017-01-03 18:34     ` Eli Zaretskii
  2017-01-03 18:59       ` Region argument Stefan Monnier
  0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2017-01-03 18:34 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Tue, 03 Jan 2017 12:37:20 -0500
> 
> Note also that in order to support rectangular regions (which are
> currently poorly supported, but which we'd like to see supported more
> generally), we should change/tweak this convention.

We could start by having Someone™ "in the know" (hint, hint) describe
the new conventions in the ELisp manual.  Right now, there's nothing
there about rectangular regions.  Nothing at all.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: Region argument
  2017-01-03 18:34     ` Eli Zaretskii
@ 2017-01-03 18:59       ` Stefan Monnier
  2017-01-03 19:19         ` Eli Zaretskii
  2017-01-04  0:57         ` Juri Linkov
  0 siblings, 2 replies; 39+ messages in thread
From: Stefan Monnier @ 2017-01-03 18:59 UTC (permalink / raw)
  To: emacs-devel

> We could start by having Someone™ "in the know" (hint, hint) describe
> the new conventions in the ELisp manual.

I remember we discussed a new convention, but I'm not sure if we did end
up implementing one.


        Stefan




^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: Region argument
  2017-01-03 18:59       ` Region argument Stefan Monnier
@ 2017-01-03 19:19         ` Eli Zaretskii
  2017-01-04  0:57         ` Juri Linkov
  1 sibling, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2017-01-03 19:19 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Tue, 03 Jan 2017 13:59:46 -0500
> 
> > We could start by having Someone™ "in the know" (hint, hint) describe
> > the new conventions in the ELisp manual.
> 
> I remember we discussed a new convention, but I'm not sure if we did end
> up implementing one.

Then what exactly are we talking about here?  If a new convention
doesn't exist, we obviously cannot change the existing convention to a
new one, can we?



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: Region argument
  2017-01-03 18:59       ` Region argument Stefan Monnier
  2017-01-03 19:19         ` Eli Zaretskii
@ 2017-01-04  0:57         ` Juri Linkov
  1 sibling, 0 replies; 39+ messages in thread
From: Juri Linkov @ 2017-01-04  0:57 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>> We could start by having Someone™ "in the know" (hint, hint) describe
>> the new conventions in the ELisp manual.
>
> I remember we discussed a new convention, but I'm not sure if we did end
> up implementing one.

IIRC, the missing piece is just a small function:

  (defun region ()
    (funcall region-extract-function 'bounds))

to provide all info including former region-beginning and region-end
for ordinary regions as well as a list of boundaries in case of
rectangular regions.  Then it could be used in the interactive spec:

  (defun occur (regexp &optional nlines region)
    (interactive
     (nconc (occur-read-primary-args)
            (list (and (use-region-p) (region)))))
    (occur-1 regexp nlines (list (current-buffer))))

Here nconc for occur-read-primary-args complicates the issue a little,
but in the general case what is needed is only

  (interactive (list (and (use-region-p) (region))))



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-03 10:19               ` Tino Calancha
@ 2017-01-18 11:04                 ` Tino Calancha
  2017-01-19 23:51                   ` Juri Linkov
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-01-18 11:04 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha



On Tue, 3 Jan 2017, Tino Calancha wrote:

>> users will like this change in cursor positioning.
> See the updated patch.  Play with it and let me know how you see it.
> In my case, just the first part of the patch, i.e., to run `occur' restricted 
> to the region is all that i need.
Hi Juri,

do you have any preference on the proposed patches?
Regards,
Tino



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-18 11:04                 ` Tino Calancha
@ 2017-01-19 23:51                   ` Juri Linkov
  2017-01-20 13:48                     ` Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Juri Linkov @ 2017-01-19 23:51 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers

>> See the updated patch.  Play with it and let me know how you see it.
>> In my case, just the first part of the patch, i.e., to run `occur'
>> restricted to the region is all that i need.
>
> do you have any preference on the proposed patches?

Please see the thread regarding the region argument:
http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00044.html
i.e. a new convention is to add a single arg ‘region’
instead of the ‘start’/‘end’ pair.

Could you try to update your patch accordingly?



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-19 23:51                   ` Juri Linkov
@ 2017-01-20 13:48                     ` Tino Calancha
  2017-01-20 16:46                       ` Davis Herring
  2017-01-20 23:17                       ` Juri Linkov
  0 siblings, 2 replies; 39+ messages in thread
From: Tino Calancha @ 2017-01-20 13:48 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha

Juri Linkov <juri@linkov.net> writes:

>>> See the updated patch.  Play with it and let me know how you see it.
>>> In my case, just the first part of the patch, i.e., to run `occur'
>>> restricted to the region is all that i need.
>>
>> do you have any preference on the proposed patches?
>
> Please see the thread regarding the region argument:
> http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00044.html
> i.e. a new convention is to add a single arg ‘region’
> instead of the ‘start’/‘end’ pair.
>
> Could you try to update your patch accordingly?
OK.  Updated the patch.
*)  First patch allow `occur' handle the region with the new convention,
    i.e., region argument instead of BEG, END.
**) The second patch add your suggestion on showing highlighted the
    current line.  When there are matches after the current line, the
    point in *Occur* is set right after such line.

I am fine with just adding *).  In case we also want **), 
an option to enable/disable that behaviour might be desirable.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 5d69affd729ceed80de9f1ede37a5c7a541b23d4 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Fri, 20 Jan 2017 22:11:11 +0900
Subject: [PATCH 1/2] Allow occur command to operate on the region

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/simple.el (region): New defun.
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional arg REGION; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search: Idem.
; etc/NEWS: Add entry to announce the change.
---
 doc/emacs/search.texi               |  3 +++
 doc/lispintro/emacs-lisp-intro.texi |  8 ++++---
 etc/NEWS                            |  2 ++
 lisp/replace.el                     | 46 +++++++++++++++++++++++++++++++------
 lisp/simple.el                      |  3 +++
 5 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index b728258973..28e25bec43 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1672,6 +1672,9 @@ Other Repeating Search
 no upper-case letters and @code{case-fold-search} is non-@code{nil}.
 Aside from @code{occur} and its variants, all operate on the text from
 point to the end of the buffer, or on the region if it is active.
+The command @code{occur} will operate on the region if
+it is active as well; when the region is not active, @code{occur}
+operates in the whole buffer.
 
 @findex list-matching-lines
 @findex occur
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 830c072cf5..36d767737d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -17151,9 +17151,11 @@ Keybindings
 
 @findex occur
 The @code{occur} command shows all the lines in the current buffer
-that contain a match for a regular expression.  Matching lines are
-shown in a buffer called @file{*Occur*}.  That buffer serves as a menu
-to jump to occurrences.
+that contain a match for a regular expression.  When the region is
+active, @code{occur} restricts matches to such region.  Otherwise it
+uses the entire buffer.
+Matching lines are shown in a buffer called @file{*Occur*}.
+That buffer serves as a menu to jump to occurrences.
 
 @findex global-unset-key
 @cindex Unbinding key
diff --git a/etc/NEWS b/etc/NEWS
index 051b97e146..d4917f402f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -301,6 +301,8 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
 \f
 * Editing Changes in Emacs 26.1
 
+
+** The 'occur' command can now operate on the region.
 +++
 ** New bindings for 'query-replace-map'.
 'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/replace.el b/lisp/replace.el
index ff91734445..d9c3a4ff3e 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1360,7 +1360,12 @@ occur-rename-buffer
                            "*")
                    (or unique-p (not interactive-p)))))
 
-(defun occur (regexp &optional nlines)
+;; Region limits when `occur' applies on a region.
+(defvar occur--region-start nil)
+(defvar occur--region-end nil)
+(defvar occur--matches-threshold nil)
+
+(defun occur (regexp &optional nlines region)
   "Show all lines in the current buffer containing a match for REGEXP.
 If a match spreads across multiple lines, all those lines are shown.
 
@@ -1369,6 +1374,10 @@ occur
 NLINES defaults to `list-matching-lines-default-context-lines'.
 Interactively it is the prefix arg.
 
+Optional arg REGION, if non-nil, mean restrict search to the
+specified region.  Otherwise search the entire buffer.
+When REGION is non-nil, it must be a cons (START . END).
+
 The lines are shown in a buffer named `*Occur*'.
 It serves as a menu to find any of the occurrences in this buffer.
 \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
@@ -1386,8 +1395,24 @@ occur
 program.  When there is no parenthesized subexpressions in REGEXP
 the entire match is collected.  In any case the searched buffer
 is not modified."
-  (interactive (occur-read-primary-args))
-  (occur-1 regexp nlines (list (current-buffer))))
+  (interactive
+   (nconc (occur-read-primary-args)
+          (and (use-region-p) (region))))
+  (let* ((start (car region))
+         (end (cdr region))
+         (in-region-p (or start end)))
+    (when in-region-p
+      (or start (setq start (point-min)))
+      (or end (setq end (point-max))))
+    (let ((occur--region-start start)
+          (occur--region-end end)
+          (occur--matches-threshold
+           (and in-region-p
+                (line-number-at-pos (min start end)))))
+      (save-excursion ; If no matches `occur-1' doesn't restore the point.
+        (and in-region-p (narrow-to-region start end))
+        (occur-1 regexp nlines (list (current-buffer)))
+        (and in-region-p (widen))))))
 
 (defvar ido-ignore-item-temp-list)
 
@@ -1545,13 +1570,15 @@ occur-engine
     (let ((global-lines 0)    ;; total count of matching lines
 	  (global-matches 0)  ;; total count of matches
 	  (coding nil)
-	  (case-fold-search case-fold))
+	  (case-fold-search case-fold)
+          (in-region-p (and occur--region-start occur--region-end)))
       ;; Map over all the buffers
       (dolist (buf buffers)
 	(when (buffer-live-p buf)
 	  (let ((lines 0)               ;; count of matching lines
 		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur--matches-threshold 1))
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
@@ -1684,7 +1711,7 @@ occur-engine
 		(let ((beg (point))
 		      end)
 		  (insert (propertize
-			   (format "%d match%s%s%s in buffer: %s\n"
+			   (format "%d match%s%s%s in buffer: %s%s\n"
 				   matches (if (= matches 1) "" "es")
 				   ;; Don't display the same number of lines
 				   ;; and matches in case of 1 match per line.
@@ -1694,7 +1721,12 @@ occur-engine
 				   ;; Don't display regexp for multi-buffer.
 				   (if (> (length buffers) 1)
 				       "" (occur-regexp-descr regexp))
-				   (buffer-name buf))
+				   (buffer-name buf)
+                                   (if in-region-p
+                                       (format " within region: %d-%d"
+                                               occur--region-start
+                                               occur--region-end)
+                                     ""))
 			   'read-only t))
 		  (setq end (point))
 		  (add-text-properties beg end `(occur-title ,buf))
diff --git a/lisp/simple.el b/lisp/simple.el
index f798cd4384..56c4551490 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1015,6 +1015,9 @@ region-extract-function
 If anything else, delete the region and return its content as a string,
 after filtering it with `filter-buffer-substring'.")
 
+(defun region ()
+  (funcall region-extract-function 'bounds))
+
 (defvar region-insert-function
   (lambda (lines)
     (let ((first t))
-- 
2.11.0

From 763ca506fed54afacc30ca1904f0727bf0bf2dbf Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Fri, 20 Jan 2017 22:14:39 +0900
Subject: [PATCH 2/2] Show current line highlighted in *Occur* buffer

* lisp/replace.el (occur--orig-line, occur--orig-line-str): New variables.
(occur, occur-engine): Use them.
(occur--final-pos): New variable.
(occur-1): Use it.
(occur-engine): Idem.
Show the current line with 'occur-current-line-face'.
Set point on the first matching line after the current one.
---
 lisp/replace.el | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 5 deletions(-)

diff --git a/lisp/replace.el b/lisp/replace.el
index d9c3a4ff3e..ed5cdb718b 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1081,6 +1081,12 @@ occur-mode-find-occurrence-hook
   :type 'hook
   :group 'matching)
 
+(defface occur-current-line-face
+  '((t (:inherit lazy-highlight)))
+  "Face for highlighting the current line in *Occur* buffer."
+  :group 'matching
+  :version "26.1")
+
 (put 'occur-mode 'mode-class 'special)
 (define-derived-mode occur-mode special-mode "Occur"
   "Major mode for output from \\[occur].
@@ -1364,6 +1370,9 @@ occur-rename-buffer
 (defvar occur--region-start nil)
 (defvar occur--region-end nil)
 (defvar occur--matches-threshold nil)
+(defvar occur--orig-line nil)
+(defvar occur--orig-line-str nil)
+(defvar occur--final-pos nil)
 
 (defun occur (regexp &optional nlines region)
   "Show all lines in the current buffer containing a match for REGEXP.
@@ -1408,7 +1417,13 @@ occur
           (occur--region-end end)
           (occur--matches-threshold
            (and in-region-p
-                (line-number-at-pos (min start end)))))
+                (line-number-at-pos (min start end))))
+          (occur--orig-line
+           (line-number-at-pos (point)))
+          (occur--orig-line-str
+           (buffer-substring-no-properties
+            (line-beginning-position)
+            (line-end-position))))
       (save-excursion ; If no matches `occur-1' doesn't restore the point.
         (and in-region-p (narrow-to-region start end))
         (occur-1 regexp nlines (list (current-buffer)))
@@ -1507,7 +1522,8 @@ occur-1
 	(occur-mode))
       (let ((inhibit-read-only t)
 	    ;; Don't generate undo entries for creation of the initial contents.
-	    (buffer-undo-list t))
+	    (buffer-undo-list t)
+            (occur--final-pos nil))
 	(erase-buffer)
 	(let ((count
 	       (if (stringp nlines)
@@ -1559,6 +1575,10 @@ occur-1
           (if (= count 0)
               (kill-buffer occur-buf)
             (display-buffer occur-buf)
+            (when occur--final-pos
+              (set-window-point
+               (get-buffer-window occur-buf 'all-frames)
+               occur--final-pos))
             (setq next-error-last-buffer occur-buf)
             (setq buffer-read-only t)
             (set-buffer-modified-p nil)
@@ -1571,7 +1591,8 @@ occur-engine
 	  (global-matches 0)  ;; total count of matches
 	  (coding nil)
 	  (case-fold-search case-fold)
-          (in-region-p (and occur--region-start occur--region-end)))
+          (in-region-p (and occur--region-start occur--region-end))
+          (multi-occur-p (cdr buffers)))
       ;; Map over all the buffers
       (dolist (buf buffers)
 	(when (buffer-live-p buf)
@@ -1579,12 +1600,16 @@ occur-engine
 		(matches 0)             ;; count of matches
 		(curr-line              ;; line count
                  (or occur--matches-threshold 1))
+                (orig-line occur--orig-line)
+                (orig-line-str occur--orig-line-str)
+                (orig-line-shown-p)
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
 		(origpt nil)
 		(begpt nil)
 		(endpt nil)
+                (finalpt nil)
 		(marker nil)
 		(curstring "")
 		(ret nil)
@@ -1685,6 +1710,17 @@ occur-engine
 			      (nth 0 ret))))
 		      ;; Actually insert the match display data
 		      (with-current-buffer out-buf
+                        (when (and (not multi-occur-p)
+                                   (not orig-line-shown-p)
+                                   (>= curr-line orig-line))
+                          (insert
+                           (concat
+                            (propertize
+                             (format "%7d:%s" orig-line orig-line-str)
+                             'face 'occur-current-line-face
+                             'mouse-face 'mode-line-highlight
+                             'help-echo "Current line") "\n"))
+                          (setq orig-line-shown-p t finalpt (point)))
 			(insert data)))
 		    (goto-char endpt))
 		  (if endpt
@@ -1698,6 +1734,17 @@ occur-engine
 			(forward-line 1))
 		    (goto-char (point-max)))
 		  (setq prev-line (1- curr-line)))
+                ;; Insert original line if haven't done yet.
+                (when (and (not multi-occur-p)
+                           (not orig-line-shown-p))
+                  (with-current-buffer out-buf
+                    (insert
+                     (concat
+                      (propertize
+                       (format "%7d:%s" orig-line orig-line-str)
+                       'face 'occur-current-line-face
+                       'mouse-face 'mode-line-highlight
+                       'help-echo "Current line") "\n"))))
 		;; Flush remaining context after-lines.
 		(when prev-after-lines
 		  (with-current-buffer out-buf
@@ -1731,8 +1778,11 @@ occur-engine
 		  (setq end (point))
 		  (add-text-properties beg end `(occur-title ,buf))
 		  (when title-face
-		    (add-face-text-property beg end title-face)))
-		(goto-char (point-min)))))))
+		    (add-face-text-property beg end title-face))
+                  (goto-char (if finalpt
+                                 (setq occur--final-pos
+                                       (cl-incf finalpt (- end beg)))
+                               (point-min)))))))))
       ;; Display total match count and regexp for multi-buffer.
       (when (and (not (zerop global-lines)) (> (length buffers) 1))
 	(goto-char (point-min))
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
 of 2017-01-20
Repository revision: 82a5e4dc889ecbfa35374616fe9c5edfa23f4504



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-20 13:48                     ` Tino Calancha
@ 2017-01-20 16:46                       ` Davis Herring
  2017-01-20 23:17                       ` Juri Linkov
  1 sibling, 0 replies; 39+ messages in thread
From: Davis Herring @ 2017-01-20 16:46 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers, Juri Linkov

> **) The second patch add your suggestion on showing highlighted the
>     current line.  When there are matches after the current line, the
>     point in *Occur* is set right after such line.

I don't care about the highlighting, but I like very much the idea of 
locating point in *Occur* at the place that corresponds to point in the 
source buffer.  It provides for free most of the benefit of 
`occur-above' and `occur-below' (by whatever names) by partitioning the 
results in an intuitive fashion.

(It's also the same idea as in my vc-diff patch (which I still need to 
finish): to show a map of interesting things in the buffer centered on 
point.)

Davis

-- 
This product is sold by volume, not by mass.  If it appears too dense or 
too sparse, it is because mass-energy conversion has occurred during 
shipping.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-20 13:48                     ` Tino Calancha
  2017-01-20 16:46                       ` Davis Herring
@ 2017-01-20 23:17                       ` Juri Linkov
  2017-01-22 10:32                         ` Tino Calancha
  1 sibling, 1 reply; 39+ messages in thread
From: Juri Linkov @ 2017-01-20 23:17 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers

> OK.  Updated the patch.
> *)  First patch allow `occur' handle the region with the new convention,
>     i.e., region argument instead of BEG, END.

Thanks.  As a prerequisite I'm going to install this patch:

diff --git a/lisp/simple.el b/lisp/simple.el
index 3d25ec1..610846b 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1015,6 +1015,9 @@ (defvar region-extract-function
 If anything else, delete the region and return its content as a string,
 after filtering it with `filter-buffer-substring'.")
 
+(defun region-bounds ()
+  "Return the boundaries of the region as a list of (START . END) positions."
+  (funcall region-extract-function 'bounds))
+
 (defvar region-insert-function
   (lambda (lines)
     (let ((first t))

> **) The second patch add your suggestion on showing highlighted the
>     current line.  When there are matches after the current line, the
>     point in *Occur* is set right after such line.
>
> I am fine with just adding *).  In case we also want **),
> an option to enable/disable that behaviour might be desirable.

Keeping traditional behaviour means not jumping to the middle of the
*Occur* output by default.  Then maybe we could use the same option
to highlight the current line and to jump to it?  Like the existing
‘list-matching-lines-buffer-name-face’, adding a nil/face choice for
‘list-matching-lines-current-line-face’, so when it's nil then don't
highlight/jump?



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-20 23:17                       ` Juri Linkov
@ 2017-01-22 10:32                         ` Tino Calancha
  2017-01-22 23:50                           ` Juri Linkov
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-01-22 10:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha

Juri Linkov <juri@linkov.net> writes:

>> OK.  Updated the patch.
>> *)  First patch allow `occur' handle the region with the new convention,
>>     i.e., region argument instead of BEG, END.
>
> Thanks.  As a prerequisite I'm going to install this patch:
> +(defun region-bounds ()
> +  "Return the boundaries of the region as a list of (START . END) positions."
> +  (funcall region-extract-function 'bounds))
> +
>  (defvar region-insert-function
>    (lambda (lines)
>      (let ((first t))
Thank you.
>> **) The second patch add your suggestion on showing highlighted the
>>     current line.  When there are matches after the current line, the
>>     point in *Occur* is set right after such line.
>>
>> I am fine with just adding *).  In case we also want **),
>> an option to enable/disable that behaviour might be desirable.
>
> Keeping traditional behaviour means not jumping to the middle of the
> *Occur* output by default.  Then maybe we could use the same option
> to highlight the current line and to jump to it?  Like the existing
> ‘list-matching-lines-buffer-name-face’, adding a nil/face choice for
> ‘list-matching-lines-current-line-face’, so when it's nil then don't
> highlight/jump?
OK, why not?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From c9a6891187de8c4df6294777ea745810d405b07a Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 22 Jan 2017 19:12:35 +0900
Subject: [PATCH 1/2] Allow occur command to operate on the region

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional arg REGION; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search: Idem.
; etc/NEWS: Add entry to announce the change.
---
 doc/emacs/search.texi               |  3 +++
 doc/lispintro/emacs-lisp-intro.texi |  8 ++++---
 etc/NEWS                            |  2 ++
 lisp/replace.el                     | 46 +++++++++++++++++++++++++++++++------
 4 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index b728258973..28e25bec43 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1672,6 +1672,9 @@ Other Repeating Search
 no upper-case letters and @code{case-fold-search} is non-@code{nil}.
 Aside from @code{occur} and its variants, all operate on the text from
 point to the end of the buffer, or on the region if it is active.
+The command @code{occur} will operate on the region if
+it is active as well; when the region is not active, @code{occur}
+operates in the whole buffer.
 
 @findex list-matching-lines
 @findex occur
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 830c072cf5..36d767737d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -17151,9 +17151,11 @@ Keybindings
 
 @findex occur
 The @code{occur} command shows all the lines in the current buffer
-that contain a match for a regular expression.  Matching lines are
-shown in a buffer called @file{*Occur*}.  That buffer serves as a menu
-to jump to occurrences.
+that contain a match for a regular expression.  When the region is
+active, @code{occur} restricts matches to such region.  Otherwise it
+uses the entire buffer.
+Matching lines are shown in a buffer called @file{*Occur*}.
+That buffer serves as a menu to jump to occurrences.
 
 @findex global-unset-key
 @cindex Unbinding key
diff --git a/etc/NEWS b/etc/NEWS
index ca66df6261..9eb5d82099 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -310,6 +310,8 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
 \f
 * Editing Changes in Emacs 26.1
 
+
+** The 'occur' command can now operate on the region.
 +++
 ** New bindings for 'query-replace-map'.
 'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/replace.el b/lisp/replace.el
index ff91734445..00e73157ff 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1360,7 +1360,12 @@ occur-rename-buffer
                            "*")
                    (or unique-p (not interactive-p)))))
 
-(defun occur (regexp &optional nlines)
+;; Region limits when `occur' applies on a region.
+(defvar occur--region-start nil)
+(defvar occur--region-end nil)
+(defvar occur--matches-threshold nil)
+
+(defun occur (regexp &optional nlines region)
   "Show all lines in the current buffer containing a match for REGEXP.
 If a match spreads across multiple lines, all those lines are shown.
 
@@ -1369,6 +1374,10 @@ occur
 NLINES defaults to `list-matching-lines-default-context-lines'.
 Interactively it is the prefix arg.
 
+Optional arg REGION, if non-nil, mean restrict search to the
+specified region.  Otherwise search the entire buffer.
+When REGION is non-nil, it must be a cons (START . END).
+
 The lines are shown in a buffer named `*Occur*'.
 It serves as a menu to find any of the occurrences in this buffer.
 \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
@@ -1386,8 +1395,24 @@ occur
 program.  When there is no parenthesized subexpressions in REGEXP
 the entire match is collected.  In any case the searched buffer
 is not modified."
-  (interactive (occur-read-primary-args))
-  (occur-1 regexp nlines (list (current-buffer))))
+  (interactive
+   (nconc (occur-read-primary-args)
+          (and (use-region-p) (region-bounds))))
+  (let* ((start (car region))
+         (end (cdr region))
+         (in-region-p (or start end)))
+    (when in-region-p
+      (or start (setq start (point-min)))
+      (or end (setq end (point-max))))
+    (let ((occur--region-start start)
+          (occur--region-end end)
+          (occur--matches-threshold
+           (and in-region-p
+                (line-number-at-pos (min start end)))))
+      (save-excursion ; If no matches `occur-1' doesn't restore the point.
+        (and in-region-p (narrow-to-region start end))
+        (occur-1 regexp nlines (list (current-buffer)))
+        (and in-region-p (widen))))))
 
 (defvar ido-ignore-item-temp-list)
 
@@ -1545,13 +1570,15 @@ occur-engine
     (let ((global-lines 0)    ;; total count of matching lines
 	  (global-matches 0)  ;; total count of matches
 	  (coding nil)
-	  (case-fold-search case-fold))
+	  (case-fold-search case-fold)
+          (in-region-p (and occur--region-start occur--region-end)))
       ;; Map over all the buffers
       (dolist (buf buffers)
 	(when (buffer-live-p buf)
 	  (let ((lines 0)               ;; count of matching lines
 		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur--matches-threshold 1))
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
@@ -1684,7 +1711,7 @@ occur-engine
 		(let ((beg (point))
 		      end)
 		  (insert (propertize
-			   (format "%d match%s%s%s in buffer: %s\n"
+			   (format "%d match%s%s%s in buffer: %s%s\n"
 				   matches (if (= matches 1) "" "es")
 				   ;; Don't display the same number of lines
 				   ;; and matches in case of 1 match per line.
@@ -1694,7 +1721,12 @@ occur-engine
 				   ;; Don't display regexp for multi-buffer.
 				   (if (> (length buffers) 1)
 				       "" (occur-regexp-descr regexp))
-				   (buffer-name buf))
+				   (buffer-name buf)
+                                   (if in-region-p
+                                       (format " within region: %d-%d"
+                                               occur--region-start
+                                               occur--region-end)
+                                     ""))
 			   'read-only t))
 		  (setq end (point))
 		  (add-text-properties beg end `(occur-title ,buf))
-- 
2.11.0

From 31b578636731c0a67dc64aad8d880d82d7c8804d Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 22 Jan 2017 19:25:34 +0900
Subject: [PATCH 2/2] Show current line highlighted in *Occur* buffer

* lisp/replace.el (occur-current-line-face): New face.
(list-matching-lines-current-line-face): New user option.
(occur--orig-line, occur--orig-line-str): New variables.
(occur, occur-engine): Use them.
(occur--final-pos): New variable.
(occur-1): Use it.
(occur-engine): Idem.
Show the current line with 'occur-current-line-face'.
Set point on the first matching line after the current one.
* etc/NEWS: Add entry for the new option.
---
 etc/NEWS        |  3 +++
 lisp/replace.el | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 9eb5d82099..ff8246506d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -311,6 +311,9 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
 * Editing Changes in Emacs 26.1
 
 
+** A new user option 'list-matching-lines-current-line-face'
+to show highlighted the current line in the *Occur* buffer.
+
 ** The 'occur' command can now operate on the region.
 +++
 ** New bindings for 'query-replace-map'.
diff --git a/lisp/replace.el b/lisp/replace.el
index 00e73157ff..3de09b48cc 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1081,6 +1081,12 @@ occur-mode-find-occurrence-hook
   :type 'hook
   :group 'matching)
 
+(defface occur-current-line-face
+  '((t (:inherit lazy-highlight)))
+  "Face for highlighting the current line in *Occur* buffer."
+  :group 'matching
+  :version "26.1")
+
 (put 'occur-mode 'mode-class 'special)
 (define-derived-mode occur-mode special-mode "Occur"
   "Major mode for output from \\[occur].
@@ -1304,6 +1310,13 @@ list-matching-lines-buffer-name-face
   :type 'face
   :group 'matching)
 
+(defcustom list-matching-lines-current-line-face nil
+  "If non-nil, \\[list-matching-lines] shows the current line highlighted.
+Set the point right after such line when there are matches after it."
+  :type '(choice (const :tag "Unset" nil)
+                 (const :tag "highlight current line" occur-current-line-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,
@@ -1364,6 +1377,9 @@ occur-rename-buffer
 (defvar occur--region-start nil)
 (defvar occur--region-end nil)
 (defvar occur--matches-threshold nil)
+(defvar occur--orig-line nil)
+(defvar occur--orig-line-str nil)
+(defvar occur--final-pos nil)
 
 (defun occur (regexp &optional nlines region)
   "Show all lines in the current buffer containing a match for REGEXP.
@@ -1381,6 +1397,9 @@ occur
 The lines are shown in a buffer named `*Occur*'.
 It serves as a menu to find any of the occurrences in this buffer.
 \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
+If `list-matching-lines-current-line-face' is non-nil, then show highlighted
+the current line; if there are matches after it, then set the
+point right after such line.
 
 If REGEXP contains upper case characters (excluding those preceded by `\\')
 and `search-upper-case' is non-nil, the matching is case-sensitive.
@@ -1408,7 +1427,13 @@ occur
           (occur--region-end end)
           (occur--matches-threshold
            (and in-region-p
-                (line-number-at-pos (min start end)))))
+                (line-number-at-pos (min start end))))
+          (occur--orig-line
+           (line-number-at-pos (point)))
+          (occur--orig-line-str
+           (buffer-substring-no-properties
+            (line-beginning-position)
+            (line-end-position))))
       (save-excursion ; If no matches `occur-1' doesn't restore the point.
         (and in-region-p (narrow-to-region start end))
         (occur-1 regexp nlines (list (current-buffer)))
@@ -1507,7 +1532,8 @@ occur-1
 	(occur-mode))
       (let ((inhibit-read-only t)
 	    ;; Don't generate undo entries for creation of the initial contents.
-	    (buffer-undo-list t))
+	    (buffer-undo-list t)
+            (occur--final-pos nil))
 	(erase-buffer)
 	(let ((count
 	       (if (stringp nlines)
@@ -1559,6 +1585,10 @@ occur-1
           (if (= count 0)
               (kill-buffer occur-buf)
             (display-buffer occur-buf)
+            (when occur--final-pos
+              (set-window-point
+               (get-buffer-window occur-buf 'all-frames)
+               occur--final-pos))
             (setq next-error-last-buffer occur-buf)
             (setq buffer-read-only t)
             (set-buffer-modified-p nil)
@@ -1571,7 +1601,8 @@ occur-engine
 	  (global-matches 0)  ;; total count of matches
 	  (coding nil)
 	  (case-fold-search case-fold)
-          (in-region-p (and occur--region-start occur--region-end)))
+          (in-region-p (and occur--region-start occur--region-end))
+          (multi-occur-p (cdr buffers)))
       ;; Map over all the buffers
       (dolist (buf buffers)
 	(when (buffer-live-p buf)
@@ -1579,12 +1610,16 @@ occur-engine
 		(matches 0)             ;; count of matches
 		(curr-line              ;; line count
                  (or occur--matches-threshold 1))
+                (orig-line occur--orig-line)
+                (orig-line-str occur--orig-line-str)
+                (orig-line-shown-p)
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
 		(origpt nil)
 		(begpt nil)
 		(endpt nil)
+                (finalpt nil)
 		(marker nil)
 		(curstring "")
 		(ret nil)
@@ -1685,6 +1720,18 @@ occur-engine
 			      (nth 0 ret))))
 		      ;; Actually insert the match display data
 		      (with-current-buffer out-buf
+                        (when (and list-matching-lines-current-line-face
+                                   (not multi-occur-p)
+                                   (not orig-line-shown-p)
+                                   (>= curr-line orig-line))
+                          (insert
+                           (concat
+                            (propertize
+                             (format "%7d:%s" orig-line orig-line-str)
+                             'face 'occur-current-line-face
+                             'mouse-face 'mode-line-highlight
+                             'help-echo "Current line") "\n"))
+                          (setq orig-line-shown-p t finalpt (point)))
 			(insert data)))
 		    (goto-char endpt))
 		  (if endpt
@@ -1698,6 +1745,18 @@ occur-engine
 			(forward-line 1))
 		    (goto-char (point-max)))
 		  (setq prev-line (1- curr-line)))
+                ;; Insert original line if haven't done yet.
+                (when (and list-matching-lines-current-line-face
+                           (not multi-occur-p)
+                           (not orig-line-shown-p))
+                  (with-current-buffer out-buf
+                    (insert
+                     (concat
+                      (propertize
+                       (format "%7d:%s" orig-line orig-line-str)
+                       'face 'occur-current-line-face
+                       'mouse-face 'mode-line-highlight
+                       'help-echo "Current line") "\n"))))
 		;; Flush remaining context after-lines.
 		(when prev-after-lines
 		  (with-current-buffer out-buf
@@ -1731,8 +1790,11 @@ occur-engine
 		  (setq end (point))
 		  (add-text-properties beg end `(occur-title ,buf))
 		  (when title-face
-		    (add-face-text-property beg end title-face)))
-		(goto-char (point-min)))))))
+		    (add-face-text-property beg end title-face))
+                  (goto-char (if finalpt
+                                 (setq occur--final-pos
+                                       (cl-incf finalpt (- end beg)))
+                               (point-min)))))))))
       ;; Display total match count and regexp for multi-buffer.
       (when (and (not (zerop global-lines)) (> (length buffers) 1))
 	(goto-char (point-min))
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
 of 2017-01-22
Repository revision: 0a49f158f1598fb92989f3cbdc238a7e5f1bd8a3



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-22 10:32                         ` Tino Calancha
@ 2017-01-22 23:50                           ` Juri Linkov
  2017-01-23  7:32                             ` Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Juri Linkov @ 2017-01-22 23:50 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers

>>> **) The second patch add your suggestion on showing highlighted the
>>>     current line.  When there are matches after the current line, the
>>>     point in *Occur* is set right after such line.
>>>
>>> I am fine with just adding *).  In case we also want **),
>>> an option to enable/disable that behaviour might be desirable.
>>
>> Keeping traditional behaviour means not jumping to the middle of the
>> *Occur* output by default.  Then maybe we could use the same option
>> to highlight the current line and to jump to it?  Like the existing
>> ‘list-matching-lines-buffer-name-face’, adding a nil/face choice for
>> ‘list-matching-lines-current-line-face’, so when it's nil then don't
>> highlight/jump?
> OK, why not?

Thanks.

> +(defface occur-current-line-face
> +  '((t (:inherit lazy-highlight)))
> +  "Face for highlighting the current line in *Occur* buffer."

I'm not sure about the new face ‘occur-current-line-face’.
Looking at the list of faces from ‘M-x list-faces-display’, there are
no other occur faces.  It would be confusing for the users to see
a single occur-related face in this list, whereas all other occur-related
faces are customized by ‘list-matching-lines-*’ variables only.

For consistency with other occur faces, maybe better to have a variable

(defcustom list-matching-lines-current-line-face 'lazy-highlight

and another boolean customizable variable list-matching-lines-jump-to-current-line
to enable locating the current line.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-22 23:50                           ` Juri Linkov
@ 2017-01-23  7:32                             ` Tino Calancha
       [not found]                               ` <87lgtu4w5c.fsf@mail.linkov.net>
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-01-23  7:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha

Juri Linkov <juri@linkov.net> writes:

>> +(defface occur-current-line-face
>> +  '((t (:inherit lazy-highlight)))
>> +  "Face for highlighting the current line in *Occur* buffer."
>
> I'm not sure about the new face ‘occur-current-line-face’.
> Looking at the list of faces from ‘M-x list-faces-display’, there are
> no other occur faces.  It would be confusing for the users to see
> a single occur-related face in this list, whereas all other occur-related
> faces are customized by ‘list-matching-lines-*’ variables only.
>
> For consistency with other occur faces, maybe better to have a variable
>
> (defcustom list-matching-lines-current-line-face 'lazy-highlight
>
> and another boolean customizable variable list-matching-lines-jump-to-current-line
> to enable locating the current line.
Thank you.  Implemented in the new patch below:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 56d13fa11b01260d9088d820a5cf6cd04d042848 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Mon, 23 Jan 2017 16:26:22 +0900
Subject: [PATCH 1/2] Allow occur command to operate on the region

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional arg REGION; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search: Idem.
; etc/NEWS: Add entry to announce the change.
---
 doc/emacs/search.texi               |  3 +++
 doc/lispintro/emacs-lisp-intro.texi |  8 ++++---
 etc/NEWS                            |  2 ++
 lisp/replace.el                     | 46 +++++++++++++++++++++++++++++++------
 4 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index b728258973..28e25bec43 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1672,6 +1672,9 @@ Other Repeating Search
 no upper-case letters and @code{case-fold-search} is non-@code{nil}.
 Aside from @code{occur} and its variants, all operate on the text from
 point to the end of the buffer, or on the region if it is active.
+The command @code{occur} will operate on the region if
+it is active as well; when the region is not active, @code{occur}
+operates in the whole buffer.
 
 @findex list-matching-lines
 @findex occur
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 830c072cf5..36d767737d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -17151,9 +17151,11 @@ Keybindings
 
 @findex occur
 The @code{occur} command shows all the lines in the current buffer
-that contain a match for a regular expression.  Matching lines are
-shown in a buffer called @file{*Occur*}.  That buffer serves as a menu
-to jump to occurrences.
+that contain a match for a regular expression.  When the region is
+active, @code{occur} restricts matches to such region.  Otherwise it
+uses the entire buffer.
+Matching lines are shown in a buffer called @file{*Occur*}.
+That buffer serves as a menu to jump to occurrences.
 
 @findex global-unset-key
 @cindex Unbinding key
diff --git a/etc/NEWS b/etc/NEWS
index ca66df6261..9eb5d82099 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -310,6 +310,8 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
 \f
 * Editing Changes in Emacs 26.1
 
+
+** The 'occur' command can now operate on the region.
 +++
 ** New bindings for 'query-replace-map'.
 'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/replace.el b/lisp/replace.el
index ff91734445..00e73157ff 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1360,7 +1360,12 @@ occur-rename-buffer
                            "*")
                    (or unique-p (not interactive-p)))))
 
-(defun occur (regexp &optional nlines)
+;; Region limits when `occur' applies on a region.
+(defvar occur--region-start nil)
+(defvar occur--region-end nil)
+(defvar occur--matches-threshold nil)
+
+(defun occur (regexp &optional nlines region)
   "Show all lines in the current buffer containing a match for REGEXP.
 If a match spreads across multiple lines, all those lines are shown.
 
@@ -1369,6 +1374,10 @@ occur
 NLINES defaults to `list-matching-lines-default-context-lines'.
 Interactively it is the prefix arg.
 
+Optional arg REGION, if non-nil, mean restrict search to the
+specified region.  Otherwise search the entire buffer.
+When REGION is non-nil, it must be a cons (START . END).
+
 The lines are shown in a buffer named `*Occur*'.
 It serves as a menu to find any of the occurrences in this buffer.
 \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
@@ -1386,8 +1395,24 @@ occur
 program.  When there is no parenthesized subexpressions in REGEXP
 the entire match is collected.  In any case the searched buffer
 is not modified."
-  (interactive (occur-read-primary-args))
-  (occur-1 regexp nlines (list (current-buffer))))
+  (interactive
+   (nconc (occur-read-primary-args)
+          (and (use-region-p) (region-bounds))))
+  (let* ((start (car region))
+         (end (cdr region))
+         (in-region-p (or start end)))
+    (when in-region-p
+      (or start (setq start (point-min)))
+      (or end (setq end (point-max))))
+    (let ((occur--region-start start)
+          (occur--region-end end)
+          (occur--matches-threshold
+           (and in-region-p
+                (line-number-at-pos (min start end)))))
+      (save-excursion ; If no matches `occur-1' doesn't restore the point.
+        (and in-region-p (narrow-to-region start end))
+        (occur-1 regexp nlines (list (current-buffer)))
+        (and in-region-p (widen))))))
 
 (defvar ido-ignore-item-temp-list)
 
@@ -1545,13 +1570,15 @@ occur-engine
     (let ((global-lines 0)    ;; total count of matching lines
 	  (global-matches 0)  ;; total count of matches
 	  (coding nil)
-	  (case-fold-search case-fold))
+	  (case-fold-search case-fold)
+          (in-region-p (and occur--region-start occur--region-end)))
       ;; Map over all the buffers
       (dolist (buf buffers)
 	(when (buffer-live-p buf)
 	  (let ((lines 0)               ;; count of matching lines
 		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur--matches-threshold 1))
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
@@ -1684,7 +1711,7 @@ occur-engine
 		(let ((beg (point))
 		      end)
 		  (insert (propertize
-			   (format "%d match%s%s%s in buffer: %s\n"
+			   (format "%d match%s%s%s in buffer: %s%s\n"
 				   matches (if (= matches 1) "" "es")
 				   ;; Don't display the same number of lines
 				   ;; and matches in case of 1 match per line.
@@ -1694,7 +1721,12 @@ occur-engine
 				   ;; Don't display regexp for multi-buffer.
 				   (if (> (length buffers) 1)
 				       "" (occur-regexp-descr regexp))
-				   (buffer-name buf))
+				   (buffer-name buf)
+                                   (if in-region-p
+                                       (format " within region: %d-%d"
+                                               occur--region-start
+                                               occur--region-end)
+                                     ""))
 			   'read-only t))
 		  (setq end (point))
 		  (add-text-properties beg end `(occur-title ,buf))
-- 
2.11.0

From 417ad35f210d74231a3529fcc44cb8f77127fb86 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Mon, 23 Jan 2017 16:26:35 +0900
Subject: [PATCH 2/2] Show current line highlighted in *Occur* buffer

* lisp/replace.el (list-matching-lines-current-line-face)
(list-matching-lines-jump-to-current-line): New user options.
(occur--orig-line, occur--orig-line-str): New variables.
(occur, occur-engine): Use them.
(occur--final-pos): New variable.
(occur-1): Use it.
(occur-engine): Idem.
Show the current line with 'list-matching-lines-current-line-face'.
Set point on the first matching line after the current one.
* etc/NEWS: Add entry for the new option.
---
 etc/NEWS        |  4 ++++
 lisp/replace.el | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 9eb5d82099..9b74ce16ed 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -311,6 +311,10 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
 * Editing Changes in Emacs 26.1
 
 
+** Two new user options 'list-matching-lines-jump-to-current-line' and
+'list-matching-lines-current-line-face' to show highlighted the current line
+in the *Occur* buffer.
+
 ** The 'occur' command can now operate on the region.
 +++
 ** New bindings for 'query-replace-map'.
diff --git a/lisp/replace.el b/lisp/replace.el
index 00e73157ff..1a80dc16c6 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1304,6 +1304,19 @@ list-matching-lines-buffer-name-face
   :type 'face
   :group 'matching)
 
+(defcustom list-matching-lines-current-line-face 'lazy-highlight
+  "Face used by \\[list-matching-lines] to highlight the current line."
+  :type 'face
+  :group 'matching
+  :version "26.1")
+
+(defcustom list-matching-lines-jump-to-current-line nil
+  "If non-nil, \\[list-matching-lines] shows the current line highlighted.
+Set the point right after such line when there are matches after it."
+:type 'boolean
+:group 'matching
+:version "26.1")
+
 (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,
@@ -1364,6 +1377,9 @@ occur-rename-buffer
 (defvar occur--region-start nil)
 (defvar occur--region-end nil)
 (defvar occur--matches-threshold nil)
+(defvar occur--orig-line nil)
+(defvar occur--orig-line-str nil)
+(defvar occur--final-pos nil)
 
 (defun occur (regexp &optional nlines region)
   "Show all lines in the current buffer containing a match for REGEXP.
@@ -1381,6 +1397,9 @@ occur
 The lines are shown in a buffer named `*Occur*'.
 It serves as a menu to find any of the occurrences in this buffer.
 \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
+If `list-matching-lines-jump-to-current-line' is non-nil, then show
+highlighted the current line and, if there are matches after it, then
+set point in the first of those matches.
 
 If REGEXP contains upper case characters (excluding those preceded by `\\')
 and `search-upper-case' is non-nil, the matching is case-sensitive.
@@ -1408,7 +1427,13 @@ occur
           (occur--region-end end)
           (occur--matches-threshold
            (and in-region-p
-                (line-number-at-pos (min start end)))))
+                (line-number-at-pos (min start end))))
+          (occur--orig-line
+           (line-number-at-pos (point)))
+          (occur--orig-line-str
+           (buffer-substring-no-properties
+            (line-beginning-position)
+            (line-end-position))))
       (save-excursion ; If no matches `occur-1' doesn't restore the point.
         (and in-region-p (narrow-to-region start end))
         (occur-1 regexp nlines (list (current-buffer)))
@@ -1507,7 +1532,8 @@ occur-1
 	(occur-mode))
       (let ((inhibit-read-only t)
 	    ;; Don't generate undo entries for creation of the initial contents.
-	    (buffer-undo-list t))
+	    (buffer-undo-list t)
+            (occur--final-pos nil))
 	(erase-buffer)
 	(let ((count
 	       (if (stringp nlines)
@@ -1559,6 +1585,10 @@ occur-1
           (if (= count 0)
               (kill-buffer occur-buf)
             (display-buffer occur-buf)
+            (when occur--final-pos
+              (set-window-point
+               (get-buffer-window occur-buf 'all-frames)
+               occur--final-pos))
             (setq next-error-last-buffer occur-buf)
             (setq buffer-read-only t)
             (set-buffer-modified-p nil)
@@ -1571,7 +1601,8 @@ occur-engine
 	  (global-matches 0)  ;; total count of matches
 	  (coding nil)
 	  (case-fold-search case-fold)
-          (in-region-p (and occur--region-start occur--region-end)))
+          (in-region-p (and occur--region-start occur--region-end))
+          (multi-occur-p (cdr buffers)))
       ;; Map over all the buffers
       (dolist (buf buffers)
 	(when (buffer-live-p buf)
@@ -1579,12 +1610,16 @@ occur-engine
 		(matches 0)             ;; count of matches
 		(curr-line              ;; line count
                  (or occur--matches-threshold 1))
+                (orig-line occur--orig-line)
+                (orig-line-str occur--orig-line-str)
+                (orig-line-shown-p)
 		(prev-line nil)         ;; line number of prev match endpt
 		(prev-after-lines nil)  ;; context lines of prev match
 		(matchbeg 0)
 		(origpt nil)
 		(begpt nil)
 		(endpt nil)
+                (finalpt nil)
 		(marker nil)
 		(curstring "")
 		(ret nil)
@@ -1685,6 +1720,18 @@ occur-engine
 			      (nth 0 ret))))
 		      ;; Actually insert the match display data
 		      (with-current-buffer out-buf
+                        (when (and list-matching-lines-jump-to-current-line
+                                   (not multi-occur-p)
+                                   (not orig-line-shown-p)
+                                   (>= curr-line orig-line))
+                          (insert
+                           (concat
+                            (propertize
+                             (format "%7d:%s" orig-line orig-line-str)
+                             'face list-matching-lines-current-line-face
+                             'mouse-face 'mode-line-highlight
+                             'help-echo "Current line") "\n"))
+                          (setq orig-line-shown-p t finalpt (point)))
 			(insert data)))
 		    (goto-char endpt))
 		  (if endpt
@@ -1698,6 +1745,18 @@ occur-engine
 			(forward-line 1))
 		    (goto-char (point-max)))
 		  (setq prev-line (1- curr-line)))
+                ;; Insert original line if haven't done yet.
+                (when (and list-matching-lines-jump-to-current-line
+                           (not multi-occur-p)
+                           (not orig-line-shown-p))
+                  (with-current-buffer out-buf
+                    (insert
+                     (concat
+                      (propertize
+                       (format "%7d:%s" orig-line orig-line-str)
+                       'face list-matching-lines-current-line-face
+                       'mouse-face 'mode-line-highlight
+                       'help-echo "Current line") "\n"))))
 		;; Flush remaining context after-lines.
 		(when prev-after-lines
 		  (with-current-buffer out-buf
@@ -1731,8 +1790,11 @@ occur-engine
 		  (setq end (point))
 		  (add-text-properties beg end `(occur-title ,buf))
 		  (when title-face
-		    (add-face-text-property beg end title-face)))
-		(goto-char (point-min)))))))
+		    (add-face-text-property beg end title-face))
+                  (goto-char (if finalpt
+                                 (setq occur--final-pos
+                                       (cl-incf finalpt (- end beg)))
+                               (point-min)))))))))
       ;; Display total match count and regexp for multi-buffer.
       (when (and (not (zerop global-lines)) (> (length buffers) 1))
 	(goto-char (point-min))
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
 of 2017-01-22
Repository revision: 03de82fe7ca09ab40fbcae394d4fcdfe3374496e



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
       [not found]                               ` <87lgtu4w5c.fsf@mail.linkov.net>
@ 2017-01-29  6:00                                 ` Tino Calancha
  2017-01-30  0:09                                   ` Juri Linkov
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-01-29  6:00 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha

[-- Attachment #1: Type: text/plain, Size: 16084 bytes --]



On Sun, 29 Jan 2017, Juri Linkov wrote:

> I think this is a useful addition, thanks.  One note below.
>
>> +Optional arg REGION, if non-nil, mean restrict search to the
>> +specified region.  Otherwise search the entire buffer.
>> +When REGION is non-nil, it must be a cons (START . END).
>
> When someone decides to add support for rectangular regions in occur later,
> your current implementation will make this problematic since it changes
> the format ((START . END)) to (START . END), that makes difficult to support
> ((START1 . END1) (START2 . END2) ...) later.
>
> Let's stick to the same format in all uses of the new ‘REGION’ arg, and
> currently in occur support only the degenerate case of ((START . END))
> for non-rectangular regions.
Thanks.  I was also a bit worry with that detail.
OK, i keep the general format ((START . END)).
Let me know if the following patch is OK to be pushed:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 40ac0b30445f9581a5b4d6988d31089468a6a969 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 29 Jan 2017 14:46:10 +0900
Subject: [PATCH 1/2] Allow occur command to operate on the region

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional arg REGION; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search: Idem.
; etc/NEWS: Add entry to announce the change.
---
  doc/emacs/search.texi               |  3 +++
  doc/lispintro/emacs-lisp-intro.texi |  8 ++++---
  etc/NEWS                            |  2 ++
  lisp/replace.el                     | 47 +++++++++++++++++++++++++++++++------
  4 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index b728258973..28e25bec43 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1672,6 +1672,9 @@ Other Repeating Search
  no upper-case letters and @code{case-fold-search} is non-@code{nil}.
  Aside from @code{occur} and its variants, all operate on the text from
  point to the end of the buffer, or on the region if it is active.
+The command @code{occur} will operate on the region if
+it is active as well; when the region is not active, @code{occur}
+operates in the whole buffer.

  @findex list-matching-lines
  @findex occur
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 830c072cf5..36d767737d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -17151,9 +17151,11 @@ Keybindings

  @findex occur
  The @code{occur} command shows all the lines in the current buffer
-that contain a match for a regular expression.  Matching lines are
-shown in a buffer called @file{*Occur*}.  That buffer serves as a menu
-to jump to occurrences.
+that contain a match for a regular expression.  When the region is
+active, @code{occur} restricts matches to such region.  Otherwise it
+uses the entire buffer.
+Matching lines are shown in a buffer called @file{*Occur*}.
+That buffer serves as a menu to jump to occurrences.

  @findex global-unset-key
  @cindex Unbinding key
diff --git a/etc/NEWS b/etc/NEWS
index 12ff21f39a..a74cdb71df 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -310,6 +310,8 @@ substituted by a home directory by writing it as "/foo:/:/~/file".

  * Editing Changes in Emacs 26.1

+
+** The 'occur' command can now operate on the region.
  +++
  ** New bindings for 'query-replace-map'.
  'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/replace.el b/lisp/replace.el
index ff91734445..0a8e480485 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1360,7 +1360,12 @@ occur-rename-buffer
                             "*")
                     (or unique-p (not interactive-p)))))

-(defun occur (regexp &optional nlines)
+;; Region limits when `occur' applies on a region.
+(defvar occur--region-start nil)
+(defvar occur--region-end nil)
+(defvar occur--matches-threshold nil)
+
+(defun occur (regexp &optional nlines region)
    "Show all lines in the current buffer containing a match for REGEXP.
  If a match spreads across multiple lines, all those lines are shown.

@@ -1369,6 +1374,11 @@ occur
  NLINES defaults to `list-matching-lines-default-context-lines'.
  Interactively it is the prefix arg.

+Optional arg REGION, if non-nil, mean restrict search to the
+specified region.  Otherwise search the entire buffer.
+REGION must be a list of (START . END) positions as returned by
+`region-bounds'.
+
  The lines are shown in a buffer named `*Occur*'.
  It serves as a menu to find any of the occurrences in this buffer.
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
@@ -1386,8 +1396,24 @@ occur
  program.  When there is no parenthesized subexpressions in REGEXP
  the entire match is collected.  In any case the searched buffer
  is not modified."
-  (interactive (occur-read-primary-args))
-  (occur-1 regexp nlines (list (current-buffer))))
+  (interactive
+   (nconc (occur-read-primary-args)
+          (and (use-region-p) (list (region-bounds)))))
+  (let* ((start (and (caar region) (max (caar region) (point-min))))
+         (end (and (cdar region) (min (cdar region) (point-max))))
+         (in-region-p (or start end)))
+    (when in-region-p
+      (or start (setq start (point-min)))
+      (or end (setq end (point-max))))
+    (let ((occur--region-start start)
+          (occur--region-end end)
+          (occur--matches-threshold
+           (and in-region-p
+                (line-number-at-pos (min start end)))))
+      (save-excursion ; If no matches `occur-1' doesn't restore the point.
+        (and in-region-p (narrow-to-region start end))
+        (occur-1 regexp nlines (list (current-buffer)))
+        (and in-region-p (widen))))))

  (defvar ido-ignore-item-temp-list)

@@ -1545,13 +1571,15 @@ occur-engine
      (let ((global-lines 0)    ;; total count of matching lines
  	  (global-matches 0)  ;; total count of matches
  	  (coding nil)
-	  (case-fold-search case-fold))
+	  (case-fold-search case-fold)
+          (in-region-p (and occur--region-start occur--region-end)))
        ;; Map over all the buffers
        (dolist (buf buffers)
  	(when (buffer-live-p buf)
  	  (let ((lines 0)               ;; count of matching lines
  		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur--matches-threshold 1))
  		(prev-line nil)         ;; line number of prev match endpt
  		(prev-after-lines nil)  ;; context lines of prev match
  		(matchbeg 0)
@@ -1684,7 +1712,7 @@ occur-engine
  		(let ((beg (point))
  		      end)
  		  (insert (propertize
-			   (format "%d match%s%s%s in buffer: %s\n"
+			   (format "%d match%s%s%s in buffer: %s%s\n"
  				   matches (if (= matches 1) "" "es")
  				   ;; Don't display the same number of lines
  				   ;; and matches in case of 1 match per line.
@@ -1694,7 +1722,12 @@ occur-engine
  				   ;; Don't display regexp for multi-buffer.
  				   (if (> (length buffers) 1)
  				       "" (occur-regexp-descr regexp))
-				   (buffer-name buf))
+				   (buffer-name buf)
+                                   (if in-region-p
+                                       (format " within region: %d-%d"
+                                               occur--region-start
+                                               occur--region-end)
+                                     ""))
  			   'read-only t))
  		  (setq end (point))
  		  (add-text-properties beg end `(occur-title ,buf))
-- 
2.11.0

From a1ac23d9b5384524591fa9f6586a2665175caf6f Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 29 Jan 2017 14:46:27 +0900
Subject: [PATCH 2/2] Show current line highlighted in *Occur* buffer

* lisp/replace.el (list-matching-lines-current-line-face)
(list-matching-lines-jump-to-current-line): New user options.
(occur--orig-line, occur--orig-line-str): New variables.
(occur, occur-engine): Use them.
(occur--final-pos): New variable.
(occur-1): Use it.
(occur-engine): Idem.
Show the current line with 'list-matching-lines-current-line-face'.
Set point on the first matching line after the current one.
* etc/NEWS: Add entry for the new option.
---
  etc/NEWS        |  4 ++++
  lisp/replace.el | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
  2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index a74cdb71df..90b53aca16 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -311,6 +311,10 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
  * Editing Changes in Emacs 26.1


+** Two new user options 'list-matching-lines-jump-to-current-line' and
+'list-matching-lines-current-line-face' to show highlighted the current line
+in the *Occur* buffer.
+
  ** The 'occur' command can now operate on the region.
  +++
  ** New bindings for 'query-replace-map'.
diff --git a/lisp/replace.el b/lisp/replace.el
index 0a8e480485..8e51792f5e 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1304,6 +1304,19 @@ list-matching-lines-buffer-name-face
    :type 'face
    :group 'matching)

+(defcustom list-matching-lines-current-line-face 'lazy-highlight
+  "Face used by \\[list-matching-lines] to highlight the current line."
+  :type 'face
+  :group 'matching
+  :version "26.1")
+
+(defcustom list-matching-lines-jump-to-current-line nil
+  "If non-nil, \\[list-matching-lines] shows the current line highlighted.
+Set the point right after such line when there are matches after it."
+:type 'boolean
+:group 'matching
+:version "26.1")
+
  (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,
@@ -1364,6 +1377,9 @@ occur-rename-buffer
  (defvar occur--region-start nil)
  (defvar occur--region-end nil)
  (defvar occur--matches-threshold nil)
+(defvar occur--orig-line nil)
+(defvar occur--orig-line-str nil)
+(defvar occur--final-pos nil)

  (defun occur (regexp &optional nlines region)
    "Show all lines in the current buffer containing a match for REGEXP.
@@ -1382,6 +1398,9 @@ occur
  The lines are shown in a buffer named `*Occur*'.
  It serves as a menu to find any of the occurrences in this buffer.
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
+If `list-matching-lines-jump-to-current-line' is non-nil, then show
+highlighted the current line and, if there are matches after it, then
+set point in the first of those matches.

  If REGEXP contains upper case characters (excluding those preceded by `\\')
  and `search-upper-case' is non-nil, the matching is case-sensitive.
@@ -1409,7 +1428,13 @@ occur
            (occur--region-end end)
            (occur--matches-threshold
             (and in-region-p
-                (line-number-at-pos (min start end)))))
+                (line-number-at-pos (min start end))))
+          (occur--orig-line
+           (line-number-at-pos (point)))
+          (occur--orig-line-str
+           (buffer-substring-no-properties
+            (line-beginning-position)
+            (line-end-position))))
        (save-excursion ; If no matches `occur-1' doesn't restore the point.
          (and in-region-p (narrow-to-region start end))
          (occur-1 regexp nlines (list (current-buffer)))
@@ -1508,7 +1533,8 @@ occur-1
  	(occur-mode))
        (let ((inhibit-read-only t)
  	    ;; Don't generate undo entries for creation of the initial contents.
-	    (buffer-undo-list t))
+	    (buffer-undo-list t)
+            (occur--final-pos nil))
  	(erase-buffer)
  	(let ((count
  	       (if (stringp nlines)
@@ -1560,6 +1586,10 @@ occur-1
            (if (= count 0)
                (kill-buffer occur-buf)
              (display-buffer occur-buf)
+            (when occur--final-pos
+              (set-window-point
+               (get-buffer-window occur-buf 'all-frames)
+               occur--final-pos))
              (setq next-error-last-buffer occur-buf)
              (setq buffer-read-only t)
              (set-buffer-modified-p nil)
@@ -1572,7 +1602,8 @@ occur-engine
  	  (global-matches 0)  ;; total count of matches
  	  (coding nil)
  	  (case-fold-search case-fold)
-          (in-region-p (and occur--region-start occur--region-end)))
+          (in-region-p (and occur--region-start occur--region-end))
+          (multi-occur-p (cdr buffers)))
        ;; Map over all the buffers
        (dolist (buf buffers)
  	(when (buffer-live-p buf)
@@ -1580,12 +1611,16 @@ occur-engine
  		(matches 0)             ;; count of matches
  		(curr-line              ;; line count
                   (or occur--matches-threshold 1))
+                (orig-line occur--orig-line)
+                (orig-line-str occur--orig-line-str)
+                (orig-line-shown-p)
  		(prev-line nil)         ;; line number of prev match endpt
  		(prev-after-lines nil)  ;; context lines of prev match
  		(matchbeg 0)
  		(origpt nil)
  		(begpt nil)
  		(endpt nil)
+                (finalpt nil)
  		(marker nil)
  		(curstring "")
  		(ret nil)
@@ -1686,6 +1721,18 @@ occur-engine
  			      (nth 0 ret))))
  		      ;; Actually insert the match display data
  		      (with-current-buffer out-buf
+                        (when (and list-matching-lines-jump-to-current-line
+                                   (not multi-occur-p)
+                                   (not orig-line-shown-p)
+                                   (>= curr-line orig-line))
+                          (insert
+                           (concat
+                            (propertize
+                             (format "%7d:%s" orig-line orig-line-str)
+                             'face list-matching-lines-current-line-face
+                             'mouse-face 'mode-line-highlight
+                             'help-echo "Current line") "\n"))
+                          (setq orig-line-shown-p t finalpt (point)))
  			(insert data)))
  		    (goto-char endpt))
  		  (if endpt
@@ -1699,6 +1746,18 @@ occur-engine
  			(forward-line 1))
  		    (goto-char (point-max)))
  		  (setq prev-line (1- curr-line)))
+                ;; Insert original line if haven't done yet.
+                (when (and list-matching-lines-jump-to-current-line
+                           (not multi-occur-p)
+                           (not orig-line-shown-p))
+                  (with-current-buffer out-buf
+                    (insert
+                     (concat
+                      (propertize
+                       (format "%7d:%s" orig-line orig-line-str)
+                       'face list-matching-lines-current-line-face
+                       'mouse-face 'mode-line-highlight
+                       'help-echo "Current line") "\n"))))
  		;; Flush remaining context after-lines.
  		(when prev-after-lines
  		  (with-current-buffer out-buf
@@ -1732,8 +1791,11 @@ occur-engine
  		  (setq end (point))
  		  (add-text-properties beg end `(occur-title ,buf))
  		  (when title-face
-		    (add-face-text-property beg end title-face)))
-		(goto-char (point-min)))))))
+		    (add-face-text-property beg end title-face))
+                  (goto-char (if finalpt
+                                 (setq occur--final-pos
+                                       (cl-incf finalpt (- end beg)))
+                               (point-min)))))))))
        ;; Display total match count and regexp for multi-buffer.
        (when (and (not (zerop global-lines)) (> (length buffers) 1))
  	(goto-char (point-min))
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
  of 2017-01-29
Repository revision: d12e1ddf42cddcac56f98c5b3a65f5219d2d5968

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-29  6:00                                 ` Tino Calancha
@ 2017-01-30  0:09                                   ` Juri Linkov
  2017-01-30  4:27                                     ` Tino Calancha
  2017-01-30  4:48                                     ` Tino Calancha
  0 siblings, 2 replies; 39+ messages in thread
From: Juri Linkov @ 2017-01-30  0:09 UTC (permalink / raw)
  To: Tino Calancha; +Cc: Emacs developers

>>> +Optional arg REGION, if non-nil, mean restrict search to the
>>> +specified region.  Otherwise search the entire buffer.
>>> +When REGION is non-nil, it must be a cons (START . END).
>>
>> When someone decides to add support for rectangular regions in occur later,
>> your current implementation will make this problematic since it changes
>> the format ((START . END)) to (START . END), that makes difficult to support
>> ((START1 . END1) (START2 . END2) ...) later.
>>
>> Let's stick to the same format in all uses of the new ‘REGION’ arg, and
>> currently in occur support only the degenerate case of ((START . END))
>> for non-rectangular regions.
>
> Thanks.  I was also a bit worry with that detail.
> OK, i keep the general format ((START . END)).
> Let me know if the following patch is OK to be pushed:

Looks good to me, but you have to ask Eli for the permission to push.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-30  0:09                                   ` Juri Linkov
@ 2017-01-30  4:27                                     ` Tino Calancha
  2017-01-30  4:48                                     ` Tino Calancha
  1 sibling, 0 replies; 39+ messages in thread
From: Tino Calancha @ 2017-01-30  4:27 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Emacs developers, Tino Calancha

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]



On Mon, 30 Jan 2017, Juri Linkov wrote:

>>>> +Optional arg REGION, if non-nil, mean restrict search to the
>>>> +specified region.  Otherwise search the entire buffer.
>>>> +When REGION is non-nil, it must be a cons (START . END).
>>>
>>> When someone decides to add support for rectangular regions in occur later,
>>> your current implementation will make this problematic since it changes
>>> the format ((START . END)) to (START . END), that makes difficult to support
>>> ((START1 . END1) (START2 . END2) ...) later.
>>>
>>> Let's stick to the same format in all uses of the new ‘REGION’ arg, and
>>> currently in occur support only the degenerate case of ((START . END))
>>> for non-rectangular regions.
>>
>> Thanks.  I was also a bit worry with that detail.
>> OK, i keep the general format ((START . END)).
>> Let me know if the following patch is OK to be pushed:
>
> Looks good to me, but you have to ask Eli for the permission to push.
OK, I will ask.
Thank you very much for your help implementing this.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-30  0:09                                   ` Juri Linkov
  2017-01-30  4:27                                     ` Tino Calancha
@ 2017-01-30  4:48                                     ` Tino Calancha
  2017-01-30 15:35                                       ` Eli Zaretskii
  1 sibling, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-01-30  4:48 UTC (permalink / raw)
  To: John Wiegley, Eli Zaretskii; +Cc: tino.calancha, Emacs developers, Juri Linkov


Hi,

Juri and me have being working on extend `occur' so that it
can run restricted to the region.
We propose the patch below.
Please let us know if it's OK for you to push this patch into
the master branch.

Best regards,
Tino

Juri Linkov <juri@linkov.net> writes:

>>> Let's stick to the same format in all uses of the new ‘REGION’ arg, and
>>> currently in occur support only the degenerate case of ((START . END))
>>> for non-rectangular regions.
>>
>> OK, i keep the general format ((START . END)).
>> Let me know if the following patch is OK to be pushed:
>
> Looks good to me, but you have to ask Eli for the permission to push.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 40ac0b30445f9581a5b4d6988d31089468a6a969 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 29 Jan 2017 14:46:10 +0900
Subject: [PATCH 1/2] Allow occur command to operate on the region

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional arg REGION; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search: Idem.
; etc/NEWS: Add entry to announce the change.
---
  doc/emacs/search.texi               |  3 +++
  doc/lispintro/emacs-lisp-intro.texi |  8 ++++---
  etc/NEWS                            |  2 ++
  lisp/replace.el                     | 47 +++++++++++++++++++++++++++++++------
  4 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index b728258973..28e25bec43 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1672,6 +1672,9 @@ Other Repeating Search
  no upper-case letters and @code{case-fold-search} is non-@code{nil}.
  Aside from @code{occur} and its variants, all operate on the text from
  point to the end of the buffer, or on the region if it is active.
+The command @code{occur} will operate on the region if
+it is active as well; when the region is not active, @code{occur}
+operates in the whole buffer.

  @findex list-matching-lines
  @findex occur
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 830c072cf5..36d767737d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -17151,9 +17151,11 @@ Keybindings

  @findex occur
  The @code{occur} command shows all the lines in the current buffer
-that contain a match for a regular expression.  Matching lines are
-shown in a buffer called @file{*Occur*}.  That buffer serves as a menu
-to jump to occurrences.
+that contain a match for a regular expression.  When the region is
+active, @code{occur} restricts matches to such region.  Otherwise it
+uses the entire buffer.
+Matching lines are shown in a buffer called @file{*Occur*}.
+That buffer serves as a menu to jump to occurrences.

  @findex global-unset-key
  @cindex Unbinding key
diff --git a/etc/NEWS b/etc/NEWS
index 12ff21f39a..a74cdb71df 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -310,6 +310,8 @@ substituted by a home directory by writing it as "/foo:/:/~/file".

  * Editing Changes in Emacs 26.1

+
+** The 'occur' command can now operate on the region.
  +++
  ** New bindings for 'query-replace-map'.
  'undo', undo the last replacement; bound to 'u'.
diff --git a/lisp/replace.el b/lisp/replace.el
index ff91734445..0a8e480485 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1360,7 +1360,12 @@ occur-rename-buffer
                             "*")
                     (or unique-p (not interactive-p)))))

-(defun occur (regexp &optional nlines)
+;; Region limits when `occur' applies on a region.
+(defvar occur--region-start nil)
+(defvar occur--region-end nil)
+(defvar occur--matches-threshold nil)
+
+(defun occur (regexp &optional nlines region)
    "Show all lines in the current buffer containing a match for REGEXP.
  If a match spreads across multiple lines, all those lines are shown.

@@ -1369,6 +1374,11 @@ occur
  NLINES defaults to `list-matching-lines-default-context-lines'.
  Interactively it is the prefix arg.

+Optional arg REGION, if non-nil, mean restrict search to the
+specified region.  Otherwise search the entire buffer.
+REGION must be a list of (START . END) positions as returned by
+`region-bounds'.
+
  The lines are shown in a buffer named `*Occur*'.
  It serves as a menu to find any of the occurrences in this buffer.
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
@@ -1386,8 +1396,24 @@ occur
  program.  When there is no parenthesized subexpressions in REGEXP
  the entire match is collected.  In any case the searched buffer
  is not modified."
-  (interactive (occur-read-primary-args))
-  (occur-1 regexp nlines (list (current-buffer))))
+  (interactive
+   (nconc (occur-read-primary-args)
+          (and (use-region-p) (list (region-bounds)))))
+  (let* ((start (and (caar region) (max (caar region) (point-min))))
+         (end (and (cdar region) (min (cdar region) (point-max))))
+         (in-region-p (or start end)))
+    (when in-region-p
+      (or start (setq start (point-min)))
+      (or end (setq end (point-max))))
+    (let ((occur--region-start start)
+          (occur--region-end end)
+          (occur--matches-threshold
+           (and in-region-p
+                (line-number-at-pos (min start end)))))
+      (save-excursion ; If no matches `occur-1' doesn't restore the point.
+        (and in-region-p (narrow-to-region start end))
+        (occur-1 regexp nlines (list (current-buffer)))
+        (and in-region-p (widen))))))

  (defvar ido-ignore-item-temp-list)

@@ -1545,13 +1571,15 @@ occur-engine
      (let ((global-lines 0)    ;; total count of matching lines
  	  (global-matches 0)  ;; total count of matches
  	  (coding nil)
-	  (case-fold-search case-fold))
+	  (case-fold-search case-fold)
+          (in-region-p (and occur--region-start occur--region-end)))
        ;; Map over all the buffers
        (dolist (buf buffers)
  	(when (buffer-live-p buf)
  	  (let ((lines 0)               ;; count of matching lines
  		(matches 0)             ;; count of matches
-		(curr-line 1)           ;; line count
+		(curr-line              ;; line count
+                 (or occur--matches-threshold 1))
  		(prev-line nil)         ;; line number of prev match endpt
  		(prev-after-lines nil)  ;; context lines of prev match
  		(matchbeg 0)
@@ -1684,7 +1712,7 @@ occur-engine
  		(let ((beg (point))
  		      end)
  		  (insert (propertize
-			   (format "%d match%s%s%s in buffer: %s\n"
+			   (format "%d match%s%s%s in buffer: %s%s\n"
  				   matches (if (= matches 1) "" "es")
  				   ;; Don't display the same number of lines
  				   ;; and matches in case of 1 match per line.
@@ -1694,7 +1722,12 @@ occur-engine
  				   ;; Don't display regexp for multi-buffer.
  				   (if (> (length buffers) 1)
  				       "" (occur-regexp-descr regexp))
-				   (buffer-name buf))
+				   (buffer-name buf)
+                                   (if in-region-p
+                                       (format " within region: %d-%d"
+                                               occur--region-start
+                                               occur--region-end)
+                                     ""))
  			   'read-only t))
  		  (setq end (point))
  		  (add-text-properties beg end `(occur-title ,buf))
-- 

2.11.0

From a1ac23d9b5384524591fa9f6586a2665175caf6f Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 29 Jan 2017 14:46:27 +0900
Subject: [PATCH 2/2] Show current line highlighted in *Occur* buffer

* lisp/replace.el (list-matching-lines-current-line-face)
(list-matching-lines-jump-to-current-line): New user options.
(occur--orig-line, occur--orig-line-str): New variables.
(occur, occur-engine): Use them.
(occur--final-pos): New variable.
(occur-1): Use it.
(occur-engine): Idem.
Show the current line with 'list-matching-lines-current-line-face'.
Set point on the first matching line after the current one.
* etc/NEWS: Add entry for the new option.
---
  etc/NEWS        |  4 ++++
  lisp/replace.el | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
  2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index a74cdb71df..90b53aca16 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -311,6 +311,10 @@ substituted by a home directory by writing it as "/foo:/:/~/file".
  * Editing Changes in Emacs 26.1


+** Two new user options 'list-matching-lines-jump-to-current-line' and
+'list-matching-lines-current-line-face' to show highlighted the current line
+in the *Occur* buffer.
+
  ** The 'occur' command can now operate on the region.
  +++
  ** New bindings for 'query-replace-map'.
diff --git a/lisp/replace.el b/lisp/replace.el
index 0a8e480485..8e51792f5e 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1304,6 +1304,19 @@ list-matching-lines-buffer-name-face
    :type 'face
    :group 'matching)

+(defcustom list-matching-lines-current-line-face 'lazy-highlight
+  "Face used by \\[list-matching-lines] to highlight the current line."
+  :type 'face
+  :group 'matching
+  :version "26.1")
+
+(defcustom list-matching-lines-jump-to-current-line nil
+  "If non-nil, \\[list-matching-lines] shows the current line highlighted.
+Set the point right after such line when there are matches after it."
+:type 'boolean
+:group 'matching
+:version "26.1")
+
  (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,
@@ -1364,6 +1377,9 @@ occur-rename-buffer
  (defvar occur--region-start nil)
  (defvar occur--region-end nil)
  (defvar occur--matches-threshold nil)
+(defvar occur--orig-line nil)
+(defvar occur--orig-line-str nil)
+(defvar occur--final-pos nil)

  (defun occur (regexp &optional nlines region)
    "Show all lines in the current buffer containing a match for REGEXP.
@@ -1382,6 +1398,9 @@ occur
  The lines are shown in a buffer named `*Occur*'.
  It serves as a menu to find any of the occurrences in this buffer.
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
+If `list-matching-lines-jump-to-current-line' is non-nil, then show
+highlighted the current line and, if there are matches after it, then
+set point in the first of those matches.

  If REGEXP contains upper case characters (excluding those preceded by `\\')
  and `search-upper-case' is non-nil, the matching is case-sensitive.
@@ -1409,7 +1428,13 @@ occur
            (occur--region-end end)
            (occur--matches-threshold
             (and in-region-p
-                (line-number-at-pos (min start end)))))
+                (line-number-at-pos (min start end))))
+          (occur--orig-line
+           (line-number-at-pos (point)))
+          (occur--orig-line-str
+           (buffer-substring-no-properties
+            (line-beginning-position)
+            (line-end-position))))
        (save-excursion ; If no matches `occur-1' doesn't restore the point.
          (and in-region-p (narrow-to-region start end))
          (occur-1 regexp nlines (list (current-buffer)))
@@ -1508,7 +1533,8 @@ occur-1
  	(occur-mode))
        (let ((inhibit-read-only t)
  	    ;; Don't generate undo entries for creation of the initial contents.
-	    (buffer-undo-list t))
+	    (buffer-undo-list t)
+            (occur--final-pos nil))
  	(erase-buffer)
  	(let ((count
  	       (if (stringp nlines)
@@ -1560,6 +1586,10 @@ occur-1
            (if (= count 0)
                (kill-buffer occur-buf)
              (display-buffer occur-buf)
+            (when occur--final-pos
+              (set-window-point
+               (get-buffer-window occur-buf 'all-frames)
+               occur--final-pos))
              (setq next-error-last-buffer occur-buf)
              (setq buffer-read-only t)
              (set-buffer-modified-p nil)
@@ -1572,7 +1602,8 @@ occur-engine
  	  (global-matches 0)  ;; total count of matches
  	  (coding nil)
  	  (case-fold-search case-fold)
-          (in-region-p (and occur--region-start occur--region-end)))
+          (in-region-p (and occur--region-start occur--region-end))
+          (multi-occur-p (cdr buffers)))
        ;; Map over all the buffers
        (dolist (buf buffers)
  	(when (buffer-live-p buf)
@@ -1580,12 +1611,16 @@ occur-engine
  		(matches 0)             ;; count of matches
  		(curr-line              ;; line count
                   (or occur--matches-threshold 1))
+                (orig-line occur--orig-line)
+                (orig-line-str occur--orig-line-str)
+                (orig-line-shown-p)
  		(prev-line nil)         ;; line number of prev match endpt
  		(prev-after-lines nil)  ;; context lines of prev match
  		(matchbeg 0)
  		(origpt nil)
  		(begpt nil)
  		(endpt nil)
+                (finalpt nil)
  		(marker nil)
  		(curstring "")
  		(ret nil)
@@ -1686,6 +1721,18 @@ occur-engine
  			      (nth 0 ret))))
  		      ;; Actually insert the match display data
  		      (with-current-buffer out-buf
+                        (when (and list-matching-lines-jump-to-current-line
+                                   (not multi-occur-p)
+                                   (not orig-line-shown-p)
+                                   (>= curr-line orig-line))
+                          (insert
+                           (concat
+                            (propertize
+                             (format "%7d:%s" orig-line orig-line-str)
+                             'face list-matching-lines-current-line-face
+                             'mouse-face 'mode-line-highlight
+                             'help-echo "Current line") "\n"))
+                          (setq orig-line-shown-p t finalpt (point)))
  			(insert data)))
  		    (goto-char endpt))
  		  (if endpt
@@ -1699,6 +1746,18 @@ occur-engine
  			(forward-line 1))
  		    (goto-char (point-max)))
  		  (setq prev-line (1- curr-line)))
+                ;; Insert original line if haven't done yet.
+                (when (and list-matching-lines-jump-to-current-line
+                           (not multi-occur-p)
+                           (not orig-line-shown-p))
+                  (with-current-buffer out-buf
+                    (insert
+                     (concat
+                      (propertize
+                       (format "%7d:%s" orig-line orig-line-str)
+                       'face list-matching-lines-current-line-face
+                       'mouse-face 'mode-line-highlight
+                       'help-echo "Current line") "\n"))))
  		;; Flush remaining context after-lines.
  		(when prev-after-lines
  		  (with-current-buffer out-buf
@@ -1732,8 +1791,11 @@ occur-engine
  		  (setq end (point))
  		  (add-text-properties beg end `(occur-title ,buf))
  		  (when title-face
-		    (add-face-text-property beg end title-face)))
-		(goto-char (point-min)))))))
+		    (add-face-text-property beg end title-face))
+                  (goto-char (if finalpt
+                                 (setq occur--final-pos
+                                       (cl-incf finalpt (- end beg)))
+                               (point-min)))))))))
        ;; Display total match count and regexp for multi-buffer.
        (when (and (not (zerop global-lines)) (> (length buffers) 1))
  	(goto-char (point-min))
-- 

2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
  of 2017-01-29
Repository revision: d12e1ddf42cddcac56f98c5b3a65f5219d2d5968



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-30  4:48                                     ` Tino Calancha
@ 2017-01-30 15:35                                       ` Eli Zaretskii
  2017-02-02 10:22                                         ` Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2017-01-30 15:35 UTC (permalink / raw)
  To: Tino Calancha; +Cc: jwiegley, emacs-devel, juri

> From: Tino Calancha <tino.calancha@gmail.com>
> Cc: Juri Linkov <juri@linkov.net>, tino.calancha@gmail.com, Emacs developers <emacs-devel@gnu.org>
> Date: Mon, 30 Jan 2017 13:48:02 +0900
> 
> Juri and me have being working on extend `occur' so that it
> can run restricted to the region.
> We propose the patch below.
> Please let us know if it's OK for you to push this patch into
> the master branch.

If everyone is happy with this, I don't see any reasons not to push.

One comment: the NEWS entry that describes features already documented
in the corresponding manual should be marked with "+++", see the
explanation at the head of NEWS.

Thanks.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-01-30 15:35                                       ` Eli Zaretskii
@ 2017-02-02 10:22                                         ` Tino Calancha
  2017-02-02 21:08                                           ` Eli Zaretskii
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-02-02 10:22 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Emacs developers, Tino Calancha



On Mon, 30 Jan 2017, Eli Zaretskii wrote:

>> Please let us know if it's OK for you to push this patch into
>> the master branch.
>
> If everyone is happy with this, I don't see any reasons not to push.
>
> One comment: the NEWS entry that describes features already documented
> in the corresponding manual should be marked with "+++", see the
> explanation at the head of NEWS.
Pushed as commits:
8e871aef10455eefc34790a9ec011c6fec5e93fe
e280b94dcd6ed42439718ddf9dd704169f6bb536

Thank you.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-02-02 10:22                                         ` Tino Calancha
@ 2017-02-02 21:08                                           ` Eli Zaretskii
  2017-02-03  3:11                                             ` Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2017-02-02 21:08 UTC (permalink / raw)
  To: Tino Calancha; +Cc: emacs-devel

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Thu, 2 Feb 2017 19:22:24 +0900 (JST)
> cc: Tino Calancha <tino.calancha@gmail.com>, 
>     Emacs developers <emacs-devel@gnu.org>
> 
> Pushed as commits:
> 8e871aef10455eefc34790a9ec011c6fec5e93fe
> e280b94dcd6ed42439718ddf9dd704169f6bb536

Thanks.

In the future, when you introduce new
variables/faces/functions/commands, please make sure to index them,
unless they are defined with the likes of @defopt and @defun, which do
that for you automatically.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-02-02 21:08                                           ` Eli Zaretskii
@ 2017-02-03  3:11                                             ` Tino Calancha
  2017-02-03  8:02                                               ` Eli Zaretskii
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-02-03  3:11 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel, Tino Calancha



On Thu, 2 Feb 2017, Eli Zaretskii wrote:

>> From: Tino Calancha <tino.calancha@gmail.com>
>> Date: Thu, 2 Feb 2017 19:22:24 +0900 (JST)
>> cc: Tino Calancha <tino.calancha@gmail.com>,
>>     Emacs developers <emacs-devel@gnu.org>
>>
>> Pushed as commits:
>> 8e871aef10455eefc34790a9ec011c6fec5e93fe
>> e280b94dcd6ed42439718ddf9dd704169f6bb536
>
> Thanks.
>
> In the future, when you introduce new
> variables/faces/functions/commands, please make sure to index them,
> unless they are defined with the likes of @defopt and @defun, which do
> that for you automatically.
I just noticed your commit df915775bc4ead095aa37d2b098de748e1821027
Now i understand that you mean the concept index.  Sure i will
do this from now on.
Thanks.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [patch] Run occur command restricted to a region
  2017-02-03  3:11                                             ` Tino Calancha
@ 2017-02-03  8:02                                               ` Eli Zaretskii
  2017-02-03 10:04                                                 ` CONTRIBUTE: Mention indexing new vars/commands in manual [was: Run occur command restricted to a region] Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2017-02-03  8:02 UTC (permalink / raw)
  To: Tino Calancha; +Cc: emacs-devel

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Fri, 3 Feb 2017 12:11:11 +0900 (JST)
> cc: Tino Calancha <tino.calancha@gmail.com>, emacs-devel@gnu.org
> 
> I just noticed your commit df915775bc4ead095aa37d2b098de748e1821027
> Now i understand that you mean the concept index.

Not just the concept index: the variables should go into the variable
indec and functions/commands into their index.  There are separate
@cindex, @vindex, and @findex commands in Texinfo.

> Sure i will do this from now on.

Thanks in advance.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* CONTRIBUTE: Mention indexing new vars/commands in manual [was: Run occur command restricted to a region]
  2017-02-03  8:02                                               ` Eli Zaretskii
@ 2017-02-03 10:04                                                 ` Tino Calancha
  2017-02-03 10:37                                                   ` Eli Zaretskii
  0 siblings, 1 reply; 39+ messages in thread
From: Tino Calancha @ 2017-02-03 10:04 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel, tino.calancha

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Tino Calancha <tino.calancha@gmail.com>
>> Date: Fri, 3 Feb 2017 12:11:11 +0900 (JST)
>> cc: Tino Calancha <tino.calancha@gmail.com>, emacs-devel@gnu.org
>> 
>> I just noticed your commit df915775bc4ead095aa37d2b098de748e1821027
>> Now i understand that you mean the concept index.
>
> Not just the concept index: the variables should go into the variable
> indec and functions/commands into their index.  There are separate
> @cindex, @vindex, and @findex commands in Texinfo.
Do you think would be worth to mention briefly about this in CONTRIBUTE?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From caa8e6955e65f3bb45e816dcfc3dc66cdd0fde28 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Fri, 3 Feb 2017 18:55:00 +0900
Subject: [PATCH] * CONTRIBUTE (Documenting your changes): Index new
 vars/commands in manual.

---
 CONTRIBUTE | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/CONTRIBUTE b/CONTRIBUTE
index c12f0cc08d..49b8919f17 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -250,6 +250,12 @@ know it does not, mark the NEWS entry with "---".  If you know
 that *all* the necessary documentation updates have been made, mark
 the entry with "+++".  Otherwise do not mark it.
 
+If your change requires updating the manuals to document new
+functions/commands/variables/faces, then use the proper Texinfo
+command to index them; for instance, use @vindex for variables and
+@findex for functions/commands.  For the full list of predefine indices, see
+http://www.gnu.org/software/texinfo/manual/texinfo/html_node/Predefined-Indices.html
+
 For more specific tips on Emacs's doc style, see
 http://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html
 Use 'checkdoc' to check for documentation errors before submitting a patch.
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 25.1.91.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
 of 2017-02-03
Repository revision: 7e02a477bbcabb4e65aeecade79b67357c0b9dae



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: CONTRIBUTE: Mention indexing new vars/commands in manual [was: Run occur command restricted to a region]
  2017-02-03 10:04                                                 ` CONTRIBUTE: Mention indexing new vars/commands in manual [was: Run occur command restricted to a region] Tino Calancha
@ 2017-02-03 10:37                                                   ` Eli Zaretskii
  2017-02-03 11:02                                                     ` Tino Calancha
  0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2017-02-03 10:37 UTC (permalink / raw)
  To: Tino Calancha; +Cc: emacs-devel

> From: Tino Calancha <tino.calancha@gmail.com>
> Cc: tino.calancha@gmail.com, emacs-devel@gnu.org
> Date: Fri, 03 Feb 2017 19:04:27 +0900
> 
> > Not just the concept index: the variables should go into the variable
> > indec and functions/commands into their index.  There are separate
> > @cindex, @vindex, and @findex commands in Texinfo.
> Do you think would be worth to mention briefly about this in CONTRIBUTE?
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> >From caa8e6955e65f3bb45e816dcfc3dc66cdd0fde28 Mon Sep 17 00:00:00 2001
> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Fri, 3 Feb 2017 18:55:00 +0900
> Subject: [PATCH] * CONTRIBUTE (Documenting your changes): Index new
>  vars/commands in manual.

Fine with me, but please also point to the node in Info notation,
since the reader might have the Texinfo manual installed.

This should go to the emacs-25 branch.

Thanks.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: CONTRIBUTE: Mention indexing new vars/commands in manual [was: Run occur command restricted to a region]
  2017-02-03 10:37                                                   ` Eli Zaretskii
@ 2017-02-03 11:02                                                     ` Tino Calancha
  0 siblings, 0 replies; 39+ messages in thread
From: Tino Calancha @ 2017-02-03 11:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Emacs developers, Tino Calancha



On Fri, 3 Feb 2017, Eli Zaretskii wrote:

>> From: Tino Calancha <tino.calancha@gmail.com>
>> Cc: tino.calancha@gmail.com, emacs-devel@gnu.org
>> Date: Fri, 03 Feb 2017 19:04:27 +0900
>>
>>> Not just the concept index: the variables should go into the variable
>>> indec and functions/commands into their index.  There are separate
>>> @cindex, @vindex, and @findex commands in Texinfo.
>> Do you think would be worth to mention briefly about this in CONTRIBUTE?
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>>> From caa8e6955e65f3bb45e816dcfc3dc66cdd0fde28 Mon Sep 17 00:00:00 2001
>> From: Tino Calancha <tino.calancha@gmail.com>
>> Date: Fri, 3 Feb 2017 18:55:00 +0900
>> Subject: [PATCH] * CONTRIBUTE (Documenting your changes): Index new
>>  vars/commands in manual.
>
> Fine with me, but please also point to the node in Info notation,
> since the reader might have the Texinfo manual installed.
>
> This should go to the emacs-25 branch.
Pushed to emacs-25 branch as commit
e1171de6d1922af4bb8e9b4eae2becf1b7b597d4



^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2017-02-03 11:02 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-29  6:36 [patch] Run occur command restricted to a region Tino Calancha
2016-12-29 16:10 ` Eli Zaretskii
2016-12-29 16:54   ` Tino Calancha
2016-12-29 18:16     ` Drew Adams
2016-12-29 18:50       ` Kaushal Modi
2016-12-29 20:52         ` Drew Adams
2016-12-30  2:57       ` Tino Calancha
2017-01-03 17:37   ` Region argument (was: [patch] Run occur command restricted to a region) Stefan Monnier
2017-01-03 18:34     ` Eli Zaretskii
2017-01-03 18:59       ` Region argument Stefan Monnier
2017-01-03 19:19         ` Eli Zaretskii
2017-01-04  0:57         ` Juri Linkov
2016-12-29 23:31 ` [patch] Run occur command restricted to a region Juri Linkov
2016-12-30  2:47   ` Tino Calancha
2016-12-30 23:20     ` Juri Linkov
2016-12-30  7:53   ` Eli Zaretskii
2016-12-30 23:16     ` Juri Linkov
2016-12-31  8:37       ` Eli Zaretskii
     [not found]       ` <87r34ozq20.fsf@gmail.com>
     [not found]         ` <87inq0xhiw.fsf@mail.linkov.net>
     [not found]           ` <alpine.DEB.2.20.1701011834290.1852@calancha-pc>
     [not found]             ` <87d1g55h8d.fsf@mail.linkov.net>
2017-01-03 10:19               ` Tino Calancha
2017-01-18 11:04                 ` Tino Calancha
2017-01-19 23:51                   ` Juri Linkov
2017-01-20 13:48                     ` Tino Calancha
2017-01-20 16:46                       ` Davis Herring
2017-01-20 23:17                       ` Juri Linkov
2017-01-22 10:32                         ` Tino Calancha
2017-01-22 23:50                           ` Juri Linkov
2017-01-23  7:32                             ` Tino Calancha
     [not found]                               ` <87lgtu4w5c.fsf@mail.linkov.net>
2017-01-29  6:00                                 ` Tino Calancha
2017-01-30  0:09                                   ` Juri Linkov
2017-01-30  4:27                                     ` Tino Calancha
2017-01-30  4:48                                     ` Tino Calancha
2017-01-30 15:35                                       ` Eli Zaretskii
2017-02-02 10:22                                         ` Tino Calancha
2017-02-02 21:08                                           ` Eli Zaretskii
2017-02-03  3:11                                             ` Tino Calancha
2017-02-03  8:02                                               ` Eli Zaretskii
2017-02-03 10:04                                                 ` CONTRIBUTE: Mention indexing new vars/commands in manual [was: Run occur command restricted to a region] Tino Calancha
2017-02-03 10:37                                                   ` Eli Zaretskii
2017-02-03 11:02                                                     ` Tino Calancha

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).