aboutsummaryrefslogtreecommitdiff
path: root/pearl.el
diff options
context:
space:
mode:
Diffstat (limited to 'pearl.el')
-rw-r--r--pearl.el44
1 files changed, 36 insertions, 8 deletions
diff --git a/pearl.el b/pearl.el
index 945c9af..1cf4b53 100644
--- a/pearl.el
+++ b/pearl.el
@@ -6813,13 +6813,18 @@ order. The keyed sort is stable, so equal keys keep document order."
(ordered (cl-stable-sort (copy-sequence keyed) cmp)))
(append ordered unkeyed))))
-(defun pearl--reorder-issue-subtrees (sort order)
+(defun pearl--reorder-issue-subtrees (sort order &optional id-ranks)
"Reorder the active view's issue subtrees in place by SORT in ORDER.
Moves whole subtrees byte-for-byte -- descriptions, comments, drawers, and any
unsaved local edits survive unchanged -- rather than reconstructing them from
parsed data. A non-issue level-2 subtree (no `LINEAR-ID') is kept and sorted
last. Returns t on success, `grouped' when issues sit below level 2 (a grouped
-view, unsupported in v1), or `no-issues' when there are none."
+view, unsupported in v1), or `no-issues' when there are none.
+
+ID-RANKS, when non-nil, is a hash mapping `LINEAR-ID' to an integer position;
+each subtree is keyed by its rank and laid out ascending, so the buffer matches
+a server-fetched order (SORT/ORDER are then ignored). This is how the
+server-side sort reorders the merged buffer without losing local edits."
(save-excursion
(let ((markers (pearl--issue-subtree-markers)))
(cond
@@ -6845,7 +6850,8 @@ view, unsupported in v1), or `no-issues' when there are none."
(end (save-excursion (org-end-of-subtree t t) (point)))
(id (org-entry-get nil "LINEAR-ID"))
(key (and id (not (string-empty-p id))
- (pearl--issue-sort-key sort)))
+ (if id-ranks (gethash id id-ranks)
+ (pearl--issue-sort-key sort))))
(text (buffer-substring-no-properties beg end)))
(unless block-beg (setq block-beg beg))
(setq block-end end)
@@ -6854,7 +6860,8 @@ view, unsupported in v1), or `no-issues' when there are none."
(goto-char end))
(goto-char (save-excursion (org-end-of-subtree t t) (point)))))
(when (and block-beg block-end)
- (let ((sorted (pearl--sort-subtree-entries (nreverse children) order)))
+ (let ((sorted (pearl--sort-subtree-entries
+ (nreverse children) (if id-ranks 'asc order))))
(delete-region block-beg block-end)
(goto-char block-beg)
(insert (mapconcat (lambda (c) (plist-get c :text)) sorted ""))))
@@ -6877,11 +6884,30 @@ toggle until you sort it."
(cons 'updated 'desc)
(cons s (if (eq o 'asc) 'desc 'asc))))))
+(defun pearl--issue-id-ranks (result source)
+ "Build a `LINEAR-ID' -> position hash from RESULT, in SOURCE's sort order.
+The fetched nodes are normalized and sorted the same way the render path sorts
+them, so the hash captures the order the server returned for the new `orderBy'."
+ (let* ((eff (pearl--effective-sort-order source))
+ (issues (pearl--sort-issues
+ (mapcar #'pearl--normalize-issue
+ (pearl--query-result-issues result))
+ (car eff) (cdr eff)))
+ (ranks (make-hash-table :test 'equal))
+ (i 0))
+ (dolist (issue issues)
+ (puthash (plist-get issue :id) i ranks)
+ (setq i (1+ i)))
+ ranks))
+
(defun pearl--apply-server-sort (source sort order)
"Refetch SOURCE (a filter) with the server `orderBy' for SORT, then persist.
-On success merges the result and writes the updated `#+LINEAR-SOURCE' header; on
-an empty/failed fetch it leaves the header unchanged and reports the merge
-outcome, so a failed sort never advertises an order the buffer doesn't show."
+Merges the result (so unpushed edits survive), reorders the buffer's issue
+subtrees to the fetched order -- a merge alone updates issues in place and never
+moves them, so the new order would be invisible -- and writes the updated
+`#+LINEAR-SOURCE' header. An empty/failed fetch leaves the header unchanged and
+just reports the merge outcome, so a failed sort never advertises an order the
+buffer doesn't show."
(let ((buffer (current-buffer)))
(pearl--progress "Refetching %s ordered by %s %s..."
(pearl--source-name source) sort order)
@@ -6892,7 +6918,9 @@ outcome, so a failed sort never advertises an order the buffer doesn't show."
(with-current-buffer buffer
(pcase (pearl--query-result-status result)
('ok
- (pearl--merge-query-result result source)
+ (let ((ranks (pearl--issue-id-ranks result source)))
+ (pearl--merge-query-result result source)
+ (pearl--reorder-issue-subtrees nil 'asc ranks))
(pearl--write-linear-source-header source)
(message "Refetched %s ordered by %s %sending"
(pearl--source-name source) sort