aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-05 02:08:43 -0500
committerCraig Jennings <c@cjennings.net>2026-06-05 02:08:43 -0500
commit877c104bfa8497324de45b2fef96dd4520da07e4 (patch)
tree6ddb080df52cada9815a704eea3b4b37981bb2e6
parent5940d7caf21f5c2b8e322a67f32657dace56fc9a (diff)
downloadpearl-877c104bfa8497324de45b2fef96dd4520da07e4.tar.gz
pearl-877c104bfa8497324de45b2fef96dd4520da07e4.zip
fix(render): serialize the source header in full regardless of print-length
The #+LINEAR-SOURCE descriptor was written with a bare prin1-to-string, which honors the user's print-length and print-level. A long source, like a Custom View's (it carries a sort vector, a url, and several keys), truncated to "..." for anyone whose config caps those (mine sits at 10). The header then read back as a malformed, odd-length plist, so refresh and the new sort commands errored on the view. A short source like my-open-issues fit under the cap and hid the bug. pearl--linear-source-string binds both to nil around the serialization, and the two header writers (the full render and the sort header rewrite) go through it. I caught it dogfooding the interactive sort live on a real view.
-rw-r--r--pearl.el13
-rw-r--r--tests/test-pearl-sort.el12
2 files changed, 23 insertions, 2 deletions
diff --git a/pearl.el b/pearl.el
index 1cf4b53..a24d7dd 100644
--- a/pearl.el
+++ b/pearl.el
@@ -4187,6 +4187,15 @@ merge rewrites keep working."
(propertize (concat (pearl--preamble-summary) "\n")
'face 'pearl-preamble-summary))))))))
+(defun pearl--linear-source-string (source)
+ "Serialize SOURCE for the `#+LINEAR-SOURCE:' header, in full.
+Binds `print-length' and `print-level' to nil so a long source (a view's
+descriptor carries a sort vector, url, and several keys) never truncates to
+`...' under a user's global print settings -- a truncated descriptor reads back
+as a malformed plist and breaks refresh and sort."
+ (let ((print-length nil) (print-level nil))
+ (prin1-to-string source)))
+
(defun pearl--build-org-content (issues &optional source truncated states account)
"Build the Org content string for the linear org file from ISSUES.
SOURCE is the active-source descriptor recorded in the header so a later
@@ -4219,7 +4228,7 @@ no side effects."
;; rest is human-readable provenance.
(when account
(insert (format "#+LINEAR-ACCOUNT: %s\n" account)))
- (insert (format "#+LINEAR-SOURCE: %s\n" (prin1-to-string src)))
+ (insert (format "#+LINEAR-SOURCE: %s\n" (pearl--linear-source-string src)))
(insert (format "#+LINEAR-RUN-AT: %s\n" (format-time-string "%Y-%m-%d %H:%M")))
(insert (format "#+LINEAR-FILTER: %s\n" (pearl--summarize-filter filter)))
(insert (format "#+LINEAR-COUNT: %d\n" (length issues)))
@@ -6782,7 +6791,7 @@ count/timestamp provenance and leaves the descriptor alone."
(save-excursion
(goto-char (point-min))
(when (re-search-forward "^#\\+LINEAR-SOURCE: .*$" nil t)
- (replace-match (format "#+LINEAR-SOURCE: %s" (prin1-to-string source)) t t))))
+ (replace-match (format "#+LINEAR-SOURCE: %s" (pearl--linear-source-string source)) t t))))
(defun pearl--active-source-or-error ()
"Return the active source descriptor, or signal a `user-error' if absent."
diff --git a/tests/test-pearl-sort.el b/tests/test-pearl-sort.el
index a5292b3..8833675 100644
--- a/tests/test-pearl-sort.el
+++ b/tests/test-pearl-sort.el
@@ -127,6 +127,18 @@ leaving its server :sort (an IssueSortInput) untouched."
(should (eq (plist-get src :sort) 'priority))
(should (eq (plist-get src :order) 'asc)))))
+(ert-deftest test-pearl-write-source-header-survives-print-length ()
+ "A long source serializes in full even when print-length/level are bound low.
+A view source is long enough to truncate under a user's `print-length', which
+would persist an unreadable #+LINEAR-SOURCE and break refresh/sort."
+ (test-pearl-sort--in-org test-pearl-sort--flat
+ (let ((print-length 2) (print-level 2)
+ (src '(:type view :name "V" :id "vid" :url "u" :sort ((:a 1))
+ :show-completed "none" :group "x"
+ :client-sort priority :client-order asc)))
+ (pearl--write-linear-source-header src)
+ (should (equal (pearl--read-active-source) src)))))
+
;;; client-side reorder
(ert-deftest test-pearl-reorder-priority-ascending ()