org-ql/tests/data.org
Adam Porter e60e217312 Tidy: Test data file
Not sure how that indentation ended up there.
2019-10-01 04:46:31 -05:00

20 KiB
Raw Permalink Blame History

Test data

Rather than using my personal agenda every time I want to take a screenshot, how about this.

Will try to open the agenda view as if it was [2017-07-05 Wed]

TODO [A] Take over the universe   universe ambition

DEADLINE: <2017-07-15 Sat -1m>

TODO [A] Take over the world   world

DEADLINE: <2017-07-07 Fri>

I'd like to be finished with this before the weekend…

TODO [A] Skype with president of Antarctica   world meetings

SCHEDULED: <2017-07-04 Tue 21:00>

Not sure what his timezone is…

TODO [B] Take over Mars

TODO Visit Mars   space travel planet

DEADLINE: <2017-09-20 Wed -3m>

Ah, the red planet…

TODO [C] Take over the moon

WAITING Visit the moon   space travel

DEADLINE: <2017-08-27 Sun -2m>

  • State "WAITING" from [2017-07-24 Mon 19:01]

Just waiting on that callback from NASA…

TODO Practice leaping tall buildings in a single bound   personal

SCHEDULED: <2017-07-05 Wed +2d>

TODO [B] Renew membership in supervillain club

DEADLINE: <2017-07-10 Mon -1w>

DONE [B] Learn universal sign language

CLOSED: [2017-07-05 Wed 03:02]

  • CLOSING NOTE [2017-07-05 Wed 03:02]
    All done!

CLOCK: [2017-07-05 Wed 02:00][2017-07-05 Wed 03:02] => 1:02

TODO Order a pizza   food dinner

SCHEDULED: <2017-07-05 Wed 18:00>

TODO [C] Get haircut   personal @town

SCHEDULED: <2017-07-05 Wed>

