| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
An issue's Linear labels now appear as Org tags on its heading (** TODO [#B] Title :bug:backend:), so the org-native gestures work: filter by tag, build a tag agenda, sparse-tree on :bug:. Before this, labels lived only in the :LINEAR-LABELS: drawer, which Org's tag machinery can't see.
pearl--label-name-to-tag slugifies a label name to a tag: downcase, non-[[:alnum:]_] runs become a single underscore, Unicode letters preserved. pearl--label-tags builds the deduplicated set, first occurrence winning on a collision. The renderer appends them, and pearl-edit-labels rewrites them through pearl--set-heading-label-tags after updating the drawer.
This is render-only. The :LINEAR-LABELS: drawer stays the source of truth, hand-edited heading tags are ignored by save and the dirty scan and get rewritten from Linear on the next change or fetch, and the way to change labels is still pearl-edit-labels. Bidirectional tag editing (heading tags back to Linear) is out of scope.
|
| |
|
|
|
|
| |
The buffer should mirror Linear: a value on the page appears exactly as Linear stores it, so the heading title matches what you'd see opening the issue in Linear itself. I flipped pearl-title-case-headings to default nil so titles render verbatim. I also stopped running the view name in the #+title through the title-caser, which was coupled to the same flag. The smart-title-case path stays as opt-in tidying for anyone who wants it.
Two transformations remain, both forced by Org's syntax rather than chosen: state names become TODO keywords (Org keywords can't contain spaces, so the real name stays in the LINEAR-STATE-NAME drawer), and descriptions and comments convert between Markdown and Org. Documented under "Fidelity to Linear" in the README.
|
| |
|
|
|
|
| |
After a refresh, merge, or comment add, pearl folds property drawers so the page stays scannable. When org-tidy-mode is on, org-tidy owns drawer display with its own compact inline symbol, so a plain native fold doesn't match. Worse, org-tidy's overlays go stale when pearl rewrites the buffer, leaving the new drawers untidied.
I added pearl--hide-or-tidy-drawers, which re-tidies via org-tidy-buffer when org-tidy-mode is active and falls back to the native fold otherwise. I routed the three drawer-hide paths (full render, single-issue refresh, comment add) through it. org-tidy stays an optional soft dependency, guarded by bound-and-true-p and fboundp, so a setup without it behaves exactly as before.
|
| |
|
|
|
|
| |
`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 save scan now flags priority, state, assignee, and labels as dirty when their live value differs from the synced baseline, so structured fields ride the same reconcile-at-save path as title and description. Each check is id/scalar-only and runs with no network: the priority cookie's number against LINEAR-PRIORITY, the explicit state id against LINEAR-STATE-ID-SYNCED (the picker arm — keyword cycling lands later), the assignee id against its baseline, and the label id set against its baseline (order-insensitive, since Linear label order isn't meaningful). A missing baseline on a legacy file reads as not-dirty; the saver's missing-property guard covers that edge.
This also makes the priority cookie faithful. The renderer mapped both None and Medium to [#C], so a None issue couldn't be told apart from a Medium one and would have read dirty the moment its baseline said 0. None now renders with no cookie, 1:1 with the four cookie levels — matching what the priority setter already did.
|
| |
|
|
|
|
| |
Save-model v2 reconciles a field by diffing its live value against a baseline last synced from Linear, but the structured fields (priority, state, assignee, labels) only stored their current value — there was nothing to diff against. The renderer now writes a synced baseline beside each: LINEAR-PRIORITY (the numeric priority), LINEAR-STATE-ID-SYNCED, LINEAR-ASSIGNEE-ID-SYNCED, and LINEAR-LABEL-IDS / LINEAR-LABEL-IDS-SYNCED (the live and baseline id sets, with LINEAR-LABELS staying display-only names).
At fetch, live equals baseline, so nothing reads dirty on a fresh issue. The merge refresh re-renders changed subtrees through the same renderer, so baselines advance there too, and a retained dirty subtree is left untouched.
|
| |
|
|
|
|
| |
I added two display-only heading tweaks, each a defcustom defaulting on. pearl-show-identifier-in-heading prefixes the title with the Linear identifier (** TODO [#B] SE-401: Fix the Bug). pearl-title-case-headings renders the title in smart title case, keeping minor words lowercase unless first or last and leaving words that already carry an uppercase letter (acronyms, identifiers) untouched.
Both stay display-only. The LINEAR-TITLE-SHA256 hash covers the rendered (cased, un-prefixed) title, and the title-sync reader strips the identifier prefix before hashing, so an unedited heading is a no-op and neither the casing nor the prefix ever pushes to Linear. A render-then-read round-trip test locks that invariant.
|
|
|
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.
|