4

Is there a way to remove occurrences in Occur mode? In particular, this piece of functionality would allow you to remove occurrences in case you are interested in editing only some out of all occurrences in Occur mode.

Example: say I have this piece of code:

import os
import time

print("Just an example")

john.age = 44
anna.age = 55
print("Something")
bob.age = 83

If I run occur searching for "age", I get:

3 matches for "age" in buffer: untitled
      6:john.age = 44
      7:anna.age = 55
      9:bob.age = 83

And after that I would like to have a function that allows me to, with the cursor in the desired line, remove that occurrence from the buffer so that any following edit will not have any effect into the removed occurrences. In the given example, if I did not want to edit line 7, I could run the desired function to get the occur buffer in the following new state:

3 matches for "age" in buffer: untitled
      6:john.age = 44
      9:bob.age = 83

I know that it is possible to use Narrowing commands inside an occur buffer, but that would not cover the case where my lines of interest are scattered around other occurrences and it would also not be as simple as selecting the lines I do not want to mess with. Also, having this functionality would save time from having to write complex regular expressions even in the case where we could get the specific occurrences we are interested in from a single search.

2 Answers 2

1

An occur buffer is just a buffer in read-only mode, that doesn't mean that it cannot be manipulated.

Something as straightforward like this can help you:

(defun occur-kill-line()
  "Quick and dirty discard line from occur resultset.
from https://emacs.stackexchange.com/a/52865/13589"
  (interactive)
  (let ((inhibit-read-only t))
    (kill-whole-line)
    (delete-blank-lines)))

invoking this function will kill the current line in occur buffer. Pressing g will revert the buffer.

Adding this:

(define-key occur-mode-map (kbd "k") 'occur-kill-line)

will bind k to occur-kill-line to occur-mode-map making it available as occur command just pressing k.

3
  • Thank you @Muihlinn. I have adapted your solution to use kill-whole-line instead of just kill-line, to make it work even if the cursor is not in the first column. Commented Oct 5, 2019 at 10:12
  • 2
    More idiomatic would be to let bind buffer-read-only around the buffer modifying code (let ((buffer-read-only nil)) ...)
    – clemera
    Commented Oct 5, 2019 at 15:01
  • 1
    @ArthurColombiniGusmão you're welcome. It was just ad-hoc code to show the idea. It can be refined in many ways, as preventing killing lines outside result list, asking for a regexp... whatever you can imagine useful.
    – Muihlinn
    Commented Oct 5, 2019 at 16:58
5

If you delete the entire line from the occur buffer, it will not touch the original buffer.

So press e to run #'occur-edit-mode, then delete the entire line (C-k).

3
  • 1
    This is the simplest answer. You can also use just C-x C-q to toggle read-only (then C-k). And if you want to remove all lines after point that match a regexp, you can use flush-lines. Or remove all that do not match a regexp: keep-lines. (And you can narrow to limit the scope of those regexp commands.) Oh, and you can do the same things with grep etc. - just toggle read-only first.
    – Drew
    Commented Sep 27, 2019 at 18:01
  • Thank you. Indeed, this is the simplest solution. I ended up adapting Muihlinn's answer as that suits my workflow better, but C-x C-q has been really useful for me in Emacs in general. Commented Oct 5, 2019 at 10:18
  • @ArthurColombiniGusmão C-x C-q in a editing buffer is as useful as it is in dired. Two aces I use a lot everyday.
    – Muihlinn
    Commented Oct 5, 2019 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.