Skip to content

Latest commit

 

History

History
923 lines (847 loc) · 33.5 KB

config-org.org

File metadata and controls

923 lines (847 loc) · 33.5 KB

The all-mighty org configuration

(require 'my-org)
(require 'my-org-agenda-files)

Plugins

fstree

(add-to-list 'load-path
             (ef "submodule/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 (ef "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 "[email protected]"
;;       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
             (ef "submodule/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-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)
   (emacs-lisp . t)
   (shell . t)
   (dot . 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")

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-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-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 (ef ".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

(when (not my-ec/is-wsl)
  (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-now

(add-to-list 'load-path (ef "submodule/org-now"))
(require 'org-now)
(setq org-now-location
      nil)

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

(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 "")

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 "TASK")
                    (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 "TASK")
                  (org-todo "TASK")))))))))

(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: (\"[email protected]\") -*-\n\n")
  (org-mode))


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

Parallel org-tags-views

;; TODO

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)

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))))
    (setq buffer-read-only t)))

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

Highlight top priority projects

(defvar my/highlight-top-priority t)

(defun org-agenda-highlight-top-priority ()
  (when my/highlight-top-priority
    (setq buffer-read-only nil)
    (save-excursion
      (goto-char (point-min))
      (let ((start-pos (point))
            (previous nil))
        (while (re-search-forward "\\[#A\\]" nil t)
          (add-face-text-property (point-at-bol) (point-at-eol) '(:background "color-19")))))
    (setq buffer-read-only t)))

(add-hook 'org-agenda-finalize-hook #'org-agenda-highlight-top-priority)

org-notmuch

(use-package notmuch
  :config
  (use-package 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/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)

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)

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)

I’m bored

(defun im-bored ()
  (interactive)
  (org-ql-search (append org-agenda-files
                         (list (my/agenda-file "when_im_bored.org")
                               (my/agenda-file "eternal.org")))
    '(and (tags-local "bored"))))

org-noter

(use-package org-noter
  :config
  ;; (unless (eq 'hash-table (type-of face-new-frame-defaults))
  ;;   (require 'face-copier)
  ;;   (def-face-copier x-show-tip-faces (sym)
  ;;     nil
  ;;     tooltip)

  ;;   (defun dont-copy-faces-for-x-show-tip (orig &rest args)
  ;;     (override1-face x-show-tip-faces
  ;;       (apply orig args)))

  ;;   (advice-add #'x-show-tip
  ;;               :around
  ;;               #'dont-copy-faces-for-x-show-tip))
  )

(use-exwm
  :config
  (setq org-noter-always-create-frame nil))

turn into tickle

(defun my/tickle-todo ()
  (interactive)
  (org-agenda-todo "TICKLER")
  (org-agenda-schedule))

(define-key org-agenda-mode-map (kbd "T") #'my/tickle-todo)

org-wiki

(require 'org-wiki)
(setq org-wiki-location-list
      '("~/MEGA/org/wiki"))

(setq org-wiki-template
      "#+TITLE: %n\n#+DESCRIPTION:\n#+KEYWORDS:\n#+STARTUP:  content\n\n\n- Related: \n\n* Backlinks\n#+STARTUP: folded\n\n* %n\n")

(defun org-wiki-insert-backlink (back-from back-to)
  (let ((wiki-link (format "[[wiki:%s][%s]]"
                           back-to back-to))
        (file (save-window-excursion (org-wiki--open-page back-from)
                                     (current-buffer))))
    (with-current-buffer file
      (beginning-of-buffer)
      (when (not (save-excursion
                   (search-forward wiki-link nil t)))
        (search-forward "* Backlinks")
        (forward-line 2)
        (beginning-of-line)
        (insert "- " wiki-link "\n")
        (save-buffer)))))


(defun my/org-wiki-insert-new ()
  (interactive)
  (let ((page-name (read-string  "Page: ")))
    (save-excursion (insert (org-make-link-string (concat "wiki:" page-name)
                                                  page-name
                                                  )))
    (org-wiki-insert-backlink
     page-name
     (org-wiki--current-page))))

(advice-add #'org-wiki-insert-new
            :override
            #'my/org-wiki-insert-new)

(defun my/org-wiki-insert-link ()
  "Insert a Wiki link at point for a existing page."
  (interactive)
  (org-wiki--helm-selection
   (lambda (page)
     (insert (org-wiki--make-link page))
     (org-wiki-insert-backlink
      page
      (org-wiki--current-page)))))

(advice-add #'org-wiki-insert-link
            :override
            #'my/org-wiki-insert-link)

org-roam

(require 'org-ql)
;; (defvar bootstrap-version)
;; (let ((bootstrap-file
;;        (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
;;       (bootstrap-version 5))
;;   (unless (file-exists-p bootstrap-file)
;;     (with-current-buffer
;;         (url-retrieve-synchronously
;;          "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
;;          'silent 'inhibit-cookies)
;;       (goto-char (point-max))
;;       (eval-print-last-sexp)))
;;   (load bootstrap-file nil 'nomessage))

;; (setq straight-vc-git-default-protocol 'ssh)

(define-prefix-command '*org-roam-map*)

(define-key pestctrl-minor-mode-map
            (kbd "C-c n")
            '*org-roam-map*)

(use-package org-roam
  :after org
  :custom
  (org-roam-directory (my/org-file "org-roam"))
  (org-roam-use-completion-everywhere t)
  :bind (:map *org-roam-map*
              ("h" . org-roam-buffer-toggle)
              ("f" . my/org-roam-find-file)
              ("F" . my/org-roam-find-daily)
              ("p" . my/org-roam-find-project)
              ("T" . org-roam-dailies-goto-today)
              ("t" . org-roam-dailies-capture-today)
              ("i" . org-roam-node-insert)
              ("w" . org-roam-refile)
              ("j" . my/org-roam-logger-capture-current)
              :map org-mode-map
              ("C-M-i" . completion-at-point))
  :init
  (setq org-roam-v2-ack t)
  :config
  (org-roam-setup)
  (setq org-roam-dailies-directory "daily/")
  (setq org-roam-dailies-capture-templates
        '(("d" "Journal" entry "* %<%H:%M> %?"
           :unnarrowed t
           :target (file+head+olp "%<%Y-%m-%d>.org"
                                  "#+title: %<%Y-%m-%d>\n#+filetags: %<:%Y:%B:dailies>\n"
                                  ("Journal")))
          ;; ("m" "Most Important Thing" entry "* TODO %? :mit:"
          ;;  :target (file+head+olp "%<%Y-%m-%d>.org"
          ;;                         "#+title: %<%Y-%m-%d>\n#+filetags: %<:%Y:%B:>\n"
          ;;                         ("Most Important Thing(s)")))
          ))

  (require 'my-org-roam-logger)
  (setq org-roam-capture-templates
        '(("d" "default" plain "%?" :target
           (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
           :unnarrowed t)
          ("t" "tech tips" plain "%?" :target
           (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+filetags: techtips\n")
           :unnarrowed t)))

  (require 'org-roam-util)

  (defun my/org-roam-find-file ()
    (interactive)
    ;; Select a project file to open, creating it if necessary
    (org-roam-node-find
     nil nil
     (lambda (node)
       (let ((tags (org-roam-node-tags node)))
         (not (member "project" tags))))))


  (defun my/org-roam-find-project ()
    (interactive)
    ;; Select a project file to open, creating it if necessary
    (org-roam-node-find
     nil nil
     (lambda (node)
       (let ((tags (org-roam-node-tags node)))
         (and (eq (org-roam-node-level node) 0)
              (member "project" tags)
              (not (member "done" tags)))))
     nil
     :templates
     '(("p" "project" plain ""
        :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}: %^{Description}\n#+category: ${title}\n#+filetags: project")
        :unnarrowed t))))

  (use-package consult-org-roam
    :demand t
    :commands (my/org-roam-find-daily)
    :config
    (require 'org-roam-util)

    (defun consult-org-roam-file-find (arg)
      "Find org-roam node with preview, if ARG open in other window."
      (interactive "P")
      (cl-letf (((symbol-function 'org-roam-node-read)
                 (symbol-function 'consult-org-roam-node-read)))
        (let ((other-window (if arg t nil)))
          (org-roam-node-find other-window nil #'consult-org-roam--node-file-p))))

    (defun my/org-roam-find-daily ()
      (interactive)
      (cl-letf (((symbol-function 'org-roam-node-read)
                 (symbol-function 'consult-org-roam-node-read)))
        (org-roam-node-find nil nil
                            (my/org-roam-filter-by-tag "dailies")
                            (lambda (x y)
                              (string-lessp (org-roam-node-file (cdr y))
                                            (org-roam-node-file (cdr x)))))))))

;; (require 'org-roam-protocol)

Variable pitch org-mode

;; (mapcar
;;  (lambda (face)
;;    (set-face-attribute face nil :inherit 'fixed-pitch))
;;  '(org-block org-block-begin-line org-block-end-line org-code
;;              org-document-info-keyword org-done org-formula org-indent
;;              org-meta-line org-special-keyword org-table org-todo
;;              org-verbatim org-date org-drawer))

Restriction from org-agenda

(define-key org-agenda-mode-map (kbd "N") #'(lambda ()
                                              (interactive)
                                              (org-agenda-set-restriction-lock-from-agenda nil)
                                              (org-agenda-redo)))
(define-key org-agenda-mode-map (kbd "U") #'org-agenda-remove-restriction-lock)

Org mode magit update commands

(when (executable-find "~/bin/gitwatch")
  (defun start-gitwatch ()
    (interactive)
    (if (and gitwatch-process
             (process-live-p gitwatch-process))
        (message "gitwatch already exists")
      (setq gitwatch-process
            (start-process-shell-command "gitwatch"
                                         nil
                                         "~/bin/gitwatch -r origin -b laptop -m 'Gitwatch commit: %d' ~/MEGA/org/agenda"))))
  (defun kill-gitwatch ()
    (interactive)
    (when (and gitwatch-process
               (process-live-p gitwatch-process))
      (kill-process gitwatch-process)))

  (defvar gitwatch-process nil)

  (add-to-list 'emacs-startup-hook
               #'start-gitwatch))

(defvar magit-sentinel-after-function nil)

(defun magit-sentinel-after (&rest args)
  (while
      (when-let (fun (pop magit-sentinel-after-function))
        (funcall fun)
        t)))

(advice-add #'magit-process-sentinel
            :after
            #'magit-sentinel-after)

(defun org-update-main ()
  (interactive)
  (let ((default-directory "~/MEGA/org/agenda"))
    (kill-gitwatch)
    ;; Make sure local changes are committed
    (when (magit-changed-files "HEAD")
      (magit-stage-modified t)
      (magit-commit-create `("-m" ,(format "Pre-merge commit: %s" (format-time-string "%D %T")))))
    ;; Update all submodules
    (shell-command "git submodule foreach git pull origin master")
    (when (magit-changed-files "HEAD")
      (magit-stage-modified t)
      (magit-commit-create `("-m" ,(format "Updated submodules: %s" (format-time-string "%D %T")))))
    ;; Do a fetch
    (push #'org-update-initiate-merge magit-sentinel-after-function)
    (magit-run-git-async '("fetch" "--all"))))

(defun org-update-initiate-merge ()
  ;; Check if mobile has updated
  (let ((base (vc-git-mergebase "laptop" "origin/mobile"))
        (laptop (vc-git--rev-parse "laptop"))
        (origin-mobile (vc-git--rev-parse "origin/mobile")))
    ;; If so, turn off gitwatch and initiate a merge.
    (when (and (not (string= base laptop))
               (not (string= base origin-mobile)))
      (add-hook 'git-commit-post-finish-hook ;;magit-post-commit-hook
                #'org-update-post-commit)
      (magit-merge-plain "origin/mobile"))))

(defun org-update-post-commit ()
  ;; After merge, do a push to both laptop and mobile
  ;; Also restart gitwatch
  (call-interactively #'magit-push-current-to-upstream)
  (magit-push-current "origin/mobile" nil)
  (start-gitwatch)
  (remove-hook 'git-commit-post-finish-hook
               #'org-update-post-commit))

(magit-run-git-async '("fetch" "--all"))

;; (setq debug-the-process (magit-run-git-async '("fetch" "--all")
;;                                              :sentinel '(lambda (process event) (message "Done"))))

elgantt

(add-to-list 'load-path (ef "submodule/elgantt"))
(require 'elgantt)

org-kanban

(use-package org-kanban)
(defun my/org-dblock-write:kanban (params)
  "Create the kanban dynamic block.
PARAMS may contain `:mirrored`, `:match`, `:scope`, `:layout`, `:range`, `:depth` and `:compressed`."
  (insert
   (let*
       (
        (mirrored (plist-get params :mirrored))
        (compressed (plist-get params :compressed))
        (match (plist-get params :match))
        (range (plist-get params :range))
        (depth (org-kanban--params-depth params))
        (layout (org-kanban//params-layout params))
        (files (org-kanban//params-files params))
        (scope (org-kanban//params-scope params files))
        (todo-keywords (split-string (plist-get params :todo) "|"))
        (sort-spec-string (plist-get params :sort))
        (sort-spec (org-kanban--prepare-comparator sort-spec-string todo-keywords))
        (todo-infos (org-map-entries 'org-kanban//todo-info-extract match scope))
        (sorted-todo-infos (if sort-spec (-sort sort-spec todo-infos) todo-infos))
        (filtered-todo-infos (-filter (lambda (todo-info)
                                        (org-kanban//range-fun
                                         (org-kanban--todo-info-get-keyword todo-info)
                                         (org-kanban//todo-info-get-keywords todo-info)
                                         (car range)
                                         (cdr range)))
                                      sorted-todo-infos))
        (filtered-todo-infos (-filter (lambda (todo-info)
                                        (if (eq scope 'tree)
                                            (let* (
                                                   (tree-info (nth 0 todo-infos))
                                                   (tree-level (org-kanban--todo-info-get-level tree-info)))
                                              (< (org-kanban--todo-info-get-level todo-info) (+ depth tree-level)))
                                          (<= (org-kanban--todo-info-get-level todo-info) depth))) filtered-todo-infos))
        (filtered-todo-infos (-filter (lambda (todo-info) (nth 4 (org-kanban//todo-info-get-heading todo-info))) filtered-todo-infos))
        (row-for (lambda (todo-info) (org-kanban//row-for todo-info todo-keywords layout)))
        (table-title (string-join todo-keywords "|"))
        (filtered (-filter (lambda (todo-info)
                             (-intersection
                              (list (org-kanban//heading-get-todo-keyword (org-kanban//todo-info-get-heading todo-info)))
                              (org-kanban//todo-info-get-keywords todo-info)))
                           filtered-todo-infos))
        (table (if compressed
                   (org-kanban//compressed-rows (-map row-for filtered))
                 (let* ((rows (-map row-for filtered)))
                   (if rows
                       (--reduce (format "%s\n%s" acc it) rows)
                     ""
                     )))))
     (format "|%s|\n|--|\n%s" table-title table)))
  (org-table-align))

(advice-add #'org-dblock-write:kanban
            :override
            #'my/org-dblock-write:kanban)

Modern views

(quelpa `(org-timeblock :repo "ichernyshovvv/org-timeblock" :fetcher github))
(use-package org-hyperscheduler)

Pretty symbols

;; (add-hook 'org-mode-hook (lambda ()
;;  "Beautify Org Checkbox Symbol"
;;  (push '("[ ]" .  "☐") prettify-symbols-alist)
;;  (push '("[X]" . "☑" ) prettify-symbols-alist)
;;  (push '("[-]" . "❍" ) prettify-symbols-alist)
;;  (prettify-symbols-mode)))