#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t" :tangle-mode (identity #o644)
#+title: Org (and related) mode configuration

* General configuration
  #+begin_src emacs-lisp
    (use-package org
      :ensure t
      :custom ((org-export-backends '(ascii html latex texinfo)))
      :init
      (defalias 'jao-open-gnus-frame 'jao-afio--goto-mail)

      (setq org-adapt-indentation t
            org-catch-invisible-edits 'smart
            org-complete-tags-always-offer-all-agenda-tags t
            org-cycle-separator-lines 0 ;; no blank lines when all colapsed
            org-deadline-warning-days 14
            org-default-notes-file (expand-file-name "inbox.org" org-directory)
            org-directory jao-org-dir
            org-display-remote-inline-images 'download ;; 'skip 'cache
            org-ellipsis " .." ;; ↴
            org-email-link-description-format "Email %c: %s"
            org-enforce-todo-dependencies t
            org-fast-tag-selection-single-key 'expert
            ;; org-list-demote-modify-bullet '(("+" . "-") ("-" . "+") ("*" . "+"))
            org-link-frame-setup
            '((gnus . (lambda (&optional x) (jao-open-gnus-frame)))
              (file . find-file-other-window))
            org-log-done nil
            org-modules '(bibtex info eww eshell git-link)
            org-odd-levels-only t
            org-outline-path-complete-in-steps nil
            org-refile-allow-creating-parent-nodes 'confirm
            org-refile-targets '((nil :maxlevel . 5)
                                 (org-agenda-files :maxlevel . 5))
            org-refile-use-outline-path 'file
            org-return-follows-link t
            org-reverse-note-order t
            org-special-ctrl-a/e t
            org-src-fontify-natively t
            org-startup-folded t
            org-tag-alist nil
            org-tags-column -75
            org-todo-keywords
            '((sequence "TODO(t)" "STARTED(s!)" "|" "DONE(d!)")
              (sequence "REPLY(r)" "WAITING(w!)" "|" "DONE(d!)")
              (sequence "TOREAD(T)" "READING(R!)" "|" "READ(a!)")
              (sequence "|" "CANCELLED(x!)" "SOMEDAY(o!)" "DONE(d!)"))
            org-use-fast-todo-selection t
            org-use-speed-commands nil ;; t and then ? to see help
            org-gnus-prefer-web-links nil))
    (require 'org)
  #+end_src
* Agenda
  #+begin_src emacs-lisp
    (setq ;; org-agenda-custom-commands
          ;; '(("w" todo "WAITING" nil)
          ;;   ("W" agenda "" ((org-agenda-ndays 21))))
          org-agenda-files (mapcar (lambda (f)
                                     (expand-file-name f jao-org-dir))
                                  '("inbox.org" "bigml.org"))
          org-agenda-block-separator " "
          org-agenda-breadcrumbs-separator "•"
          org-agenda-current-time-string "•" ;; "*"
          org-agenda-time-grid
          '((daily today require-timed)
            (800 1000 1200 1400 1600 1800 2000) "" "·")
          org-agenda-include-diary t
          org-agenda-include-inactive-timestamps t
          org-agenda-inhibit-startup nil
          org-agenda-restore-windows-after-quit t
          org-agenda-show-all-dates t
          org-agenda-skip-deadline-if-done t
          org-agenda-skip-scheduled-if-done nil
          org-agenda-span 14
          org-agenda-start-on-weekday nil
          org-agenda-window-setup 'current-window)
  #+end_src
* Capture templates
  #+BEGIN_SRC emacs-lisp
    (setq  org-capture-templates
           '(("t" "TODO" entry
              (file+headline "inbox.org" "Todo")
              "* TODO %?\n  %i%a" :prepend t)
             ("r" "REPLY" entry
              (file+headline "inbox.org" "Todo")
              "* REPLY %:subject%?\n  %t\n %i%a" :prepend t)
             ("a" "Appointment" entry
              (file+olp "inbox.org" "Appointments")
              "* %^T %?\n  %a" :time-prompt t)
             ("i" "Inbox note" entry (file+headline "inbox.org" "Notes")
              "* %a\n  %i%?(added on: %u)" :prepend t)))
    ;; (org-capture-upgrade-templates org-capture-templates)
  #+END_SRC