Should probably do this before I take over the world. Want to look my best. (Not that it will matter once I'm in charge.)

TODO [B] Internet   bills

DEADLINE: <2017-07-21 Fri -1m>

TODO [A] Spaceship lease   bills spaceship

DEADLINE: <2017-08-01 Tue -1m>

TODO [B] Fix flux capacitor   spaceship shopping @computer

SCHEDULED: <2017-07-05 Wed>

If I don't, the frobnicator will probably fall off halfway to Mars…

Gotta buy one first, though.

Recurring

CHECK /r/emacs   website Emacs

DEADLINE: <2017-07-05 Wed +1w>

TODO Shop for groceries   food shopping @town

SCHEDULED: <2017-07-05 Wed +1w>

Sunrise/sunset

%%(org-super-agendatest-diary-sunrise) %%(org-super-agendatest-diary-sunset)

Ideas

SOMEDAY Rewrite Emacs in Common Lisp   Emacs elisp computers software programming

SCHEDULED: <2017-07-05 Wed>

  • State "SOMEDAY" from "MAYBE" [2017-07-24 Mon 18:59]
  • State "MAYBE" from [2017-07-24 Mon 18:58]

I mean, since no one has ever tried doing it before…

SOMEDAY Write a symphony   music

I don't know when I'll get to this, so it's undated.

Code

  (cl-defun ap/org-tweak-timestamps (&key (offset 0) epoch-ts)
    "Advance all timestamps in the current buffer as if the earliest one was on today.
  OFFSET changes which timestamp (in chronological order) is set to
  today.  Or, if EPOCH-TS is non-nil, use it as the new zero-point
  for today."
    (let* ((tss (->> (org-with-wide-buffer
                      (goto-char (point-min))
                      (cl-loop while (re-search-forward org-ts-regexp-both nil t)
                               collect (ts-parse-org (match-string 0))))
                     (-sort #'ts<)))
           (epoch-ts (if epoch-ts
                         (ts-parse-org epoch-ts)
                       (nth offset tss)))
           (difference-secs (ts-diff (ts-now) epoch-ts))
           (days (floor (/ difference-secs 86400))))
      (org-with-wide-buffer
       (goto-char (point-min))
       (while (re-search-forward org-ts-regexp-both nil t)
         (let* ((ts (ts-parse-org (match-string 0)))
                (timed-p (string-match-p (rx (repeat 2 digit) ":" (repeat 2 digit) (or ">" "]")) (match-string 0)))
                (type (cond ((string-prefix-p "<" (match-string 0)) 'active)
                            ((string-prefix-p "[" (match-string 0)) 'inactive)
                            (t (error "Unknown ts type"))))
                (brackets (cl-ecase type
                            ('active (cons "<" ">"))
                            ('inactive (cons "[" "]"))))
                (format-string (concat (car brackets)
                                       (if timed-p
                                           "%Y-%m-%d %a %H:%M"
                                         "%Y-%m-%d %a")
                                       (cdr brackets)))
                (new-ts (ts-adjust 'day days ts))
                (new-ts-string (ts-format format-string new-ts)))
           (replace-match new-ts-string t t nil 0))))
      (message "Tweaked from epoch: %s" (ts-format epoch-ts))))
(org-time-string-to-absolute (org-entry-get (point) "SCHEDULED"))
;; Setup code
(require 'org-super-agenda)
(org-super-agenda-mode 1)
(require 'org-habit)
(setq org-todo-keywords
      '((sequence "TODO(t!)" "TODAY(a!)" "NEXT(n!)" "STARTED(s!)" "IN-PROGRESS(p!)" "UNDERWAY(u!)" "WAITING(w@)" "SOMEDAY(o!)" "MAYBE(m!)" "|" "DONE(d@)" "CANCELED(c@)")
        (sequence "CHECK(k!)" "|" "DONE(d@)")
        (sequence "TO-READ(r!)" "READING(R!)" "|" "HAVE-READ(d@)")
        (sequence "TO-WATCH(!)" "WATCHING(!)" "SEEN(!)")))
(with-current-buffer "test.org" (revert-buffer))

(defmacro with-org-today-date (date &rest body)
  "Run BODY with the `org-today' function set to return simply DATE.
DATE should be a date-time string (both date and time must be included)."
  (declare (indent defun))
  `(let ((day (date-to-day ,date))
         (orig (symbol-function 'org-today)))
     (unwind-protect
         (progn
           (fset 'org-today (lambda () day))
           ,@body)
       (fset 'org-today orig))))
  (defun diary-sunrise ()
    (let ((dss (diary-sunrise-sunset)))
      (with-temp-buffer
        (insert dss)
        (goto-char (point-min))
        (search-forward ",")
        (buffer-substring (point-min) (match-beginning 0)))))

  (defun diary-sunset ()
    (let ((dss (diary-sunrise-sunset))
          start end)
      (with-temp-buffer
        (insert dss)
        (goto-char (point-min))
        (search-forward ", ")
        (setq start (match-end 0))
        (search-forward " at")
        (setq end (match-beginning 0))
        (goto-char start)
        (capitalize-word 1)
        (buffer-substring start end))))

Note: Removing tests from here as they're added to test.el.

  (org-super-agenda--test-with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/emacs/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-super-agenda-groups
           '((:name "Time grid items in all-uppercase with RosyBrown1 foreground"
                    :time-grid t
                    :transformer (--> it
                                      (upcase it)
                                      (propertize it 'face '(:foreground "RosyBrown1"))))
             (:name "Priority >= C items underlined, on black background"
                    :face (:background "black" :underline t)
                    :not (:priority>= "C")
                    :order 100))))
      (org-agenda nil "a")))
  (org-super-agenda--test-with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/emacs/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-super-agenda-groups
           '((:name none
                    :time-grid t)
             (:name "Should be all-uppercase RosyBrown1 on black"
                    :face (:background "black" :foreground "RosyBrown1")
                    :transformer #'upcase
                    :not (:priority>= "C")
                    :order 100))))
      (org-agenda nil "a")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-super-agenda-groups
           '((:name none
                    :time-grid t)
             (:name none
                    :not (:priority>= "C")
                    :order 100))))
      (org-agenda nil "a")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-super-agenda-groups
           '((:name "Items with child TODOs"
                    :children todo))))
      (org-agenda nil "a")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-super-agenda-groups
           '((:name "Items with child TODOs"
                    :children "CHECK"))))
      (org-agenda nil "a")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-agenda-custom-commands
           '(("u" "Super view"
              ((agenda "" ((org-super-agenda-groups
                            '((:name "Today"
                                     :time-grid t
                                     :scheduled today
                                     :deadline today)))))
               (todo "" ((org-super-agenda-groups
                          '((:name "Projects"
                                   :children t)
                            (:discard (:anything t)))))))))))
      (org-agenda nil "u")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-agenda-custom-commands
           '(("u" "Super view"
              ((agenda "" ((org-super-agenda-groups
                            '((:name "Today"
                                     :time-grid today)))))
               (todo "" ((org-super-agenda-groups
                          '((:name "Projects"
                                   :children t)
                            (:discard (:anything t)))))))))))
      (org-agenda nil "u")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-agenda-custom-commands
           '(("u" "Super view"
              ((agenda "" ((org-super-agenda-groups
                            '((:name "Schedule"
                                     :time-grid t
                                     :date today)
                              (:name "Due today"
                                     :deadline today)
                              (:name "Due soon"
                                     :deadline t)))))
               (todo "" ((org-agenda-overriding-header "")
                         (org-super-agenda-groups
                          '((:name "Projects"
                                   :children t)
                            (:discard (:anything t)))))))))))
      (org-agenda nil "u")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-agenda-span 'day)
          (org-super-agenda-groups
           '((:scheduled (before "2017-07-06")))))
      (org-agenda nil "a")))
  (with-org-today-date "2017-07-05 00:00"
    (let ((org-super-agenda-groups
           '((:todo "WAITING")))
          (org-agenda-files (list "~/src/org-super-agenda/test/test.org")))
      (org-todo-list)))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-super-agenda-groups
           '((:todo "SOMEDAY")))
          (org-agenda-files (list "~/src/org-super-agenda/test/test.org")))
      (org-tags-view nil "Emacs")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-super-agenda-groups
           '((:todo "CHECK")))
          (org-agenda-files (list "~/src/org-super-agenda/test/test.org")))
;; org-search-view doesn't seem to set the todo-state property, so the matcher doesn't work
      (org-search-view nil "Emacs")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-super-agenda-groups
           '((:regexp ("moon" "mars"))))
          (org-agenda-files (list "~/src/org-super-agenda/test/test.org")))
      (org-search-view nil "space")))

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-super-agenda-groups
           '((:todo "SOMEDAY")))
          (org-agenda-files (list "~/src/org-super-agenda/test/test.org")))
      (org-agenda-list nil nil 'day)))

Agenda examining

This helps a lot.

  (defun data-debug-show-string-with-properties (s)
    (with-current-buffer (get-buffer-create "argh")
      (erase-buffer)
      (print s (current-buffer))

      ;; Convert string reader representations to plain lists that can be set
      (cl-loop for (match replace) in '(("#(" "'(")
                                        ("#<" "'(")
                                        (">" ")"))
               do (progn
                    (goto-char (point-min))
                    (while (search-forward match nil 'noerror)
                      (replace-match replace 'fixedcase 'literal))))

      ;; Surround content in a list which `argh' is set to, then eval
      ;; the buffer to do it
      (goto-char (point-min))
      (insert "(setq argh (list '")
      (delete-forward-char 2)
      (goto-char (point-max))
      (insert "))")

      ;; Okay, sure, eval'ing the buffer is dangerous and bad and wrong.
      ;; But this is the only way I can find to make this work.  (Maybe
      ;; `text-properties-at' could be used to get actual lists...)
      (eval-buffer)

      (data-debug-show-stuff argh "argh")
      ;;  (switch-to-buffer (current-buffer))
      ))

  (defun data-debug-show-current-line-with-properties ()
    (interactive)
    (data-debug-show-string-with-properties (buffer-substring (line-beginning-position) (line-end-position))))

  (with-current-buffer "*Org Agenda*"
    (data-debug-show-string-with-properties (seq-subseq (split-string (buffer-string) "\n")
                                                        0 5)))

Agenda censoring

For sharing screenshots of the agenda without revealing private data.

  (defun org-agenda-sharpie ()
    "Censor the text of items in the agenda."
    (interactive)
    (let (regexp old-heading new-heading properties)
      ;; Save face properties of line in agenda to reapply to changed text
      (setq properties (text-properties-at (point)))

      ;; Go to source buffer
      (org-with-point-at (org-find-text-property-in-string 'org-marker
                                                           (buffer-substring (line-beginning-position)
                                                                             (line-end-position)))
        ;; Save old heading text and ask for new text
        (line-beginning-position)
        (unless (org-at-heading-p)
          ;; Not sure if necessary
          (org-back-to-heading))
        (setq old-heading (when (looking-at org-complex-heading-regexp)
                            (match-string 4))))
      (setq new-heading (read-from-minibuffer "Overwrite visible heading with: "))
      (add-text-properties 0 (length new-heading) properties new-heading)
      ;; Back to agenda buffer
      (save-excursion
        (when (and old-heading new-heading)
          ;; Replace agenda text
          (let ((inhibit-read-only t))
            (goto-char (line-beginning-position))
            (when (search-forward old-heading (line-end-position))
              (replace-match new-heading 'fixedcase 'literal)))))))

Auto grouping

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-super-agenda-groups
           '((:auto-group t)))
          (org-agenda-files (list "~/src/org-super-agenda/test/test.org")))
      (org-agenda-list nil nil 'day)))

Auto categories

  (let ((org-super-agenda-groups
         '((:auto-category t))))
    (org-agenda-list nil nil 'day))

Date

  (with-org-today-date "2017-07-05 00:00"
    (-let* ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
            (org-agenda-span 'day)
            ((sec minute hour day month year dow dst utcoff) (list 0 0 0 5 7 2017 3 t nil))
            (last-day-of-month
             ;; A hack that seems to work fine
             (1+ (calendar-last-day-of-month month year)))
            (target-date (format "%d-%02d-%02d" year month last-day-of-month))
            (org-super-agenda-groups
             `((:deadline (before ,target-date))
               (:discard (:anything t)))))
      (org-todo-list)))

  (with-org-today-date "2017-07-05 00:00"
    (-let* ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
            (org-agenda-span 'day)
            ((sec minute hour day month year dow dst utcoff) (list 0 0 0 5 7 2017 3 t nil))
            (last-day-of-month  (calendar-last-day-of-month month year))
            (target-date (format "%d-%02d-%02d" year month last-day-of-month))
            (org-super-agenda-groups
             `((:deadline (before ,target-date))
               (:discard (:anything t)))))
      (org-todo-list)))

Effort

  (with-org-today-date "2017-07-05 00:00"
    (let ((org-agenda-files (list "~/src/org-super-agenda/test/test.org"))
          (org-super-agenda-groups
           '((:effort< "0:06"))))
      (org-agenda-list nil nil 'day)))

Misc

let-plist

I don't need this right now, but it might come in handy here or elsewhere.

  (defmacro osa/let-plist (keys plist &rest body)
    "`cl-destructuring-bind' without the boilerplate for plists."
    ;; See https://emacs.stackexchange.com/q/22542/3871

    ;; I really don't understand why Emacs doesn't have this already.
    ;; So many things come close to it: pcase, pcase-let, map-let,
    ;; cl-destructuring-bind, -let...but none of them let you simply
    ;; bind all the values of a plist to variables with the same name as
    ;; their keys. You always have to type the name of the key twice.

    ;; For example, compare these two forms:

    ;; (-let (((&keys :from from :to to :date date :subject subject) email))
    ;;   (list from to date subject))

    ;; (osa/let-plist (:from :to :date :subject) email
    ;;   (list from to date subject))

    ;; Now, sure, sometimes you need to bind values to differently named
    ;; variables. But when you don't, I know which one I prefer.
    (declare (indent defun))
    (setq keys (cl-loop for key in keys
                        collect (intern (replace-regexp-in-string (rx bol ":") ""
                                                                  (symbol-name key)))))
    `(cl-destructuring-bind
         (&key ,@keys &allow-other-keys)
         ,plist
       ,@body))

Profiling

  (defmacro profile-it (times &rest body)
    `(let (output)
       (dolist (p '("org-super-agenda-" "map" "org-" "string-" "s-" "buffer-" "append" "delq" "map" "list" "car" "save-" "outline-" "delete-dups" "sort" "line-" "nth" "concat" "char-to-string" "rx-" "goto-" "when" "search-" "re-"))
         (elp-instrument-package p))
       (dotimes (x ,times)
         ,@body)
       (elp-results)
       (elp-restore-all)
       (point-min)
       (forward-line 20)
       (delete-region (point) (point-max))
       (setq output (buffer-substring-no-properties (point-min) (point-max)))
       (kill-buffer)
       (delete-window)
       output))