From a74334bc9a321ddbb9b2ba81266f264d3522cc8c Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Wed, 27 May 2026 19:19:35 -0500 Subject: refactor: verb-align command names and prefixes, use issue not ticket 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. --- pearl.el | 65 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 30 deletions(-) (limited to 'pearl.el') diff --git a/pearl.el b/pearl.el index f08f636..8f7fa3c 100644 --- a/pearl.el +++ b/pearl.el @@ -1157,7 +1157,7 @@ CALLBACK is called with the created issue data." (pearl--graphql-request-async query variables success-fn error-fn))) -(defun pearl-create-issue (title description team-id) +(defun pearl--create-issue (title description team-id) "Create a new issue (synchronous wrapper for backward compatibility). TITLE is the issue title. DESCRIPTION is the issue description. @@ -2577,7 +2577,7 @@ create callback fires with another buffer current (the compose path)." (message "Added comment to %s" issue-id))))) ;;;###autoload -(defun pearl-add-comment (&optional body) +(defun pearl-create-comment (&optional body) "Add a comment to the Linear issue at point. Interactively, opens an Org compose buffer (C-c C-c sends, C-c C-k cancels) and converts the composed Org to Markdown before sending -- room to write a real @@ -2946,7 +2946,7 @@ yields the hardcoded default. Pure function, no side effects." ;; Affordance preamble (org comments -- not rendered content). (insert "#\n") (insert "# Body = the issue description; edit it, then M-x pearl-save-issue to push.\n") - (insert "# Comments subtree = the thread; add with M-x pearl-add-comment.\n") + (insert "# Comments subtree = the thread; add with M-x pearl-create-comment.\n") (insert "# State/assignee/labels: M-x pearl-edit-state / -assignee / -labels; priority: the org cookie (C-c ,). All push at save.\n") (insert "# Refresh with M-x pearl-refresh-current-view (whole file) or -current-issue (one).\n") (insert "\n") @@ -3552,7 +3552,7 @@ the deferred smerge path." "Save the description of the issue subtree at MARKER, calling CALLBACK. A push advances both `LINEAR-DESC-SHA256' (the markdown baseline used by the remote conflict gate) and `LINEAR-DESC-ORG-SHA256' (the rendered-Org baseline -used by the local dirty scan), so the next scan sees the ticket as clean." +used by the local dirty scan), so the next scan sees the issue as clean." (org-with-point-at marker (let* ((issue-id (org-entry-get nil "LINEAR-ID")) (identifier (org-entry-get nil "LINEAR-IDENTIFIER")) @@ -4147,7 +4147,7 @@ yours\". Returns a plist (:issues :titles :descriptions :priorities :states VIEWER-ID gates comment ownership; VIEWER-FAILED marks a failed viewer lookup so the prompt counts comments as viewer-unavailable rather than read-only. BUFFER is surfaced if anything pushed. Declining the prompt mutates nothing. The -queue continues past a per-field conflict, so one conflicted ticket does not +queue continues past a per-field conflict, so one conflicted issue does not stop the rest." (if (not (y-or-n-p (pearl--save-all-prompt (pearl--save-all-counts scan viewer-id viewer-failed)))) @@ -4195,7 +4195,7 @@ reported. A clean file does nothing." "Non-nil if the issue subtree at point has any unpushed local edit. Broader than `pearl--subtree-dirty-p', which inspects only the description: this also covers a changed title, state, priority, assignee, labels, or comment. -A merge refresh uses it so it keeps a ticket you have touched in any field, not +A merge refresh uses it so it keeps an issue you have touched in any field, not just ones whose description changed." (pearl--issue-has-dirty-fields-p (pearl--issue-dirty-fields))) @@ -4477,7 +4477,7 @@ resolves to a single label." (when (and selected-label-name (not (string-empty-p selected-label-name))) (cdr (assoc selected-label-name issue-types))))) -(defun pearl-new-issue () +(defun pearl-create-issue () "Create a new Linear issue with additional attributes." (interactive) ;; Select team first (needed for states, members, etc.) @@ -4846,9 +4846,9 @@ body stay." ;; delete); fetch / view / setup are the operational groups with no keymap ;; equivalent. The org-sync commands (enable / disable / push-file) are ;; deliberately not surfaced -- they are plumbing (see the todo). - ["Ticket" + ["Issue" ["Save" - ("e" "save ticket" pearl-save-issue) + ("e" "save issue" pearl-save-issue) ("E" "save all" pearl-save-all)] ["Edit" ("D" "edit description" pearl-edit-description) @@ -4856,11 +4856,11 @@ body stay." ("s" "edit state" pearl-edit-state) ("a" "edit assignee" pearl-edit-assignee) ("L" "edit labels" pearl-edit-labels)] - ["New" - ("n" "new ticket" pearl-new-issue) - ("c" "new comment" pearl-add-comment)] + ["Create" + ("n" "create issue" pearl-create-issue) + ("c" "create comment" pearl-create-comment)] ["Delete" - ("k" "delete ticket" pearl-delete-current-issue) + ("k" "delete issue" pearl-delete-current-issue) ("K" "delete comment" pearl-delete-current-comment)]] ["Workspace" ["Fetch" @@ -4873,7 +4873,7 @@ body stay." ("g" "refresh view" pearl-refresh-current-view) ("r" "refresh issue" pearl-refresh-current-issue) ("b" "open view in Linear" pearl-open-current-view-in-linear) - ("o" "open ticket in browser" pearl-open-current-issue)] + ("o" "open issue in browser" pearl-open-current-issue)] ["Setup" ("T" "test connection" pearl-test-connection) ("C" "check setup" pearl-check-setup) @@ -4922,27 +4922,32 @@ body stay." map) "Pearl edit commands; a sub-keymap of `pearl-prefix-map'.") -(defvar pearl-new-map +(defvar pearl-create-map (let ((map (make-sparse-keymap))) - (define-key map "t" (cons "new ticket" #'pearl-new-issue)) - (define-key map "c" (cons "new comment" #'pearl-add-comment)) + (define-key map "t" (cons "create issue" #'pearl-create-issue)) + (define-key map "c" (cons "create comment" #'pearl-create-comment)) map) - "Pearl new-object commands; a sub-keymap of `pearl-prefix-map'.") + "Pearl create commands; a sub-keymap of `pearl-prefix-map'.") (defvar pearl-delete-map (let ((map (make-sparse-keymap))) - (define-key map "t" (cons "delete ticket" #'pearl-delete-current-issue)) + (define-key map "t" (cons "delete issue" #'pearl-delete-current-issue)) (define-key map "c" (cons "delete comment" #'pearl-delete-current-comment)) map) "Pearl delete commands; a sub-keymap of `pearl-prefix-map'.") -(defvar pearl-url-map +(defvar pearl-open-map (let ((map (make-sparse-keymap))) - (define-key map "o" (cons "open issue in browser" #'pearl-open-current-issue)) - (define-key map "c" (cons "copy issue URL" #'pearl-copy-issue-url)) + (define-key map "i" (cons "open issue in browser" #'pearl-open-current-issue)) (define-key map "v" (cons "open view in Linear" #'pearl-open-current-view-in-linear)) map) - "Pearl URL commands; a sub-keymap of `pearl-prefix-map'.") + "Pearl open commands; a sub-keymap of `pearl-prefix-map'.") + +(defvar pearl-copy-map + (let ((map (make-sparse-keymap))) + (define-key map "u" (cons "copy issue URL" #'pearl-copy-issue-url)) + map) + "Pearl copy commands; a sub-keymap of `pearl-prefix-map'.") (defvar pearl-prefix-map (let ((map (make-sparse-keymap))) @@ -4950,21 +4955,21 @@ body stay." (define-key map "l" (cons "list my open issues" #'pearl-list-issues)) (define-key map "g" (cons "refresh view" #'pearl-refresh-current-view)) (define-key map "r" (cons "refresh issue" #'pearl-refresh-current-issue)) - (define-key map "s" (cons "save ticket" #'pearl-save-issue)) + (define-key map "s" (cons "save issue" #'pearl-save-issue)) (define-key map "S" (cons "save all" #'pearl-save-all)) (define-key map "d" (cons "edit description" #'pearl-edit-description)) - (define-key map "c" (cons "new comment" #'pearl-add-comment)) (define-key map "m" (cons "menu" #'pearl-menu)) - ;; Category sub-maps -- two keys. + ;; Category sub-maps -- two keys; each prefix names an action verb. (define-key map "f" (cons "+fetch" pearl-fetch-map)) (define-key map "e" (cons "+edit" pearl-edit-map)) - (define-key map "n" (cons "+new" pearl-new-map)) + (define-key map "c" (cons "+create" pearl-create-map)) (define-key map "k" (cons "+delete" pearl-delete-map)) - (define-key map "u" (cons "+url" pearl-url-map)) + (define-key map "o" (cons "+open" pearl-open-map)) + (define-key map "y" (cons "+copy" pearl-copy-map)) map) "Pearl command prefix keymap. -Hot-path commands are bound directly; the rest live under the category -sub-maps (fetch / edit / new / delete / url). `pearl-mode' binds this under +Hot-path commands are bound directly; the rest live under verb sub-maps +\(fetch / edit / create / delete / open / copy). `pearl-mode' binds this under `pearl-keymap-prefix' inside Pearl buffers; you can also bind it globally \(see the Commentary above).") -- cgit v1.2.3