mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-02-16 16:24:18 +00:00
59 KiB
59 KiB
- Plugins
- org-agenda base folder
- Keybindings
- Different kinds of follow
- count archive tree characters
- My Template
- Face
- Variables
- Tag hierarchy
- More alternative views
- Stuff
- memoization attempt
- Agenda custom commands
- Checkbox hack
- View org files
- Capture templates
- Weekly Reviews Implementation
- prompt for automatic org-board
- Parallel org-tags-views
- empty lines
- invisibel
- link abbreviation
- refile to datetree
- org-link use qutebrowser
- convert orgzly scheduled timestamps to created
- new stuff
- org-use-speed-commands
- new headline set property
- Code for deleting empty blocks
- org-mode faces
- org-notmuch
- remove inherited tags
- archive sibling remove sub archive sibling
- org agenda start on saturday
- org mode startup
- Learning chinese, setup org-drill
- Plan module
- My org-indent look
- Insert inactive timestamp after last org-datetree–find-create
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)))))))))
(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" todo "DONE|CANCELLED|COMPLETE|ABANDON"
((org-agenda-overriding-header "Done Tasks")
(org-agenda-files ',(remove-if (lambda (x)
(member (expand-file-name x) my/non-agenda-files))
my/all-agenda-files))
(org-agenda-skip-function 'my/skip-if-top-level-dev)))
("ma" "Archive trees"
((tags "ARCHIVE"
((org-agenda-overriding-header "Big archive trees")
(org-tags-match-list-sublevels nil)
(org-agenda-skip-archived-trees nil)
(org-agenda-skip-function 'my/show-big-top-levels)))
(tags "ARCHIVE"
((org-agenda-overriding-header "Small archive trees")
(org-tags-match-list-sublevels nil)
(org-agenda-skip-archived-trees nil)
(org-agenda-skip-function 'my/show-small-top-levels))))
((my/delete-blocks 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")))))
("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-datetree–find-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)