From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Augusto Stoffel Newsgroups: gmane.emacs.bugs Subject: bug#59888: [PATCH] Add 'grep-heading-mode' Date: Wed, 07 Dec 2022 18:57:37 +0100 Message-ID: <87v8mndrla.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="40255"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) To: 59888@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Dec 07 18:58:20 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p2ygW-000AFb-Cw for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 07 Dec 2022 18:58:20 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p2ygG-0004Mt-Pl; Wed, 07 Dec 2022 12:58:04 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p2ygF-0004MH-5R for bug-gnu-emacs@gnu.org; Wed, 07 Dec 2022 12:58:03 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p2ygE-0000It-Tr for bug-gnu-emacs@gnu.org; Wed, 07 Dec 2022 12:58:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1p2ygE-0005YY-JY for bug-gnu-emacs@gnu.org; Wed, 07 Dec 2022 12:58:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Augusto Stoffel Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 07 Dec 2022 17:58:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 59888 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.167043587321348 (code B ref -1); Wed, 07 Dec 2022 17:58:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 7 Dec 2022 17:57:53 +0000 Original-Received: from localhost ([127.0.0.1]:51375 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p2yg4-0005YG-PU for submit@debbugs.gnu.org; Wed, 07 Dec 2022 12:57:53 -0500 Original-Received: from lists.gnu.org ([209.51.188.17]:58776) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p2yfz-0005YA-Sr for submit@debbugs.gnu.org; Wed, 07 Dec 2022 12:57:51 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p2yfz-0004KY-Me for bug-gnu-emacs@gnu.org; Wed, 07 Dec 2022 12:57:47 -0500 Original-Received: from mail-ej1-x62d.google.com ([2a00:1450:4864:20::62d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p2yfu-0000Gi-ML for bug-gnu-emacs@gnu.org; Wed, 07 Dec 2022 12:57:47 -0500 Original-Received: by mail-ej1-x62d.google.com with SMTP id t17so15884539eju.1 for ; Wed, 07 Dec 2022 09:57:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:user-agent:message-id:date:subject:to:from:from:to:cc :subject:date:message-id:reply-to; bh=vHnNiD0wcr6SZMRx6FGhwkUdqZseopj12VQVnJd6v1Q=; b=S/Irjz++dIF9XQjj2uaC/0yyVrzoOPpe5MKozsFlZfFmRnR/UqDLIcuhrYN7nDOaqH Pgk6ByddM8KPxLyrKjZ7Ep3urT0U3PrpQhs4TW+s1wPqdunhw7AknFfPUespQatR/3rT Zndo6T93E31+Tt3s8xkGWgigBQgBDoARl/THal73InKCJxRMnjYu7EgQ7AbKq1cg/5PL pNFmPWXIi8AKtXQNqzMbEPtWD48rFZ8sN/umh00bKqNFWEQk8ANGfwM8VKD1Vx62baZq zLjen7IIoYfORO043MsptOgOPgeMLmuvJC49679YaBChacTIUxCBSI/9jtfdFbWbszCM B76Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:message-id:date:subject:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vHnNiD0wcr6SZMRx6FGhwkUdqZseopj12VQVnJd6v1Q=; b=r3Jl7jSvXlqlw0hSlfQg7/ZfBRDEIlbcZHVrU5RGrnLjZi8MPr//73mOWDZu6TijHV uNxWPrBi9mxSBXqGfh8/ohRPJjHwlN8TGlc8BOfjZ4rXa8uupTj//dAPw/RCsevT0u3D JkPOmtGsd72PEj+ZGgqV8kQ/2wBvPbOt1JmLww3tP4YdJCYqeX4XRSHeFccBEvItuyjy 0+DPTvt1ctav/zY7hLQaO2AbKMvhbe5rNUlAnW+GL91fg2/5apo4RbMFNm5UrpYEneBI pG2oL5KQDAOjQWmyohij7hl2++otUUOKrvAWBgzFOEuy71hgtGYNYXxGfK22xdLyQm3q f0Bw== X-Gm-Message-State: ANoB5pmVOZgnKbQyMj5TKIM2kvQL1oQ3Z9/sBaQ8aY83sy5vz8DIOY9W C8e3t/cLqZ4fqeJb0zqoAeVtJd2u8Nw= X-Google-Smtp-Source: AA0mqf74yaXBkH47kOgJeOew5Jo8aubQ8hwugVxae6LBloOYKSt5kQ44GSxmfr7JUd2pfbekrlF8/g== X-Received: by 2002:a17:906:ee1:b0:78a:efde:b84a with SMTP id x1-20020a1709060ee100b0078aefdeb84amr77282403eji.744.1670435859992; Wed, 07 Dec 2022 09:57:39 -0800 (PST) Original-Received: from ars3 ([2a02:8109:8ac0:56d0::a4bf]) by smtp.gmail.com with ESMTPSA id ck3-20020a0564021c0300b0046778ce5fdfsm2505081edb.10.2022.12.07.09.57.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Dec 2022 09:57:38 -0800 (PST) Received-SPF: pass client-ip=2a00:1450:4864:20::62d; envelope-from=arstoffel@gmail.com; helo=mail-ej1-x62d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:250205 Archived-At: --=-=-= Content-Type: text/plain 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--- --=-=-= Content-Type: text/patch Content-Disposition: attachment; filename=0001-Add-grep-heading-mode.patch >From 2247f006845000032fedc3dda9a073b14043a270 Mon Sep 17 00:00:00 2001 From: Augusto Stoffel 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. * 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 --=-=-= Content-Type: text/plain 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. --=-=-=--