aboutsummaryrefslogtreecommitdiff
path: root/tests/test-pearl-menu.el
Commit message (Collapse)AuthorAgeFilesLines
* feat(views): offer open-default-view in the transient menuCraig Jennings2026-06-021-0/+1
| | | | | | The keymap's l hot key opens the default view, but the transient could only run literal my-open-issues, so the menu couldn't reach a configured default. Now the Fetch group's l mirrors the keymap and runs pearl-open-default-view. Literal my-open-issues moves to m so it stays reachable from the menu. Suite holds at 809, compile and lint clean.
* feat(views): wire the default view into the keymap, transient, and docsCraig Jennings2026-06-021-1/+3
| | | | | | | | | | Phase 3, the last of the default-view spec: surface the phase 1-2 commands and flip the hot key over. Top-level l now runs pearl-open-default-view instead of pearl-list-issues, so it opens your default. The literal my-open-issues fetch stays reachable at f o, and l is unchanged until you set a default. v D binds pearl-set-default-view (the slot the keybinding reconciliation reserved), and the transient Views group gets a . suffix for it. D there stays save-locally. README documents the default view: what l does, how to set and clear it, the Customize persistence, and the per-account scoping under multiple accounts. Keymap and menu tests updated for the l rebind, the v D binding, and the transient suffix. Suite holds at 809, compile and lint clean.
* feat(keys): dedicated views group, de-overloaded fetch, account bindingCraig Jennings2026-06-021-1/+5
| | | | | | | | | | The C-; L keymap and the transient menu had drifted into two different letter schemes for the same commands, the fetch sub-map carried both issue-fetching and view-movement, and pearl-switch-account was bound nowhere. Give views their own group under v: l/L run local/Linear, c/e/k create/edit/delete, u/U publish local/current, d save a Linear view locally. Fetch (f) is now issue sources only. A new workspace group (w) binds switch-account plus the setup commands, which previously lived only in the transient. v D is reserved, unbound, for the not-yet-built set-default-view. The transient already had an issue-only fetch group and a dedicated views group, so its changes are additive: switch-account and copy-issue-url were both missing from the menu and are added, and save/save-all/edit-description take s/S/d to match the keymap's hot keys. Matching those three cascades a few view and edit letters because the transient is a flat keyspace where every command needs a unique key. Suite 789 to 792, compile and lint clean.
* refactor: rename saved-query surface to local-view vocabularyCraig Jennings2026-06-011-4/+4
| | | | | | | | I renamed Pearl's "saved query" surface to the local/Linear view vocabulary, with no obsolete aliases, since Pearl has no users to protect. The defcustom pearl-saved-queries is now pearl-local-views. The commands pearl-run-saved-query, pearl-delete-saved-query, pearl-sync-saved-query-to-linear, pearl-run-view, and pearl-publish-current-source become pearl-run-local-view, pearl-delete-local-view, pearl-publish-local-view, pearl-run-linear-view, and pearl-publish-current-view. User-facing prompts, messages, and docstrings drop "saved query" for "local view", and the publish command reads "publish" instead of "sync". Internal GraphQL and helper names keep their "query" terms, which a user never sees. A naming-regression test asserts the new symbols exist, the old ones are gone rather than aliased, and no public command exposes "query". Phase 1 of docs/local-and-linear-views-spec.org. No behavior change. Suite, compile, and lint are green.
* feat(view-sync): pearl-publish-current-source convenience wrapperCraig Jennings2026-05-281-0/+1
| | | | | | | | | | 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.
* feat(view-sync): pearl-sync-saved-query-to-linear + transient entryCraig Jennings2026-05-281-0/+1
| | | | | | | | | | | | | | | | | | | | | pearl-sync-saved-query-to-linear promotes a local pearl-saved-queries entry to a Linear Custom View via customViewCreate, or updates an already-synced entry in place via customViewUpdate. This is Phase 2 of docs/saved-query-sync-spec.org. Re-syncing keeps the stored scope. First-time sync prompts for the destination (team + visibility), with each candidate spelling out the complete end-state. Same-name collisions in the chosen scope prompt Replace / Rename / Cancel. A successful sync extends the entry with :linear-view-id, :linear-view-team-id, :linear-view-shared, :linear-view-synced-at. If the customize-save-variable persist fails after a successful API call, the message names the orphan view's id explicitly so the user can re-sync with Replace to reconcile. I bound the command under C-; L f S in pearl-fetch-map and added ("S" "sync saved query") to the transient's Fetch group. filterData is the existing pearl--build-issue-filter output verbatim. The 2026-05-28 live probe confirmed the shape passes through customView.filterData with no translation needed. Four related fixes ride along: - Extended pearl-get-teams-async to fetch `key' alongside `id name'. It shares pearl--cache-teams with pearl--all-teams, so an async-first populate would otherwise leave the cache without `key' and silently break filter-team lookups. - Normalized the stored :linear-view-shared flag to a strict boolean at the re-sync read site. `:json-false' is truthy in Elisp, so an unnormalized stored false would flip the view to team-shared on re-sync without asking. - pearl--sync-saved-query-await now returns `(:success nil :timeout t)' on a wait-for elapse, so the caller can distinguish a timeout from a Linear-side rejection and tell the user the request may still complete server-side. - The success path now emits a single message via pearl--sync-record-or-orphan-error. The prior code clobbered the orphan-recoverable view-id with a second message. I hoisted the prompt-sentinel block (pearl--filter-cancel etc.) above its first user. The prior order produced a forward-reference compile error the moment any other change touched the file. I added 31 tests in test-pearl-saved-query-sync.el covering the scope candidates, the customViewCreate/Update parsing, the entry persistence (including the :json-false overwrite case), the orphan-id error path, the timeout sentinel, and the get-teams-async cache parity. The keymap and menu tests gained coverage for the new binding. 631 ert tests total green. make compile and make lint clean. Lower-severity findings filed as follow-ups: stale pearl--cache-views across a schema upgrade, empty filter encoding to null filterData, the pearl--save-query-mark-synced rebuild dropping unknown plist keys, and the scope-label rassoc rebuilding the candidate list to look up a string the picker already had.
* refactor: verb-align command names and prefixes, use issue not ticketCraig Jennings2026-05-271-2/+2
| | | | | | The keybinding prefixes now each name an action verb: f fetch, e edit, c create, k delete, o open, y copy. The url group is gone, its actions split into open and copy, and the direct lowercase c (new comment) is dropped so c can head the create group. Two commands carried non-verb names, so I renamed them: pearl-new-issue is now pearl-create-issue and pearl-add-comment is now pearl-create-comment. The old sync helper that already held the pearl-create-issue name moved to the private pearl--create-issue, where it belongs as internal plumbing. I also swept "ticket" to "issue" across the labels, transient, docstrings, and README. Linear's own term is "issue" and the buffer mirrors Linear, so the command names already said "issue" while the labels said "ticket". Now they agree. The transient's per-entry keys still trail the keymap verbs, which stays its own task.
* refactor(save): retire the immediate-push field setters for buffer-editorsCraig Jennings2026-05-251-1/+1
| | | | | | | | The structured fields now reconcile at save (the previous commits), so the immediate-push setters are the duplicate path that made the package feel like it had two save models. I retired them. pearl-set-priority is deleted outright — priority is edited org-natively through the heading cookie. pearl-set-state, pearl-set-assignee, and pearl-set-labels become pearl-edit-state / -assignee / -labels: the same completing-read picker, but it writes the buffer representation (keyword/name/id, the assignee drawer, the labels drawer plus the live LINEAR-LABEL-IDS set) and marks the field dirty instead of pushing. The change goes out at the next pearl-save-issue / pearl-save-all. pearl-compose-current-description is renamed pearl-edit-description (its compose-and-push behavior is unchanged — v2 doesn't touch the compose buffers). The transient, the C-; L e keymap, the affordance preamble, and the README follow the new names, and the priority slots are dropped (no command — it's the org cookie). Deleting the setters left pearl--push-issue-field and pearl--priority-choices with no callers, so both are gone, along with the killed-buffer test that only exercised the removed helper. I filed a follow-up: the atomic savers' async commit callbacks need the same killed-buffer guard that helper carried. The setter command tests are rewritten to assert the buffer-write-and-no-push contract. The reconcile-and-push path they used to cover is exercised in test-pearl-save.
* feat: add the pearl-prefix-map keymap and regroup the transient menuCraig Jennings2026-05-251-1/+2
| | | | | | | | | | The command surface had no muscle-memory path. Everything went through M-x or the transient, and the transient grouped commands by an ad-hoc mix (issue-at-point, create, org-sync) rather than by what you're doing. I added pearl-prefix-map, an opt-in prefix keymap organized as save / edit / new / delete. It isn't bound at load, because a global multi-key prefix isn't reliably free across terminals and GUIs. Each binding is a (label . command) menu item, so which-key shows the label without pearl depending on which-key. The user binds the map to a free prefix (the README suggests C-; L). So C-; L s s saves the ticket at point, s a saves the whole file, e p edits priority, n t creates a ticket, m opens the transient. I regrouped the transient to mirror those categories: Save, Edit, New, Delete for ticket actions, and Fetch, View, Setup for the workspace. I added the two save commands and relabeled every entry to the verb wording. The per-field push entries (edit-desc, edit-title) are gone since the save model subsumes them, though the commands still work from M-x. I pulled the org-sync commands (enable, disable, push-file) from the menu too, since they're plumbing, tracked separately for going private. The keymap binds the existing command names. Aligning those names with the labels (edit-state, new-comment) is a separate task, as is the delete-comment command that will fill the d c slot.
* feat: pearl — manage Linear issues from org-modeCraig Jennings2026-05-241-0/+73
Pearl fetches Linear issues into an org file and syncs edits back. It covers list / custom views / saved queries, per-issue and bulk rendering with comments inline, conflict-aware sync of descriptions, titles, and comments, field commands for priority / state / assignee / labels, and a transient dispatch menu. The render folds to a scannable outline and nests issues under a sortable parent. Based on and inspired by Gael Blanchemain's linear-emacs.