;;; ycp-org.el -- My config for org -*- lexical-binding: t -*- ;; Copyright (C) 2023 Free Software Foundation. ;; Author: Yuchen Pei ;; Package-Requires: ((emacs "28.2")) ;; This file is part of dotted. ;; dotted is free software: you can redistribute it and/or modify it under ;; the terms of the GNU Affero General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; dotted is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General ;; Public License for more details. ;; You should have received a copy of the GNU Affero General Public ;; License along with dotted. If not, see . ;;; Commentary: ;; My config for org. ;;; Code: ;;; the glorious org mode (my-package org (my-keybind global-map "M-u" #'org-store-link "C-c a" #'org-agenda "C-c c" #'org-capture ) (setq org-startup-folded 'overview) (my-override org-next-link) (my-override org-previous-link) (my-override org--mouse-open-at-point) (my-keybind org-mode-map "C-a" #'my-org-beginning-of-line-or-indent "C-k" #'my-org-kill-line "M-k" #'my-org-kill-line-backwards "M-l" #'org-insert-last-stored-link "M-n" #'org-next-link "M-p" #'org-previous-link "C-c C-l" #'org-insert-link ) (if (string< (org-version) "9.6") (my-keybind org-mode-map "C-j" #'org-return-and-maybe-indent) (my-keybind org-mode-map "C-j" #'default-indent-new-line)) (my-keybind minibuffer-mode-map "M-l" #'org-insert-last-stored-link) (my-setq-from-local my-org-common-properties org-directory my-org-doc-dir) ;; disable auto-indent on RET (add-hook 'org-mode-hook (lambda () (electric-indent-local-mode -1))) ;; tab-width 8 is needed for newer versions of org-mode, which I am ;; not using due to performance issues (add-hook 'org-mode-hook (lambda () (setq-local tab-width 2))) ;; The world does not end by 2038 (hopefully) (setq org-read-date-force-compatible-dates nil) (setq org-adapt-indentation 'headline-data) (setq org-special-ctrl-a/e t) (setq org-special-ctrl-k t) (setq org-M-RET-may-split-line '((default . t))) (setq org-catch-invisible-edits 'error) (setq org-modules '(ol-bbdb ol-gnus ol-info)) (setq org-use-sub-superscripts '{}) (setq org-todo-keywords '((sequence "TODO(t)" "DOIN(i)" "WAIT(w)" "|" "DONE(d)" "OBSO(o)" "DUPL(u)"))) (setq org-closed-keep-when-no-todo t) (setq org-enforce-todo-dependencies t org-enforce-todo-checkbox-dependencies nil) (setq org-use-fast-todo-selection 'expert) (setq org-fontify-quote-and-verse-blocks t) (setq org-highlight-latex-and-related nil) ; other options affect elisp regexp ; in src blocks (setq org-log-done 'time) (setq org-archive-location "%s_archive::") (setq org-file-apps '((auto-mode . emacs) (directory . emacs) ("\\.mm\\'" . default) ("\\.x?html?\\'" . emacs) ("\\.pdf\\'" . emacs) ("\\.mp4\\'" . "xdg-open %s"))) (setq org-structure-template-alist '(("a" . "export ascii") ("c" . "center") ("C" . "comment") ("e" . "example") ("E" . "export") ("h" . "export html") ("l" . "export latex") ("m" . "src emacs-lisp") ("q" . "quote") ("s" . "src") ("v" . "verse"))) (setq org-use-tag-inheritance nil) (my-setq-from-local org-default-notes-file) (setq org-export-backends '(ascii beamer html latex md odt org)) (setq org-export-with-sub-superscripts '{}) (setq org-image-actual-width '(400)) (setq org-log-into-drawer t) (plist-put org-format-latex-options :scale 1.5) (setq org-reverse-note-order t) (add-hook 'before-save-hook #'my-org-update-updated) ;; Add org mode line string, including `org-clock-get-clock-string' (setq frame-title-format '(multiple-frames "%b" ("" "%b - GNU Emacs at " system-name " " org-mode-line-string))) ) (my-package org-duration (my-setq-from-local org-duration-units)) (my-package org-goto (setq org-goto-interface 'outline-path-completion) ) (my-package org-element ;; org-persist is buggy with encoding etc. let's disable it (setq org-element-cache-persistent nil) ) ;;; ox - org export (my-package ox (:delay 60) (setq org-export-headline-levels 8) (require 'ox-html) (setq org-html-prefer-user-labels t) (setq org-html-self-link-headlines t) (require 'ox-icalendar) (setq org-icalendar-include-bbdb-anniversaries t) (setq org-icalendar-include-todo t) (setq org-icalendar-use-scheduled '(event-if-todo todo-start)) ) (my-package org-id (setq org-id-link-to-org-use-id t) ) ;;; cite (my-package oc (:delay 60) (my-setq-from-local org-cite-global-bibliography) ) (my-package org-src (:delay 10) (setq org-edit-src-persistent-message nil) (my-keybind org-src-mode-map "C-c C-c" #'org-edit-src-exit) (setq org-src-window-setup 'current-window) (setq org-src-preserve-indentation t) ;; useful for yaml and python ) (my-package org-agenda (:delay 10) ;; We want to prevent switching not-done to done for items with ;; not-done children or checkboxes (see ;; `org-enforce-todo-dependencies' and ;; `org-enforce-todo-checkbox-dependencies' but we don't want them ;; marked as blocked, because blocked should be marked explicitly ;; and dimmed when they are truly blocked by a task somewhere else. (my-override org-entry-blocked-p) (my-keybind global-map "C-c g" 'my-org-store-agenda-view-A) (setq org-agenda-confirm-kill t) (setq org-agenda-follow-indirect t) (setq org-agenda-time-leading-zero t) (setq org-agenda-todo-ignore-time-comparison-use-seconds t) (setq org-agenda-todo-ignore-deadlines 'all) (setq org-agenda-todo-ignore-scheduled 'all) (setq org-agenda-todo-ignore-with-date 'all) (setq org-agenda-todo-ignore-timestamp 'all) (setq org-agenda-tags-todo-honor-ignore-options t) (setq org-agenda-dim-blocked-tasks t) (setq org-agenda-sticky t) (setq org-agenda-inhibit-startup t) (my-setq-from-local org-agenda-files) (setq org-agenda-skip-deadline-if-done nil) (setq org-agenda-skip-scheduled-if-done nil) (setq org-agenda-skip-timestamp-if-done t) (setq org-agenda-start-on-weekday nil) (setq org-agenda-custom-commands `(("A" "Agenda and next" ((agenda "" ((org-agenda-span 32) ;; only works when `org-agenda-start-on-weekday' ;; is nil (org-agenda-start-day "-2d"))) (tags-todo "PRIORITY=\"A\"" nil)) nil ,(my-get-from-local my-org-agenda-and-next-export-files)) ("B" "Agenda and context" ((agenda "" ((org-agenda-span 'week))) (tags-todo "{^@.*}")) nil) ("@" "context todos" ((tags-todo "{^@.*}")) nil))) (setq org-agenda-prefix-format '((agenda . "%?-12t% s") (todo . "") (tags . "") (search . ""))) (setq org-agenda-use-tag-inheritance nil) (add-hook 'org-agenda-mode-hook #'hl-line-mode) (add-hook 'org-agenda-after-show-hook 'my-org-agenda-after-show) (org-defkey org-agenda-mode-map "d" #'org-agenda-deadline) (org-defkey org-agenda-mode-map "s" #'org-agenda-schedule) ;; For whatever reason, `org-agenda-quit' deletes window instead of ;; burying the buffer when `org-agenda-window-setup' is not ;; 'current-window and `(one-window-p)' returns nil (org-defkey org-agenda-mode-map "q" #'bury-buffer) (setq org-agenda-window-setup 'other-window) ) (my-package ob-core (setq org-babel-load-languages '((emacs-lisp . t) (shell . t))) (setq org-confirm-babel-evaluate nil) ) (my-package org-capture (my-override org-capture-set-plist) (setq org-capture-templates `(("w" "Today's work" checkitem (file+headline org-default-notes-file "Today's work") ;; the :priority link prop requires overloading ;; `org-id-store-link' below to work "- [ ] [#%:priority] %a%?" :prepend t) ("j" "Journal" entry (file+olp+datetree ,(my-get-from-local my-org-journal-file)) "* %? :PROPERTIES: :CREATED: %U :END: ") ("t" "Todo" entry (file+headline org-default-notes-file "Inbox") "* TODO %? :PROPERTIES: :CREATED: %U :Referral: %a :END: %(unless (string-empty-p \"%i\") (format \"#+begin_example %s #+end_example\" (org-escape-code-in-string \"%i\"))) " :prepend t) ("ya" "Blank audio" entry (file+headline org-default-notes-file "Audios") nil :prepend t) ("book" "Blank books and papers" entry (file+headline org-default-notes-file "Books and papers") nil :prepend t) ("video" "Blank videos" entry (file+headline org-default-notes-file "Videos") nil :prepend t) ("entity" "Blank entities" entry (file+headline org-default-notes-file "Entities") nil :prepend t) ("videogame" "Blank video games" entry (file+headline org-default-notes-file "Video games") nil :prepend t) ("software" "Blank software" entry (file+headline org-default-notes-file "Software") nil :prepend t) ("organisation" "Blank organisation" entry (file+headline org-default-notes-file "Organisations") nil :prepend t) ("people" "Blank people" entry (file+headline org-default-notes-file "People") nil :prepend t) ("game" "Blank games" entry (file+headline org-default-notes-file "Games") nil :prepend t) ("location" "Blank location" entry (file+headline org-default-notes-file "Locations") nil :prepend t)))) (my-package org-clock (setq org-clock-history-length 100) (setq org-clock-in-switch-to-state "DOIN") (setq org-clock-idle-time 15) (setq org-clock-mode-line-total 'auto) (setq org-clock-persist 'history) (org-clock-persistence-insinuate)) (my-package org-refile (setq org-outline-path-complete-in-steps nil) (setq org-refile-allow-creating-parent-nodes 'confirm) (setq org-refile-targets '((org-agenda-files :maxlevel . 5))) (setq org-refile-use-cache t) (setq org-refile-use-outline-path t) ) ;;; todo: some of these commands will take a while to be ready (my-package org-keys (setq org-return-follows-link t) (setq org-use-speed-commands t) (setq org-speed-commands '(("User commands") ("." . my-org-task-add-id) ("'" . my-org-task-associate) ("!" . my-org-task-remove-id) ("\"" . my-org-task-dissociate) ("T" . my-org-swap-referral-with-headline) ("D" . my-org-clean-up-entry) ("g" . org-delete-property) ("W" . my-org-refile-logbook) ("+" . my-org-vote-up) ("-" . my-org-vote-down) ("m" . my-magit-clone-org-source) ("c" . my-org-copy-property-value) ("x" . my-org-osm-goto) ("X" . my-osm-org-add-properties) ("Y" . my-org-logbook-yank) ("y" . my-grok-update-properties) ("z" . my-org-orgzly-merge-link) ("A" . org-attach) ("P" . my-org-set-common-property) ("N" . my-org-jump-to-last-visible-child) ("d" . org-deadline) ("s" . org-schedule) ("S" . org-toggle-narrow-to-subtree) (";" . org-timer-set-timer) ("," . org-timer-pause-or-continue) ("h" . my-org-entry-toggle-drawer-visibility) ("Outline Navigation") ("n" org-speed-move-safe 'org-next-visible-heading) ("p" org-speed-move-safe 'org-previous-visible-heading) ("f" org-speed-move-safe 'org-forward-heading-same-level) ("b" org-speed-move-safe 'org-backward-heading-same-level) ("F" . org-next-block) ("B" . org-previous-block) ("u" org-speed-move-safe 'outline-up-heading) ("j" . org-goto) ("g" org-refile '(4)) ("Outline Visibility") ("C" . org-shifttab) (" " . org-display-outline-path) ("s" . org-toggle-narrow-to-subtree) ("k" . org-cut-subtree) ("=" . org-columns) ("Outline Structure Editing") ("U" . org-metaup) ("D" . org-metadown) ("r" . org-metaright) ("l" . org-metaleft) ("R" . org-shiftmetaright) ("L" . org-shiftmetaleft) ("i" . my-org-append-subheading) ("^" . org-sort) ("w" . org-refile) ("a" . org-archive-subtree-default-with-confirmation) ("@" . org-mark-subtree) ("#" . org-toggle-comment) ("Clock Commands") ("I" . org-clock-in) ("O" . org-clock-out) ("Meta Data Editing") ("t" . org-todo) ("," org-priority) ("0" org-priority 32) ("1" org-priority 65) ("2" org-priority 66) ("3" org-priority 67) (":" . org-set-tags-command) ("e" . org-set-effort) ("E" . org-inc-effort) ("W" lambda (m) (interactive "sMinutes before warning: ") (org-entry-put (point) "APPT_WARNTIME" m)) ("Agenda Views etc") ("v" . org-agenda) ("/" . org-sparse-tree) ("Misc") ("o" . org-open-at-point) ("?" . org-speed-command-help) ("<" org-agenda-set-restriction-lock 'subtree) (">" org-agenda-remove-restriction-lock))) ) ;;;; ;; org attach ;;;; (my-package org-attach (:delay 15) (setq org-attach-store-link-p 'attached) (setq org-attach-sync-delete-empty-dir t) (require 'my-org) (my-setq-from-local my-org-attach-copy-attached-targets) (add-to-list 'org-attach-commands '((?k) my-org-attach-copy-attached-docs "Copy attached docs.")) (require 'my-scihub) (add-to-list 'org-attach-commands '((?p) my-org-attach-scihub "Download document from scihub.")) (require 'my-calibre) (add-to-list 'org-attach-commands '((?C) org-attach-calibre-book "Attach from local calibre libray.")) (add-to-list 'org-attach-commands '((?V) my-org-attach-all-url-plaintext "Fetch all urls to plaintext file")) (my-override org-attach-url) (add-to-list 'org-attach-commands '((?U) my-org-attach-url-plaintext "Fetch url to plaintext file")) (add-to-list 'org-attach-commands '((?A) my-org-attach-url-plaintext-all-media "Fetch url to plaintext file, and all media files therein.")) ) ;; org-protocol (my-package org-protocol (:delay 30) (require 'my-org) (add-to-list 'org-protocol-protocol-alist '("grok" :protocol "grok" :function my-org-protocol-grok))) ;; org man links (my-package ol-man (:delay 30) (setq org-man-command 'woman)) (my-package ol (:delay 10) (require 'my-buffer) (advice-add 'org-gnus-no-new-news :before 'my-org-gnus-other-window-advice) (add-to-list 'org-link-frame-setup (cons 'file 'my-find-file-maybe-other-window)) ) (my-package my-org (:delay 10) (my-keybind global-map "" #'my-org-open-or-cycle-notes) (my-keybind org-mode-map "C-c 1" #'my-org-insert-date-range "C-c ns" #'my-org-substitute-gnus-link-after-archiving "C-x w" #'my-org-copy-link-at-point "C-'" #'my-org-store-link-and-return "C-c M-w" #'my-org-copy-dwim "C-c " #'my-org-open-shell-at-attach-dir "C-M-n" #'my-org-next-block-or-results "C-M-p" #'my-org-previous-block-or-results) (add-hook 'org-follow-link-hook 'my-org-follow-link-after) ;; When in prog-mode, use line number as search item. (add-to-list 'org-create-file-search-functions 'my-link-to-line-number-in-prog-mode) (my-override org-insert-all-links) (my-override org-open-at-point-global) (my-override org-refile-get-targets) (my-override org-insert-last-stored-link) (my-override org-id-store-link) (org-link-set-parameters "info" :follow #'my-org-info-open-new-window) (org-link-set-parameters "rt" :follow #'my-org-rt-open-new-window) (my-override org-src--make-source-overlay) (my-server-timer my-org-clock-save-timer nil 600 'my-org-clock-maybe-save) (my-server-idle-timer my-org-refile-rebuild-cache-timer 600 t 'my-org-refile-cache-rebuild) (my-server-idle-timer my-org-agenda-redo-all-timer 1200 t 'my-org-agenda-redo-all) (org-defkey org-agenda-mode-map "0" #'my-org-agenda-priority-0) (org-defkey org-agenda-mode-map "1" #'my-org-agenda-priority-A) (org-defkey org-agenda-mode-map "2" #'my-org-agenda-priority-B) (org-defkey org-agenda-mode-map "3" #'my-org-agenda-priority-C) (with-eval-after-load "org-capture" (advice-add 'org-capture-place-template :around 'my-org-capture-place-template-dont-delete-windows)) (advice-add 'org-insert-structure-template :after 'my-org-edit-special) (advice-add 'org-edit-src-exit :before 'my-org-edit-src-before-exit) (advice-add 'org-edit-src-exit :after 'my-org-edit-src-after-exit) (my-setq-from-local my-org-task-categories)) (my-package my-org (:delay 30) (require 'my-web) (org-link-set-parameters "http" :follow (lambda (url arg) (my-browse-url (concat "http:" url) arg))) (org-link-set-parameters "https" :follow (lambda (url arg) (my-browse-url (concat "https:" url) arg))) (require 'eww) (define-key eww-mode-map (kbd "C-'") 'my-eww-org-protocol-grok) ) (my-package ox-jira (:delay 60) (require 'my-ox-jira)) (provide 'ycp-org) ;;; ycp-org.el ends here