unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alex Kost <alezost@gmail.com>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: guix-devel@gnu.org
Subject: [PATCH] emacs: Add commands to show/hide build log phases.
Date: Tue, 15 Sep 2015 21:56:06 +0300	[thread overview]
Message-ID: <87k2rrtsu1.fsf_-_@gmail.com> (raw)
In-Reply-To: <87si6htdhr.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Mon, 14 Sep 2015 14:02:56 +0200")

[-- Attachment #1: Type: text/plain, Size: 215 bytes --]

Ludovic Courtès (2015-09-14 15:02 +0300) wrote:

> As future work ;-), it would be neat if tab and S-tab would do
> folding/unfolding of build phases as in Magit and Org.

Here it is.  Thanks for the idea!


[-- Attachment #2: 0001-emacs-Add-commands-to-show-hide-build-log-phases.patch --]
[-- Type: text/x-patch, Size: 5639 bytes --]

From f4fad1ab1c78a84ac3b2fdedba4850c5e589ce0d Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Tue, 15 Sep 2015 21:27:44 +0300
Subject: [PATCH] emacs: Add commands to show/hide build log phases.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Suggested by Ludovic Courtès <ludo@gnu.org>.

* emacs/guix-build-log.el (guix-build-log-phase-end-regexp): New
  variable.
  (guix-build-log-phase-start, guix-build-log-phase-end,
  guix-build-log-phase-hide, guix-build-log-phase-show,
  guix-build-log-phase-hidden-p, guix-build-log-phase-toggle-function,
  guix-build-log-phase-toggle, guix-build-log-phase-toggle-all): New functions.
  (guix-build-log-mode-map): Add 'TAB'/'S-TAB' key bindings.
* doc/emacs.texi (Emacs Build Log): Document them.
---
 doc/emacs.texi          |  6 ++++
 emacs/guix-build-log.el | 81 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/doc/emacs.texi b/doc/emacs.texi
index 33bdbd2..6777346 100644
--- a/doc/emacs.texi
+++ b/doc/emacs.texi
@@ -591,6 +591,12 @@ Move to the next build phase.
 @item M-p
 Move to the previous build phase.
 
+@item @key{TAB}
+Toggle (show/hide) the body of the current build phase.
+
+@item S-@key{TAB}
+Toggle (show/hide) the bodies of all build phases.
+
 @end table
 
 There is also @kbd{M-x guix-build-log-minor-mode} which also provides
diff --git a/emacs/guix-build-log.el b/emacs/guix-build-log.el
index 6d71521..6faa37c 100644
--- a/emacs/guix-build-log.el
+++ b/emacs/guix-build-log.el
@@ -144,6 +144,12 @@ STATE is a symbol denoting how a build phase was ended.  It should be
            (group (1+ digit)) " seconds")
      t)))
 
