3

Thanks to helm-swoop, I know how to display occurrences of a single word. Now, I'd like to display at the same time occurrences of many different words (of a given, single buffer).

Let me be specific: say, I have a buffer containing multiple occurrences of the two words 'Hello' and 'Bye', and I'd like to check each 'Hello' is followed by a 'Bye' before any further 'Hello'. For this, I'd like to filter at the same time the occurrences of these two words. How could I achieve this?

Drew
  • 75,699
  • 9
  • 109
  • 225
Denis Bitouzé
  • 398
  • 2
  • 14

4 Answers4

6

Using helm-swoop

Solution

Use helm-swoop to find occurrences of words WORD1 and WORD2 in the buffer.

M-x helm-swoop RET WORD1\|WORD2 RET

Old answer

Use helm-swoop to find occurrences of pairs of words WORD1 and WORD2 in the buffer, in the same line.

M-x helm-swoop RET WORD1 WORD2 RET

enter image description here

Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
  • For some reason I don't understand, that doesn't work with my `GNU Emacs 24.4.1` (i686-pc-linux-gnu, GTK+ Version 3.10.6) and an up to date `helm-swoop` (version 20150121.20), as shown by [this screenshot](http://gte.univ-littoral.fr/members/dbitouze/pub/divers/emacs/how-to-display-at-the/downloadFile/file/ehs.png). What could I check? – Denis Bitouzé Jan 21 '15 at 17:31
  • @DenisBitouzé the words have to be on the same line. Give it a prefix argument if you want it to cross lines. (like `C-u 4 M-x helm-swoop` to search across 4 lines.) – nanny Jan 21 '15 at 18:06
  • Unfortunately, the words are disseminated in the whole big file. – Denis Bitouzé Jan 21 '15 at 18:11
  • 1
    @DenisBitouzé For such cases, I use the non-helm way: `C-M-s WORD1[[:ascii:][:nonascii:]]*?WORD2`. This does search of `WORD1` followed any *anything*, even multiple lines, followed by `WORD2`. – Kaushal Modi Jan 21 '15 at 18:31
2

If the question is not limited to Helm, you can do this in Icicles using command icicle-occur (bound to C-c ') in either of these ways, depending on what you want:

  • Type the regexp Hello.*Bye, if you want to look for Hello followed by Bye.

  • Type Hello then S-SPC then Bye, if you want to look for both words in either order.

C-c ' uses lines as search contexts. Whatever you type as the dynamic text to look for in lines is matched.

The two examples above assume that you want to match both Hello and Bye in the same line. If you want to match either instead of both within a line, then use a pattern that matches either: Hello\|Bye.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • Am I supposed to hit ENTER after that? In such a case, it doesn't work neither. – Denis Bitouzé Jan 21 '15 at 17:52
  • Please read the doc a bit. `S-TAB` shows you all of the matches. `C-down` to cycle among matches. `RET` to exit (stay at) a match. ***"It doesn't work"*** is not particularly helpful in letting me understand your problem so that I can help you. My advice, if you are interested, is to [**start with the doc**](http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview). That's why I linked to it. – Drew Jan 21 '15 at 18:00
  • 1
    I'm sorry, despite a look at the doc, I couldn't make it work. Here is my workflow: `C-c '` → Choose an occurrence: → Hello → `S-SPC` → [2] Match also (regexp): → Bye. And then, nothing happens e.g. if I hit `S-TAB` (except [No apropos completion] appears for few seconds). – Denis Bitouzé Jan 21 '15 at 18:30
  • Either (a) navigate to an occurrence (using `down` or `C-down`) and then hit `RET` or (b) type stuff that reduces the matches to a single match. If `S-TAB` tells you there is no match then my guess is that there is no match - no line with both `Hello` and `Bye`. If you are expecting matches that are *not* in the same line, then use command `icicle-search` (bound to ``C-c ` ``), not `icicle-occur` (`C-c '`). – Drew Jan 21 '15 at 18:49
  • 1
    If you want to match lines that have *either* `Hello` or `Bye`, then use `C-c '` with, for example, regexp `Hello\|Bye` (use `S-TAB` to see the matches). If you want to match text within occurrences of `Hello` and `Bye` (anywhere - i.e., search only the `Hello` and `Bye` zones of text) then use ``C-c ` `` with the context-defining regexp `Hello\|Bye`. Beyond this help, please see the doc. This is not the place for a discussion or a tutorial. – Drew Jan 21 '15 at 18:59
  • OK, and in fact, the `Hello\|Bye` regexp works with `helm-swoop` as well. One of the `helm-swoop`'s advantages is that navigating from occurrence to another in the `helm-swoop` buffer, you navigate in the same time in the main buffer, and could look at the context. – Denis Bitouzé Jan 21 '15 at 20:05
  • 1
    "*One of the `helm-swoop`'s advantages...*" - The same is true in Icicles, using **`C-`** with the navigate keys (e.g., `C-down` vs just `down`), as I said. One advantage of having both is that you can, if you want, cycle to choose particular occurrences to visit, without needing to visit the occurrences in between. If you *want* to visit them, then just hold down the modifier key `C-` while you cycle. You can also sort the matches in various ways, so that you cycle in different orders - another advantage of showing matches both separately and in context. (All in the Icicles docs, of course.) – Drew Jan 21 '15 at 21:43
  • Indeed, Icicles also has the features I was looking for. – Denis Bitouzé Jan 22 '15 at 06:27
2

Thanks to @Drew answer, I could manage to make helm-swoop filter at the same time the occurrences of two words (say 'Hello' and 'Bye'): M-x helm-swoop RET Hello\|Bye.

Denis Bitouzé
  • 398
  • 2
  • 14
  • 1
    Great, but then change the accepted answer to one of the Helm answers (yours or kaushalmodi's which also have this solution added), so those who search for this Helm problem and find this helm-swoop question, can see the Helm answer as accepted, because that's what they are interested in, and that's what fits the question. – Tom Jan 22 '15 at 16:21
1

Using Occur

Solution

Use Occur to find occurrences of words WORD1 and WORD2 in the buffer.

M-x occur RET WORD1\|WORD2 RET

Then use M-g M-n and M-g M-p to navigate the results from the buffer containing text.

Old answer

Use Occur to find occurrences of pairs of words WORD1 and WORD2 in the buffer, which could be across multiple lines.

M-x occur RET WORD1[[:ascii:][:nonascii:]]*?WORD2 RET

enter image description here

Note: Word highlighting is done using hl-anything package, available through Melpa.

Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
  • AFAICS, this doesn't *filter* the relevant lines. – Denis Bitouzé Jan 21 '15 at 20:06
  • 1
    @DenisBitouzé I then did not understand how you wanted the filtering to be done. First have a look at the last occurrence of `Hello` and `Bye` in the `*scratch*` buffer. Now look at last match in the `*Occur*` buffer.. you will see that it has filtered out only the line including and between the lines containing those 2 words, from line 32 to line 35. The previous occurrence of those 2 words was between lines 25-26, and so on. In all, it found 5 occurrences of `Hello ... Bye` across multiple lines. – Kaushal Modi Jan 21 '15 at 20:18
  • 1
    @DenisBitouzé From your comments in the other post, I realized you need to see all occurrences of `Hello` and `Bye`, not necessarily in pairs. In that case, the same `Hello\|Bye` expression would work for Occur too. About navigating easily to all the occurrences, it is already supported out-of-the box, [use `M-g M-n` and `M-g M-p` from the buffer containing the text](http://www.masteringemacs.org/article/searching-buffers-occur-mode). – Kaushal Modi Jan 21 '15 at 20:24