diff options
Diffstat (limited to 'pearl.el')
| -rw-r--r-- | pearl.el | 91 |
1 files changed, 84 insertions, 7 deletions
@@ -229,7 +229,7 @@ leave the buffer expanded after updates." :group 'pearl) (defcustom pearl-help-header t - "When non-nil, render a folded \"* Pearl\" heading atop each Linear file. + "When non-nil, render a folded \"* Pearl Help\" heading atop each Linear file. The heading collapses on open (via a `:VISIBILITY: folded' property) and carries the edit-then-save reminder, the keymap cues, and the priority-cookie legend, so the help is discoverable without a dozen lines of `#' preamble cluttering the @@ -238,6 +238,22 @@ it entirely, leaving just the machine `#+' keywords." :type 'boolean :group 'pearl) +(defcustom pearl-hide-preamble t + "When non-nil, collapse the `#+' keyword preamble to a one-line summary. +A display overlay replaces the `#+' block atop each Linear file with a styled +\"Pearl - <view> · <count> · <time>\" line in `pearl-preamble-summary' face. +The buffer text is untouched, so refresh and parsing still work; the overlay +only governs display. Set to nil to show the raw `#+' keyword lines." + :type 'boolean + :group 'pearl) + +(defface pearl-preamble-summary + '((t :inherit org-document-title :foreground "goldenrod")) + "Face for the one-line summary that replaces the hidden `#+' preamble block. +Inherits `org-document-title' for the large title look; override via Customize +\(e.g. a different colour for a light theme)." + :group 'pearl) + (defcustom pearl-title-case-headings nil "When non-nil, render issue titles in the heading in smart title case. The default is nil: titles render verbatim, exactly as Linear stores them, so @@ -3618,7 +3634,7 @@ only add the ones a failed team fetch left out." (defvar pearl-keymap-prefix) (defun pearl--help-header-string () - "Return the folded \"* Pearl\" heading shown atop a Linear file. + "Return the folded \"* Pearl Help\" heading shown atop a Linear file. A collapsible section (`:VISIBILITY: folded') carrying the edit-then-save reminder, a note that the section is local-only, the keymap cues, the priority-cookie legend, and how to hide it. The cues reflect the live @@ -3628,7 +3644,7 @@ heading carries no `LINEAR-ID', so save and merge skip it (they walk only `LINEAR-ID'-bearing subtrees -- see `pearl--issue-subtree-markers')." (let ((p pearl-keymap-prefix)) (concat - "* Pearl\n" + "* Pearl Help\n" ":PROPERTIES:\n" ":VISIBILITY: folded\n" ":END:\n" @@ -3642,6 +3658,59 @@ heading carries no `LINEAR-ID', so save and merge skip it (they walk only "Priority cookies: [#A] Urgent, [#B] High, [#C] Medium, [#D] Low, no cookie = None.\n" "Hide this section: set pearl-help-header to nil (M-x customize-variable RET pearl-help-header).\n"))) +(defun pearl--preamble-region () + "Return (BEG . END) for the `#+' keyword preamble of the current buffer. +BEG is `point-min'; END is the start of the first heading. nil when the buffer +has no heading." + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "^\\*+ " nil t) + (cons (point-min) (match-beginning 0))))) + +(defun pearl--preamble-keyword (keyword) + "Return the value of file KEYWORD (e.g. \"LINEAR-COUNT\") in the buffer, or nil." + (save-excursion + (goto-char (point-min)) + (when (re-search-forward (format "^#\\+%s: \\(.*\\)$" (regexp-quote keyword)) + nil t) + (string-trim (match-string 1))))) + +(defun pearl--preamble-summary () + "Compose the one-line preamble summary for the current Linear buffer. +\"Pearl - <view> · <count> · <time>\", read from `#+LINEAR-SOURCE' (its name), +`#+LINEAR-COUNT', and the time portion of `#+LINEAR-RUN-AT'. Missing fields are +omitted. Leads with \"Pearl\" so the line doubles as the buffer's identity." + (let* ((src (pearl--read-active-source)) + (name (or (and src (plist-get src :name)) "Linear")) + (count (pearl--preamble-keyword "LINEAR-COUNT")) + (runat (pearl--preamble-keyword "LINEAR-RUN-AT")) + (time (and runat (car (last (split-string runat)))))) + (concat "Pearl - " name + (and count (format " · %s" count)) + (and time (format " · %s" time))))) + +(defun pearl--hide-preamble (&optional buffer) + "Collapse the `#+' keyword preamble of BUFFER to a styled one-line summary. +When `pearl-hide-preamble' is non-nil, lay (or refresh) a single overlay over +the preamble region (`pearl--preamble-region') whose `display' is +`pearl--preamble-summary' in `pearl-preamble-summary' face. Idempotent: removes +any prior pearl overlay first, so re-rendering never stacks duplicates; when the +option is nil it just removes it. Buffer text is untouched, so parsing and the +merge rewrites keep working." + (with-current-buffer (or buffer (current-buffer)) + (dolist (o (overlays-in (point-min) (point-max))) + (when (overlay-get o 'pearl-preamble) + (delete-overlay o))) + (when pearl-hide-preamble + (let ((region (pearl--preamble-region))) + (when region + (let ((ov (make-overlay (car region) (cdr region)))) + (overlay-put ov 'pearl-preamble t) + (overlay-put ov 'evaporate t) + (overlay-put ov 'display + (propertize (concat (pearl--preamble-summary) "\n") + 'face 'pearl-preamble-summary)))))))) + (defun pearl--build-org-content (issues &optional source truncated states account) "Build the Org content string for the linear org file from ISSUES. SOURCE is the active-source descriptor recorded in the header so a later @@ -3750,7 +3819,8 @@ just writing the file and leaving it off-screen." (save-buffer) (goto-char (min recorded-point (point-max))) (pearl--restore-page-visibility) - (pearl-highlight-comments))) + (pearl-highlight-comments) + (pearl--hide-preamble))) (message "Updated Linear issues in %s with %d active issues" org-file-path (length issues)) (pearl--surface-buffer existing-buf)) @@ -3768,7 +3838,8 @@ just writing the file and leaving it off-screen." (save-buffer) (goto-char (point-min)) (pearl--restore-page-visibility) - (pearl-highlight-comments))) + (pearl-highlight-comments) + (pearl--hide-preamble))) (message "Updated Linear issues in %s with %d active issues" org-file-path (length issues)) (pearl--surface-buffer existing-buf)) @@ -3778,6 +3849,7 @@ just writing the file and leaving it off-screen." (pearl--update-source-header (length issues) truncated) (pearl--update-derived-todo-header (pearl--gather-header-states issues)) (pearl-highlight-comments) + (pearl--hide-preamble) ;; Fold only the subtrees the merge re-rendered or appended; leave ;; the rest of the page (and point) as the user had them, so an ;; edit-then-merge flow doesn't collapse the subtree they were @@ -6962,9 +7034,14 @@ in already-open buffers." Binds `pearl-prefix-map' under `pearl-keymap-prefix' so every Pearl command is reachable from the keyboard. Turns on automatically in any buffer Pearl rendered (one carrying a `#+LINEAR-SOURCE' header); see -`pearl--maybe-enable-mode' on `org-mode-hook'." +`pearl--maybe-enable-mode' on `org-mode-hook'. +On enable it also collapses the `#+' keyword preamble (see +`pearl--hide-preamble'), so opening a Linear file hides it the same way a fresh +fetch does." :lighter (:eval (pearl--mode-line-lighter)) - :keymap pearl-mode-map) + :keymap pearl-mode-map + (when pearl-mode + (pearl--hide-preamble))) (defun pearl--buffer-is-pearl-p () "Non-nil when the current buffer is a Pearl-rendered Linear file. |