* MIME and file apps
  #+BEGIN_SRC emacs-lisp
    (setq org-file-apps
          '((system . mailcap)
            (".*\\.djvu" . system)
            (t . emacs)))
  #+END_SRC
* Appearance
  #+begin_src emacs-lisp
    ;; Show hidden emphasis markers
    (use-package org-appear
      :ensure t
      :hook (org-mode . org-appear-mode))

    ;; #+caption: Image caption.
    ;;  #+attr_org: :width 100
    ;;  [[file:path/to/image.png]]

    (setq org-startup-indented nil
          org-pretty-entities nil
          org-hide-emphasis-markers t
          org-hide-leading-stars t
          org-startup-with-inline-images t
          org-image-actual-width '(300))

    (use-package org-modern
      :ensure t
      :init (setq org-modern-label-border 1))

    ;; (unless (display-graphic-p) (global-org-modern-mode 1))

  #+end_src
* LaTeX
  #+begin_src emacs-lisp
    (use-package org-fragtog
      :after org
      :ensure t
      :hook ((org-mode . org-fragtog-mode)))

    (require 'org-fragtog)

    (setq org-format-latex-options
          `(:foreground default
                        :background
                        ,(if (jao-colors-scheme-dark-p) "black" "white")
                        :scale 1.25
                        :html-foreground "black"
                        :html-background "Transparent"
                        :html-scale 1.0
                        :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))
          org-preview-latex-image-directory
          (expand-file-name "~/.emacs.d/cache/ltximg/")
          org-latex-hyperref-template nil
          org-highlight-latex-and-related '(latex script entities))

    (require 'ox-latex)
  #+end_src

* Export (minted)

  #+begin_src emacs-lisp
    (setq org-latex-listings 'minted
          org-latex-packages-alist '(("" "minted"))
          org-latex-pdf-process
          '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
            "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
  #+end_src

* Babel and literate programming
  - [[http://cachestocaches.com/2018/6/org-literate-programming][Literate Programming with Org-mode]]
  - [[http://howardism.org/Technical/Emacs/literate-devops.html][Literate DevOps]]

  #+begin_src emacs-lisp
    (setq org-src-window-setup 'other-window) ;; current-window
    (require 'org-tempo nil t) ;; <s TAB for 9.2 and later

    (use-package poly-org :ensure t)

    (use-package ob-prolog
      :ensure t
      :after org)

    (org-babel-do-load-languages
     'org-babel-load-languages
     '((calc . t)
       (clojure . t)
       ;; (elixir . t)
       (emacs-lisp .t)
       (gnuplot .t)
       (haskell . t)
       (makefile . t)
       (ocaml . t)
       (org . t)
       (python . t)
       (scheme .t)
       (shell . t)
       (prolog . t)))
  #+end_src

* Org cliplink (link from clipboard)
  [[https://github.com/rexim/org-cliplink][GitHub - rexim/org-cliplink: Insert org-mode links from clipboard]]

  #+BEGIN_SRC emacs-lisp
    (use-package org-cliplink
      :ensure t
      :bind (:map org-mode-map ("C-c C-f" . org-cliplink))
      :config
      (add-to-list 'org-capture-templates
                   '("k" "Cliplink capture task" entry
                     (file+headline "inbox.org" "Todo")
                     "* TODO %(org-cliplink-capture) %?" :prepend t)
                   t))
  #+END_SRC

* Notes
  #+begin_src emacs-lisp
    (use-package jao-org-notes
      :commands (jao-org-notes-setup)
      :config
      (defun jao-org-notes-note-p ()
        (string-prefix-p jao-org-notes-dir (buffer-file-name)))

      (defun jao-org-notes-recoll ()
        "Use consult-recoll to search notes."
        (interactive)
        (consult-recoll (format "dir:%s " jao-org-notes-dir)))

      (jao-transient-major-mode org
        ["Notes"
         ("o" "find and open note" jao-org-notes-open)
         ("c" "open or create note" jao-org-notes-open-or-create)
         ("\\" "grep notes" jao-org-notes-grep)
         ("r" "recoll notes" jao-org-notes-recoll)]
        ["Current note" :if jao-org-notes-note-p
         ("i" "insert link" jao-org-notes-insert-link)
         ("t" "insert tags" jao-org-notes-insert-tags)
         ("v" "show backlinks" jao-org-notes-backlinks)]))

    (jao-org-notes-setup "n")
  #+end_src
* Links
  #+begin_src emacs-lisp
    (require 'ol-eshell nil t)
    ;; (require 'ol-bbdb nil t)
    (require 'ol-info nil t)
    (setq org-link-abbrev-alist '(("jao.io" "https://jao.io/")))

    (defun jao-org-link-at-point (&optional copy)
      (when (thing-at-point-looking-at "\\[\\[\\([^]]+\\)\\]\\[[^]]+\\]\\]")
        (when copy (kill-ring-save (match-beginning 1) (match-end 1)))
        (match-string-no-properties 1)))

    (defun jao-org-copy-link-at-point ()
      (interactive)
      (message "%s" (or (jao-org-link-at-point t) "No link at point")))

    (defun jao-org-insert-link (url title)
      (insert (format "[[%s][%s]]" url title)))

    (defun jao-insert-eww-link ()
      "Look for last eww buffer and insert an org link to it."
      (interactive)
      (when-let (b (car (jao-eww-session--list-buffers)))
        (let ((lnk (with-current-buffer b
                     (format "[[%s][%s]]"
                             (eww-current-url)
                             (jao-eww-buffer-title)))))
          (insert lnk))))

    (use-package jao-org-links
      :commands jao-org-links-setup
      :bind (("C-c T" . jao-org-insert-doc)))

    (jao-org-links-setup jao-sink-dir)

    (with-eval-after-load "pdf-view"
      (define-key pdf-view-mode-map (kbd "C-c o") #'jao-org-pdf-goto-org)
      (define-key pdf-view-mode-map (kbd "C-c O") #'jao-org-pdf-goto-org*))

    (with-eval-after-load "doc-view"
      (define-key doc-view-mode-map (kbd "C-c o") #'jao-org-pdf-goto-org)
      (define-key doc-view-mode-map (kbd "C-c O") #'jao-org-pdf-goto-org*))

    #+end_src
* eldoc
  #+begin_src emacs-lisp
    (defun jao-org-eldoc--hook ()
      (set (make-local-variable 'eldoc-documentation-function)
           'jao-org-link-at-point)
      (eldoc-mode))
    (add-hook 'org-mode-hook 'jao-org-eldoc--hook)
  #+end_src
* savedoc
  #+begin_src emacs-lisp
    (defun jao-org--show-if-hidden ()
      (when (outline-invisible-p)
        (save-excursion
          (outline-previous-visible-heading 1)
          (org-show-subtree))))
    (add-hook 'org-mode-hook 'jao-org--show-if-hidden t)
  #+end_src
* Keybindings
    #+begin_src emacs-lisp
      (define-key mode-specific-map [?a] 'org-agenda)
      (define-key org-mode-map "\C-cv" 'jao-org-copy-link-at-point)
      (define-key org-mode-map [(control ?c) tab] 'org-force-cycle-archived)
      (define-key org-mode-map [(f7)] 'org-archive-to-archive-sibling)
      (define-key org-mode-map "\C-cE" 'jao-insert-eww-link)
      (define-key org-mode-map "\C-cW" 'jao-insert-eww-link)
      (define-key org-mode-map "\C-c'" 'org-edit-src-code)
      (define-key org-mode-map "\C-cO" 'outline-hide-other)
      (global-set-key "\C-cr" 'org-capture)
      (global-set-key "\C-c\C-l" 'org-store-link)
      ;; (global-set-key "\C-cL" 'org-insert-link-global)
      (global-set-key "\C-cO" 'org-open-at-point-global)

      (jao-transient-major-mode+ org
        ["Links"
         ("le" "insert current eww link" jao-insert-eww-link)
         ("lf" "insert link from clipboard" org-cliplink)
         ("lc" "copy link at point" jao-org-copy-link-at-point)])

    #+end_src