aboutsummaryrefslogtreecommitdiff
path: root/pearl.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-28 09:36:06 -0500
committerCraig Jennings <c@cjennings.net>2026-05-28 09:36:06 -0500
commit0975e7de0c7bfdc6f65bb64537d4eff1aeb09a7e (patch)
tree4b872db4e0417e173595409c63c7d1291015adbd /pearl.el
parentfd94237903c15883173e438a5af4ba4e6bfdbd46 (diff)
downloadpearl-0975e7de0c7bfdc6f65bb64537d4eff1aeb09a7e.tar.gz
pearl-0975e7de0c7bfdc6f65bb64537d4eff1aeb09a7e.zip
feat(view-sync): pearl-publish-current-source convenience wrapper
This is Phase 5 of docs/saved-query-sync-spec.org (§ New: pearl-publish-current-source). When I'm reading a local saved query rendered in pearl and decide it should be a Linear view, I now have a one-chord publish instead of the M-x round-trip through pearl-sync-saved-query-to-linear with the name lookup. The new command reads the active buffer's #+LINEAR-SOURCE header and dispatches to pearl-sync-saved-query-to-linear with the name pre-filled when the source is a :type filter that matches an entry in pearl-saved-queries. Other shapes refuse with a clear message: no source header at all, the source is already a :type view (no publish needed), the type isn't filter, the source has no usable name (transient ad-hoc filter, or whitespace-only name), or the recorded name doesn't match any local saved query. I bound the command under C-; L f P in pearl-fetch-map. The transient gets ("U" "upload current source") in the Fetch group because P is taken in the transient's flat namespace, and the verb-prefix shape revisit task tracks reshaping that. 7 new tests cover each refusal branch and the dispatch path, including a regression for the whitespace-only :name case the pre-commit review surfaced. The prior check used string-empty-p, which let " " fall through to the no-matching-saved-query branch with a visibly-blank name in the error message. string-blank-p routes it to the cleaner no-name branch. The keymap and transient menu tests gained coverage for the new binding. 660 ert tests total green. make compile and make lint clean.
Diffstat (limited to 'pearl.el')
-rw-r--r--pearl.el38
1 files changed, 37 insertions, 1 deletions
diff --git a/pearl.el b/pearl.el
index 724664b..61c4934 100644
--- a/pearl.el
+++ b/pearl.el
@@ -4040,6 +4040,39 @@ scope-and-visibility display string for the success message."
(message "Failed to sync %s: %s" name
(or (plist-get result :error) "Linear refused the create"))))))
+;;;###autoload
+(defun pearl-publish-current-source ()
+ "Publish the active buffer's local saved query to Linear as a Custom View.
+Convenience wrapper. Reads `#+LINEAR-SOURCE' from the current buffer.
+When it's a `:type filter' source whose `:name' matches a local saved
+query, dispatches to `pearl-sync-saved-query-to-linear' with that name
+pre-filled. Otherwise refuses with a clear message: the source is
+already a Linear view (no publish needed), the filter is transient (no
+name to sync under), or no local saved query matches the recorded name.
+
+Bound under \\='C-; L f P\\=' inside `pearl-mode' buffers; reachable
+through the transient as the `U' (upload) entry in the Fetch group."
+ (interactive)
+ (let* ((source (pearl--read-active-source))
+ (type (and source (plist-get source :type)))
+ (name (and source (plist-get source :name))))
+ (cond
+ ((null source)
+ (user-error "No active source header in this buffer; nothing to publish"))
+ ((eq type 'view)
+ (user-error "Source is already a Linear view (%s); no publish needed"
+ (or name "<unnamed>")))
+ ((not (eq type 'filter))
+ (user-error "Unsupported source type %s; only filter sources can be published"
+ type))
+ ((or (null name) (and (stringp name) (string-blank-p name)))
+ (user-error "Source has no name; save it first via pearl-list-issues-filtered then re-publish"))
+ ((not (assoc name pearl-saved-queries))
+ (user-error "No local saved query named %s; save it first via pearl-list-issues-filtered"
+ name))
+ (t
+ (pearl-sync-saved-query-to-linear name)))))
+
(defun pearl--sync-saved-query-do-update (name view-id team-id shared
filter-data scope-label)
"Update an existing Linear view from saved query NAME by VIEW-ID.
@@ -5772,7 +5805,8 @@ body stay."
("f" "build a filter" pearl-list-issues-filtered)
("v" "custom view" pearl-run-view)
("Q" "saved query" pearl-run-saved-query)
- ("S" "sync saved query" pearl-sync-saved-query-to-linear)]
+ ("S" "sync saved query" pearl-sync-saved-query-to-linear)
+ ("U" "upload current source" pearl-publish-current-source)]
["View"
("g" "refresh view" pearl-refresh-current-view)
("r" "refresh issue" pearl-refresh-current-issue)
@@ -5816,6 +5850,8 @@ body stay."
(define-key map "q" (cons "saved query" #'pearl-run-saved-query))
(define-key map "S" (cons "sync saved query to Linear"
#'pearl-sync-saved-query-to-linear))
+ (define-key map "P" (cons "publish current source to Linear"
+ #'pearl-publish-current-source))
map)
"Pearl fetch commands; a sub-keymap of `pearl-prefix-map'.")