emacs-config/config-org.org

60 KiB
Raw Blame History

Plugins

fstree

  (add-to-list 'load-path
               "~/.emacs.d/custom/org-fstree")
  (require 'org-fstree)

org-bullets

(use-package org-bullets)
(when (not (eq system-type 'windows-nt))
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))

calfw-org

  (use-package calfw)
  (use-package calfw-ical)
  (use-package calfw-gcal)
  (use-package calfw-org)
  (global-set-key (kbd "C-c A") 'cfw:open-org-calendar)
  (setq cfw:org-overwrite-default-keybinding t)

sync with google calendar

  (defvar url-http-method)
  (defvar url-http-data)
  (defvar url-http-extra-headers)
  (defvar oauth--token-data)
  (defvar url-callback-function)

  (require 'url-http)
  (unless (package-installed-p 'org-caldav)
    (use-package oauth2)
    (use-package org-caldav))
  (setq epa-pinentry-mode 'loopback)
  (setq plstore-cache-passphrase-for-symmetric-encryption t)

  (save-excursion
    (let ((filename "~/.emacs.d/google-calendar-secret.el"))
      (when (file-exists-p filename)
        (set-buffer (find-file-noselect filename))
        (let ((var (eval (read (buffer-string)))))
          (setq org-caldav-oauth2-client-id (car var)
                org-caldav-oauth2-client-secret (cadr var)))
        (kill-buffer))))

  ;; (setq org-caldav-url 'google
  ;;       org-caldav-calendar-id "jqeua8pamjrclakq3bg8mpnlis@group.calendar.google.com"
  ;;       org-caldav-inbox "~/MEGA/org/agenda/test.org"
  ;;       org-caldav-files '("~/MEGA/org/agenda/agenda.org")
  ;;       org-icalendar-include-todo nil
  ;;       org-icalendar-include-sexps t
  ;;       org-icalendar-categories '(all-tags category)
  ;;       org-icalendar-use-deadline '(event-if-todo event-if-not-todo todo-due)
  ;;       org-icalendar-use-scheduled '(event-if-todo event-if-not-todo todo-start)
  ;;       org-icalendar-with-timestamps nil
  ;;       org-caldav-delete-org-entries 'never)

  (setq org-caldav-url "https://99.57.234.31/remote.php/dav/calendars/bchu"
        org-caldav-calendar-id "orgmode"
        org-caldav-inbox "~/MEGA/org/agenda/test.org"
        org-caldav-files '("~/MEGA/org/agenda/agenda.org" "~/MEGA/org/agenda/classes_caldav_workaround.org"))

  (setq org-icalendar-alarm-time 30
        org-icalendar-include-todo nil
        org-icalendar-include-sexps t
        org-icalendar-categories '(all-tags category)
        org-icalendar-use-deadline '(event-if-todo event-if-not-todo todo-due)
        org-icalendar-use-scheduled '(todo-start event-if-todo)
        org-icalendar-with-timestamps nil
        org-caldav-delete-org-entries 'never)

  (setq org-caldav-skip-conditions '(nottodo ("TODO" "NEXT"))
        org-caldav-exclude-tags '("ARCHIVE" "_nosync_"))

Reveal.js

  (use-package org-re-reveal)
  (setq org-re-reveal-root "file:///home/benson/.reveal.js")

Old ox-reveal package

  (add-to-list 'load-path
               "~/.emacs.d/custom/org-reveal")
  (require 'ox-reveal)
  (setq org-reveal-root "file:///home/benson/.reveal.js")
  (setq org-structure-template-alist (remove-if (lambda (c) (string= (car c) "n")) org-structure-template-alist))

org-protocol

  (require 'org-protocol)

org-timeline

  (use-package org-timeline)
  (remove-hook 'org-agenda-finalize-hook 'org-timeline-insert-timeline)

Code-blocks

  (require 'ob-core)
  (require 'ob-clojure)
  (require 'ob-plantuml)
  (use-package plantuml-mode)

  (setq org-babel-clojure-backend 'cider)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((clojure . t)
     (plantuml . t)))

  (defun my-org-confirm-babel-evaluate (lang body)
    (not (member lang '("plantuml"))))

  (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
  (setq org-plantuml-jar-path "/usr/share/java/plantuml/plantuml.jar")

org-super-agenda

  (use-package org-super-agenda)
  (org-super-agenda-mode)

helm-org-rifle

  (use-package helm-org-rifle)
  (global-set-key (kbd "C-c o r") 'helm-org-rifle)
  (setq helm-org-rifle-test-against-path t)

org-agenda base folder

  (defconst my/org-folder "~/MEGA/org")
  (defconst my/agenda-folder (expand-file-name "2019-05-agenda" my/org-folder))

  (defun my/org-file (str)
    (expand-file-name str my/org-folder))
  (defun my/agenda-file (str)
    (expand-file-name str my/agenda-folder))

Keybindings

  (use-package org)
  (require 'org-agenda)

  (global-set-key "\C-cl" 'org-store-link)
  (global-set-key "\C-cc" 'org-capture)
  (global-set-key (kbd "<f5>") 'org-agenda)
  (global-set-key (kbd "C-x C-o") 'org-agenda)
  (define-key org-agenda-mode-map (kbd "a") 'org-agenda)

  (setq org-src-window-setup 'current-window)

  (setq org-list-allow-alphabetical t)  

  ;; This is for safety
  (define-key org-mode-map (kbd "C-S-<backspace>") 
    (lambda (arg)
      (interactive "P")
      (if (string= "yes" (completing-read "Are you sure you want to use that keybinding? " '("yes" "no")))
          (kill-whole-line arg)
        (org-cut-subtree))))

Different kinds of follow

  (advice-add #'org-agenda-follow-mode
              :before
              #'my/org-agenda-follow-mode)

  (defun my/org-agenda-get-name ()
    (-> (rx "*Org Agenda("
            (group (+? anything))
            (or ")"
                (and 
                 ":"
                 (one-or-more anything)))
            "*")
        (s-match-strings-all (buffer-name))
        (cadar)
        (assoc org-agenda-custom-commands)
        (cadr)))

  (defun my/org-agenda-follow-mode ()
    (if org-agenda-follow-mode
        (advice-unadvice #'org-agenda-do-context-action)
      (pcase (my/org-agenda-get-name)
        ("Reviews" (advice-add #'org-agenda-do-context-action
                               :override
                               #'my/org-agenda-do-context-action-for-review))
        ("Reviews and Journals" (advice-add #'org-agenda-do-context-action
                                            :override
                                            #'my/org-agenda-do-context-action-for-journal))
        ("Dev" (advice-add #'org-agenda-do-context-action
                           :override
                           #'my/org-agenda-do-context-action-for-project))
        (_ (advice-unadvice #'org-agenda-do-context-action)))))

  (defun advice-unadvice (sym)
    "Remove all advices from symbol SYM."
    (interactive "aFunction symbol: ")
    (advice-mapc (lambda (advice _props) (advice-remove sym advice)) sym))

  (defun my/org-agenda-show-project (&optional full-entry)
    "Display the Org file which contains the item at point.
      With prefix argument FULL-ENTRY, make the entire entry visible
      if it was hidden in the outline."
    (interactive "P")
    (let ((win (selected-window)))
      (org-agenda-goto t)
      (org-narrow-to-subtree)
      (org-flag-subtree t)
      (call-interactively 'outline-show-branches)
      (org-hide-archived-subtrees (point-min) (point-max))
      (select-window win)))

  (defun my/org-agenda-do-context-action-for-project ()
    "Show outline path and, maybe, follow mode window."
    (let ((m (org-get-at-bol 'org-marker)))
      (when (and (markerp m) (marker-buffer m))
        (and org-agenda-follow-mode
             (if org-agenda-follow-indirect
                 (org-agenda-tree-to-indirect-buffer nil)
               (my/org-agenda-show-project)))
        (and org-agenda-show-outline-path
             (org-with-point-at m (org-display-outline-path t))))))

  (defun my/org-agenda-show-review (&optional full-entry)
    "Display the Org file which contains the item at point.
      With prefix argument FULL-ENTRY, make the entire entry visible
      if it was hidden in the outline."
    (interactive "P")
    (let ((win (selected-window)))
      (org-agenda-goto t)
      (org-narrow-to-subtree)
      (org-flag-subtree t)
      (call-interactively 'org-show-entry)
      (org-hide-archived-subtrees (point-min) (point-max))
      (select-window win)))

  (defun my/org-agenda-do-context-action-for-review ()
    "Show outline path and, maybe, follow mode window."
    (let ((m (org-get-at-bol 'org-marker)))
      (when (and (markerp m) (marker-buffer m))
        (and org-agenda-follow-mode
             (if org-agenda-follow-indirect
                 (org-agenda-tree-to-indirect-buffer nil)
               (my/org-agenda-show-review)))
        (and org-agenda-show-outline-path
             (org-with-point-at m (org-display-outline-path t))))))

  (defun my/org-agenda-show-journal (&optional full-entry)
    "Display the Org file which contains the item at point.
      With prefix argument FULL-ENTRY, make the entire entry visible
      if it was hidden in the outline."
    (interactive "P")
    (let ((win (selected-window)))
      (org-agenda-goto t)
      (org-narrow-to-subtree)
      (org-flag-subtree t)
      (call-interactively 'org-show-all)
      (org-hide-archived-subtrees (point-min) (point-max))
      (select-window win)))

  (defun my/org-agenda-do-context-action-for-journal ()
    "Show outline path and, maybe, follow mode window."
    (let ((m (org-get-at-bol 'org-marker)))
      (when (and (markerp m) (marker-buffer m))
        (and org-agenda-follow-mode
             (if org-agenda-follow-indirect
                 (org-agenda-tree-to-indirect-buffer nil)
               (my/org-agenda-show-journal)))
        (and org-agenda-show-outline-path
             (org-with-point-at m (org-display-outline-path t))))))

  (defun org-agenda-goto-disable-follow (&optional highlight)
    (interactive)
    (when org-agenda-follow-mode
      (org-agenda-follow-mode))
    (org-agenda-goto highlight))

  (define-key org-agenda-mode-map (kbd "<tab>") #'org-agenda-goto-disable-follow)

count archive tree characters

  (defun my/org-count-subtree-characters ()
    (interactive)
    (save-window-excursion
      (org-agenda-goto t)
      (org-mark-subtree)
      (message (format "This subtree has %d characters. " (- (region-end) (region-beginning))))))

  (define-key org-agenda-mode-map (kbd "C") #'my/org-count-subtree-characters)

My Template

  (add-to-list 'org-structure-template-alist
               '("sv" . "src :results value"))
  (add-to-list 'org-structure-template-alist
               '("so" . "src :results output"))

Face

  (when (and (not (eq system-type 'windows-nt))
             (find-font (font-spec :name "Font Awesome 5 Free")))
    (setq org-ellipsis " "))

Variables

  (setq org-log-done 'time)
  (setq org-agenda-window-setup 'current-window)
  (setq org-agenda-restore-windows-after-quit t)

  (setq org-agenda-sticky t)

  ;;(org-agenda-load-file-list)

  ;; Targets include this file and any file contributing to the agenda - up to 9 levels deep
  (setq org-refile-targets `((nil :maxlevel . 9)
                             (my/all-agenda-files :maxlevel . 9)
                             ("~/MEGA/org/entries/panic.org" :maxlevel . 9)))

  (setq org-refile-use-cache t)

  (setq org-refile-target-verify-function
        (lambda () 
          (let ((tags (org-get-tags-at)))
            (and (not (member "ARCHIVE" tags))
                 (not (equal "DONE" (org-get-todo-state)))))))

  (setq org-agenda-show-future-repeats nil)

  ;; Use full outline paths for refile targets - we file directly with IDO
  (setq org-refile-use-outline-path 'file)

  ;; Targets complete directly with IDO
  (setq org-outline-path-complete-in-steps nil)

  ;; Allow refile to create parent tasks with confirmation
  (setq org-refile-allow-creating-parent-nodes (quote confirm))

  ;; Use the current window for indirect buffer display
  (setq org-indirect-buffer-display 'current-window)

  ;; Do not dim blocked tasks
  (setq org-agenda-dim-blocked-tasks nil)

  (setq org-agenda-compact-blocks t)

Tag hierarchy

  (setq org-tag-alist
        '((:startgrouptag)
          ("all" . nil)
          (:grouptags)
          ("time" . nil)
          ("nontime" . nil)
          (:endgrouptag)
          (:startgrouptag)
          ("time" . nil)
          (:grouptags)
          ("prod" . ?1)
          (:endgrouptag)
          (:startgrouptag)
          ("nontime" . nil)
          (:grouptags)
          ("sandbox" . ?3)
          (:endgrouptag)
          (:startgrouptag)
          ("sandbox" . ?3)
          (:grouptags)
          ("dev" . ?2)
          ("people" . nil)
          (:endgrouptag)
          (:startgroup . nil)
          ("short" . ?s)
          ("long" . ?l)
          (:endgroup . nil)
          (:startgroup . nil)
          ("watch" . ?w)
          ("read" . ?r)
          (:endgroup . nil)
          (:startgroup . nil)
          ("grow" . ?g)
          ("rest" . ?R)
          (:endgroup . nil)
          (:startgroup . nil)
          ("active" . ?a)
          ("idle" . ?i)
          (:endgroup . nil)
          ;; (:startgrouptag)
          ;; ("online")
          ;; (:grouptags)
          ;; ("article")
          ;; (:endgrouptag)
          ;; (:startgrouptag)
          ;; ("read")
          ;; (:grouptags)
          ;; ("article")
          ;; (:endgrouptag)
          (:startgrouptag)
          ("active")
          (:grouptags)
          ("prog")
          (:endgrouptag)
          (:startgrouptag)
          ("people" . nil)
          (:grouptags)
          ("family" . nil)
          (:endgrouptag)
          ))


  (setq org-agenda-hide-tags-regexp
        (mapconcat #'identity (list "time" "nontime" "prod" "dev" "sandbox"
                                    "refile"
                                    "short" "long" "watch" "read" "grow" "rest" "active" "idle")
                   "\\|"))

  (defconst category-tags '("computers"))

More alternative views

  (defun cfw:open-org-calendar-no-projects (&args)
    "Open an org schedule calendar in the new buffer."
    (interactive)
    (save-excursion
      (let ((buf (get-buffer "*cfw-calendar*")))
        (if buf
            (switch-to-buffer buf)
          (let* ((org-agenda-skip-function 'my/agenda-custom-skip)
                 (source1 (cfw:org-create-source))
                 (curr-keymap (if cfw:org-overwrite-default-keybinding cfw:org-custom-map cfw:org-schedule-map))
                 (cp (cfw:create-calendar-component-buffer
                      :view 'two-weeks
                      :contents-sources (list source1)
                      :custom-map curr-keymap
                      :sorter 'cfw:org-schedule-sorter)))
            (switch-to-buffer (cfw:cp-get-buffer cp))
            (set (make-variable-buffer-local 'org-agenda-skip-function)
                 'my/agenda-custom-skip)
            (when (not org-todo-keywords-for-agenda)
              (message "Warn : open org-agenda buffer first.")))
          ))))

Stuff   FIX

    (setq org-agenda-tags-todo-honor-ignore-options t)

    (defun bh/org-auto-exclude-function (tag)
      "Automatic task exclusion in the agenda with / RET"
      (when (string= tag "online")
        (concat "-" tag)))

    (org-defkey org-agenda-mode-map
                "A"
                'org-agenda)

    (setq org-agenda-auto-exclude-function 'bh/org-auto-exclude-function)
    (setq org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled)
    (setq org-agenda-skip-scheduled-if-deadline-is-shown nil)
    (setq org-agenda-log-mode-items '(clock closed))

    (defun org-agenda-add-separater-between-project ()
      (setq buffer-read-only nil)
      (save-excursion
        (goto-char (point-min))
        (let ((start-pos (point))
              (previous t))
          (re-search-forward " +agenda: +[^\\. ]" nil t)
          (while (re-search-forward " +agenda: +[^\\. ]" nil t)
            (beginning-of-line)
            (insert "=============================================\n")
            (forward-line)))))

    ;; I don't think this code is necessary
    ;; (add-to-list 'org-agenda-entry-types :deadlines*)

    (setq org-agenda-hide-tags-regexp "NOT_TASKS\\|PROJECT")

    (use-package htmlize)
    (org-super-agenda-mode)
    (setq org-super-agenda-header-separator "")

memoization attempt

  ;; (defmacro measure-time (&rest body)
  ;;   "Measure the time it takes to evaluate BODY."
  ;;   `(let ((time (current-time)))
  ;;      ,@body
  ;;      (message "%.06f" (float-time (time-since time)))))

  ;; (require 'memoize)
  ;; (defun reset-memo-for-projects ()
  ;;   (interactive)
  ;;   (ignore-errors
  ;;     (memoize-restore 'my/get-project-type))
  ;;   (memoize 'my/get-project-type))
  ;; (add-hook 'org-agenda-finalize-hook
  ;;           #'reset-memo-for-projects)

  ;; (defvar my/stuck-projects-flag nil)

  ;; (defvar my/stuck-projects-file nil)

  ;; (defun my/show-stuck-projects ()
  ;;   "Only show subtrees that are stuck projects"
  ;;   (setq stuck-here t)
  ;;   (save-restriction
  ;;     (widen)
  ;;     (let ((subtree-end (save-excursion (org-end-of-subtree t))))
  ;;       (if (and my/stuck-projects-flag
  ;;                (string= my/stuck-projects-file
  ;;                         (buffer-file-name))
  ;;                (< (point) my/stuck-projects-flag))
  ;;           (if (or (my/is-next-task)
  ;;                   (my/is-unactionable-task)
  ;;                   (and (not (my/is-a-task))
  ;;                        (not (eq (my/get-project-type buffer-file-name (point) t)
  ;;                            'stuck))))
  ;;               subtree-end
  ;;             nil)
  ;;         (setq my/stuck-projects-flag nil
  ;;               my/stuck-projects-file nil)
  ;;         (cond ((and (my/is-a-task)
  ;;                     (my/is-standalone-task)
  ;;                     (not (org-get-scheduled-time (point)))
  ;;                     (not (org-get-deadline-time (point))))
  ;;                nil)
  ;;               ((eq (my/get-project-type buffer-file-name
  ;;                                         (point) t)
  ;;                    'stuck)
  ;;                (setq my/stuck-projects-flag subtree-end)
  ;;                (setq my/stuck-projects-file (buffer-file-name))
  ;;                nil)
  ;;               (t subtree-end))))))

  ;; (defvar my/done-projects-flag nil)
  ;; (defvar my/next-task-flag nil)

  ;; (defun my/org-agenda-reset-vars ()
  ;;   (interactive)
  ;;   (setq my/stuck-projects-flag nil
  ;;         my/done-projects-flag nil
  ;;         my/next-task-flag nil))

  ;; (add-to-list 'org-agenda-finalize-hook
  ;;              #'my/org-agenda-reset-vars)

Agenda custom commands

  (add-to-list 'load-path 
               "~/.emacs.d/custom/org-ql")
  (require 'org-ql)
  (require 'org-ql-search)
  (require 'org-ql-custom-stuck-projects)

  (defvar org-ql-indent-levels nil)

  (defun org-agenda-add-separater-between-project ()
    (setq buffer-read-only nil)
    (save-excursion
      (goto-char (point-min))
      (let ((start-pos (point))
            (previous t))
        (re-search-forward " +agenda: +[^\\. ]" nil t)
        (while (re-search-forward " +agenda: +[^\\. ]" nil t)
          (beginning-of-line)
          (insert "=============================================\n")
          (forward-line)))))

  (defun production-agenda (tag)
    `((tags-todo ,(concat tag "/STUFF")
                 ((org-agenda-overriding-header "Refile tasks")))
      (tags-todo ,(concat tag "/" (mapconcat #'identity my/active-projects-and-tasks "|"))
                 ((org-agenda-overriding-header "Stuck Projects")
                  (org-agenda-skip-function 'my/show-stuck-projects)
                  (org-tags-match-list-sublevels 'indented)))
      (tags-todo ,(concat tag "/WAIT")
                 ((org-agenda-overriding-header "Tasks in other courts")))
      (tags-todo ,(concat tag "/NEXT")
                 ((org-agenda-overriding-header "Things to do")))
      (agenda ""
              ((org-agenda-skip-function 'my/agenda-custom-skip)
               (org-agenda-span 'day)
               (org-agenda-tag-filter-preset (quote (,tag)))
               (org-agenda-skip-deadline-if-done t)
               (org-agenda-skip-scheduled-if-done t)
               (org-super-agenda-groups '((:name "Dev things" :file-path "dev.org")
                                          (:name "Overdue" :and (:deadline past :log nil))
                                          (:name "Upcoming" :deadline future)
                                          (:name "Should do" :and (:scheduled past :log nil))
                                          (:name "Today" :time-grid t
                                                 :and (:not (:and (:not (:scheduled today)
                                                                        :not (:deadline today)))))))))))

  (defconst my/non-agenda-files
    `(,(my/org-file "entries/reviews.gpg") 
      ,(my/agenda-file "datetree.org") 
      ,(my/agenda-file "reference.org") 
      ,(my/org-file "entries/journal.gpg")))

  (defconst my/all-agenda-files
    (cons (my/agenda-file "eternal.org")
          org-agenda-files))

  (defun my/valid-todo ()
    (let (seen-non-todo)
      (save-excursion 
        (not
         (catch 'break
           (while (org-up-heading-safe)
             (if (null (org-get-todo-state))
                 (setf seen-non-todo t)
               (when seen-non-todo
                 (throw 'break t)))))))))

  (defun my/ambiguous-todo ()
    (and (opr/type-of-project)
         (opr/type-of-task))))

  (let* ((prod-tag "+time")
         (dev-tag "+dev")
         (sandbox-tag "+sandbox"))
    (setq org-agenda-custom-commands
          `(("d" "Dev"
             ((org-ql-block '(and (tags "dev")
                                  (tags "refile"))
                            ((org-ql-block-header "Refile tasks")))
              (my/org-ql-stuck-projects nil
                                        ((org-ql-block-header "Stuck Projects")
                                         (org-ql-indent-levels t)))
              (my/org-ql-active-projects nil
                                         ((org-ql-block-header "Active Projects")
                                          (org-ql-indent-levels t)))
              (org-ql-block '(and (tags "dev")
                                  (todo "WAIT"))
                            ((org-ql-block-header "Waiting tasks")))
              (org-ql-block '(and (tags "dev")
                                  (todo "NEXT"))
                            ((org-ql-block-header "Things to do")))
              (agenda ""
                      ((org-agenda-span 'day)
                       (org-agenda-tag-filter-preset (quote (,dev-tag)))
                       (org-agenda-skip-deadline-if-done t)
                       (org-agenda-skip-scheduled-if-done t)
                       (org-super-agenda-groups '((:name "The Plan" :tag "PLAN")
                                                  (:name "Overdue" :and (:deadline past :log nil))
                                                  (:name "Upcoming" :deadline future)
                                                  (:name "Should do" :and (:scheduled past :log nil))
                                                  (:name "Today" :time-grid t
                                                         :and (:not (:and (:not (:scheduled today)
                                                                                :not (:deadline today)))))))))))
            ("h" "Dev Hold and Delay"
             ((org-ql-block '(and (tags "dev")
                                  (todo "TODO" "ONE" "META" "META1" "EMPTY" "SEQ")
                                  (property "DELAYED")
                                  (org-time> (org-entry-get (point) "DELAYED")
                                             (org-matcher-time "<now>")))
                            ((org-ql-block-header "Delayed projects")))
              (tags-todo "dev/!HOLD"
                         ((org-agenda-overriding-header "Hold projects")))))
            ("n" "Next Tasks List" tags-todo "-REFILE-HOLD-WAIT"
             ((org-agenda-skip-function 'my/show-next-tasks-and-standalone-tasks)
              (org-agenda-overriding-header "Next Tasks list")
              (org-tags-match-list-sublevels t)
              (org-agenda-sorting-strategy '(deadline-up))))
            ("L" "Leaf Task List" tags-todo "-REFILE-HOLD-WAIT"
             ((org-agenda-skip-function 'my/show-leaf-tasks)
              (org-tags-match-list-sublevels 'indented)
              (org-agenda-overriding-header "Next Tasks list")
              (org-agenda-finalize-hook '(org-agenda-add-separater-between-project))))
            ("a" . "Agendas")
            ("aa" "Regular Agenda" agenda "")
            ("ad" "Agenda 1 day" agenda ""
             ((org-agenda-span 'day)))
            ("aw" "Weekly view" agenda ""
             ((org-agenda-overriding-arguments (list nil (my/this-or-last-saturday) 
                                                     9))
              (org-agenda-tag-filter-preset (quote (,dev-tag)))
              (org-agenda-skip-scheduled-if-done t)
              (org-agenda-skip-deadline-if-done t)))
            ("al" "Last week" agenda ""
             ((org-agenda-overriding-arguments (list nil (my/this-or-last-saturday) 
                                                     9))
              (org-agenda-tag-filter-preset (quote (,dev-tag)))))
            ("ad" "Dev agenda" agenda ""
             ((org-agenda-skip-function 'my/agenda-custom-skip)
              (org-agenda-span 'day)
              (org-agenda-tag-filter-preset (quote (,dev-tag)))
              (org-agenda-skip-deadline-if-done t)
              (org-agenda-skip-scheduled-if-done t)
              (org-super-agenda-groups '((:name "The Plan" :tag "PLAN")
                                         (:name "Overdue" :and (:deadline past :log nil))
                                         (:name "Upcoming" :deadline future)
                                         (:name "Should do" :and (:scheduled past :log nil))
                                         (:name "Today" :time-grid t
                                                :and (:not (:and (:not (:scheduled today)
                                                                       :not (:deadline today)))))))))
            ("p" . "Prod")
            ("pa" "All" ,(production-agenda prod-tag))
            ("pw" "work" ,(production-agenda "+work"))
            ("ps" "school" ,(production-agenda "+school"))
            ("g" "General View"
             ((tags-todo "+sandbox+refile"
                         ((org-agenda-overriding-header "Refile tasks")))
              (tags-todo "+sandbox"
                         ((org-agenda-overriding-header "Stuck Projects")
                          (org-tags-match-list-sublevels 'indented)
                          (org-agenda-skip-function 'my/show-stuck-projects)
                          (org-agenda-sorting-strategy
                           '(category-keep))))
              (tags-todo "-REFILE-HOLD+TODO+sandbox/WAIT"
                         (;(org-agenda-skip-function 'my/only-next-projects-and-tasks)
                          (org-agenda-overriding-header "Tasks in other courts")
                          (org-tags-match-list-sublevels t)))
              ;;(org-ql-agenda-function "")
              (agenda ""
                      ((org-agenda-skip-function 'my/agenda-custom-skip)
                       (org-agenda-span 'day)
                       (org-agenda-tag-filter-preset (quote ("+sandbox")))
                       (org-agenda-skip-deadline-if-done t)
                       (org-agenda-skip-scheduled-if-done t)
                       (org-super-agenda-groups '((:name "Overdue" :and (:deadline past :log nil ))
                                                  (:name "Upcoming" :deadline future)
                                                  (:name "Should do" :and (:scheduled past :log nil ))
                                                  (:name "Today" :time-grid t
                                                         :and (:not (:and (:not (:scheduled today)
                                                                                :not (:deadline today)))))))))))
            ("m" . "Maintainence")
            ("md" "Done Tasks"
             ((org-ql-block '(and (not (tags "ARCHIVE"))
                                  (todo "DONE" "ABANDON")
                                  (or (not (my/top-level))
                                      (not (tags "dev"))))
                            ((org-ql-block-header "Done tasks")
                             (org-agenda-files ',(remove-if (lambda (x) 
                                                              (member (expand-file-name x) my/non-agenda-files)) 
                                                            my/all-agenda-files))))))
            ("ma" "Archive trees"
             ((org-ql-block '(and (tags "ARCHIVE")
                                  (my/top-level)
                                  (let ((size (- (save-excursion (org-end-of-subtree t t)) (point))))
                                    (>= size 50000)))
                            ((org-ql-block-header "Big archive trees")))
              (org-ql-block '(and (tags "ARCHIVE")
                                  (my/top-level)
                                  (let ((size (- (save-excursion (org-end-of-subtree t t)) (point))))
                                    (< size 50000)))
                            ((org-ql-block-header "Small archive trees"))))
              ((my/delete-blocks nil)
               (org-use-tag-inheritance nil)))
            ("mr" "Recategorize dev to sandbox" todo (mapconcat #'identity org-done-keywords-for-agenda "|")
             ((org-agenda-skip-function 'my/show-top-level)
              (org-agenda-files '(,(my/agenda-file "dev.org")))))
            ("mv" "Invalid todos"
             ((org-ql-block '(and (tags "prod")
                                  (todo "TODO" "META" "META1" "EMPTY" "ONE")
                                  (not (my/valid-todo)))
                            ((org-ql-block-header "Production")))
              (org-ql-block '(and (tags "dev")
                                  (todo "TODO" "META" "META1" "EMPTY" "ONE")
                                  (not (my/valid-todo)))
                            ((org-ql-block-header "dev")))
              (org-ql-block '(and (tags "sandbox")
                                  (todo "TODO" "META" "META1" "EMPTY" "ONE")
                                  (not (my/valid-todo)))
                            ((org-ql-block-header "sandbox")))))
            ("mA" "Ambiguous todos"
             ((org-ql-block '(and (todo)
                                  (my/ambiguous-todo))
                            ((org-ql-block-header "sandbox")))))
            ("f" . "Flip through")
            ("fc" "Comms" tags-todo "datetime"
             ((org-agenda-overriding-header "Comms")))
            ("fC" "Look at clocking" agenda ""
             ((org-agenda-span 'day)
              (org-agenda-start-with-log-mode '(closed clock))
              (org-agenda-clockreport-mode t)))
            ("fj" "Reviews and Journals" tags "LEVEL=3&ITEM={Review for}|LEVEL=3&journal"
             ((org-agenda-files '(,(my/org-file "entries/reviews.gpg") 
                                  ,(my/org-file "entries/journal.gpg")))
              (org-agenda-sorting-strategy '(tsia-down))))
            ("fr" "Reviews" tags "LEVEL=3&ITEM={Review for}"
             ((org-agenda-files '(,(my/org-file "entries/reviews.gpg") 
                                  ,(my/org-file "entries/journal.gpg")))
              (org-agenda-sorting-strategy '(tsia-down))))
            ("o" "Offline" tags-todo "offline"
             ((org-tags-match-list-sublevels nil)))
            ("b" "Bored" tags-todo "+short-grow"
             ((org-tags-match-list-sublevels nil))))))


  (defun my/this-or-last-saturday ()
    (org-read-date nil nil
                   (if (string= "6" (format-time-string "%u"))
                       "."
                     "-sat")))

  ;; (pop org-agenda-custom-commands)

Checkbox hack

  (defun my/org-checkbox-todo ()
    "Switch header TODO state to DONE when all checkboxes are ticked, to TODO otherwise"
    (let ((todo-state (org-get-todo-state)) beg end)
      (unless (not todo-state)
        (save-excursion
          (org-back-to-heading t)
          (setq beg (point))
          (end-of-line)
          (setq end (point))
          (goto-char beg)
          (if (re-search-forward "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                                 end t)
              (if (match-end 1)
                  (if (equal (match-string 1) "100%")
                      (unless (string-equal todo-state "DONE")
                        (org-todo 'done))
                    (unless (string-equal todo-state "TODO")
                      (org-todo 'todo)))
                (if (and (> (match-end 2) (match-beginning 2))
                         (equal (match-string 2) (match-string 3)))
                    (unless (string-equal todo-state "DONE")
                      (org-todo 'done))
                  (unless (string-equal todo-state "TODO")
                    (org-todo 'todo)))))))))

  (add-hook 'org-checkbox-statistics-hook 'my/org-checkbox-todo)

View org files

  (defun make-org-file (filename)
    "Make an org buffer in folder for all new incoming org files"
    (interactive "MName: ")
    (switch-to-buffer (find-file-noselect (concat "~/MEGA/org/random/" filename ".org"))))

  (defun make-encrypted-org-file (filename) 
    (interactive "MName: ")
    (switch-to-buffer (find-file-noselect (concat "~/MEGA/org/random/" filename ".gpg")))
    (insert "# -*- mode:org; epa-file-encrypt-to: (\"bensonchu457@gmail.com\") -*-\n\n")
    (org-mode))


  (defun view-org-files ()
    "Convenient way for openning up org folder in dired"
    (interactive)
    (dired "~/MEGA/org/"))

Capture templates

  (setq org-capture-templates
        `(("t" "Todo" entry (file ,(my/agenda-file "refile.org"))
           "* STUFF %?\n:PROPERTIES:\n:CREATED: %U\n:VIEWING: %a\n:END:")
          ("r" "Reviews")
          ("ra" "Automatic Review" entry (file+function ,(my/org-file "entries/reviews.gpg") setup-automatic-review)
           (file ,(my/org-file "templates/weekly-review.org")))
          ("rm" "Manual Review" entry (file+function ,(my/org-file "entries/reviews.gpg") setup-manual-review)
           (file ,(my/org-file "templates/weekly-review.org")))
          ("ro" "Reorient" entry (file ,(my/org-file "entries/reviews.gpg"))
           (file ,(my/org-file "templates/reorient.org")))
          ;; ("rt" "Review Task" entry (file+headline ,(my/org-file "entries/reviews.gpg") "Tasks")
          ;;  "* TODO %?")
          ("d" "Dream" entry (file+olp+datetree ,(my/org-file "entries/dream.org"))
           "* %?")
          ("D" "Distracted" entry (file ,(my/agenda-file "dev.org"))
           "* TODO %?" :clock-in t :clock-resume t)
          ("T" "New Task" entry (file ,(my/agenda-file "dev.org"))
           "* TODO %?" :clock-in t :clock-keep t)
          ("m" "Money")
          ("mc" "Credit Card" plain (file ,(my/org-file "entries/finances/ledger.ledger"))
           (file ,(my/org-file "templates/credit.ledger")) :unnarrowed t :empty-lines 1)
          ("mg" "General" plain (file ,(my/org-file "entries/finances/ledger.ledger"))
           (file ,(my/org-file "templates/basic.ledger")) :unnarrowed t :empty-lines 1)
          ("c" "Record Comms Message" entry (file+olp+datetree ,(my/agenda-file "datetree.org"))
           "* TODO %?")
          ("e" "Emacs config snippet" entry (file+headline "~/.emacs.d/config.org" "New")
           "* %^{Title}\n#+begin_src emacs-lisp\n %?\n#+end_src")
          ("j" "Journal")
          ("jd" "Decision template" entry (file+olp+datetree ,(my/org-file "entries/journal.gpg"))
           (file ,(my/org-file "templates/decide.org")))
          ("je" "Journal Entry" entry (file+olp+datetree ,(my/org-file "entries/journal.gpg"))
           "* %<%R> %?")
          ;; ("jp" "Plan your day" entry (file+olp+datetree ,(my/org-file "entries/journal.gpg"))
          ;;  (file ,(my/org-file "templates/daily-plan.org")))
          ("jp" "Programming Interview Prep Journal" entry (file+olp+datetree ,(my/org-file "entries/journal.gpg"))
           "* ")
          ("C" "Create checklist")
          ("Cc" "Conference Via Bus" entry (file ,(my/agenda-file "dev.org"))
           (file ,(my/org-file "checklists/conference.org"))
           :conference/airplane nil)
          ("Cm" "Morning routine" entry (file ,(my/org-file "entries/routines.org"))
           (file ,(my/org-file "checklists/mornings.org")))
          ("Cn" "Nightly routine" entry (file ,(my/org-file "entries/routines.org"))
           (file ,(my/org-file "checklists/nights.org")))
          ;; ("y" "Elfeed YouTube" entry (file+olp ,(my/agenda-file "dev.org") "rewards" "Videos")
          ;;  "* TODO %(identity elfeed-link-org-capture)")
          ("p" "Protocol" entry (file ,(my/agenda-file "refile.org"))
           "* STUFF %^{Title}\n:PROPERTIES:\n:CREATED: %U\n:URL: %:link\n:END:\n#+begin_example\n%i\n#+end_example\n%?")
          ("L" "Protocol Link" entry (file ,(my/agenda-file "refile.org"))
           "* STUFF %? [[%:link][%:description]]\n:PROPERTIES:\n:CREATED: %U\n:URL: %:link\n:END:")
          ("l" "Add to lists conveniently")
          ("lc" "Cringe" entry (file ,(my/org-file "entries/cringe.gpg")) "* %?")
          ("lm" "Mental Model" entry (file ,(my/org-file "entries/mental_models.gpg")) "* %?")
          ("li" "Important Information" entry (file ,(my/org-file "entries/important.gpg")) "* %?")))

Weekly Reviews Implementation

Attempt 3

  (defun completed-tags-search (start-date end-date)
    (let ((org-agenda-overriding-header "* Log")
          (tag-search (concat (format "TODO=\"DONE\"&CLOSED>=\"<%s>\"&CLOSED<=\"<%s>\""
                                      start-date
                                      end-date))))
      (org-tags-view nil tag-search)))

  (defun get-tasks-from (start-date end-date)
    (let (string)
      (save-window-excursion
        (completed-tags-search start-date end-date)
        (setq string (mapconcat 'identity
                                (mapcar (lambda (a)
                                          (concat "***" a))
                                        (butlast (cdr (split-string (buffer-string) "\n")) 1)) 
                                "\n"))
        (kill-buffer))
      string))

  (defun weekly-review-file ()
    (set-buffer
     (org-capture-target-buffer (format "~/MEGA/org/entries/review/%s/Year of %s, Week %s.org"
                                        (format-time-string "%Y")
                                        yearly-theme
                                        (format-time-string "%V")))))

  (defun make-up-review-file ()
    (let* ((date (org-read-date))
           (week (number-to-string
                  (org-days-to-iso-week
                   (org-time-string-to-absolute date)))))
      (org-capture-put :start-date date)
      (org-capture-put :start-week week)
      (set-buffer 
       (org-capture-target-buffer
        (format "~/MEGA/org/entries/review/%s/Year of %s, Week %s-%s.org"
                (format-time-string "%Y")
                yearly-theme
                week
                (format-time-string "%V"))))))

  (defun setup-make-up-review ()
    (let* ((date (org-read-date))
           (week (number-to-string
                  (org-days-to-iso-week
                   (org-time-string-to-absolute date)))))
      (org-capture-put :start-date date)
      (org-capture-put :start-week week)))

  (defvar my/review-visibility-level nil)

  (defun my/review-set-visibility ()
    (when my/review-visibility-level
      (outline-hide-sublevels my/review-visibility-level)
      (org-show-entry)
      (setq my/review-visibility-level nil)))

  (add-hook 'org-capture-mode-hook
            'my/review-set-visibility)

Attempt 4

  (defvar yearly-theme "Thought")

  ;; Functions required by template
  (defun get-journal-entries-from (start-date end-date)
    (let ((string "")
          match)
      (save-window-excursion
        (switch-to-buffer (find-file "~/MEGA/org/entries/journal.gpg"))
        (goto-char (point-min))
        (while (setq match 
                     (re-search-forward
                      "^\\*\\*\\* \\(2[0-9]\\{3\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\) \\w+$" nil t))
          (let ((date (match-string 1)))
            (when (and (org-time< start-date date)
                       (or (not end-date) (org-time< date end-date)))
              (org-narrow-to-subtree)
              (setq string (concat string "\n" (buffer-string)))
              (widen))))
        (not-modified)
        (kill-buffer))
      string))

  ;; Setup stuff, called by capture template
  (defun get-last-review-date ()
    (save-window-excursion
      (set-buffer (find-file "~/.emacs.d/last-review.el"))
      (let ((res (buffer-string)))
        (kill-buffer)
        res)))

  (defun output-incomplete-date ()
    (save-window-excursion
      (switch-to-buffer (find-file "~/.emacs.d/review-incomplete.el"))
      (erase-buffer)
      (insert (org-read-date nil nil ""))
      (save-buffer)
      (kill-buffer)))

  (defvar my/review-date-old nil)
  (defun setup-automatic-review ()
    ;; Check for older review
    (when (and (file-exists-p "~/.emacs.d/review-incomplete.el")
               (y-or-n-p "Woah, we found an incomplete review. Would you like to use that date as the start date? "))
      (shell-command "mv ~/.emacs.d/review-incomplete.el ~/.emacs.d/last-review.el"))
    ;; Setup current review
    (let* ((date (org-read-date nil nil (get-last-review-date)))
           (week (format "%02d" 
                         (org-days-to-iso-week
                          (org-time-string-to-absolute date)))))
      (output-incomplete-date)
      (setq my/review-date-old date)
      (setq my/review-visibility-level 6)
      (org-capture-put :start-date date)
      (org-capture-put :start-week week)
      (goto-char (point-min))
      (re-search-forward "Reviews")))


  (defun setup-manual-review ()
    ;; Read the date manually, and setup review accordingly
    (let* ((org-read-date-prefer-future nil)
           (date (org-read-date))
           (week (format "%02d" 
                         (org-days-to-iso-week
                          (org-time-string-to-absolute date)))))
      (output-incomplete-date)
      (setq my/review-date-old date)
      (setq my/review-visibility-level 6)
      (org-capture-put :start-date date)
      (org-capture-put :start-week week)
      (goto-char (point-min))
      (re-search-forward "Reviews")))

  ;; Teardown stuff, called through hooks
  (defun finalize-review ()
    "Save a copy of the weekly agenda, and write the current date
  as the most current weekly review."
    (let ((desc (plist-get org-capture-current-plist :description)))
      (when (and (string= desc "Automatic Review")
                 my/review-date-old)
        (my/save-agenda-week my/review-date-old)
        (shell-command "rm ~/.emacs.d/review-incomplete.el")
        (save-window-excursion
          (switch-to-buffer (find-file "~/.emacs.d/last-review.el"))
          (erase-buffer)
          (insert (org-read-date nil nil ""))
          (save-buffer)
          (kill-buffer)
          "")
        (setq my/review-date-old nil))))
  (add-hook 'org-capture-before-finalize-hook 'finalize-review)

  (defun clear-out-review-files ()
    (when (file-exists-p "~/.emacs.d/review-incomplete.el")
      (shell-command "rm ~/.emacs.d/review-incomplete.el")))
  (add-hook 'org-capture-after-finalize-hook #'clear-out-review-files)

Make agenda from dates with archive

  (defconst my/org-agenda-snapshot-pdf-filename "~/MEGA/org/entries/review/%Y_%m_%d.pdf")
  (defconst my/org-agenda-snapshot-html-filename "~/MEGA/org/entries/review/%Y_%m_%d.html")

  (defun my/agenda-dates (start &optional end)
    (interactive (list (let ((org-read-date-prefer-future nil))
                         (org-read-date))))
    (when-let (buf (get-buffer "*Org Agenda(a)*"))
      (kill-buffer buf))
    (or end (setq end (org-read-date nil nil ".")))
    (let* ((span (- (org-time-string-to-absolute end)
                    (org-time-string-to-absolute start)))
           (org-agenda-archives-mode t)
           (org-agenda-start-with-log-mode '(closed clock))
           (org-agenda-start-on-weekday nil)
           (org-agenda-start-day start)
           (org-agenda-span span))
      (org-agenda-list nil)
      (put 'org-agenda-redo-command 'org-lprops
           `((org-agenda-archives-mode t)
             (org-agenda-start-with-log-mode '(closed clock))
             (org-agenda-start-on-weekday nil)
             (org-agenda-start-day ,start)
             (org-agenda-span ,span)))))

  ;; (my/agenda-dates "2019-07-14")

  (defun my/save-agenda-week (start &optional end)
    (interactive (list (let ((org-read-date-prefer-future nil))
                         (org-read-date))))
    (let ((end (or end (org-read-date nil nil "."))))
      (save-window-excursion
        (my/agenda-dates start end)
        (org-agenda-write (format-time-string my/org-agenda-snapshot-pdf-filename (org-time-string-to-time end)))
        (org-agenda-write (format-time-string my/org-agenda-snapshot-html-filename (org-time-string-to-time end))))))

  ;; (my/save-agenda-week "2019-06-03" "2019-08-18")

  ;; (my/save-agenda-week "2019-07-14")

prompt for automatic org-board

  (defun my/org-add-tag (tag)
    (org-set-tags (cons tag (org-get-tags nil t))))

  (defun org-board-add-offline-tag (&rest args)
    (my/org-add-tag "offline"))

  (advice-add #'org-board-archive :after
              #'org-board-add-offline-tag)

  (defun my/org-board-prompt ()
    (let ((desc (plist-get org-capture-current-plist :description)))
      (when (and (not org-note-abort)
                 (string= desc "Protocol Link")
                 (y-or-n-p "Do you want to archive the page? "))
        (call-interactively #'org-board-archive))))

  (add-hook 'org-capture-before-finalize-hook 'my/org-board-prompt)

Parallel org-tags-views

  ;; TODO

empty lines

  (setq org-cycle-separator-lines 0)

invisibel

  (setq org-catch-invisible-edits 'show-and-error)

link abbreviation

  (setq org-link-abbrev-alist 
        '(("youtube" . "https://youtube.com/watch?v=")))

refile to datetree

  (defun my/org-read-datetree-date (d)
    "Parse a time string D and return a date to pass to the datetree functions."
    (let ((dtmp (nthcdr 3 (parse-time-string d))))
      (list (cadr dtmp) (car dtmp) (caddr dtmp))))

  (defun my/org-refile-to-archive-datetree (&optional bfn)
    "Refile an entry to a datetree under an archive."
    (interactive)
    (require 'org-datetree)
    (let* ((org-read-date-prefer-future nil)
           (bfn (or bfn (find-file-noselect (expand-file-name (my/agenda-file "datetree.org")))))
           (datetree-date (my/org-read-datetree-date (org-read-date t nil))))
      (org-refile nil nil (list nil (buffer-file-name bfn) nil
                                (with-current-buffer bfn
                                  (save-excursion
                                    (org-datetree-find-date-create datetree-date)
                                    (point))))))
    (setq this-command 'my/org-refile-to-journal))

org-link use qutebrowser

  (defun my/browse-url-qutebrowser (url &optional new-window)
    (interactive)
    (start-process (concat "qutebrowser " url)
                   nil
                   "qutebrowser"
                   url))

  ;;(setq browse-url-browser-function #'my/browse-url-qutebrowser)
  (setq browse-url-browser-function #'browse-url-firefox)

convert orgzly scheduled timestamps to created

  (defun my/scheduled-to-created ()
    (when-let (time (org-get-scheduled-time (point)))
      (let ((ts (format-time-string "[%Y-%m-%d %a]" time)))
        (org-schedule '(4))
        (org-set-property "CREATED" ts))))


  (defun my/convert-orgzly-scheduled-to-created ()
    (interactive)
    (while (progn
             (my/scheduled-to-created)
             (outline-next-heading))))

new stuff

org-mru-clock

  (use-package org-mru-clock)

org-clock-convenience

  (defun my/org-clock-move-to-other ()
    (interactive)
    (forward-char 6)
    (while (condition-case nil
               (progn 
                 (previous-line)
                 (org-clock-convenience-goto-ts)
                 nil)
             (error t))))

  (defun my/org-clock-move-up ()
    (interactive)
    (org-clock-convenience-timestamp-up)
    (my/org-clock-move-to-other)
    (org-clock-convenience-timestamp-up))

  (use-package org-clock-convenience
    :ensure t
    :bind (:map org-agenda-mode-map
                ("<S-up>" . org-clock-convenience-timestamp-up)
                ("<S-down>" . org-clock-convenience-timestamp-down)
                ("<S-M-up>" . org-clock-convenience-timestamp-up)
                ("<S-M-down>" . org-clock-convenience-timestamp-down)
                ("ö" . org-clock-convenience-fill-gap)
                ("é" . org-clock-convenience-fill-gap-both)))

org-clock-consisitency

  (setq org-agenda-clock-consistency-checks
        '(:max-duration "10:00"
                        :min-duration 0
                        :max-gap 0
                        :gap-ok-around ("4:00")
                        ;; :default-face ((:background "DarkRed")
                        ;;                (:foreground "white"))
                        ;; :overlap-face nil
                        ;; :gap-face ((:background "DarkRed")
                        ;;            (:foreground "white"))
                        ;; :no-end-time-face nil
                        ;; :long-face nil
                        ;; :short-face nil
                        ))

org-clock stuff

  (org-clock-persistence-insinuate)
  (setq org-clock-in-resume t)
  (setq org-clock-mode-line-total 'today)
  (setq org-clock-persist t)
  (org-clock-persistence-insinuate)
  (setq org-clock-continuously t)

org-edna

  (use-package org-edna)
  (org-edna-load)

org agenda goto headline AND narrow

  (defun my/org-agenda-narrow ()
    (interactive)
    (org-agenda-switch-to)
    (org-narrow-to-subtree)
    (outline-show-branches))
  (define-key org-agenda-mode-map (kbd "S-<return>") 'my/org-agenda-narrow)

org-brain

  (use-package org-brain :ensure t
    :init
    (global-set-key (kbd "M-'") 'org-brain-visualize)
    (setq org-brain-path "~/MEGA/org/brain/")
    ;; For Evil users
    (with-eval-after-load 'evil
      (evil-set-initial-state 'org-brain-visualize-mode 'emacs))
    :config
    (setq org-id-track-globally t)
    (setq org-id-locations-file "~/.emacs.d/.org-id-locations")
    (push '("b" "Brain" plain (function org-brain-goto-end)
            "* %i%?" :empty-lines 1)
          org-capture-templates)
    (setq org-brain-visualize-default-choices 'all)
    (setq org-brain-title-max-length 0)
    (define-key org-brain-visualize-mode-map (kbd "^") 'org-brain-visualize-back))

Open links with firefox

  (setq browse-url-browser-function 'browse-url-firefox)

org-export

  (require 'ox-latex)
  (require 'ox-beamer)

org-jira

  (use-package org-jira)
  (setq jiralib-url "https://wenningbai.atlassian.net/")

org-board

  (use-package org-board)
  (add-to-list 'org-board-agent-header-alist
               '("Linux" . "--user-agent=\"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4\""))
  (setq org-board-wget-show-buffer nil)

org-now

  (add-to-list 'load-path "~/.emacs.d/custom/org-now")
  (require 'org-now)
  (setq org-now-location
        nil)

org-use-speed-commands

  (setq org-use-speed-commands t)

new headline set property

  (defun my/org-set-created-property (&rest args)
    (when-let (f (buffer-file-name))
      (let ((fname (expand-file-name f)))
        (when (remove-if-not (lambda (x) (string= fname (expand-file-name x))) org-agenda-files)
          (let ((ts (format-time-string "[%Y-%m-%d %a %H:%M]")))
            (org-set-property "CREATED" ts))))))

  (advice-add #'org-insert-heading
              :after
              #'my/org-set-created-property)

Code for deleting empty blocks

  (defvar my/delete-blocks t)

  (defun org-agenda-delete-empty-compact-blocks ()
    "Function removes empty compact blocks. 
   If two lines next to each other have the 
   org-agenda-structure face, then delete the 
   previous block."
    (unless org-agenda-compact-blocks
      (user-error "Compact blocks must be on"))
    (when my/delete-blocks
      (setq buffer-read-only nil)
      (save-excursion
        (goto-char (point-min))
        (let ((start-pos (point))
              (previous nil))
          (while (not (eobp))
            (cond
             ((let ((face (get-char-property (point) 'face)))
                (or (eq face 'org-agenda-structure)
                    (eq face 'org-agenda-date-today)))
              (if previous
                  (delete-region start-pos
                                 (point))
                (setq start-pos (point)))
              (unless (org-agenda-check-type nil 'agenda)
                (setq previous t)))
             (t (setq previous nil)))
            (forward-line))))))

  (add-hook 'org-agenda-finalize-hook #'org-agenda-delete-empty-compact-blocks)

org-mode faces

  (set-face-attribute 'org-agenda-date-today t :inherit 'org-agenda-date :foreground "cyan" :slant 'italic :weight 'bold :height 1.1)
  (set-face-attribute 'org-agenda-structure  t :foreground "LightSkyBlue" :box '(:line-width 1 :color "grey75" :style 'released-button))
  (set-face-attribute 'org-ellipsis          t :foreground "turquoise" :underline nil)

org-notmuch

  (require 'ol-notmuch)

remove inherited tags

  (defun my/org-remove-inherited-tag-strings ()
    "Removes inherited tags from the headline-at-point's tag string.
  Note this does not change the inherited tags for a headline,
  just the tag string."
    (interactive)
    (org-set-tags (seq-remove (lambda (tag)
                                (get-text-property 0 'inherited tag))
                              (org-get-tags))))

  (defun my/org-clean-tags ()
    "Visit last refiled headline and remove inherited tags from tag string."
    (save-window-excursion
      (org-refile-goto-last-stored)
      (my/org-remove-inherited-tag-strings)))

  (defun my/org-refile-preserve-tags (orig &rest args)
    (let ((tags (org-get-tags)))
      (apply orig args)))

  (add-hook 'org-after-refile-insert-hook 'my/org-clean-tags)

archive sibling remove sub archive sibling

  (defun my/org-un-project ()
    (interactive)
    (let ((level (org-current-level)))
      (org-map-entries 'org-do-promote (format "LEVEL>%d" level) 'tree)
      (org-cycle t)))

  (defun my/org-delete-promote ()
    (interactive)
    (my/org-un-project)
    (org-cut-subtree))

  (defun my/is-archive-tree ()
    (and (string= "Archive"
                  (org-get-heading t t t t))
         (member "ARCHIVE" (org-get-tags))))

  (defun my/archive-remove-all-sibling (&rest args)
    (save-excursion
      (let (points)
        (ol/descendants
          (when (my/is-archive-tree)
            (push (point) points)))
        (mapcar (lambda (p)
                  (goto-char p)
                  (my/org-delete-promote))
                points))))

  (advice-add #'org-archive-to-archive-sibling
              :before
              #'my/archive-remove-all-sibling)

org agenda start on saturday

  (setq org-agenda-start-on-weekday 6)

org mode startup

  (with-eval-after-load 'org
    (setq org-startup-indented t) ; Enable `org-indent-mode' by default
    (add-hook 'org-mode-hook #'visual-line-mode)
    (add-hook 'org-mode-hook #'auto-fill-mode))

Learning chinese, setup org-drill

  (use-package org-drill)

  (defun org-drill-present-one-side-always (session)
    (org-drill-with-hidden-comments
     (org-drill-with-hidden-cloze-hints
      (org-drill-with-hidden-cloze-text
       (let ((drill-sections (org-drill-hide-all-subheadings-except nil)))
         (when drill-sections
           (save-excursion
             (goto-char (nth 0 drill-sections))
             (org-show-subtree)))
         (org-drill--show-latex-fragments)
         (ignore-errors
           (org-display-inline-images t))
         (org-cycle-hide-drawers 'all)
         (prog1 (org-drill-presentation-prompt session)
           (org-drill-hide-subheadings-if 'org-drill-entry-p)))))))

  (add-to-list 'org-drill-card-type-alist
               '("oneside" org-drill-present-one-side-always nil t))

  ;; (pop org-drill-card-type-alist)

Plan module

  (add-to-list 'org-capture-templates
               `("P" "The Plan" entry (file+headline ,(my/agenda-file "dev.org") "The plan")
                 (file ,(my/org-file "templates/daily-plan.org"))))

My org-indent look

  (defun my/org-indent-prefixes ()
    "Compute prefix strings for regular text and headlines."
    (setq org-indent--heading-line-prefixes
          (make-vector org-indent--deepest-level nil))
    (setq org-indent--inlinetask-line-prefixes
          (make-vector org-indent--deepest-level nil))
    (setq org-indent--text-line-prefixes
          (make-vector org-indent--deepest-level nil))
    (dotimes (n org-indent--deepest-level)
      (let ((indentation (if (<= n 1) 0
                           (* (1- org-indent-indentation-per-level)
                              (1- n)))))
        ;; Headlines line prefixes.
        (let ((heading-prefix ""))
          (aset org-indent--heading-line-prefixes
                n
                (org-add-props heading-prefix nil 'face 'org-indent))
          ;; Inline tasks line prefixes
          (aset org-indent--inlinetask-line-prefixes
                n
                (cond ((<= n 1) "")
                      ((bound-and-true-p org-inlinetask-show-first-star)
                       (concat org-indent-inlinetask-first-star
                               (substring heading-prefix 1)))
                      (t (org-add-props heading-prefix nil 'face 'org-indent)))))
        ;; Text line prefixes.
        (aset org-indent--text-line-prefixes
              n
              (org-add-props
                  (concat (make-string (if (< n 2) n
                                         (1+ indentation)) ?\s)
                          (and (> n 0)
                               (char-to-string org-indent-boundary-char)))
                  nil 'face 'org-indent)))))


  (advice-add #'org-indent--compute-prefixes
              :override
              #'my/org-indent-prefixes)

Insert inactive timestamp after last org-datetreefind-create

  (defun org-datetree--find-create-add-timestamp (regex-template year &optional month day insert)
    (save-excursion
      (when day
        (let ((lnum (line-number-at-pos)))
          (next-line)
          (when (= lnum (line-number-at-pos))
            (end-of-line)
            (insert "\n")))
        (unless (looking-at-p (rx "[" (repeat 4 digit) "-" (repeat 2 digit) "-"
                                  (repeat 2 digit) " " (repeat 3 alpha) "]"))
          (insert (format-time-string "[%Y-%m-%d %a]"))))))

  (advice-add #'org-datetree--find-create
              :after
              #'org-datetree--find-create-add-timestamp)

repeat to previous state

  (setq org-todo-repeat-to-state t)