| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
`pearl-state-to-todo-mapping` and its derived regex stopped doing real work once keyword rendering moved to slugifying the Linear state name (`pearl--state-name-to-keyword`) and the keyword-to-state direction moved to resolving through the team's workflow states. The defcustom fed only `pearl--get-todo-states-pattern`, which had no caller left, and the two cache vars existed only to serve that dead function. State extraction reads `org-get-todo-state` off the buffer's `#+TODO` line, so nothing live touched the mapping.
I removed the defcustom, both cache vars, and the dead function, and dropped the three pattern tests that exercised it. Removing the defcustom orphaned the mapping bindings that ~12 test setup macros still carried. They were passing through slugification rather than the map, so I stripped them too and kept the `org-todo-keywords` bindings the temp buffers actually need. Also dropped the stale README config row.
|
| |
|
|
|
|
| |
The Comments heading rendered the count marker as `Comments 💬 5/18`, with the glyph wedged between the word and the count. I moved the 💬 to the front of the heading, rendering `💬 Comments 5/18`, so it reads as an icon for the section rather than part of the number. `pearl--comment-count-marker` now returns just ` 5/18`, and `pearl--format-comments` leads with the glyph.
The append locator that finds an issue's Comments subtree now tolerates the leading 💬, and still matches the old `Comments 💬 N/N` layout so a buffer rendered before this change keeps working on the next add-comment.
|
| |
|
|
|
|
| |
Cycling a ticket's TODO keyword (C-c C-t) now counts as a state edit. The dirty scan gains a keyword-cycle arm: state is dirty when the explicit id moved off its baseline (the picker arm, as before) or when the keyword diverged from the synced state name's slug. At save, the picker arm pushes the explicit id; the keyword-cycle arm resolves the keyword to a team state id by slug match, first by position, and pushes that. A keyword no team state matches is reported skipped rather than guessed.
set-heading-state now slugifies the keyword instead of the static-map lookup, so the picker writes the same keyword the renderer derives. Without that, a picker edit to a non-standard state would read as permanently cycled. That retires pearl--map-linear-state-to-org, whose only caller this was, and its tests.
|
| |
|
|
|
|
| |
The README still described the old per-field push commands and the org-sync hook mode, both removed in save-model-v2. I rewrote the editing section around the one write path: you edit in the buffer, save the ticket, and Pearl reconciles each changed field against the remote. It now leads with pearl-save-issue / pearl-save-all, spells out how each field is edited (the cookie for priority, a picker for state/assignee/labels, hand-editing for text), explains that picking a constrained field marks it changed rather than pushing, and describes the conflict gate for both free-text and atomic fields.
The old "Org TODO sync" section drops the removed enable/disable hooks and keeps the state-to-keyword mapping as render config, with pearl-edit-state as the way to change state. The intro, the feature list, and the use-package and prefix-key examples lose their stale references. I kept the keyword-cycle-to-state and keyword-derivation work named as planned follow-ups rather than claiming they work, since they're not in yet.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
Pearl could render, create, and edit comments but not delete one, so removing your own comment meant leaving Emacs for the web app. I added the delete command and filled the reserved C-; L d c keymap slot.
pearl-delete-current-comment runs from inside a comment's subtree. It's own-only, reusing the viewer gate from pearl-edit-current-comment: a comment authored by someone else, a bot, or an integration is refused with no commentDelete call. It confirms before the destructive mutation, and on success removes that comment's Org subtree, leaving sibling comments and the issue body untouched. pearl--delete-comment-async mirrors pearl--delete-issue-async.
The delete is permanent. I verified Linear's commentDelete against the live API: the comment is not found immediately after, with no restore path, so unlike issueDelete this isn't a recoverable soft delete. Because of that, a comment with unsaved local edits (or no stored hash) gets a stronger "discard your local edits" confirmation rather than the plain prompt.
I surfaced it as K in the transient Delete group and as d c in the prefix keymap, and inverted the keymap test that asserted d c was unbound.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
| |
I made the recursive backronym the README title — Pearl Edits and Reflects Linear (P=Pearl, E=Edits, A=and, R=Reflects, L=Linear) — and named it in the opening line, matching the sibling projects' READMEs (Chime, emacs-wttrin). Added an Umberto Eco epigraph, "We like lists because we don't want to die.", in the same quote style they use. The cgit repo description on cjennings.net is set to match.
|
| |
|
|
| |
I rewrote the README into a sectioned guide — a nav header over Features, Installation, Quick Start, Commands, The Org File, Configuration, Development & Testing, FAQ, Troubleshooting, History, and License — and repointed every repository URL off the deleted github.com/cjennings/pearl onto https://git.cjennings.net/pearl.git. The repoint also covers the URL header in pearl.el, the Eask website-url, and the package-summary repo link. The upstream credit to Gael Blanchemain's linear-emacs is unchanged.
|
|
|
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.
|