From 64bc1c762bdb25925d1b317cfc76ce8c6cd0f608 Mon Sep 17 00:00:00 2001 From: Daniel Borchmann Date: Sat, 19 Nov 2022 16:09:38 +0100 Subject: [PATCH] Jump to first open checkbox in currently clocked-in item by default When no open checkbox is found, just jump to the headline of the item, as before. --- init.el | 2 +- site-lisp/db-customize.el | 2 +- site-lisp/db-org.el | 91 ++++++++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/init.el b/init.el index cd8596c..11ec6fb 100644 --- a/init.el +++ b/init.el @@ -767,7 +767,7 @@ db/org-add-link-to-current-clock hydra-org-linking/body org-dblock-write:db/org-backlinks - db/org-goto-first-open-checkbox-in-subtree)) + db/org-clock-goto-first-open-checkbox)) (use-package org :pin "gnu" diff --git a/site-lisp/db-customize.el b/site-lisp/db-customize.el index 9444ddb..dd3dd7c 100644 --- a/site-lisp/db-customize.el +++ b/site-lisp/db-customize.el @@ -145,7 +145,7 @@ in the main agenda view." ("Shell" ?s db/run-or-hide-shell) ("EShell" ?e db/run-or-hide-eshell) ("Refile File" ?r #'(lambda () (interactive) (find-file db/org-default-refile-file))) - ("Org Clock Goto" ?c org-clock-goto) + ("Goto Currnet Clock" ?c db/org-clock-goto-first-open-checkbox) ("Info Lookup" ?I counsel-info-lookup-symbol) ("Unicode Lookup" ?U counsel-unicode-char) ("Timeline of Day" ?T timeline-tools-format-timeline-of-day) diff --git a/site-lisp/db-org.el b/site-lisp/db-org.el index 6052b6a..d2c4df5 100644 --- a/site-lisp/db-org.el +++ b/site-lisp/db-org.el @@ -1015,32 +1015,55 @@ cache if that's in use." (when (derived-mode-p 'org-agenda-mode) (org-agenda-redo))) -(defun db/org-goto-first-open-checkbox-in-subtree () +(defun db/org-goto-first-open-checkbox-in-subtree (&optional silent) "Jump to first open checkbox in the current subtree. First search for started checkboxes, i.e. [-], and if those are not found, go to the first open checkbox, i.e. [ ]. -If there's no such open checkbox, emit a message and stay put." - (interactive) +If there's no such open checkbox, emit a message (unless SILENT +is non-nil) and stay put. + +Note: when lists are nested, those are not (yet) descended into +to find the logically first open checkbox. This should be fixed +somewhen, though." + (unless (derived-mode-p 'org-mode) (user-error "Not in Org buffer, exiting")) + (save-restriction (let ((original-point (point))) (widen) (org-back-to-heading 'invisible-ok) (org-narrow-to-subtree) (unless - ;; Yes, progn is not strictly necessary, but it feels cleaner this way. + ;; Yes, those `progn's are not strictly necessary, but it feels + ;; cleaner this way. (or (progn (goto-char (point-min)) (re-search-forward " \\[-\\] " nil 'no-error)) (progn (goto-char (point-min)) (re-search-forward " \\[ \\] " nil 'no-error))) - (message "No open checkbox in subtree") + (unless silent + (message "No open checkbox in subtree")) (goto-char original-point))))) +(defun db/org-clock-goto-first-open-checkbox (&optional select) + "Go to the currently clocked-in item or most recently clocked item. + +Move point to first open checkbox there, if there's one. See +`db/org-goto-first-open-checkbox-in-subtree' for details. + +If SELECT is non-nil, offer a choice of the most recently +clocked-in tasks to jump to." + (interactive "@P") + (org-clock-goto select) + ;; `org-clock-goto' will barf if there's no currently clocked-in task, so + ;; there is no need to check this again; just try to find the first checkbox + ;; now. + (db/org-goto-first-open-checkbox-in-subtree :silent)) + ;;; Calendar @@ -1049,35 +1072,35 @@ If there's no such open checkbox, emit a message and stay put." This is done only if the value of this variable is not null." (interactive) (cond - ((null org-icalendar-combined-agenda-file) - (message "`org-icalendar-combined-agenda-file’ not set, not exporting diary.")) - ((not (file-name-absolute-p org-icalendar-combined-agenda-file)) - (user-error "`org-icalendar-combined-agenda-file’ not an absolute path, aborting")) - (t - (progn - (org-save-all-org-buffers) - (let ((org-agenda-files (cl-remove-if #'null - (list db/org-default-org-file - db/org-default-home-file - db/org-default-work-file))) - (org-agenda-new-buffers nil)) - ;; check whether we need to do something - (when (cl-some (lambda (org-file) - (file-newer-than-file-p org-file - org-icalendar-combined-agenda-file)) - org-agenda-files) - (message "Exporting diary ...") - ;; open files manually to avoid polluting `org-agenda-new-buffers’; we - ;; don’t want these buffers to be closed after exporting - (mapc #'find-file-noselect org-agenda-files) - ;; actual export; calls `org-release-buffers’ and may thus close - ;; buffers we want to keep around … which is why we set - ;; `org-agenda-new-buffers’ to nil - (when (file-exists-p org-icalendar-combined-agenda-file) - (delete-file org-icalendar-combined-agenda-file) - (sit-for 3)) - (org-icalendar-combine-agenda-files) - (message "Exporting diary ... done."))))))) + ((null org-icalendar-combined-agenda-file) + (message "`org-icalendar-combined-agenda-file’ not set, not exporting diary.")) + ((not (file-name-absolute-p org-icalendar-combined-agenda-file)) + (user-error "`org-icalendar-combined-agenda-file’ not an absolute path, aborting")) + (t + (progn + (org-save-all-org-buffers) + (let ((org-agenda-files (cl-remove-if #'null + (list db/org-default-org-file + db/org-default-home-file + db/org-default-work-file))) + (org-agenda-new-buffers nil)) + ;; check whether we need to do something + (when (cl-some (lambda (org-file) + (file-newer-than-file-p org-file + org-icalendar-combined-agenda-file)) + org-agenda-files) + (message "Exporting diary ...") + ;; open files manually to avoid polluting `org-agenda-new-buffers’; we + ;; don’t want these buffers to be closed after exporting + (mapc #'find-file-noselect org-agenda-files) + ;; actual export; calls `org-release-buffers’ and may thus close + ;; buffers we want to keep around … which is why we set + ;; `org-agenda-new-buffers’ to nil + (when (file-exists-p org-icalendar-combined-agenda-file) + (delete-file org-icalendar-combined-agenda-file) + (sit-for 3)) + (org-icalendar-combine-agenda-files) + (message "Exporting diary ... done."))))))) ;;; Find items by link to current headline