aboutsummaryrefslogtreecommitdiff
path: root/pearl.el
diff options
context:
space:
mode:
Diffstat (limited to 'pearl.el')
-rw-r--r--pearl.el147
1 files changed, 146 insertions, 1 deletions
diff --git a/pearl.el b/pearl.el
index ae694c1..e7e67e5 100644
--- a/pearl.el
+++ b/pearl.el
@@ -1674,7 +1674,7 @@ PRIORITY-NUM is 0=None, 1=Urgent, 2=High, 3=Medium, 4=Low."
((eq priority-num 2) "High")
((eq priority-num 3) "Medium")
((eq priority-num 4) "Low")
- (t "Medium")))
+ (t "None")))
(defun pearl--md-emphasis-to-org (s)
"Convert markdown links / bold / italic in S to Org markup.
@@ -3718,6 +3718,151 @@ Picker-authoritative: the live id is `LINEAR-ASSIGNEE-ID', diffed against
(org-entry-put marker "LINEAR-ASSIGNEE-ID-SYNCED" remote-id)))))
(pearl--run-atomic-field-save spec callback))))
+(defun pearl--node-priority (node)
+ "The priority number (0-4) of raw issue NODE."
+ (or (cdr (assoc 'priority node)) 0))
+
+(defun pearl--node-state-id (node)
+ "The state id of raw issue NODE, or \"\"."
+ (or (cdr (assoc 'id (cdr (assoc 'state node)))) ""))
+
+(defun pearl--node-state-name (node)
+ "The state name of raw issue NODE, or \"\"."
+ (or (cdr (assoc 'name (cdr (assoc 'state node)))) ""))
+
+(defun pearl--node-label-ids (node)
+ "The sorted label ids of raw issue NODE."
+ (sort (mapcar (lambda (l) (or (cdr (assoc 'id l)) ""))
+ (pearl--node-list (cdr (assoc 'labels node))))
+ #'string<))
+
+(defun pearl--node-label-names (node)
+ "The label display names of raw issue NODE, comma-separated."
+ (mapconcat (lambda (l) (or (cdr (assoc 'name l)) ""))
+ (pearl--node-list (cdr (assoc 'labels node))) ", "))
+
+(defun pearl--save-priority-field (marker callback)
+ "Save the priority of the issue subtree at MARKER, calling CALLBACK.
+The live value is the heading cookie's number, diffed against `LINEAR-PRIORITY'."
+ (org-with-point-at marker
+ (let* ((issue-id (org-entry-get nil "LINEAR-ID"))
+ (identifier (org-entry-get nil "LINEAR-IDENTIFIER"))
+ (live (pearl--priority-number-at-point))
+ (base-str (org-entry-get nil "LINEAR-PRIORITY"))
+ (spec
+ (list
+ :issue-id issue-id :identifier identifier :field 'priority
+ :marker marker :label (format "%s priority" (or identifier issue-id))
+ :live live
+ :baseline (and base-str (string-to-number base-str))
+ :equal #'eql
+ :live-display (pearl--get-linear-priority-name live)
+ :remote-display (lambda (n) (pearl--get-linear-priority-name n))
+ :fetch-remote
+ (lambda (cb)
+ (pearl--fetch-issue-async
+ issue-id
+ (lambda (node)
+ (if (memq node '(:error :missing))
+ (funcall cb :error)
+ (funcall cb (pearl--node-priority node))))))
+ :push
+ (lambda (cb)
+ (pearl--update-issue-async issue-id (list (cons "priority" live)) cb))
+ :commit-local
+ (lambda () (org-entry-put marker "LINEAR-PRIORITY" (number-to-string live)))
+ :commit-remote
+ (lambda (n)
+ (org-with-point-at marker (pearl--set-priority-cookie n))
+ (org-entry-put marker "LINEAR-PRIORITY" (number-to-string n))))))
+ (pearl--run-atomic-field-save spec callback))))
+
+(defun pearl--save-state-field (marker callback)
+ "Save the workflow state of the issue subtree at MARKER, calling CALLBACK.
+The picker arm: the explicit `LINEAR-STATE-ID' is diffed against
+`LINEAR-STATE-ID-SYNCED'. A push sends `stateId'."
+ (org-with-point-at marker
+ (let* ((issue-id (org-entry-get nil "LINEAR-ID"))
+ (identifier (org-entry-get nil "LINEAR-IDENTIFIER"))
+ (live (or (org-entry-get nil "LINEAR-STATE-ID") ""))
+ (remote-node nil)
+ (spec
+ (list
+ :issue-id issue-id :identifier identifier :field 'state
+ :marker marker :label (format "%s state" (or identifier issue-id))
+ :live live
+ :baseline (org-entry-get nil "LINEAR-STATE-ID-SYNCED")
+ :equal #'string=
+ :live-display (or (org-entry-get nil "LINEAR-STATE-NAME") "")
+ :remote-display (lambda (_id) (pearl--node-state-name remote-node))
+ :fetch-remote
+ (lambda (cb)
+ (pearl--fetch-issue-async
+ issue-id
+ (lambda (node)
+ (if (memq node '(:error :missing))
+ (funcall cb :error)
+ (setq remote-node node)
+ (funcall cb (pearl--node-state-id node))))))
+ :push
+ (lambda (cb)
+ (pearl--update-issue-async issue-id (list (cons "stateId" live)) cb))
+ :commit-local
+ (lambda () (org-entry-put marker "LINEAR-STATE-ID-SYNCED" live))
+ :commit-remote
+ (lambda (remote-id)
+ (org-with-point-at marker
+ (pearl--set-heading-state (pearl--node-state-name remote-node) remote-id))
+ (org-entry-put marker "LINEAR-STATE-ID-SYNCED" remote-id)))))
+ (pearl--run-atomic-field-save spec callback))))
+
+(defun pearl--save-labels-field (marker callback)
+ "Save the labels of the issue subtree at MARKER, calling CALLBACK.
+The live id set is `LINEAR-LABEL-IDS', diffed order-insensitively against
+`LINEAR-LABEL-IDS-SYNCED' (canonicalized to a sorted space-joined string). A
+push sends `labelIds'."
+ (org-with-point-at marker
+ (let* ((issue-id (org-entry-get nil "LINEAR-ID"))
+ (identifier (org-entry-get nil "LINEAR-IDENTIFIER"))
+ (live-ids (sort (split-string
+ (or (org-entry-get nil "LINEAR-LABEL-IDS") "") " " t)
+ #'string<))
+ (live (string-join live-ids " "))
+ (base-str (org-entry-get nil "LINEAR-LABEL-IDS-SYNCED"))
+ (remote-node nil)
+ (spec
+ (list
+ :issue-id issue-id :identifier identifier :field 'labels
+ :marker marker :label (format "%s labels" (or identifier issue-id))
+ :live live
+ :baseline (and base-str
+ (string-join (sort (split-string base-str " " t) #'string<) " "))
+ :equal #'string=
+ :live-display (or (org-entry-get nil "LINEAR-LABELS") "[]")
+ :remote-display (lambda (_) (format "[%s]" (pearl--node-label-names remote-node)))
+ :fetch-remote
+ (lambda (cb)
+ (pearl--fetch-issue-async
+ issue-id
+ (lambda (node)
+ (if (memq node '(:error :missing))
+ (funcall cb :error)
+ (setq remote-node node)
+ (funcall cb (string-join (pearl--node-label-ids node) " "))))))
+ :push
+ (lambda (cb)
+ (pearl--update-issue-async
+ issue-id (list (cons "labelIds" (vconcat live-ids))) cb))
+ :commit-local
+ (lambda () (org-entry-put marker "LINEAR-LABEL-IDS-SYNCED" live))
+ :commit-remote
+ (lambda (remote-str)
+ (org-entry-put marker "LINEAR-LABEL-IDS" remote-str)
+ (org-entry-put marker "LINEAR-LABELS"
+ (format "[%s]" (pearl--node-label-names remote-node)))
+ (org-entry-put marker "LINEAR-LABEL-IDS-SYNCED" remote-str)))))
+ (pearl--run-atomic-field-save spec callback))))
+
(defun pearl--save-field-thunks (marker dirty viewer-id)
"Build the ordered save thunks for the DIRTY fields of the issue at MARKER.
Title first, then description, then each changed comment candidate (VIEWER-ID