From 7efe4c807444476e9cb0c1d808ecbf549c1e9684 Mon Sep 17 00:00:00 2001 From: ndwarshuis Date: Sun, 10 Apr 2022 18:56:00 -0400 Subject: [PATCH] ENH load org-x-dag in proper order --- local/lib/org-x/org-x-const.el | 269 ++++++++++++++++++++++++ local/lib/org-x/org-x-dag.el | 25 ++- local/lib/org-x/org-x-files.el | 155 ++++++++++++++ local/lib/org-x/org-x.el | 374 +-------------------------------- 4 files changed, 440 insertions(+), 383 deletions(-) create mode 100644 local/lib/org-x/org-x-const.el create mode 100644 local/lib/org-x/org-x-files.el diff --git a/local/lib/org-x/org-x-const.el b/local/lib/org-x/org-x-const.el new file mode 100644 index 0000000..d0c6e0f --- /dev/null +++ b/local/lib/org-x/org-x-const.el @@ -0,0 +1,269 @@ +;;; org-x-const.el --- Extra Org Constants -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Nathan Dwarshuis + +;; Author: Nathan Dwarshuis + +;; 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 . + +;;; 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 diff --git a/local/lib/org-x/org-x-dag.el b/local/lib/org-x/org-x-dag.el index 02351eb..54fa00f 100644 --- a/local/lib/org-x/org-x-dag.el +++ b/local/lib/org-x/org-x-dag.el @@ -29,6 +29,9 @@ (require 'either) (require 'ht) +(require 'org-x-files) +(require 'org-x-const) + ;;; DATE/TIME FUNCTIONS ;; current state @@ -69,6 +72,17 @@ ;; 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) (org-x-dag-with-times 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) :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) "Return the next timestamp repeater of DATETIME." (pcase reptype diff --git a/local/lib/org-x/org-x-files.el b/local/lib/org-x/org-x-files.el new file mode 100644 index 0000000..edfabba --- /dev/null +++ b/local/lib/org-x/org-x-files.el @@ -0,0 +1,155 @@ +;;; org-x-files.el --- Extra Org file bits -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Nathan Dwarshuis + +;; Author: Nathan Dwarshuis + +;; 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 . + +;;; 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 diff --git a/local/lib/org-x/org-x.el b/local/lib/org-x/org-x.el index 0beaccb..7df2cce 100644 --- a/local/lib/org-x/org-x.el +++ b/local/lib/org-x/org-x.el @@ -39,283 +39,6 @@ (require 'org-x-agg) (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 ;; TODO ;unscheduled should trump all @@ -386,13 +109,6 @@ the current time." (org-ml-to-string)))) (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) "Return a list of headlines from file at PATH. 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-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 ;; 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.") (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) (has-non-todoitem-parent)) (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! :level 3 :title-text title - :tags `(,(org-x-life-category-tag ,category)) + :tags `(,(org-x-life-category-tag category)) goals))) (sort-goal-cats (cons h it))))))))