branch: elpa/logview
commit 673c90b48a94755c0f7d8d91ad9e2a7c529e7a1a
Author: Paul Pogonyshev <pogonys...@gmail.com>
Commit: Paul Pogonyshev <pogonys...@gmail.com>

    Experimentally preview filtering results when editing filters in a separate 
buffer.
---
 logview.el | 89 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 70 insertions(+), 19 deletions(-)

diff --git a/logview.el b/logview.el
index 5b384252ee..8c1a2176e2 100644
--- a/logview.el
+++ b/logview.el
@@ -692,7 +692,14 @@ settings) with this face.")
 
 (defvar-local logview--main-filter-text             "")
 (defvar-local logview--thread-narrowing-filter-text "")
-(defvar-local logview--effective-filter             nil)
+
+(defvar-local logview--preview-filter-text nil
+  "Filters for which to show a preview.
+Take precedence over real filters.  When set, must be a cons cell
+of (IS-MAIN . FILTER-TEXT).")
+
+(defvar-local logview--effective-filter nil
+  "See `logview--do-parse-filters' for the format.")
 
 ;; I also considered using private cons cells where we could reset `car' e.g. 
from
 ;; `logview-filtered' to nil.  However, this is very shaky and will stop 
working if any
@@ -745,6 +752,7 @@ settings) with this face.")
 (defvar-local logview-filter-edit--editing-views-for-submode nil)
 (defvar-local logview-filter-edit--parent-buffer             nil)
 (defvar-local logview-filter-edit--window-configuration      nil)
+(defvar-local logview-filter-edit--preview-timer             nil)
 
 (defvar logview-filter-edit--filters-hint-comment
   "# Press C-c C-c to save edited filters, C-c C-k to quit without saving.
@@ -3351,18 +3359,33 @@ See `logview--iterate-entries-forward' for details."
 
 ;; Return non-nil if filters have changed.
 (defun logview--parse-filters (&optional to-reset)
-  (let ((filters (logview--do-parse-filters logview--main-filter-text 
logview--thread-narrowing-filter-text to-reset)))
-    (unless (prog1 (equal (cdar logview--effective-filter) (cdar filters))
-              (setf logview--effective-filter             filters
-                    logview--main-filter-text             (or (caar (car 
filters)) "")
-                    logview--thread-narrowing-filter-text (or (cdar (car 
filters)) "")))
-      (logview--refilter)
-      (logview--update-mode-name)
-      t)))
+  (let ((main-filters             logview--main-filter-text)
+        (thread-narrowing-filters logview--thread-narrowing-filter-text)
+        (preview-filters          logview--preview-filter-text))
+    (when preview-filters
+      (setf (if (car preview-filters) main-filters thread-narrowing-filters) 
(cdr preview-filters)))
+    (let ((filters (logview--do-parse-filters main-filters 
thread-narrowing-filters to-reset)))
+      (unless (prog1 (equal (cdar logview--effective-filter) (cdar filters))
+                (setf logview--effective-filter filters)
+                (unless (and preview-filters (car preview-filters))
+                  (setf logview--main-filter-text (or (caar (car filters)) 
"")))
+                (unless (and preview-filters (not (car preview-filters)))
+                  (setf logview--thread-narrowing-filter-text (or (cdar (car 
filters)) ""))))
+        (logview--refilter)
+        (logview--update-mode-name)
+        t))))
 
-;; Returns (((MAIN-FILTER-TEXT . THREAD-NARROWING-FILTER-TEXT) . KEY) . 
VALIDATOR-FN) or nil
-;; if there are no filters.
 (defun logview--do-parse-filters (filters &optional thread-narrowing-filters 
to-reset-in-main-filters)
+  "Parse given FILTERS and optional THREAD-NARROWING-FILTERS.
+TO-RESET-IN-MAIN-FILTERS may be a list of strings like \"a+\" of
+filter types to discard.
+
+Returns
+
+    (((MAIN-FILTER-TEXT . THREAD-NARROWING-FILTER-TEXT) . KEY)
+     . VALIDATOR-FN)
+
+or nil if there are no filters."
   (let (non-discarded-lines-main
         non-discarded-lines-narrowing
         min-shown-level
@@ -3981,7 +4004,10 @@ This list is preserved across Emacs session in
 (define-derived-mode logview-filter-edit-mode nil "Logview Filters"
   "Major mode for editing filters of a Logview buffer."
   (logview-filter-edit--font-lock-region (point-min) (point-max))
-  (add-hook 'after-change-functions 'logview-filter-edit--font-lock-region t 
t))
+  ;; FIXME: Use `font-lock-defaults' as in the main buffer.  Not very 
important, as filter
+  ;;        buffers are usually not large.
+  (add-hook 'after-change-functions #'logview-filter-edit--font-lock-region t 
t)
+  (add-hook 'after-change-functions #'logview-filter-edit--schedule-preview t 
t))
 
 (defun logview-filter-edit-save ()
   "Save the edited filters or views and quit the buffer and window."
@@ -4004,11 +4030,17 @@ only edits after it get discarded."
   (interactive)
   (logview-filter-edit--do nil t))
 
