aboutsummaryrefslogtreecommitdiff
path: root/modules/org-capture-config.el
diff options
context:
space:
mode:
Diffstat (limited to 'modules/org-capture-config.el')
-rw-r--r--modules/org-capture-config.el123
1 files changed, 43 insertions, 80 deletions
diff --git a/modules/org-capture-config.el b/modules/org-capture-config.el
index 393f1d97b..2f245185f 100644
--- a/modules/org-capture-config.el
+++ b/modules/org-capture-config.el
@@ -76,6 +76,21 @@
"Return the cache key for PATH and HEADLINE."
(list (org-capture-expand-file path) headline))
+(defun cj/--org-find-or-create-top-heading (search-regexp heading-line)
+ "Move point to the top-level heading matched by SEARCH-REGEXP in this buffer.
+Search from the start of the buffer; on a match leave point at the start of
+that heading line. With no match, append HEADING-LINE (a full \"* ...\" line,
+without a trailing newline) at the end of the buffer and leave point on it.
+Returns point."
+ (goto-char (point-min))
+ (if (re-search-forward search-regexp nil t)
+ (forward-line 0)
+ (goto-char (point-max))
+ (unless (bolp) (insert "\n"))
+ (insert heading-line "\n")
+ (forward-line -1))
+ (point))
+
(defun cj/org-capture--goto-file-headline (path headline)
"Move to capture target PATH and HEADLINE, using a cached marker when valid.
This implements Org's `file+headline' target positioning behavior, but avoids
@@ -94,15 +109,9 @@ re-scanning large target files after the first successful lookup."
(marker (gethash key cj/org-capture--file-headline-target-cache)))
(if (cj/org-capture--headline-marker-valid-p marker headline)
(goto-char marker)
- (goto-char (point-min))
- (if (re-search-forward (format org-complex-heading-regexp-format
- (regexp-quote headline))
- nil t)
- (forward-line 0)
- (goto-char (point-max))
- (unless (bolp) (insert "\n"))
- (insert "* " headline "\n")
- (forward-line -1))
+ (cj/--org-find-or-create-top-heading
+ (format org-complex-heading-regexp-format (regexp-quote headline))
+ (concat "* " headline))
(puthash key (copy-marker (point))
cj/org-capture--file-headline-target-cache))))
@@ -177,27 +186,17 @@ file path. Return a plist (:file F :open-work BOOL :project NAME :warn MSG):
"Move point to a top-level \"... Open Work\" heading in the current buffer.
Create \"* PROJECT-NAME Open Work\" at end of buffer when none exists.
Leave point at the start of the heading line."
- (goto-char (point-min))
- (if (re-search-forward cj/--org-open-work-heading-regexp nil t)
- (forward-line 0)
- (goto-char (point-max))
- (unless (bolp) (insert "\n"))
- (insert (format "* %s Open Work\n" project-name))
- (forward-line -1)))
+ (cj/--org-find-or-create-top-heading
+ cj/--org-open-work-heading-regexp
+ (format "* %s Open Work" project-name)))
(defun cj/--org-capture-goto-exact-headline (headline)
"Move point to the top-level HEADLINE in the current buffer.
Create \"* HEADLINE\" at end of buffer when absent. Leave point at the
start of the heading line."
- (goto-char (point-min))
- (if (re-search-forward (format org-complex-heading-regexp-format
- (regexp-quote headline))
- nil t)
- (forward-line 0)
- (goto-char (point-max))
- (unless (bolp) (insert "\n"))
- (insert "* " headline "\n")
- (forward-line -1)))
+ (cj/--org-find-or-create-top-heading
+ (format org-complex-heading-regexp-format (regexp-quote headline))
+ (concat "* " headline)))
(defun cj/--org-capture-project-location ()
"Org-capture `function' target for project-aware Task/Bug capture.
@@ -400,34 +399,21 @@ never split the small floating frame."
cj/org-capture--display-sole-window))
;; The desktop quick-capture popup is launched globally (no browser selection,
-;; no mu4e message, no pdf/epub buffer), so most templates make no sense there:
-;; the context fields (%:link, %i) come up empty or point at the daemon's last
-;; buffer, and the pdf templates error outright. `cj/quick-capture' offers only
-;; Task, Bug, and Event; Task and Bug file to the global inbox rather than a
-;; project todo.org, since a desktop capture has no meaningful project context.
-;; It also closes the popup frame on every exit path (abort, error, finalize) —
-;; `org-capture' only runs `org-capture-after-finalize-hook' on a completed
-;; capture, so a q/C-g at the template menu or an erroring template would
-;; otherwise orphan the frame. The Hyprland script calls this instead of
-;; `org-capture'.
-
-(defun cj/--org-capture-popup-templates (templates inbox)
- "Return the desktop-popup subset of TEMPLATES: Task, Bug, Event.
-Task (\"t\") and Bug (\"b\") are retargeted to INBOX's \"Inbox\" headline;
-Event (\"e\") passes through unchanged. All other templates are dropped.
-Template bodies and properties are preserved."
- (delq nil
- (mapcar
- (lambda (entry)
- (pcase (car-safe entry)
- ((or "t" "b")
- ;; (KEY DESC TYPE TARGET TEMPLATE . PROPS) -> retarget TARGET
- (append (list (nth 0 entry) (nth 1 entry) (nth 2 entry)
- (list 'file+headline inbox "Inbox"))
- (nthcdr 4 entry)))
- ("e" entry)
- (_ nil)))
- templates)))
+;; no mu4e message, no pdf/epub buffer), so the context-dependent templates make
+;; no sense there. `cj/quick-capture' captures a single Task straight into the
+;; global inbox -- no template menu -- under its "Inbox" headline, since a
+;; desktop capture has no meaningful project context. It closes the popup frame
+;; on every exit path (abort, error, finalize): `org-capture' runs
+;; `org-capture-after-finalize-hook' only on a completed capture, so a C-g or an
+;; erroring template would otherwise orphan the frame. The Hyprland script
+;; calls this instead of `org-capture'.
+
+(defun cj/--quick-capture-template (inbox)
+ "Return the desktop quick-capture template: a single Task into INBOX's Inbox.
+INBOX is the inbox file path; the Task files under its \"Inbox\" headline."
+ (list (list "t" "Task" 'entry
+ (list 'file+headline inbox "Inbox")
+ "* TODO %?" :prepend t)))
(defun cj/org-capture--popup-frame ()
"Return a live frame named \"org-capture\" (the quick-capture popup), or nil."
@@ -438,8 +424,8 @@ Template bodies and properties are preserved."
(defun cj/quick-capture ()
"Org-capture entry point for the Hyprland desktop popup (frame \"org-capture\").
-Offers only Task, Bug, and Event; Task and Bug file to the global inbox.
-Closes the popup frame on abort or error so a stray selection never orphans it.
+Captures a single Task into the global inbox, with no template menu.
+Closes the popup frame on abort or error so a stray launch never orphans it.
Selects the \"org-capture\" frame by name before capturing rather than trusting
the ambient selected frame: the launching =emacsclient -c -e= runs before
@@ -450,34 +436,11 @@ daemon's main frame and the capture would otherwise land there."
(condition-case err
(progn
(when frame (select-frame-set-input-focus frame))
- (let ((org-capture-templates
- (cj/--org-capture-popup-templates org-capture-templates inbox-file)))
- (org-capture)))
+ (let ((org-capture-templates (cj/--quick-capture-template inbox-file)))
+ (org-capture nil "t")))
(quit (cj/org-capture--delete-popup-frame))
(error (message "Quick-capture: %s" (error-message-string err))
(cj/org-capture--delete-popup-frame)))))
-;; The template menu's "C — Customize org-capture-templates" special makes no
-;; sense in the desktop popup (it would open a Customize buffer in the floating
-;; frame). Strip it from the menu when the selection runs in the popup frame,
-;; keeping "q — Abort". `org-mks' is the menu primitive; advising it (gated on
-;; the frame name) catches the capture template selection without touching
-;; org-mks's other callers.
-
-(defun cj/--org-capture-popup-strip-specials (specials)
- "Remove the \"C\" Customize entry from org-mks SPECIALS, keeping the rest.
-SPECIALS is the org-mks specials alist (e.g. the Customize and Abort entries)."
- (delq nil (mapcar (lambda (s) (unless (equal (car-safe s) "C") s)) specials)))
-
-(defun cj/org-capture--popup-mks-advice (orig table title &optional prompt specials)
- "Around-advice for `org-mks': hide the Customize special in the quick-capture popup.
-ORIG is the real `org-mks'; TABLE TITLE PROMPT SPECIALS are its arguments."
- (funcall orig table title prompt
- (if (cj/org-capture--popup-frame-p)
- (cj/--org-capture-popup-strip-specials specials)
- specials)))
-
-(advice-add 'org-mks :around #'cj/org-capture--popup-mks-advice)
-
(provide 'org-capture-config)
;;; org-capture-config.el ends here.