this post was submitted on 20 Oct 2023
2 points (100.0% liked)

Emacs

311 readers
2 users here now

A community for the timeless and infinitely powerful editor. Want to see what Emacs is capable of?!

Get Emacs

Rules

  1. Posts should be emacs related
  2. Be kind please
  3. Yes, we already know: Google results for "emacs" and "vi" link to each other. We good.

Emacs Resources

Emacs Tutorials

Useful Emacs configuration files and distributions

Quick pain-saver tip

founded 1 year ago
MODERATORS
 

Hi there,

I use orgmode links extensively. In particular, I have hundreds (our thousands) of links to emails (in notmuch). I would very much like to add a tag to any email that is being referenced from org.

So, what I need to do first is be able to find all matches of a regular expression in all my org files. Non-interactively.

I have been playing around with xref-matches-in-directory but that would not cover when multiple emails are mentioned in the same line...

I have been looking and looking but everything I find missed the non-interactive part.

So: What is the function to "search for this REGEX in FILES in DIR and return the first capture group"? (the regex has a capture group for the msgid)

The regex:

  (rx-to-string
   (rx "notmuch:id:"
       (group (1+ (not "]")))))
top 11 comments
sorted by: hot top controversial new old
[–] telenieko@alien.top 1 points 1 year ago (1 children)

I ask only for the first step. After I have all the referenced message IDs I will start working on the notmuch side to find and tag!

[–] yantar92@alien.top 1 points 1 year ago (1 children)

You can simply loop over all the org files, open one by one, and search within each file individually using (while (re-seacrch-forward ...) ...).

[–] telenieko@alien.top 1 points 1 year ago (1 children)

I plan on searching hundreds of files (all notes) so... some way that does not open all of them would be preferable.

[–] yantar92@alien.top 1 points 1 year ago

If opening a file is a problem, you can create temporary buffer and then use insert-file-contents + search + erase-buffer.

[–] terminal_prognosis@alien.top 1 points 1 year ago (2 children)
find . -name "*.org" -exec sed -nr 's/.*notmuch:id:([^]\n]*).*$/\1/p' {} \;
[–] terminal_prognosis@alien.top 1 points 1 year ago

With filenames:

for file in `find . -name "*.org"`; do sed -nr "s;.*notmuch:id:([^]\n]*).*$;$file: \1;p" "$file"; done
[–] telenieko@alien.top 1 points 1 year ago (1 children)

This is r/emacs !! Looking for an Emacs Lisp solution 😁

[–] terminal_prognosis@alien.top 1 points 1 year ago (1 children)

Emacs can run subprocesses just fine. I assumed you wanted a solution to a problem rather than an exercise.

[–] telenieko@alien.top 1 points 1 year ago (1 children)

It's an opportunity to learn more lisp!

I do currently have a shell script using ripgrep & notmuch-tag, but felt it could be an interesting problem to solve within Emacs :)

[–] mmaug@alien.top 1 points 1 year ago

The lispy/emacs-like solution is to open each file, search it, and close it. Don't optimize too early. Build the simplest most straightforward implementation and then worry about performance. But understand why the most emacs-like solution fails.

[–] Y_Pon@alien.top 1 points 1 year ago
  • dired open needed dir
  • M-x grep-find (regexp)

Comes to my mind