From: Augusto Stoffel <arstoffel@gmail.com>
To: 59888@debbugs.gnu.org
Subject: bug#59888: [PATCH] Add 'grep-heading-mode'
Date: Wed, 07 Dec 2022 18:57:37 +0100 [thread overview]
Message-ID: <87v8mndrla.fsf@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 763 bytes --]
Tags: patch
This simulates the --heading option of certain grep-like tools. The
output is like this:
--8<---------------cut here---------------start------------->8---
-*- mode: grep; default-directory: "~/Projects/emacs/" -*-
Grep started at Wed Dec 7 18:43:40
find [...] -exec grep --color=auto -i -nH --null -e test \{\} +
./nextstep/Makefile.in
104: find ${ns_appdir} -exec test \! -e {} \; -ls
./nextstep/INSTALL
12:Tested on GNU/Linux, may work on other systems.
./nextstep/Makefile
104: find ${ns_appdir} -exec test \! -e {} \; -ls
./nextstep/README
62: 10.6.8 (Snow Leopard) to the latest official release.
86:* This allows other Emacs developers to test their changes on the NS
--8<---------------cut here---------------end--------------->8---
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-grep-heading-mode.patch --]
[-- Type: text/patch, Size: 4316 bytes --]
From 2247f006845000032fedc3dda9a073b14043a270 Mon Sep 17 00:00:00 2001
From: Augusto Stoffel <arstoffel@gmail.com>
Date: Wed, 7 Dec 2022 18:44:07 +0100
Subject: [PATCH] Add 'grep-heading-mode'
New minor mode to subdivide grep output into sections, as in the
'--heading' option of certain grep-like programs.
* lisp/progmodes/grep.el (grep-heading-regexp): New user option.
(grep-heading): New face.
(grep--heading-format, grep--current-heading, grep--heading-filter):
Filter function for grep processes and supporting variables.
(grep-heading-mode): New minor mode.
---
etc/NEWS | 8 +++++
lisp/progmodes/grep.el | 71 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/etc/NEWS b/etc/NEWS
index 3eeef0ab4c..54c3b2447a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -41,6 +41,14 @@ connection.
\f
* Changes in Specialized Modes and Packages in Emacs 30.1
+** Compile
+
+*** New minor mode 'grep-heading-mode'.
+In this mode, the grep output is split into sections, one for each
+file, instead of having file names prefixed to each line. It is
+equivalent to the --heading option of some tools such as 'git grep'
+and 'rg.
+
** VC
---
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index 2446e86abb..132f905734 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -30,6 +30,7 @@
;;; Code:
(eval-when-compile (require 'cl-lib))
+(eval-when-compile (require 'rx))
(require 'compile)
(defgroup grep nil
@@ -1407,6 +1408,76 @@ grep-file-at-point
;;;###autoload
(defalias 'rzgrep #'zrgrep)
+;;; Headings mode
+(defcustom grep-heading-regexp
+ (rx bol
+ (or
+ (seq "Grep" (* (any "/a-zA-Z")) " "
+ (or "started" "finished" "exited" "interrupt" "killed" "terminated")
+ (* (not (any "\0\n"))))
+ (seq
+ (group-n 2
+ (group-n 1 (+? any))
+ (any "\0-:="))
+ (+ digit)
+ (any "-:="))))
+ "Regexp used to create headings from grep output lines.
+It should be anchored at beginning of line. The first capture
+group, if present, should match the heading associated to the
+line. The buffer range of the second capture, if present, is
+made invisible (presumably because displaying it would be
+redundant)."
+ :type 'regexp
+ :version "30.1")
+
+(defface grep-heading '((t :inherit font-lock-function-name-face))
+ "Face of headings when using `grep-heading-mode'.")
+
+(defvar grep--heading-format
+ #("\n%s\n" 1 3 (font-lock-face grep-heading outline-level 1))
+ "Format string of grep headings.
+This is passed to `format' with one argument, the text of the
+first capture group of `grep-heading-regexp'.")
+
+(defvar-local grep--current-heading nil
+ "Used by `grep--heading-filter' to keep track of the current heading.")
+
+(defun grep--heading-filter ()
+ "Filter function to add headings to output of a grep process."
+ (save-excursion
+ (let ((bound (copy-marker (pos-bol))))
+ (goto-char compilation-filter-start)
+ (forward-line 0)
+ (while (re-search-forward grep-heading-regexp bound t)
+ (let ((heading (match-string-no-properties 1))
+ (start (match-beginning 2))
+ (end (match-end 2)))
+ (when start
+ (put-text-property start end 'invisible t))
+ (when (and heading (not (equal heading grep--current-heading)))
+ (save-excursion
+ (forward-line 0)
+ (insert-before-markers (format grep--heading-format heading)))
+ (setq grep--current-heading heading)))))))
+
+;;;###autoload
+(define-minor-mode grep-heading-mode
+ "Subdivide grep output into sections, one per file."
+ :interactive 'grep-mode
+ (if (not grep-heading-mode)
+ (recompile)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((inhibit-read-only t)
+ (compilation-filter-start (point-min)))
+ (goto-char (point-max))
+ (grep--heading-filter))))
+ (add-hook 'compilation-filter-hook #'grep--heading-filter 80 t)
+ (setq-local outline-search-function #'outline-search-level
+ outline-level (lambda () (get-text-property
+ (point) 'outline-level)))))
+
(provide 'grep)
;;; grep.el ends here
--
2.38.1
[-- Attachment #3: Type: text/plain, Size: 539 bytes --]
Some comments:
1. It's necessary to insert text into the grep buffer, which is a bit
concerning because 'compilation-filter-start' is not a marker, just a
number. This could cause other filter functions to get confused.
This is why I'm adding to 'compilation-filter-hook at a higher depth.
Perhaps there are better approaches here.
2. One could get rid of the awkward first alternative of
`grep-heading-regexp' if there was a way to distringuish the grep
process output from the header and footer added by grep-mode.
next reply other threads:[~2022-12-07 17:57 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-07 17:57 Augusto Stoffel [this message]
2022-12-07 18:14 ` bug#59888: [PATCH] Add 'grep-heading-mode' Eli Zaretskii
2022-12-08 8:59 ` Augusto Stoffel
2022-12-08 10:57 ` Eli Zaretskii
2022-12-08 0:19 ` Stefan Kangas
2022-12-08 9:06 ` Augusto Stoffel
2022-12-09 7:23 ` Juri Linkov
2022-12-09 11:58 ` Augusto Stoffel
2022-12-09 12:18 ` bug#59888: [PATCH] Add 'grep-use-headings' Augusto Stoffel
2022-12-09 19:36 ` Eli Zaretskii
2022-12-09 20:03 ` Augusto Stoffel
2022-12-09 20:29 ` Eli Zaretskii
2022-12-10 20:08 ` Augusto Stoffel
2022-12-10 20:16 ` Eli Zaretskii
2022-12-11 11:30 ` Augusto Stoffel
2022-12-15 8:05 ` Juri Linkov
2023-02-25 8:34 ` Augusto Stoffel
2023-02-25 18:00 ` Juri Linkov
2023-02-26 13:17 ` Robert Pluim
2023-02-26 15:07 ` Augusto Stoffel
2023-02-27 6:24 ` Robert Pluim
2023-02-27 11:26 ` Augusto Stoffel
2023-02-27 16:51 ` Robert Pluim
2023-02-27 18:53 ` Juri Linkov
2023-02-27 19:06 ` Augusto Stoffel
2023-02-27 19:15 ` Juri Linkov
2023-02-28 17:24 ` Juri Linkov
2023-02-28 18:17 ` Augusto Stoffel
2023-03-01 17:52 ` Juri Linkov
2022-12-09 20:40 ` Gregory Heytings
2022-12-10 17:24 ` Juri Linkov
2022-12-08 9:57 ` bug#59888: [PATCH] Add 'grep-heading-mode' Mattias Engdegård
2022-12-08 10:28 ` Augusto Stoffel
2022-12-08 10:48 ` Mattias Engdegård
2023-02-27 14:18 ` Mattias Engdegård
2022-12-09 7:28 ` Juri Linkov
2022-12-09 11:58 ` Augusto Stoffel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v8mndrla.fsf@gmail.com \
--to=arstoffel@gmail.com \
--cc=59888@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).