Browse Source

org-agenda.el: Rewrite agenda filtering using text properties

* org-agenda.el (org-agenda-write): Code cleanup.
(org-agenda-fix-tags-filter-overlays-at): Delete.
(org-agenda-remove-marked-text): Use the `property' argument
instead of hard-coding 'org-filtered.
(org-agenda-filter-remove-all): Use `org-agenda-finalize'.
(org-agenda-filter-hide-line): Rewrite using text properties
instead of overlays.
(org-agenda-remove-filter): New function.
(org-agenda-filter-show-all-re): Rewrite using
Bastien Guerry 6 years ago
1 changed files with 23 additions and 75 deletions
  1. 23 75

+ 23 - 75

@@ -2092,11 +2092,8 @@ When nil, `q' will kill the single agenda buffer."
-    org-agenda-tag-filter-overlays
-    org-agenda-cat-filter-overlays
-    org-agenda-re-filter-overlays
@@ -3324,19 +3321,12 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
   (org-let (if nosettings nil org-agenda-exporter-settings)
-	 (org-agenda-mark-filtered-text)
 	 (let ((bs (copy-sequence (buffer-string))) beg content)
-	   (org-agenda-unmark-filtered-text)
 	     (rename-buffer org-agenda-write-buffer-name t)
 	     (set-buffer-modified-p nil)
 	     (insert bs)
 	     (org-agenda-remove-marked-text 'org-filtered)
-	     (while (setq beg (text-property-any (point-min) (point-max)
-						 'org-filtered t))
-	       (delete-region
-		beg (or (next-single-property-change beg 'org-filtered)
-			(point-max))))
 	     (run-hooks 'org-agenda-before-write-hook)
 	      ((org-bound-and-true-p org-mobile-creating-agendas)
@@ -3402,28 +3392,6 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
   (when open (org-open-file file)))
-(defvar org-agenda-tag-filter-overlays nil)
-(defvar org-agenda-cat-filter-overlays nil)
-(defvar org-agenda-re-filter-overlays nil)
-(defun org-agenda-mark-filtered-text ()
-  "Mark all text hidden by filtering with a text property."
-  (let ((inhibit-read-only t))
-    (mapc
-     (lambda (o)
-       (when (equal (overlay-buffer o) (current-buffer))
-	 (put-text-property
-	  (overlay-start o) (overlay-end o)
-	  'org-filtered t)))
-     (append org-agenda-tag-filter-overlays
-	     org-agenda-cat-filter-overlays
-	     org-agenda-re-filter-overlays))))
-(defun org-agenda-unmark-filtered-text ()
-  "Remove the filtering text property."
-  (let ((inhibit-read-only t))
-    (remove-text-properties (point-min) (point-max) '(org-filtered t))))
 (defun org-agenda-remove-marked-text (property &optional value)
   "Delete all text marked with VALUE of PROPERTY.
 VALUE defaults to t."
@@ -3432,7 +3400,7 @@ VALUE defaults to t."
     (while (setq beg (text-property-any (point-min) (point-max)
 					property value))
-       beg (or (next-single-property-change beg 'org-filtered)
+       beg (or (next-single-property-change beg property)
 (defun org-agenda-add-entry-text ()
@@ -7400,7 +7368,8 @@ With two prefix arguments, remove the regexp filters."
   (when org-agenda-category-filter
   (when org-agenda-regexp-filter
-    (org-agenda-filter-show-all-re)))
+    (org-agenda-filter-show-all-re))
+  (org-agenda-finalize))
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
   "Keep only those lines in the agenda buffer that have a specific tag.
@@ -7672,50 +7641,31 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
 (defun org-agenda-filter-hide-line (type)
   "Hide lines with TYPE in the agenda buffer."
   (let* ((b (max (point-min) (1- (point-at-bol))))
-	 (e (point-at-eol))
-	 (ov (make-overlay b e)))
-    (overlay-put ov 'invisible t)
-    (overlay-put ov 'intangible t)
-    (overlay-put ov 'type type)
-    (cond ((eq type 'tag) (push ov org-agenda-tag-filter-overlays))
-	  ((eq type 'category) (push ov org-agenda-cat-filter-overlays))
-	  ((eq type 'regexp) (push ov org-agenda-re-filter-overlays)))))
-(defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
-  (setq pos (or pos (point)))
-  (save-excursion
-    (dolist (ov (overlays-at pos))
-      (when (and (overlay-get ov 'invisible)
-		 (eq (overlay-get ov 'type) 'tag))
-	(goto-char pos)
-	(if (< (overlay-start ov) (point-at-eol))
-	    (move-overlay ov (point-at-eol)
-			  (overlay-end ov)))))))
+	 (e (point-at-eol)))
+    (let ((inhibit-read-only t))
+      (add-text-properties
+       b e `(invisible t org-filtered t org-filter-type ,type)))))
-(defun org-agenda-filter-show-all-tag nil
-  "Remove tag filter overlays from the agenda buffer."
-  (mapc 'delete-overlay org-agenda-tag-filter-overlays)
-  (setq org-agenda-tag-filter-overlays nil
-	org-agenda-tag-filter nil
-	org-agenda-filter-form nil)
+(defun org-agenda-remove-filter (type)
+  (interactive)
+  "Remove filter of type TYPE from the agenda buffer."
+  (goto-char (point-min))
+  (let ((inhibit-read-only t) pos)
+    (while (setq pos (text-property-any (point) (point-max) 'org-filter-type type))
+      (goto-char pos)
+      (remove-text-properties
+       (point) (next-single-property-change (point) 'org-filter-type)
+       `(invisible t org-filter-type ,type))))
+  (set (intern (format "org-agenda-%s-filter" (intern-soft type))) nil)
+  (setq org-agenda-filter-form nil)
+(defun org-agenda-filter-show-all-tag nil
+  (org-agenda-remove-filter 'tag))
 (defun org-agenda-filter-show-all-re nil
-  "Remove regexp filter overlays from the agenda buffer."
-  (mapc 'delete-overlay org-agenda-re-filter-overlays)
-  (setq org-agenda-re-filter-overlays nil
-	org-agenda-regexp-filter nil
-	org-agenda-filter-form nil)
-  (org-agenda-set-mode-name))
+  (org-agenda-remove-filter 'regexp))
 (defun org-agenda-filter-show-all-cat nil
-  "Remove category filter overlays from the agenda buffer."
-  (mapc 'delete-overlay org-agenda-cat-filter-overlays)
-  (setq org-agenda-cat-filter-overlays nil
-	org-agenda-filtered-by-category nil
-	org-agenda-category-filter nil
-	org-agenda-filter-form nil)
-  (org-agenda-set-mode-name))
+  (org-agenda-remove-filter 'category))
 (defun org-agenda-manipulate-query-add ()
   "Manipulate the query by adding a search term with positive selection.
@@ -9180,8 +9130,6 @@ Called with a universal prefix arg, show the priority instead of setting it."
 	(when (equal marker (org-get-at-bol 'org-marker))
 	  (remove-text-properties (point-at-bol) (point-at-eol) '(display))
 	  (org-move-to-column (- (window-width) (length stamp)) t)
-	  (org-agenda-fix-tags-filter-overlays-at (point))
           (if (featurep 'xemacs)
 	      ;; Use `duplicable' property to trigger undo recording
               (let ((ex (make-extent nil nil))