+(defvar guix-build-log-phase-end-regexp
+  ;; For efficiency, it is better to have a regexp for the general line
+  ;; of the phase end, then to call the function all the time.
+  (guix-build-log-phase-end-regexp)
+  "Regexp for the end line of a 'build' phase.")
+
 (defvar guix-build-log-font-lock-keywords
   `((,(guix-build-log-title-regexp 'start)
      (1 'guix-build-log-title-head)
@@ -177,9 +183,84 @@ STATE is a symbol denoting how a build phase was ended.  It should be
     (set-keymap-parent map special-mode-map)
     (define-key map (kbd "M-n") 'guix-build-log-next-phase)
     (define-key map (kbd "M-p") 'guix-build-log-previous-phase)
+    (define-key map (kbd "TAB") 'guix-build-log-phase-toggle)
+    (define-key map (kbd "<tab>") 'guix-build-log-phase-toggle)
+    (define-key map (kbd "<backtab>") 'guix-build-log-phase-toggle-all)
+    (define-key map [(shift tab)] 'guix-build-log-phase-toggle-all)
     map)
   "Keymap for `guix-build-log-mode' buffers.")
 
+(defun guix-build-log-phase-start (&optional with-header?)
+  "Return the start point of the current build phase.
+If WITH-HEADER? is non-nil, do not skip 'starting phase ...' header.
+Return nil, if there is no phase start before the current point."
+  (save-excursion
+    (end-of-line)
+    (when (re-search-backward guix-build-log-phase-start-regexp nil t)
+      (unless with-header? (end-of-line))
+      (point))))
+
+(defun guix-build-log-phase-end ()
+  "Return the end point of the current build phase."
+  (save-excursion
+    (beginning-of-line)
+    (when (re-search-forward guix-build-log-phase-end-regexp nil t)
+      (point))))
+
+(defun guix-build-log-phase-hide ()
+  "Hide the body of the current build phase."
+  (interactive)
+  (let ((beg (guix-build-log-phase-start))
+        (end (guix-build-log-phase-end)))
+    (when (and beg end)
+      ;; If not on the header line, move to it.
+      (when (and (> (point) beg)
+                 (< (point) end))
+        (goto-char (guix-build-log-phase-start t)))
+      (remove-overlays beg end 'invisible t)
+      (let ((o (make-overlay beg end)))
+        (overlay-put o 'evaporate t)
+        (overlay-put o 'invisible t)))))
+
+(defun guix-build-log-phase-show ()
+  "Show the body of the current build phase."
+  (interactive)
+  (let ((beg (guix-build-log-phase-start))
+        (end (guix-build-log-phase-end)))
+    (when (and beg end)
+      (remove-overlays beg end 'invisible t))))
+
+(defun guix-build-log-phase-hidden-p ()
+  "Return non-nil, if the body of the current build phase is hidden."
+  (let ((beg (guix-build-log-phase-start)))
+    (and beg
+         (cl-some (lambda (o)
+                    (overlay-get o 'invisible))
+                  (overlays-at beg)))))
+
+(defun guix-build-log-phase-toggle-function ()
+  "Return a function to toggle the body of the current build phase."
+  (if (guix-build-log-phase-hidden-p)
+      #'guix-build-log-phase-show
+    #'guix-build-log-phase-hide))
+
+(defun guix-build-log-phase-toggle ()
+  "Show/hide the body of the current build phase."
+  (interactive)
+  (funcall (guix-build-log-phase-toggle-function)))
+
+(defun guix-build-log-phase-toggle-all ()
+  "Show/hide the bodies of all build phases."
+  (interactive)
+  (save-excursion
+    ;; Some phases may be hidden, and some shown.  Whether to hide or to
+    ;; show them, it is determined by the state of the first phase here.
+    (goto-char (point-min))
+    (guix-build-log-next-phase)
+    (let ((fun (guix-build-log-phase-toggle-function)))
+      (while (re-search-forward guix-build-log-phase-start-regexp nil t)
+        (funcall fun)))))
+
 (defun guix-build-log-next-phase (&optional arg)
   "Move to the next build phase.
 With ARG, do it that many times.  Negative ARG means move
-- 
2.5.0


  parent reply	other threads:[~2015-09-15 18:56 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-13 19:39 [PATCH 0/3] emacs: Add 'guix-build-log-mode' and friends Alex Kost
2015-09-13 19:39 ` [PATCH 1/3] emacs: Display guix command errors in the minibuffer Alex Kost
2015-09-14  7:22   ` Alex Kost
2015-09-14 11:55     ` Ludovic Courtès
2015-09-14 11:54   ` Ludovic Courtès
2015-09-13 19:39 ` [PATCH 2/3] emacs: Add modes for viewing build logs Alex Kost
2015-09-14 12:01   ` Ludovic Courtès
2015-09-14 12:02   ` Ludovic Courtès
2015-09-15 12:21     ` Alex Kost
2015-09-15 18:56     ` Alex Kost [this message]
2015-09-18  9:42       ` [PATCH] emacs: Add commands to show/hide build log phases Ludovic Courtès
2015-09-13 19:39 ` [PATCH 3/3] emacs: Add "View build log" action to build popup Alex Kost
2015-09-14 12:03   ` Ludovic Courtès
2015-09-14 11:54 ` [PATCH 0/3] emacs: Add 'guix-build-log-mode' and friends Ludovic Courtès

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://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k2rrtsu1.fsf_-_@gmail.com \
    --to=alezost@gmail.com \
    --cc=guix-devel@gnu.org \
    --cc=ludo@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/guix.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).