From 7cdd9a7490e6a3d0725adcf6fea8c678fafc4416 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 28 Jun 2026 14:47:49 -0400 Subject: feat(calibre): open calibredb filtered to the in-progress books Every calibredb launch (the dashboard "b", M-x, anywhere) now opens filtered to the in-progress books rather than the whole library, via an :after advice on calibredb. Clear with L or x to see everything. The filter scopes to the tag field (calibredb-tag-filter-p), not a bare keyword search. A bare keyword matches any field, which surfaced books that only mention "in-progress" in their description. --- modules/calibredb-epub-config.el | 34 ++++++++++++- ...est-calibredb-epub-config--open-to-favorites.el | 57 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tests/test-calibredb-epub-config--open-to-favorites.el diff --git a/modules/calibredb-epub-config.el b/modules/calibredb-epub-config.el index 8518ffe91..38aa0de05 100644 --- a/modules/calibredb-epub-config.el +++ b/modules/calibredb-epub-config.el @@ -33,6 +33,15 @@ ;; calibredb commands the curated menu drives (all autoloaded by calibredb) (declare-function calibredb-switch-library "calibredb" ()) +(declare-function calibredb-search-keyword-filter "calibredb-search") + +;; calibredb's filter-scope flags (set in `cj/--calibredb-open-to-favorites'); +;; declared special so the assignments compile clean when calibredb is absent. +(defvar calibredb-tag-filter-p) +(defvar calibredb-favorite-filter-p) +(defvar calibredb-author-filter-p) +(defvar calibredb-date-filter-p) +(defvar calibredb-format-filter-p) (declare-function calibredb-filter-by-book-format "calibredb" ()) (declare-function calibredb-filter-by-author-sort "calibredb" ()) (declare-function calibredb-search-clear-filter "calibredb" ()) @@ -87,6 +96,26 @@ which re-applies `calibredb-search-filter' instead." (setq calibredb-sort-by field) (calibredb-search-refresh-or-resume)) +(defun cj/--calibredb-open-to-favorites (&rest _) + "Filter the calibredb search to books tagged `calibredb-favorite-keyword'. +Advice (:after) on `calibredb' so every launch lands on the favorite-keyword +books (Craig's \"in-progress\" reading list); clear with L / x to see the +whole library. Scopes to the tag field (sets `calibredb-tag-filter-p', +clears the other filter-scope flags), because a bare keyword filter matches +the keyword in any field -- title, author, or the description -- and would +surface books that merely mention it. No-op unless a non-empty string +keyword is set." + (when (and (boundp 'calibredb-favorite-keyword) + (stringp calibredb-favorite-keyword) + (not (string-empty-p calibredb-favorite-keyword)) + (fboundp 'calibredb-search-keyword-filter)) + (setq calibredb-tag-filter-p t + calibredb-favorite-filter-p nil + calibredb-author-filter-p nil + calibredb-date-filter-p nil + calibredb-format-filter-p nil) + (calibredb-search-keyword-filter calibredb-favorite-keyword))) + (use-package calibredb :commands calibredb :bind @@ -155,7 +184,10 @@ which re-applies `calibredb-search-filter' instead." (setq calibredb-order "asc") (setq calibredb-id-width 7) (setq calibredb-favorite-icon "🔖") - (setq calibredb-favorite-keyword "in-progress")) + (setq calibredb-favorite-keyword "in-progress") + ;; Open every calibredb launch (dashboard, M-x, elsewhere) filtered to the + ;; in-progress favorites; L / x clears to the whole library. + (advice-add 'calibredb :after #'cj/--calibredb-open-to-favorites)) ;; ------------------------------ Nov Epub Reader ------------------------------ diff --git a/tests/test-calibredb-epub-config--open-to-favorites.el b/tests/test-calibredb-epub-config--open-to-favorites.el new file mode 100644 index 000000000..d11618081 --- /dev/null +++ b/tests/test-calibredb-epub-config--open-to-favorites.el @@ -0,0 +1,57 @@ +;;; test-calibredb-epub-config--open-to-favorites.el --- in-progress open filter -*- lexical-binding: t; -*- + +;;; Commentary: +;; `cj/--calibredb-open-to-favorites' advises `calibredb' :after so every launch +;; lands filtered to `calibredb-favorite-keyword' (Craig's "in-progress" books). +;; It scopes the filter to the TAG field (sets `calibredb-tag-filter-p', clears +;; the other filter-p flags) before delegating to `calibredb-search-keyword-filter', +;; so the keyword can't over-match in a book's title or description. It no-ops +;; when no usable keyword is set. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'calibredb-epub-config) + +;; calibredb defcustom + internal flags; declared special so `let' binds them +;; dynamically (all unbound under `make test', which never runs the use-package +;; :config or loads calibredb). +(defvar calibredb-favorite-keyword) +(defvar calibredb-tag-filter-p) +(defvar calibredb-favorite-filter-p) +(defvar calibredb-author-filter-p) +(defvar calibredb-date-filter-p) +(defvar calibredb-format-filter-p) + +(ert-deftest test-calibredb-open-to-favorites-applies-keyword-scoped-to-tags () + "Normal: with a favorite keyword set, the filter runs with that keyword and is +scoped to the tag field (so it can't over-match a description); a stale +non-tag filter flag is cleared." + (let ((applied :unset) + (calibredb-favorite-keyword "in-progress") + (calibredb-tag-filter-p nil) + (calibredb-favorite-filter-p t) ; stale, must be cleared + (calibredb-author-filter-p nil) + (calibredb-date-filter-p nil) + (calibredb-format-filter-p nil)) + (cl-letf (((symbol-function 'calibredb-search-keyword-filter) + (lambda (kw) (setq applied kw)))) + (cj/--calibredb-open-to-favorites)) + (should (equal applied "in-progress")) ; keyword applied + (should (eq calibredb-tag-filter-p t)) ; scoped to the tag field + (should-not calibredb-favorite-filter-p))) ; stale flag cleared + +(ert-deftest test-calibredb-open-to-favorites-noop-without-usable-keyword () + "Boundary/Error: nil, empty, or non-string keyword applies no filter." + (dolist (kw (list nil "" 42)) + (let ((applied :unset) + (calibredb-favorite-keyword kw)) + (cl-letf (((symbol-function 'calibredb-search-keyword-filter) + (lambda (k) (setq applied k)))) + (cj/--calibredb-open-to-favorites)) + (should (eq applied :unset))))) + +(provide 'test-calibredb-epub-config--open-to-favorites) +;;; test-calibredb-epub-config--open-to-favorites.el ends here -- cgit v1.2.3