ENH load org-x-dag in proper order

This commit is contained in:
Nathan Dwarshuis 2022-04-10 18:56:00 -04:00
parent 7b8e5f3d52
commit 7efe4c8074
4 changed files with 440 additions and 383 deletions

View File

@ -0,0 +1,269 @@
;;; org-x-const.el --- Extra Org Constants -*- lexical-binding: t; -*-
;; Copyright (C) 2022 Nathan Dwarshuis
;; Author: Nathan Dwarshuis <natedwarshuis@gmail.com>
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(require 'dash)
;;; TODO KEYWORDS
(defconst org-x-kw-todo "TODO"
"Headline todo keyword for open task or project.")
(defconst org-x-kw-next "NEXT"
"Headline todo keyword for next task.")
(defconst org-x-kw-wait "WAIT"
"Headline todo keyword for task that is waiting on something.")
(defconst org-x-kw-hold "HOLD"
"Headline todo keyword for task or project that is held.")
(defconst org-x-kw-done "DONE"
"Headline todo keyword for completed task or project.")
(defconst org-x-kw-canc "CANC"
"Headline todo keyword for canceled task or project.")
(defconst org-x-done-keywords `(,org-x-kw-done ,org-x-kw-canc)
"Headline todo keywords that mark a task as 'complete'.")
(defconst org-x-meeting-keywords (cons org-x-kw-todo org-x-done-keywords)
"Allowed keywords for meetings.")
;;; TAGS
(defun org-x-prepend-char (char string)
"Return STRING with CHAR appended to the front."
(concat (char-to-string char) string))
(defconst org-x-tag-location-prefix ?@
"Prefix character denoting location context tag.")
(defconst org-x-tag-resource-prefix ?#
"Prefix character denoting resource context tag.")
(defconst org-x-tag-misc-prefix ?%
"Prefix character denoting misc tag.")
(defconst org-x-tag-category-prefix ?_
"Prefix character denoting life category tag.")
(defconst org-x-exclusive-prefixes (list org-x-tag-category-prefix
org-x-tag-location-prefix)
"Tag prefixes which denote mutually exclusive groups.")
(defconst org-x-tag-errand
(org-x-prepend-char org-x-tag-location-prefix "errand")
"Tag denoting an errand location.")
(defconst org-x-tag-home
(org-x-prepend-char org-x-tag-location-prefix "home")
"Tag denoting a home location.")
(defconst org-x-tag-work
(org-x-prepend-char org-x-tag-location-prefix "work")
"Tag denoting a work location.")
(defconst org-x-tag-travel
(org-x-prepend-char org-x-tag-location-prefix "travel")
"Tag denoting a travel location.")
(defconst org-x-tag-laptop
(org-x-prepend-char org-x-tag-resource-prefix "laptop")
"Tag denoting a laptop resource.")
(defconst org-x-tag-phone
(org-x-prepend-char org-x-tag-resource-prefix "phone")
"Tag denoting a phone resource.")
(defconst org-x-tag-deep
(org-x-prepend-char org-x-tag-misc-prefix "deep")
"Tag denoting deep work.")
(defconst org-x-tag-note
(org-x-prepend-char org-x-tag-misc-prefix "note")
"Tag denoting a note.")
(defconst org-x-tag-incubated
(org-x-prepend-char org-x-tag-misc-prefix "inc")
"Tag denoting an incubated task.")
(defconst org-x-tag-maybe
(org-x-prepend-char org-x-tag-misc-prefix "maybe")
"Tag denoting a maybe task.")
(defconst org-x-tag-subdivision
(org-x-prepend-char org-x-tag-misc-prefix "subdiv")
"Tag denoting a task awaiting subdivision.")
(defconst org-x-tag-flagged
(org-x-prepend-char org-x-tag-misc-prefix "flag")
"Tag denoting a flagged task.")
(defconst org-x-tag-meeting
(org-x-prepend-char org-x-tag-misc-prefix "meeting")
"Tag denoting a meeting.")
;; (defconst org-x-tag-environmental
;; (org-x-prepend-char org-x-tag-category-prefix "env")
;; "Tag denoting an environmental life category.")
;; (defconst org-x-tag-financial
;; (org-x-prepend-char org-x-tag-category-prefix "fin")
;; "Tag denoting a financial life category.")
;; (defconst org-x-tag-intellectual
;; (org-x-prepend-char org-x-tag-category-prefix "int")
;; "Tag denoting an intellectual life category.")
;; (defconst org-x-tag-metaphysical
;; (org-x-prepend-char org-x-tag-category-prefix "met")
;; "Tag denoting an metaphysical life category.")
;; (defconst org-x-tag-physical
;; (org-x-prepend-char org-x-tag-category-prefix "phy")
;; "Tag denoting an physical life category.")
;; (defconst org-x-tag-professional
;; (org-x-prepend-char org-x-tag-category-prefix "pro")
;; "Tag denoting a professional life category.")
;; (defconst org-x-tag-recreational
;; (org-x-prepend-char org-x-tag-category-prefix "rec")
;; "Tag denoting a recreational life category.")
;; (defconst org-x-tag-social
;; (org-x-prepend-char org-x-tag-category-prefix "soc")
;; "Tag denoting a social life category.")
(defconst org-x-tag-no-agenda "NA"
"Tag denoting a headlines that shouldn't go in the agenda.")
(defconst org-x-tag-no-archive "NRXIV"
"Tag denoting a headlines that shouldn't go in the archive.")
(defconst org-x-tag-refile "REFILE"
"Tag denoting a headlines that are to be refiled.")
(defconst org-x-life-categories
(->> (list "environmental"
"financial"
"intellectual"
"metaphysical"
"physical"
"professional"
"recreational"
"social")
(--map (let* ((abbr (substring it 0 3))
(key (intern abbr))
(tag (org-x-prepend-char org-x-tag-category-prefix abbr)))
(list key :tag tag :desc it))))
"Alist of life categories.
The car of each member is a symbol representing the category, the
cdr is a plist which has entries for :tag and :desc which are the
org tag and a long name respectively for the category.")
(defun org-x-life-category-plist-get (key category-sym)
(plist-get (alist-get category-sym org-x-life-categories) key))
(defun org-x-life-category-tag (category-sym)
(org-x-life-category-plist-get :tag category-sym))
(defun org-x-life-category-desc (category-sym)
(org-x-life-category-plist-get :desc category-sym))
;;; PROPERTIES
;; all follow the nomenclature `org-x-prop-PROPNAME' (key) or
;; `org-x-prop-PROPNAME-VALNAME' (value)
(defconst org-x-prop-parent-type "PARENT_TYPE"
"Property denoting iterator/periodical headline.")
(defconst org-x-prop-parent-type-periodical "periodical"
"Property value for a periodical parent type.")
(defconst org-x-prop-parent-type-iterator "iterator"
"Property value for an iterator parent type.")
(defconst org-x-prop-time-shift "TIME_SHIFT"
"Property denoting time shift when cloning iterator/periodical headlines.")
(defconst org-x-prop-location "X-LOCATION"
"Property denoting location for meetings.")
;; TODO this is a WIP
(defconst org-x-prop-thread "THREAD"
"Property denoting an email thread to track.")
(defconst org-x-prop-routine "X-ROUTINE"
"Property denoting a routine group.")
(defconst org-x-prop-routine-morning "morning"
"Property value for morning routine.")
(defconst org-x-prop-routine-evening "evening"
"Property value for evening routine.")
(defconst org-x-prop-created "CREATED"
"Property denoting when a headline was created.")
(defconst org-x-prop-expire "X-EXPIRE"
"Property denoting when a headline will expire.")
(defconst org-x-prop-days-to-live "X-DAYS_TO_LIVE"
"Property denoting after how many days a headline will expire.")
(defconst org-x-prop-goal "X-GOAL"
"Property denoting the goal this headline fulfills.")
(defconst org-x-prop-allocate "X-ALLOCATE"
"Property the property denoting intended time allocation.")
;;; DRAWERS
(defconst org-x-drwr-agenda "AGENDA_ITEMS"
"Drawer to hold agenda items in meetings.")
(defconst org-x-drwr-action "ACTION_ITEMS"
"Drawer to hold action items in meetings.")
(defconst org-x-drwr-categories "X_CATEGORIES"
"Drawer to hold ranked categories for a quarterly plan.")
;;; PUBLIC VARS
(defconst org-x-archive-delay 30
"The number of days to wait before tasks are considered archivable.")
(defconst org-x-inert-delay-days 90
"The number of days to wait before tasks are considered inert.")
(defconst org-x-iterator-active-future-offset (* 7 24 60 60)
"Iterators must have at least one task this far in the future to be active.")
(defconst org-x-periodical-active-future-offset
org-x-iterator-active-future-offset
"Periodicals must have at least one heading this far in the future to be active.")
(provide 'org-x-const)
;;; org-x-const.el ends here

View File

@ -29,6 +29,9 @@
(require 'either) (require 'either)
(require 'ht) (require 'ht)
(require 'org-x-files)
(require 'org-x-const)
;;; DATE/TIME FUNCTIONS ;;; DATE/TIME FUNCTIONS
;; current state ;; current state
@ -69,6 +72,17 @@
;; datetime operations ;; datetime operations
(defmacro org-x-dag-with-times (datetime0 datetime1 form)
;; ASSUME all digits in this comparison are on the calendar/clock (eg day 32
;; does not 'rollover' to day 1 on the next month)
(declare (indent 2))
`(if (or (and (org-ml-time-is-long ,datetime0)
(org-ml-time-is-long ,datetime1))
(not (or (org-ml-time-is-long ,datetime0)
(org-ml-time-is-long ,datetime1))))
,form
(error "Datetimes are invalid lengths: %S and %S" ,datetime0 ,datetime1)))
(defun org-x-dag-datetime< (datetime0 datetime1) (defun org-x-dag-datetime< (datetime0 datetime1)
(org-x-dag-with-times datetime0 datetime1 (org-x-dag-with-times datetime0 datetime1
(-when-let (next (->> (-zip-with #'cons datetime0 datetime1) (-when-let (next (->> (-zip-with #'cons datetime0 datetime1)
@ -2483,17 +2497,6 @@ encountered will be returned."
:repeater (org-ml-timestamp-extract-modulus 'repeater ts) :repeater (org-ml-timestamp-extract-modulus 'repeater ts)
:warning (org-ml-timestamp-extract-modulus 'warning ts))) :warning (org-ml-timestamp-extract-modulus 'warning ts)))
(defmacro org-x-dag-with-times (datetime0 datetime1 form)
;; ASSUME all digits in this comparison are on the calendar/clock (eg day 32
;; does not 'rollover' to day 1 on the next month)
(declare (indent 2))
`(if (or (and (org-ml-time-is-long ,datetime0)
(org-ml-time-is-long ,datetime1))
(not (or (org-ml-time-is-long ,datetime0)
(org-ml-time-is-long ,datetime1))))
,form
(error "Datetimes are invalid lengths: %S and %S" ,datetime0 ,datetime1)))
(defun org-x-dag-repeater-get-next (sel-datetime datetime shift shifttype reptype) (defun org-x-dag-repeater-get-next (sel-datetime datetime shift shifttype reptype)
"Return the next timestamp repeater of DATETIME." "Return the next timestamp repeater of DATETIME."
(pcase reptype (pcase reptype

View File

@ -0,0 +1,155 @@
;;; org-x-files.el --- Extra Org file bits -*- lexical-binding: t; -*-
;; Copyright (C) 2022 Nathan Dwarshuis
;; Author: Nathan Dwarshuis <natedwarshuis@gmail.com>
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(require 'f)
;; files and directories (all relative to `org-directory')
(defvar org-x-action-files nil
"List of relative paths or globs that hold actions (not incubated).")
(defvar org-x-incubator-files nil
"List of relative paths or globs that hold incubated actions.")
(defvar org-x-reference-files nil
"List of relative paths or globs that hold referenced headlines.")
(defvar org-x-capture-file nil
"Path to capture file.")
(defvar org-x-endpoint-goal-file nil
"Path to endpoint goal file.")
(defvar org-x-survival-goal-file nil
"Path to survival goal file.")
(defvar org-x-quarterly-plan-file nil
"Path to quarterly plan file.")
(defvar org-x-weekly-plan-file nil
"Path to weekly plan file.")
(defvar org-x-lifetime-goal-file nil
"Path to lifetime goal file.")
(defvar org-x-daily-plan-file nil
"Path to daily plan file.")
(defvar org-x-meeting-archive-file nil
"Path to meeting archive file.")
;;; ORG FILE LOCATIONS
(defun org-x--abs-org-path (path)
"Return PATH as an absolute path string.
PATH is a assumed to be a path relative to `org-directory'.
If PATH is not relative, return nil and print a warning."
(if (f-relative-p path)
(f-canonical (f-join org-directory path))
(message "WARNING: %s is not a relative path" path)))
(defun org-x--valid-org-file-p (path)
"Return t if PATH points to a valid org file.
Valid means that it exists and ends in '.org'."
(cond
((not (f-file-p path))
(message "WARNING: %s does not exist; ignoring" path)
nil)
((not (s-matches-p ".*\\.org" path))
(message "WARNING: %s does not end with '.org'; ignoring" path)
nil)
(t
t)))
(defun org-x--expand-path-list (globs)
"Return GLOBS as expanded list of paths.
GLOBS is a list of strings to be consumed by `f-glob'. Only
expand files that end in '.org' and that exist are returned. All
members of GLOBS should be relative to `org-directory'."
(->> (-map #'org-x--abs-org-path globs)
(-non-nil)
(-mapcat #'f-glob)
(-filter #'org-x--valid-org-file-p)
(-uniq)))
(defun org-x--expand-path (path)
"Return PATH as an expanded path.
PATH must be relative to `org-directory' and end in '.org'."
(-when-let (a (org-x--abs-org-path path))
(when (org-x--valid-org-file-p a)
a)))
(defun org-x-get-endpoint-goal-file ()
"Return the absolute path of `org-x-endpoint-goal-file'."
(org-x--expand-path org-x-endpoint-goal-file))
(defun org-x-get-lifetime-goal-file ()
"Return the absolute path of `org-x-lifetime-goal-file'."
(org-x--expand-path org-x-lifetime-goal-file))
(defun org-x-get-survival-goal-file ()
"Return the absolute path of `org-x-survival-goal-file'."
(org-x--expand-path org-x-survival-goal-file))
(defun org-x-get-capture-file ()
"Return the absolute path of `org-x-capture-file'."
(org-x--expand-path org-x-capture-file))
(defun org-x-get-action-files ()
"Return the absolute path of `org-x-action-files'."
(org-x--expand-path-list org-x-action-files))
(defun org-x-get-daily-plan-file ()
"Return the absolute path of `org-x-daily-plan-file'."
(org-x--expand-path org-x-daily-plan-file))
(defun org-x-get-weekly-plan-file ()
"Return the absolute path of `org-x-weekly-plan-file'."
(org-x--expand-path org-x-weekly-plan-file))
(defun org-x-qtp-get-file ()
"Return the absolute path of `org-x-quarterly-plan-file'."
(org-x--expand-path org-x-quarterly-plan-file))
(defun org-x-get-incubator-files ()
"Return the absolute path of `org-x-incubator-files'."
(org-x--expand-path-list org-x-incubator-files))
(defun org-x-get-reference-files ()
"Return the absolute path of `org-x-reference-files'."
(org-x--expand-path-list org-x-reference-files))
(defun org-x-get-action-and-incubator-files ()
"Return combined list of paths for incubator and action files."
(append (org-x-get-action-files)
(org-x-get-incubator-files)))
(defmacro org-x-with-file (path &rest body)
"Open PATH and execute BODY."
(declare (indent 1))
`(with-current-buffer (find-file-noselect ,path)
(save-excursion
,@body)))
(provide 'org-x-files)
;;; org-x-files.el ends here

View File

@ -39,283 +39,6 @@
(require 'org-x-agg) (require 'org-x-agg)
(require 'org-x-dag) (require 'org-x-dag)
;;; TODO KEYWORDS
(defconst org-x-kw-todo "TODO"
"Headline todo keyword for open task or project.")
(defconst org-x-kw-next "NEXT"
"Headline todo keyword for next task.")
(defconst org-x-kw-wait "WAIT"
"Headline todo keyword for task that is waiting on something.")
(defconst org-x-kw-hold "HOLD"
"Headline todo keyword for task or project that is held.")
(defconst org-x-kw-done "DONE"
"Headline todo keyword for completed task or project.")
(defconst org-x-kw-canc "CANC"
"Headline todo keyword for canceled task or project.")
(defconst org-x-done-keywords `(,org-x-kw-done ,org-x-kw-canc)
"Headline todo keywords that mark a task as 'complete'.")
(defconst org-x-meeting-keywords (cons org-x-kw-todo org-x-done-keywords)
"Allowed keywords for meetings.")
;;; TAGS
(defun org-x-prepend-char (char string)
"Return STRING with CHAR appended to the front."
(concat (char-to-string char) string))
(defconst org-x-tag-location-prefix ?@
"Prefix character denoting location context tag.")
(defconst org-x-tag-resource-prefix ?#
"Prefix character denoting resource context tag.")
(defconst org-x-tag-misc-prefix ?%
"Prefix character denoting misc tag.")
(defconst org-x-tag-category-prefix ?_
"Prefix character denoting life category tag.")
(defconst org-x-exclusive-prefixes (list org-x-tag-category-prefix
org-x-tag-location-prefix)
"Tag prefixes which denote mutually exclusive groups.")
(defconst org-x-tag-errand
(org-x-prepend-char org-x-tag-location-prefix "errand")
"Tag denoting an errand location.")
(defconst org-x-tag-home
(org-x-prepend-char org-x-tag-location-prefix "home")
"Tag denoting a home location.")
(defconst org-x-tag-work
(org-x-prepend-char org-x-tag-location-prefix "work")
"Tag denoting a work location.")
(defconst org-x-tag-travel
(org-x-prepend-char org-x-tag-location-prefix "travel")
"Tag denoting a travel location.")
(defconst org-x-tag-laptop
(org-x-prepend-char org-x-tag-resource-prefix "laptop")
"Tag denoting a laptop resource.")
(defconst org-x-tag-phone
(org-x-prepend-char org-x-tag-resource-prefix "phone")
"Tag denoting a phone resource.")
(defconst org-x-tag-deep
(org-x-prepend-char org-x-tag-misc-prefix "deep")
"Tag denoting deep work.")
(defconst org-x-tag-note
(org-x-prepend-char org-x-tag-misc-prefix "note")
"Tag denoting a note.")
(defconst org-x-tag-incubated
(org-x-prepend-char org-x-tag-misc-prefix "inc")
"Tag denoting an incubated task.")
(defconst org-x-tag-maybe
(org-x-prepend-char org-x-tag-misc-prefix "maybe")
"Tag denoting a maybe task.")
(defconst org-x-tag-subdivision
(org-x-prepend-char org-x-tag-misc-prefix "subdiv")
"Tag denoting a task awaiting subdivision.")
(defconst org-x-tag-flagged
(org-x-prepend-char org-x-tag-misc-prefix "flag")
"Tag denoting a flagged task.")
(defconst org-x-tag-meeting
(org-x-prepend-char org-x-tag-misc-prefix "meeting")
"Tag denoting a meeting.")
;; (defconst org-x-tag-environmental
;; (org-x-prepend-char org-x-tag-category-prefix "env")
;; "Tag denoting an environmental life category.")
;; (defconst org-x-tag-financial
;; (org-x-prepend-char org-x-tag-category-prefix "fin")
;; "Tag denoting a financial life category.")
;; (defconst org-x-tag-intellectual
;; (org-x-prepend-char org-x-tag-category-prefix "int")
;; "Tag denoting an intellectual life category.")
;; (defconst org-x-tag-metaphysical
;; (org-x-prepend-char org-x-tag-category-prefix "met")
;; "Tag denoting an metaphysical life category.")
;; (defconst org-x-tag-physical
;; (org-x-prepend-char org-x-tag-category-prefix "phy")
;; "Tag denoting an physical life category.")
;; (defconst org-x-tag-professional
;; (org-x-prepend-char org-x-tag-category-prefix "pro")
;; "Tag denoting a professional life category.")
;; (defconst org-x-tag-recreational
;; (org-x-prepend-char org-x-tag-category-prefix "rec")
;; "Tag denoting a recreational life category.")
;; (defconst org-x-tag-social
;; (org-x-prepend-char org-x-tag-category-prefix "soc")
;; "Tag denoting a social life category.")
(defconst org-x-tag-no-agenda "NA"
"Tag denoting a headlines that shouldn't go in the agenda.")
(defconst org-x-tag-no-archive "NRXIV"
"Tag denoting a headlines that shouldn't go in the archive.")
(defconst org-x-tag-refile "REFILE"
"Tag denoting a headlines that are to be refiled.")
(defconst org-x-life-categories
(->> (list "environmental"
"financial"
"intellectual"
"metaphysical"
"physical"
"professional"
"recreational"
"social")
(--map (let* ((abbr (substring it 0 3))
(key (intern abbr))
(tag (org-x-prepend-char org-x-tag-category-prefix abbr)))
(list key :tag tag :desc it))))
"Alist of life categories.
The car of each member is a symbol representing the category, the
cdr is a plist which has entries for :tag and :desc which are the
org tag and a long name respectively for the category.")
(defun org-x-life-category-plist-get (key category-sym)
(plist-get (alist-get category-sym org-x-life-categories) key))
(defun org-x-life-category-tag (category-sym)
(org-x-life-category-plist-get :tag category-sym))
(defun org-x-life-category-desc (category-sym)
(org-x-life-category-plist-get :desc category-sym))
;;; PROPERTIES
;; all follow the nomenclature `org-x-prop-PROPNAME' (key) or
;; `org-x-prop-PROPNAME-VALNAME' (value)
(defconst org-x-prop-parent-type "PARENT_TYPE"
"Property denoting iterator/periodical headline.")
(defconst org-x-prop-parent-type-periodical "periodical"
"Property value for a periodical parent type.")
(defconst org-x-prop-parent-type-iterator "iterator"
"Property value for an iterator parent type.")
(defconst org-x-prop-time-shift "TIME_SHIFT"
"Property denoting time shift when cloning iterator/periodical headlines.")
(defconst org-x-prop-location "X-LOCATION"
"Property denoting location for meetings.")
;; TODO this is a WIP
(defconst org-x-prop-thread "THREAD"
"Property denoting an email thread to track.")
(defconst org-x-prop-routine "X-ROUTINE"
"Property denoting a routine group.")
(defconst org-x-prop-routine-morning "morning"
"Property value for morning routine.")
(defconst org-x-prop-routine-evening "evening"
"Property value for evening routine.")
(defconst org-x-prop-created "CREATED"
"Property denoting when a headline was created.")
(defconst org-x-prop-expire "X-EXPIRE"
"Property denoting when a headline will expire.")
(defconst org-x-prop-days-to-live "X-DAYS_TO_LIVE"
"Property denoting after how many days a headline will expire.")
(defconst org-x-prop-goal "X-GOAL"
"Property denoting the goal this headline fulfills.")
(defconst org-x-prop-allocate "X-ALLOCATE"
"Property the property denoting intended time allocation.")
;;; DRAWERS
(defconst org-x-drwr-agenda "AGENDA_ITEMS"
"Drawer to hold agenda items in meetings.")
(defconst org-x-drwr-action "ACTION_ITEMS"
"Drawer to hold action items in meetings.")
(defconst org-x-drwr-categories "X_CATEGORIES"
"Drawer to hold ranked categories for a quarterly plan.")
;;; PUBLIC VARS
(defconst org-x-archive-delay 30
"The number of days to wait before tasks are considered archivable.")
(defconst org-x-inert-delay-days 90
"The number of days to wait before tasks are considered inert.")
(defconst org-x-iterator-active-future-offset (* 7 24 60 60)
"Iterators must have at least one task this far in the future to be active.")
(defconst org-x-periodical-active-future-offset
org-x-iterator-active-future-offset
"Periodicals must have at least one heading this far in the future to be active.")
;; files and directories (all relative to `org-directory')
(defvar org-x-action-files nil
"List of relative paths or globs that hold actions (not incubated).")
(defvar org-x-incubator-files nil
"List of relative paths or globs that hold incubated actions.")
(defvar org-x-reference-files nil
"List of relative paths or globs that hold referenced headlines.")
(defvar org-x-capture-file nil
"Path to capture file.")
(defvar org-x-endpoint-goal-file nil
"Path to endpoint goal file.")
(defvar org-x-survival-goal-file nil
"Path to survival goal file.")
(defvar org-x-quarterly-plan-file nil
"Path to quarterly plan file.")
(defvar org-x-weekly-plan-file nil
"Path to weekly plan file.")
(defvar org-x-lifetime-goal-file nil
"Path to lifetime goal file.")
(defvar org-x-daily-plan-file nil
"Path to daily plan file.")
(defvar org-x-meeting-archive-file nil
"Path to meeting archive file.")
;;; INTERNAL CONSTANTS ;;; INTERNAL CONSTANTS
;; TODO ;unscheduled should trump all ;; TODO ;unscheduled should trump all
@ -386,13 +109,6 @@ the current time."
(org-ml-to-string)))) (org-ml-to-string))))
(org-ml-headline-set-node-property org-x-prop-created ts headline))) (org-ml-headline-set-node-property org-x-prop-created ts headline)))
(defmacro org-x-with-file (path &rest body)
"Open PATH and execute BODY."
(declare (indent 1))
`(with-current-buffer (find-file-noselect ,path)
(save-excursion
,@body)))
(defun org-x-parse-file-subtrees (path which) (defun org-x-parse-file-subtrees (path which)
"Return a list of headlines from file at PATH. "Return a list of headlines from file at PATH.
WHICH is passed to the one argument of `org-ml-parse-subtrees'." WHICH is passed to the one argument of `org-ml-parse-subtrees'."
@ -405,92 +121,6 @@ WHICH is passed to the one argument of `org-ml-parse-headlines'."
(org-x-with-file path (org-x-with-file path
(org-ml-parse-headlines which))) (org-ml-parse-headlines which)))
;;; ORG FILE LOCATIONS
(defun org-x--abs-org-path (path)
"Return PATH as an absolute path string.
PATH is a assumed to be a path relative to `org-directory'.
If PATH is not relative, return nil and print a warning."
(if (f-relative-p path)
(f-canonical (f-join org-directory path))
(message "WARNING: %s is not a relative path" path)))
(defun org-x--valid-org-file-p (path)
"Return t if PATH points to a valid org file.
Valid means that it exists and ends in '.org'."
(cond
((not (f-file-p path))
(message "WARNING: %s does not exist; ignoring" path)
nil)
((not (s-matches-p ".*\\.org" path))
(message "WARNING: %s does not end with '.org'; ignoring" path)
nil)
(t
t)))
(defun org-x--expand-path-list (globs)
"Return GLOBS as expanded list of paths.
GLOBS is a list of strings to be consumed by `f-glob'. Only
expand files that end in '.org' and that exist are returned. All
members of GLOBS should be relative to `org-directory'."
(->> (-map #'org-x--abs-org-path globs)
(-non-nil)
(-mapcat #'f-glob)
(-filter #'org-x--valid-org-file-p)
(-uniq)))
(defun org-x--expand-path (path)
"Return PATH as an expanded path.
PATH must be relative to `org-directory' and end in '.org'."
(-when-let (a (org-x--abs-org-path path))
(when (org-x--valid-org-file-p a)
a)))
(defun org-x-get-endpoint-goal-file ()
"Return the absolute path of `org-x-endpoint-goal-file'."
(org-x--expand-path org-x-endpoint-goal-file))
(defun org-x-get-lifetime-goal-file ()
"Return the absolute path of `org-x-lifetime-goal-file'."
(org-x--expand-path org-x-lifetime-goal-file))
(defun org-x-get-survival-goal-file ()
"Return the absolute path of `org-x-survival-goal-file'."
(org-x--expand-path org-x-weekly-plan-file))
(defun org-x-get-capture-file ()
"Return the absolute path of `org-x-capture-file'."
(org-x--expand-path org-x-capture-file))
(defun org-x-get-action-files ()
"Return the absolute path of `org-x-action-files'."
(org-x--expand-path-list org-x-action-files))
(defun org-x-get-daily-plan-file ()
"Return the absolute path of `org-x-daily-plan-file'."
(org-x--expand-path org-x-daily-plan-file))
(defun org-x-get-weekly-plan-file ()
"Return the absolute path of `org-x-weekly-plan-file'."
(org-x--expand-path org-x-weekly-plan-file))
(defun org-x-qtp-get-file ()
"Return the absolute path of `org-x-quarterly-plan-file'."
(org-x--expand-path org-x-quarterly-plan-file))
(defun org-x-get-incubator-files ()
"Return the absolute path of `org-x-incubator-files'."
(org-x--expand-path-list org-x-incubator-files))
(defun org-x-get-reference-files ()
"Return the absolute path of `org-x-reference-files'."
(org-x--expand-path-list org-x-reference-files))
(defun org-x-get-action-and-incubator-files ()
"Return combined list of paths for incubator and action files."
(append (org-x-get-action-files)
(org-x-get-incubator-files)))
;;; STATEFUL BUFFER HEADLINE FUNCTIONS ;;; STATEFUL BUFFER HEADLINE FUNCTIONS
;; All of these functions operate on the current headline ;; All of these functions operate on the current headline
@ -715,7 +345,7 @@ return KEYWORD if WHEN-FORM is t."
"Return todo keyword if current headline has one.") "Return todo keyword if current headline has one.")
(defun org-x-headline-has-discontinuous-parent () (defun org-x-headline-has-discontinuous-parent ()
"Return t if heading has a non-todoitem parent which in turn has a todoitem parent." "Return t if heading is discontinuous."
(let ((has-todoitem-parent) (let ((has-todoitem-parent)
(has-non-todoitem-parent)) (has-non-todoitem-parent))
(save-excursion (save-excursion
@ -1506,7 +1136,7 @@ epoch time or a list of integers as returned by `current-time')."
(let ((h (apply #'org-ml-build-headline! (let ((h (apply #'org-ml-build-headline!
:level 3 :level 3
:title-text title :title-text title
:tags `(,(org-x-life-category-tag ,category)) :tags `(,(org-x-life-category-tag category))
goals))) goals)))
(sort-goal-cats (cons h it)))))))) (sort-goal-cats (cons h it))))))))