-(defun logview-filter-edit--do (save quit)
+(defun logview-filter-edit--do (process-filters quit)
   (let* ((mode    logview-filter-edit--mode)
          (parent  logview-filter-edit--parent-buffer)
-         (windows logview-filter-edit--window-configuration))
-    (when save
+         (windows logview-filter-edit--window-configuration)
+         filters-changed)
+    (when quit
+      (with-current-buffer parent
+        (when logview--preview-filter-text
+          (setf logview--preview-filter-text nil
+                filters-changed              t))))
+    (when process-filters
       (if (eq mode 'views)
           (let ((new-views (save-excursion
                              (goto-char 1)
@@ -4024,14 +4056,18 @@ only edits after it get discarded."
             (logview--after-updating-view-definitions)
             (with-current-buffer parent
               (logview--update-mode-name)))
-        (let ((filters      (when save
-                              (buffer-substring-no-properties 1 (1+ 
(buffer-size)))))
+        (let ((filters      (buffer-substring-no-properties 1 (1+ 
(buffer-size))))
               (hint-comment (logview-filter-edit--hint-comment)))
             (when (string-prefix-p hint-comment filters)
               (setf filters (substring filters (length hint-comment))))
             (with-current-buffer parent
-              (setf (if (eq mode 'main-filters) logview--main-filter-text 
logview--thread-narrowing-filter-text) filters)
-              (logview--parse-filters)))))
+              (if (eq process-filters 'preview)
+                  (setf logview--preview-filter-text `(,(eq mode 
'main-filters) . ,filters))
+                (setf (if (eq mode 'main-filters) logview--main-filter-text 
logview--thread-narrowing-filter-text) filters))
+              (setf filters-changed t)))))
+    (when filters-changed
+      (with-current-buffer parent
+        (logview--parse-filters)))
     (when quit
       (kill-buffer)
       (switch-to-buffer parent)
@@ -4124,6 +4160,21 @@ only edits after it get discarded."
                (put-text-property begin end 'face 'error))
              (< (point) region-end))))))))
 
+(defun logview-filter-edit--schedule-preview (&rest _ignored)
+  (unless (or logview-filter-edit--preview-timer (eq logview-filter-edit--mode 
'views))
+    (setf logview-filter-edit--preview-timer (run-with-idle-timer 0.2 nil 
#'logview-filter-edit--trigger-preview (current-buffer)))))
+
+(defun logview-filter-edit--trigger-preview (buffer)
+  (let ((debug-on-error t))
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (logview-filter-edit--do 'preview nil)
+        ;; Clear the timer only now, so if it gets rescheduled above, it gets 
removed
+        ;; instantly.
+        (when logview-filter-edit--preview-timer
+          (cancel-timer logview-filter-edit--preview-timer)
+          (setf logview-filter-edit--preview-timer nil))))))
+
 (defun logview-filter-edit--hint-comment ()
   (pcase logview-filter-edit--mode
     (`main-filters             logview-filter-edit--filters-hint-comment)

Reply via email to