making next-error and previous-error work with helm-grep and helm-occur candidates

36 views
Skip to first unread message

Sameer Sahasrabuddhe

unread,
Sep 7, 2016, 1:42:00 AM9/7/16
to emacs-helm

The following flow is very useful:

1. Use helm-grep or helm-occur to search for a pattern.
2. Select a candidate and jump to it.
3. At this point, the buffer showing the candidates disappears.
4. Press "M-g n" or "M-g p" to traverse the candidates just like compilation minor mode.

I would ideally like this to work with any source that has follow-mode enabled.

But as a reduced scenario, I tried to make this work with the "*hgrep*" buffer that is created when you press "C-x C-s" to save grep candidates. I tried two approaches with limited success:

A) Make helm-grep-mode a child of compilation-minor-mode
This works quite well, but it loses the original formatting of the "*hgrep*" buffer.

B) The other option is to bind 'next-error in the "*hgrep*" buffer using helm-grep-mode-hook as follows:

(add-hook 'helm-grep-mode-hook
      (lambda () (setq next-error-function 'helm-grep-mode-jump-1)))

(defun helm-grep-mode-jump-1 (arg rst)
  (interactive)
  (let ((candidate (buffer-substring (point-at-bol) (point-at-eol))))
    (forward-line arg)
    (helm-grep-action candidate)))

This works, but it does not pop-up the "*hgrep*" buffer like compilation-minor-mode.

To repeat, although we could eventually fix this to work with helm-grep-mode, it still requires the user to press "C-x C-s" and create that buffer in the first place. It would be more useful if "M-g n" worked seamlessly with the last helm session. For example, manually enabling compilation-minor mode in the buffer "*helm grep*" also works, but again it does not look pretty, and I have not found any way to always enable it automatically.

Sameer.

Thierry Volpiatto

unread,
Sep 7, 2016, 3:00:45 AM9/7/16
to emacs...@googlegroups.com

Sameer Sahasrabuddhe <same...@gmail.com> writes:

> The following flow is very useful:
>
> 1. Use helm-grep or helm-occur to search for a pattern.
> 2. Select a candidate and jump to it.
> 3. At this point, the buffer showing the candidates disappears.

Just call M-x helm-resume to ressurect it.

next/previous-error is not useful for helm IMO.
I don't believe cycling (more than around five candidates) is something
reliable, it is why I never used next/previous-error and never implement
it in helm (and will not).

--
Thierry

Sameer Sahasrabuddhe

unread,
Sep 7, 2016, 6:52:21 AM9/7/16
to emacs-helm
On Wednesday, September 7, 2016 at 12:30:45 PM UTC+5:30, thierry v wrote:

Sameer Sahasrabuddhe <same...@gmail.com> writes:

> The following flow is very useful:
>
> 1. Use helm-grep or helm-occur to search for a pattern.
> 2. Select a candidate and jump to it.
> 3. At this point, the buffer showing the candidates disappears.

Just call M-x helm-resume to ressurect it.

That was indeed the first thing I played with. I wrote a function that calls helm-resume and then calls helm-next-line. The problem is that helm resume insists on prompting you for the pattern, because it assumes you are interested in a full-fledged helm session. But I am only interested in going to the next candidate from my previous session.

If there was an equivalent "helm-resume-and-next-line" that dwim's without prompting, then that would be great.
 
next/previous-error is not useful for helm IMO.
I don't believe cycling (more than around five candidates) is something
reliable, it is why I never used next/previous-error and never implement
it in helm (and will not).

Well, there are multiple ways to look at this.

1. For someone who has been using vanilla grep and occur for a long time, it makes complete sense to expect next/previous-error to work in the same way in a helm session. Which means, "when I am already visiting a candidate, give me a way to visit the next candidate with no additional prompts". The next/previous-error framework is already designed to make this work automagically ... all one has to do is bind a suitable function to next-error-function etc.

2. Even without vanilla grep and occur, for a user who created a *hgrep* buffer using "C-x C-s" in a helm buffer, it makes sense to have a key binding that jumps to the next/previous candidate in that buffer, but without switching to that buffer. Again, next/previous-error functions are meant for just that.

Note that the contents of both buffers *helm grep* and *hgrep* are already in a format that is understood by compilation-minor-mode. All that is needed is to hookup a suitable action to next/previous-error functions.

Sameer.

Thierry Volpiatto

unread,
Sep 7, 2016, 7:09:25 AM9/7/16
to emacs...@googlegroups.com

Sameer Sahasrabuddhe <same...@gmail.com> writes:

> That was indeed the first thing I played with. I wrote a function that
> calls helm-resume and then calls helm-next-line. The problem is that
> helm resume insists on prompting you for the pattern, because it
> assumes you are interested in a full-fledged helm session. But I am
> only interested in going to the next candidate from my previous
> session.
>
> If there was an equivalent "helm-resume-and-next-line" that dwim's
> without prompting, then that would be great.

No, the only thing you have to do is helm-resume, C-n and RET.
This is much better because you can visually see where you go and
eventually go to nth next candidate.

> Well, there are multiple ways to look at this.
>
> 1. For someone who has been using vanilla grep and occur for a long
> time, it makes complete sense to expect next/previous-error to work in
> the same way in a helm session. Which means, "when I am already
> visiting a candidate, give me a way to visit the next candidate with
> no additional prompts". The next/ previous-error framework is already
> designed to make this work automagically ... all one has to do is bind
> a suitable function to next-error-function etc.

More than ten years I use emacs and I always found next/previous error are
unuseful.
This is a user interface of another age, really deprecated and predated
by helm-resume.

As I said cycling like emacs vanilla does in many places
(next/previous-error, isearch, dabbrev etc...) is a pain unless the
number of candidates to cycle with is <= 5 more or less, after it
becomes a pain.

So don't expect a change in helm for next/previous-error, as said above,
just hit M-x helm-resume, C-n and RET.

--
Thierry

Sameer Sahasrabuddhe

unread,
Sep 7, 2016, 7:29:16 AM9/7/16
to emacs-helm
On Wednesday, September 7, 2016 at 4:39:25 PM UTC+5:30, thierry v wrote:


> If there was an equivalent "helm-resume-and-next-line" that dwim's
> without prompting, then that would be great.

No, the only thing you have to do is helm-resume, C-n and RET.
This is much better because you can visually see where you go and
eventually go to nth next candidate.

That's three different verbs inside my head (resume, next-line, jump) instead of just jumping to the next candidate. By the time I select my first candidate in the helm session, I am usually sure that I have all the candidates I am interested in. All I want to do is jump to the next one ... I definitely do not need to see where I am going. I just did that in the helm session.

More than ten years I use emacs and I always found next/previous error are
unuseful.

I have been using emacs since ~2003, and I have always found next/previous errors to be extremely useful. This is why I am expending the energy to investigate this.
 
This is a user interface of another age, really deprecated and predated
by helm-resume.

No comment. To each emacs user his own idea of good interfaces. But I must add that next/previous-error is anything but deprecated!
 
As I said cycling like emacs vanilla does in many places
(next/previous-error, isearch, dabbrev etc...) is a pain unless the
number of candidates to cycle with is <= 5 more or less, after it
becomes a pain.

The number of candidates never bothered me in my years of usage, as long as I could reliably filter the right set of candidates, and helm-grep really shines in that respect.
 
So don't expect a change in helm for next/previous-error, as said above,
just hit M-x helm-resume, C-n and RET.

The good part about emacs and lisp is that it is extensible in crazy ways. I am not really expecting a specific change to make this a feature in helm. I am just looking for hooks that I can make use of, and I already made some good progress on that. But if required, would you be averse to introducing a hook that was good enough for my purpose, but which I can show to be useful in general?

Sameer.

Thierry Volpiatto

unread,
Sep 7, 2016, 10:44:35 AM9/7/16
to emacs...@googlegroups.com

Sameer Sahasrabuddhe <same...@gmail.com> writes:

> All that is needed is to hookup a suitable action to
> next/previous-error functions.

If I had to implement next/previous-error, I would not use the helm
approach, that is finding back the helm buffer with whatever method
(resume etc..), I would use the following approach, forgetting the
academic emacs method using next-error-function etc...


1) Exit with a list of candidate stored somewhere,
store also the index of current candidate and the PA to be used.
Up to you to find the container, alist, list etc...

2) Create two anonymous functions that run the saved PA on
the next item of an iterator starting at INDEX.
Each function should regenerate the other function with a new iterator starting
at the new INDEX.

3) Bind these two functions to a key, but each function should rebind the key on itself
when the iterator is renewed.

PS If you don't know iterators, have a look at:

https://github.com/thierryvolpiatto/iterator

helm already have some code from iterator inlined like helm-iter-list
which should be enough with helm-iter-next to implement what you want.

--
Thierry
Reply all
Reply to author
Forward
0 new messages