;;; 08-custom-packages --- Provide all the use-package declarations

;;; Commentary:
;;
;; See https://github.com/jwiegley/use-package for help
;; USE PACKAGE help
;; (use-package package-here
;;   :commands (cmd cmd-all cmd-etc)  ;; List commands used to ":defer" the package
;;   :bind-keymap
;;   ("M-q" . package-here-keymap)    ;; Setup an entire keymap using Prefix "M-q"
;;   :bind
;;   (("M-s" . cmd)                   ;; Available Globally
;;    :map here-mode-map
;;    ("C-t" . cmd-all)               ;; Available only in "here-mode"
;;    ("C-e" . cmd-etc))              ;; Available only in "here-mode"
;;   :init
;;   (setq stuff t)                   ;; declar vars etc...
;;   :config
;;   (here-mode 1)                    ;; eval stuff here after the init
;;
;; (use-package ruby-mode
;;   :mode "\\.rb\\'"
;;   :interpreter "ruby"
;;
;; ;; OR when the package name isn't the same as the =mode=
;; (use-package python
;;   :mode ("\\.py\\'" . python-mode)
;;   :interpreter ("python" . python-mode))
;;
;; USE ":defer" when you aren't using either :commands, :bind, :bind*, :bind-keymap, :bind-keymap*, :mode, :interpreter, or :hook
;; (use-package deferred-package
;;   :defer t)

;;; Code:

(use-package use-package-ensure-system-package
  :defer t)

(use-package ag
  :commands ag)

;; https://melpa.org/#/async
(use-package async
  :commands (async-start async-start-process))

;; https://github.com/myrjola/diminish.el
(use-package diminish
  :demand t)

;; https://elpa.gnu.org/packages/delight.html
(use-package delight
  :demand t)

;; https://github.com/winterTTr/ace-jump-mode
(use-package ace-jump-mode
  :bind
  (("C-c SPC" . just-one-space)
   ("M-SPC" . ace-jump-mode)))

;; https://github.com/jacktasia/dumb-jump
(use-package dumb-jump
  :disabled
  :hook js-mode
  :bind (
         ("M-." . dumb-jump-go)
         ("M-," . dumb-jump-back)
         ("M->" . dumb-jump-quick-look)
         )
  :config
  (setq dumb-jump-selector 'ivy)
  (setq dumb-jump-force-searcher 'rg))

;; https://github.com/NicolasPetton/zerodark-theme
(use-package zerodark-theme
  :demand t
  :init
  (setq max-specpdl-size 3000)
  (setq max-lisp-eval-depth 3000)
  :config
  (load-theme 'zerodark t)
  (zerodark-setup-modeline-format))

;; ;; https://github.com/belak/base16-emacs
;; (use-package base16-theme
;;   :disabled
;;   :config
;;   (load-theme 'base16-tomorrow t))

;; https://github.com/Malabarba/beacon
(use-package beacon
  :commands beacon-mode
  :diminish
  :init
  (setq beacon-size 70
        beacon-color "#5B6268"
        beacon-blink-delay 0.1
        beacon-blink-duration 0.4
        beacon-blink-when-focused t)
  (beacon-mode 1))

;; https://github.com/iqbalansari/emacs-emojify
(use-package emojify
  :defer 25
  :config
  (global-emojify-mode 1))

;; https://github.com/hrs/engine-mode
(use-package engine-mode
  :commands (engine/get-query engine/execute-search)
  :config
  ;; C-x / to start
  (defengine google "https://www.google.com/search?q=%s"
    :keybinding "a")
  (defengine github "https://github.com/search?q=%s"
    :keybinding "g")
  (defengine vlocity "https://success.vlocity.com/s/searchunifylightning?searchString=%s"
    :keybinding "v")
  (defengine duckduckgo "https://duckduckgo.com/?q=%s"
    :keybinding "d")
  (defengine melpa "https://melpa.org/#/?q=%s"
    :keybinding "m")
  (engine-mode 1))

(use-package excorporate
  :disabled
  :defer 5
  :straight (:host github :repo "emacsmirror/excorporate" :branch "master")
  :config
  (setq-default excorporate-configuration (quote ("lolson@eaglecrk.com" . "https://outlook.office365.com/EWS/Exchange.asmx"))
                org-agenda-include-diary t)

  (add-hook 'diary-mark-entries-hook 'diary-mark-included-diary-files)

  (defun my/agenda-update-diary ()
    "Update exchange diary."
    (interactive)
    (exco-diary-diary-advice
     (calendar-current-date)
     (calendar-current-date)
     #'message "Diary updated"))

  ;; Update diary each time the agenda is refreshed
  ;; (add-hook 'org-agenda-cleanup-fancy-diary-hook 'my/agenda-update-diary)

  ;; activate excorporate and request un/pw
  (excorporate)

  ;; enable diary integration
  (excorporate-diary-enable)
  )

;; https://github.com/Fanael/rainbow-delimiters
(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

;; rainbow-mode
(use-package rainbow-mode
  :hook prog-mode)

;; M-x all-the-icons-install-fonts
(use-package all-the-icons
  :demand t
  :config
  (setq inhibit-compacting-font-caches t))

;; https://github.com/emacs-dashboard/emacs-dashboard
(use-package dashboard
  :demand t
  :preface
  (defvar show-week-agenda-p)
  :init
  (setq dashboard-items '((recents  . 10)
                          (bookmarks . 10)
                          (projects . 5)
                          (agenda . 5)))
  (setq dashboard-center-content t)
  (setq dashboard-banner-logo-title "Let's do this...")
  (setq dashboard-startup-banner 1)
  (setq dashboard-show-shortcuts t)
  (setq show-week-agenda-p t)
  (setq dashboard-org-agenda-categories '("eaglecrk"))
  :config
  (dashboard-setup-startup-hook))

(use-package amx
  :commands amx-mode)

;; https://github.com/abo-abo/swiper
(use-package counsel
  :bind
  ("M-x"        . counsel-M-x)
  ("C-c k"      . counsel-rg)
  ("C-x C-f"    . counsel-find-file)
  ("C-x f"      . counsel-recentf)
  ("C-x C-d"    . counsel-dired)
  ("C-x p"      . counsel-package)
  ("C-x b"      . counsel-bookmark)
  ("C-x c"      . counsel-colors-web)
  ("C-c C-d"    . counsel-org-capture)

  ;; Describe Replacements
  ("C-h f" . counsel-describe-function)
  ("C-h v" . counsel-describe-variable)
  ("C-h b" . counsel-descbinds)

  ("M-y" . counsel-yank-pop)
  ;; Ivy
  ("C-c b" . ivy-switch-buffer)
  ("C-c c" . ivy-resume)

  ;; Swiper
  ("C-s" . swiper)
  :config
  (ivy-mode 1)
  (amx-mode 1)
  )

;; https://github.com/magnars/expand-region.el
(use-package expand-region
  :bind
  ("C-@" . er/expand-region)
  ("C-#" . er/contract-region))

;; https://github.com/thanhvg/emacs-howdoyou
(use-package howdoyou
  :bind
  ("C-c h q" . howdoyou-query)
  ("C-c h n" . howdoyou-next-link)
  ("C-c h p" . howdoyou-previous-link)
  ("C-c h f" . howdoyou-go-back-to-first-link)
  ("C-c h r" . howdoyou-reload-link))

;; https://github.com/magnars/multiple-cursors.el
(use-package multiple-cursors
  :bind
  ("C-}" . mc/mark-next-like-this)
  ("C-)" . mc/unmark-next-like-this)
  ("C-{" . mc/mark-previous-like-this)
  ("C-(" . mc/unmark-previous-like-this))

;; https://github.com/skeeto/elfeed
(use-package elfeed
  :bind
  ("C-x C-l e" . elfeed)
  (:map elfeed-search-mode-map
        ("a" . (lambda () (interactive) (elfeed-search-set-filter "")))
        ("e" . (lambda () (interactive) (elfeed-search-set-filter "+emacs")))
        ("x" . (lambda () (interactive) (elfeed-search-set-filter "xkcd")))
        ("=" . elfeed-search-set-filter))
  :init
  (setq elfeed-feeds
        '(
          ("https://insideevs.com/rss/make/tesla/" news tesla ev)
          ("https://insideevs.com/rss/make/rivian/" news rivian ev)
          ("https://insideevs.com/rss/category/battery-tech/" news battery ev)
          ("https://www.google.com/alerts/feeds/13353713273807811484/17577790586956417498" news google cybertruck tesla ev)
          ("https://www.google.com/alerts/feeds/13353713273807811484/2710948715805064535" news google tesla ev)
          ("https://www.google.com/alerts/feeds/13353713273807811484/17638090915837343269" news google pixel4)

          ("https://teslapodcast.libsyn.com/rss" podcast tesla ev)
          ("http://feeds.twit.tv/sn.xml" podcast security twit)
          ("https://feeds.fireside.fm/linuxunplugged/rss" podcast linux)
          ("https://latenightlinux.com/feed/all" podcast linux)

          ("https://www.youtube.com/feeds/videos.xml?channel_id=UCbgBDBrwsikmtoLqtpc59Bw" youtube 3dp)

          ("http://www.reddit.com/r/emacs/.rss" emacs)

          ("http://telescoper.wordpress.com/feed/" daily)
          ("http://xkcd.com/rss.xml" daily)
          ("http://pragmaticemacs.com/feed/" emacs)
          ("http://endlessparentheses.com/atom.xml" emacs)
          ("http://feeds.feedburner.com/XahsEmacsBlog" emacs)
          ("http://emacs.stackexchange.com/feeds" emacs)
          ))
  :config
  (defun yt-dl-it (url)
    "Downloads the URL in an async shell"
    (let ((default-directory "~/Videos"))
      (async-shell-command (format "youtube-dl %s" url))))

  (defun elfeed-youtube-dl (&optional use-generic-p)
    "Youtube-DL link"
    (interactive "P")
    (let ((entries (elfeed-search-selected)))
      (cl-loop for entry in entries
               do (elfeed-untag entry 'unread)
               when (elfeed-entry-link entry)
               do (yt-dl-it it))
      (mapc #'elfeed-search-update-entry entries)
      (unless (use-region-p) (forward-line))))

  (define-key elfeed-search-mode-map (kbd "d") 'elfeed-youtube-dl)
  (elfeed-update))

;; https://github.com/rmuslimov/browse-at-remote
(use-package browse-at-remote
  :bind ("C-c B" . browse-at-remote))

;; https://github.com/justbur/emacs-which-key
(use-package which-key
  :diminish
  :defer 5
  :config
  (which-key-setup-minibuffer)
  (which-key-mode))

;; https://github.com/lewang/fic-mode
(use-package fic-mode
  ;; :hook (prog-mode js-mode)
  :custom-face
  (fic-face  ((t :foreground "red" :weight bold)))
  (fic-author-face ((t :foreground "red" :underline t))))

;; https://github.com/joaotavora/yasnippet
(use-package yasnippet
  :commands yas-reload-all
  :hook (prog-mode . yas-minor-mode)
  :init
  (setq yas-snippet-dirs (list (concat user-emacs-directory "snippets")))
  :config
  (yas-reload-all))

;; https://company-mode.github.io/
(use-package company
  :defer 25
  :commands company-mode
  :hook (
         (prog-mode . company-mode)
         (ledger-mode . company-mode)
         )
  :bind
  (:map company-active-map
        ("M-n" . nil)
        ("M-p" . nil)
        ("C-n" . company-select-next)
        ("C-p" . company-select-previous))
  :config
  (setq company-idle-delay 0.1)
  (setq company-minimum-prefix-length 3)
  (setq company-dabbrev-downcase nil))

;; https://github.com/pashky/restclient.el
(use-package restclient
  :mode ("\\.rest\\'" . restclient-mode))

;; https://github.com/iquiw/company-restclient
(use-package company-restclient
  :after (company restclient))

;; https://github.com/magit/magit
(use-package magit
  :bind
  ("C-x g" . magit-status)
  ("C-c g" . magit-status))

;; This is used in `rg-menu'
(use-package rg
  :defer t)

;; This is used in `projectile'
(use-package ripgrep
  :commands rg-project)

;; https://github.com/bbatsov/projectile
(use-package projectile
  :delight '(:eval (concat " [" (projectile-project-name) "]"))
  :bind (
         ("C-c p" . projectile-command-map)
         :map projectile-command-map
         ("s r" . rg-project)
         )
  :init
  (setq projectile-completion-system 'ivy)
  :config
  (projectile-mode 1))

;; https://github.com/ledger/ledger-mode
(use-package ledger-mode
  :mode ("\\.dat\\'" "\\.ledger\\'")
  :bind
  (("C-x C-l l" . (lambda () (interactive) (find-file "~/Documents/finance-records/ledger.dat")))
   :map ledger-mode-map
   ("M-q" . leo/kill-this-buffer-unless-scratch)
   ("C-<tab>" . ledger-mode-clean-buffer)
   ("<backtab>" . ledger-post-align-dwim)
   )
  :hook
  (ledger-mode . (lambda ()
                   (setq tab-always-indent 'complete)
                   (setq-local completion-cycle-threshold t)
                   (setq-local ledger-complete-in-steps t)
                   ))
  )

;; https://github.com/magit/git-modes
(use-package gitignore-mode
  :mode ("\\.gitignore\\'"))

;; https://github.com/magit/git-modes
(use-package gitconfig-mode
  :mode ("\\.gitconfig\\'"))

;; http://web-mode.org/
(use-package web-mode
  :hook (html-mode nxml-mode))

;; JAVASCRIPT SECTION
(use-package lsp-mode
  :straight (:host github :repo "emacs-lsp/lsp-mode" :branch "master")
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  :init (setq lsp-keymap-prefix "C-c l")
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         (js-mode . lsp)
         (css-mode . lsp)
         (yaml-mode . lsp)
         ;; if you want which-key integration
         (lsp-mode . lsp-enable-which-key-integration))
  :bind
  (
   :map js-mode-map
   ("M-." . lsp-find-definition)
   )
  :commands lsp)

(use-package lsp-ui
  :straight (:host github :repo "emacs-lsp/lsp-ui" :branch "master")
  :commands lsp-ui-mode)
(use-package company-lsp
  :straight (:host github :repo "tigersoldier/company-lsp" :branch "master")
  :commands company-lsp)
(use-package lsp-ivy
  :straight (:host github :repo "emacs-lsp/lsp-ivy" :branch "master")
  :commands lsp-ivy-workspace-symbol)
(use-package lsp-treemacs
  :straight (:host github :repo "emacs-lsp/lsp-treemacs" :branch "master")
  :commands lsp-treemacs-errors-list)

(use-package js2-mode
  :disabled
  :mode ("\\.js\\'"))
(use-package typescript-mode
  :disabled
  :mode ("\\.js\\'"))
(use-package tide
  :disabled
  :ensure t
  :after (typescript-mode company flycheck)
  :hook ((typescript-mode . tide-setup)
         (typescript-mode . tide-hl-identifier-mode)
         (before-save . tide-format-before-save))
  :bind (
         ("M-?" . tide-references)
         ("M-r" . tide-rename-symbol)
         ("M-/" . tide-jsdoc-template)
         ("M-o" . tide-organize-imports)
         ))




;; https://github.com/smihica/emmet-mode
(use-package emmet-mode
  :hook (html-mode web-mode css-mode))

(use-package dash-at-point
  :if (eq system-type 'darwin)
  :ensure-system-package
  ("/Applications/Dash.app" . "brew cask install dash"))

;; https://github.com/joshwnj/json-mode
(use-package json-mode
  :mode "\\.json\\'")

;; https://github.com/mojochao/npm-mode
;; Disabled in favor of just running npm commands in comint buffer via
;; (leo/exec-process "npm run start" "npm-start" t)
(use-package npm-mode
  :disabled
  :defer 10
  :custom
  (npm-mode-command-prefix "C-c r"))

;; https://github.com/antonj/scss-mode
(use-package scss-mode
  :mode ("\\.s?css\\'" . scss-mode))

;; https://github.com/yoshiki/yaml-mode
(use-package yaml-mode
  :mode ("\\.ya?ml\\'" . yaml-mode))

;; https://github.com/kwrooijen/cargo.el
(use-package cargo
  :hook (rust-mode . cargo-minor-mode))

;; https://github.com/flycheck/flycheck
(use-package flycheck
  :diminish
  :preface
  (defvar flycheck-emacs-lisp-load-path)
  :init
  (setq flycheck-emacs-lisp-load-path 'inherit)
  (global-flycheck-mode))

;; Mu4e
(use-package mu4e
  :load-path "/usr/local/share/emacs/site-lisp/mu/mu4e"
  :commands mu4e
  :bind
  (
   ("C-x C-l m" . mu4e)
   ;; :map mu4e-headers-mode-map
   )
  :config
  (setq mu4e-maildir                       "/Users/leviolson/Maildir"
        mu4e-mu-binary                     "/usr/local/bin/mu"
        mail-user-agent                    'mu4e-user-agent
        mu4e-change-filenames-when-moving  t                                       ;; Rename files when moving (required by mbsync)
        mu4e-compose-in-new-frame          t                                       ;; New compose gets new frame
        mu4e-context-policy                'pick-first
        mu4e-get-mail-command              "true" ; /Users/leviolson/scripts/bash/get-email.sh
        ;; Get mail automatically (outside emacs) via brew services
        ;; "mbsync -a && mu index && open bitbar://refreshPlugin?name=mail.sh"
        ;; MBSYNC is the mail cmd
        mu4e-html2text-command             "/usr/local/bin/w3m -T text/html"       ;; HTML to text command
        mu4e-headers-include-related       nil                                     ;; Stop threading in INBOX
        mu4e-sent-messages-behavior        'delete                                 ;; Delete sent messages
        mu4e-update-interval               60                                      ;; 1 min
        mu4e-use-fancy-chars               t                                       ;; use 'fancy' chars
        mu4e-user-mail-address-list        '("lolson@eaglecrk.com")

        mu4e-view-show-images              t                                       ;; attempt to show images
        mu4e-view-image-max-width          400                                     ;; max image size

        message-citation-line-format       "On %a %d %b %Y at %R, %f wrote:\n"     ;; customize the reply-quote-string
        message-citation-line-function     'message-insert-formatted-citation-line ;; choose to use the formatted string
        message-kill-buffer-on-exit        t                                       ;; don't keep messages around

        send-mail-function                 'smtpmail-send-it                       ;; Default email send function
        smtpmail-default-smtp-server       "smtp.office365.com"
        smtpmail-smtp-service              587
        )

  (setq mu4e-contexts
        `(
          ,(make-mu4e-context
            :name "EagleCreek"
            :enter-func (lambda () (mu4e-message "Entering EagleCreek"))
            :leave-func (lambda () (mu4e-message "Leaving EagleCreek"))
            ;; we match based on the contact-fields of the message
            :match-func (lambda (msg)
                          (when msg
                            (string= (mu4e-message-field msg :maildir) "/eaglecrk")))
            :vars '( ( user-mail-address      . "lolson@eaglecrk.com"  )
                     ( smtpmail-mail-address  . "lolson@eaglecrk.com" )
                     ( smtpmail-smtp-user     . "lolson@eaglecrk.com" )
                     ( smtpmail-smtp-server   . "smtp.office365.com" )
                     ( user-full-name         . "Levi Olson" )
                     ( mu4e-compose-signature .
                                              (concat
                                               "Levi Olson\n"
                                               "Eagle Creek Software Services\n"
                                               "Senior Application Developer Consultant\n"))
                     ( mu4e-sent-folder       . "/eaglecrk/Sent Items" )
                     ( mu4e-refile-folder     . "/eaglecrk/Archive" )
                     ( mu4e-drafts-folder     . "/eaglecrk/Drafts" )
                     ( mu4e-trash-folder      . "/eaglecrk/Deleted Items" )
                     ( mu4e-maildir-shortcuts . (("/eaglecrk/Inbox" . ?i)
                                                 ("/eaglecrk/Sent Items" . ?s)
                                                 ("/eaglecrk/Deleted Items" . ?t)
                                                 ("/eaglecrk/Archive" . ?a)
                                                 ))))
          ;; ,(make-mu4e-context
          ;;   :name "Gmail"
          ;;   :enter-func (lambda () (mu4e-message "Entering Gmail"))
          ;;   :leave-func (lambda () (mu4e-message "Leaving Gmail"))
          ;;   ;; this matches maildir /Arkham and its sub-directories
          ;;   :match-func (lambda (msg)
          ;;                 (when msg
          ;;                   (string= (mu4e-message-field msg :maildir) "/gmail")))
          ;;   :vars '( ( user-mail-address      . "olson.levi@gmail.com" )
          ;;            ( smtpmail-mail-address  . "olson.levi@gmail.com" )
          ;;            ( smtpmail-smtp-user     . "olson.levi@gmail.com" )
          ;;            ( smtpmail-smtp-server   . "smtp.gmail.com" )
          ;;            ( user-full-name         . "Levi Olson" )
          ;;            ( mu4e-compose-signature .
          ;;                                     (concat
          ;;                                      "Levi\n"))
          ;;            ( mu4e-sent-folder       . "/gmail/[Gmail]/Sent Mail" )
          ;;            ( mu4e-refile-folder     . "/gmail/[Gmail]/All Mail" )
          ;;            ( mu4e-drafts-folder     . "/gmail/[Gmail]/Drafts" )
          ;;            ( mu4e-trash-folder      . "/gmail/[Gmail]/Trash" )
          ;;            ( mu4e-maildir-shortcuts . (("/gmail/Inbox" . ?i)
          ;;                                        ("/gmail/[Gmail]/Sent Mail" . ?s)
          ;;                                        ("/gmail/[Gmail]/Trash" . ?t)
          ;;                                        ("/gmail/[Gmail]/All Mail" . ?a)
          ;;                                        ))))
          ))

  ;; Add option to view HTML in browser
  (add-to-list 'mu4e-headers-actions
               '("in browser" . mu4e-action-view-in-browser) t)
  (add-to-list 'mu4e-view-actions
               '("in browser" . mu4e-action-view-in-browser) t)

  (defun my-message-current-line-cited-p ()
    "Indicate whether the line at point is a cited line."
    (save-match-data
      (string-match (concat "^" message-cite-prefix-regexp)
                    (buffer-substring (line-beginning-position) (line-end-position)))))

  (defun my-message-says-attachment-p ()
    "Return t if the message suggests there can be an attachment."
    (save-excursion
      (goto-char (point-min))
      (save-match-data
        (let (search-result)
          (while
              (and (setq search-result (re-search-forward "\\(attach\\|pdf\\|file\\)" nil t))
                   (my-message-current-line-cited-p)))
          search-result))))

  (defun my-message-has-attachment-p ()
    "Return t if the message has an attachment."
    (save-excursion
      (goto-char (point-min))
      (save-match-data
        (re-search-forward "<#part" nil t))))

  (defun my-message-pre-send-check-attachment ()
    (when (and (my-message-says-attachment-p)
               (not (my-message-has-attachment-p)))
      (unless
          (y-or-n-p "No attachment, send anyway? ")
        (error "It seems that an attachment is needed, but none was found.  Aborting sending"))))

  (add-hook 'message-send-hook 'my-message-pre-send-check-attachment))


;; https://orgmode.org/elpa.html
(use-package org
  :commands org-capture
  :ensure org-plus-contrib
  :mode ("\\.org\\'" . org-mode)
  :bind (
         ("C-," . org-cycle-agenda-files)
         ("C-c C-d"   . org-capture)
         ("C-x C-l a" . org-agenda)
         :map org-mode-map
         ("M-RET"     . org-insert-todo-heading)
         ("M-n"       . leo/org-narrow-next-tree)
         ("M-p"       . leo/org-narrow-prev-tree)
         ("M-P"       . leo/org-present)
         )
  :preface
  (defvar org-html-validation-link)
  (defvar org-html-text-markup-alist)
  (defvar org-capture-templates)
  :init
  (setq org-agenda-files '("~/Dropbox/Org/todo.org"
                           "~/Dropbox/Org/diary/eaglecrk.org"
                           "~/Dropbox/Org/archive.org"
                           "~/Projects/vlocity/cmt-training-org/LightningWebComponents/README.org"
                           ;; "~/.emacs.d/excorporate/diary-excorporate-today"
                           ))
  (setq org-agenda-include-diary t)
  (add-to-list 'safe-local-variable-values '(eval leo/deft-insert-boilerplate))
  (setq org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)")
                            (sequence "BUG(b)" "INPROGRESS(i)" "|" "FIXED(f)")
                            (sequence "TEST(T)" "NOTEST(N)" "|" "COMPLETE(C)")
                            (sequence "QUESTION(Q)" "|" "ANSWERED(A)")
                            (sequence "|" "CANCELED(c)")
                            (sequence "|" "NEEDCLARIFICATION(n)")
                            (sequence "|" "PROVIDEUPDATE(p)")
                            (sequence "WAITING(w)" "|"))
        org-refile-targets '((nil :maxlevel . 3)
                             (org-agenda-files :maxlevel . 3))
        org-directory "~/Dropbox/Org"
        org-default-notes-file (concat org-directory "/todo.org")
        org-src-fontify-natively t
        org-startup-folded t
        org-startup-indented t
        org-startup-align-all-tables t
        org-startup-with-inline-images t
        org-startup-with-latex-preview t
        org-src-tab-acts-natively t
        org-confirm-babel-evaluate nil
        org-log-done t
        org-log-done-with-time t
        org-log-into-drawer t
        org-hide-leading-stars t
        org-pretty-entities t
        org-use-property-inheritance t
        org-html-validation-link nil
        org-html-text-markup-alist '((bold . "<b>%s</b>")
                                     (code . "<code>%s</code>")
                                     (italic . "<i>%s</i>")
                                     (strike-through . "<del>%s</del>")
                                     (underline . "<span class=\"underline\">%s</span>")
                                     (verbatim . "<code class=\"verbatim\">%s</code>"))
        )
  :config
  (defun org-src-disable-flycheck-doc ()
    "Disable flycheck comment doc string checking when (C-c ') ing a file."
    (interactive)
    (setq flycheck-disabled-checkers '(emacs-lisp-checkdoc)))
  (add-to-list 'org-src-mode-hook 'org-src-disable-flycheck-doc)

  (when (version<= "9.2" (org-version))
    (require 'org-tempo))
  (org-babel-do-load-languages 'org-babel-load-languages '((js . t)
                                                           (shell . t)
                                                           (restclient . t)
                                                           (emacs-lisp . t)))

  (setq org-capture-templates
        '(("t" "new task" entry (file+headline "~/Dropbox/Org/todo.org" "Tasks")
           "* TODO [#A] %?\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n%a\n")
          ("n" "new note" entry (file+headline org-default-notes-file "Notes")
           "* %?\n%i\n")
          ("l" "store link" entry (file+olp org-default-notes-file "Links" "Unfiled")
           "* %a\n%?\n")
          ("d" "store link w/drawer" entry (file+olp org-default-notes-file "Links" "Unfiled")
           "* %?\n%l\n:COPIED_TEXT:\n    %i\n:END:\n")
          ))

  (setq org-structure-template-alist
        '(("r" . "src restclient :results raw")
          ("j" . "src js :cmd \"/usr/local/bin/babel-node\" :results output code")
          ("e" . "src emacs-lisp :results silent")
          ("a" . "export ascii")
          ("c" . "center")
          ("C" . "comment")
          ("E" . "export")
          ("h" . "export html")
          ("l" . "export latex")
          ("q" . "quote")
          ("s" . "src")
          ("v" . "verse")))
  (defconst checkbox-fontlock-keywords-alist
    (mapcar (lambda (regex-char-pair)
              `(,(car regex-char-pair)
                (0 (prog1 ()
                     (compose-region (match-beginning 1)
                                     (match-end 1)
                                     ,(concat (list ?\C-i)
                                              (list (decode-char 'ucs (cadr regex-char-pair)))))))))
            '(("\\(\\[ \\]\\)"      #XF096);2B1C
              ("\\(\\[-\\]\\)"      #XF147);29C7;F458
              ("\\(\\[X\\]\\)"      #XF046);2BBD
              )))

  (defun add-checkbox-symbol-keywords ()
    "Add checkbox font to font-lock."
    (font-lock-add-keywords nil checkbox-fontlock-keywords-alist))

  (add-hook 'org-mode-hook 'add-checkbox-symbol-keywords)
  )

;; https://github.com/seanohalpin/org-link-minor-mode
(use-package org-link-minor-mode
  :straight (:host github :repo "seanohalpin/org-link-minor-mode" :branch "master")
  :commands org-link-minor-mode)

;; (use-package ob-restclient
;;   :disabled
;;   :ensure t
;;   :config
;;   (setq org-babel-default-header-args:restclient
;;         `((:results . "output"))))

;; https://github.com/astahlman/ob-async
;; Run a begin_src block asynchronously via :async
(use-package ob-async
  :disabled
  :ensure t
  :after org)

;; https://github.com/sabof/org-bullets
(use-package org-bullets
  :hook (org-mode . org-bullets-mode)
  :config
  (setq org-bullets-bullet-list '( "○" "◉" "●" "●" "●" "●" "●"))
  (set-face-attribute 'org-level-1 nil :height 1.5)
  (set-face-attribute 'org-level-2 nil :height 1.0)
  (set-face-attribute 'org-level-3 nil :height 1.0)
  (set-face-attribute 'org-level-4 nil :height 1.0)
  (set-face-attribute 'org-level-5 nil :height 1.0)
  (set-face-attribute 'org-scheduled-today nil :height 2.0)
  (set-face-attribute 'org-agenda-date-today nil :height 2.0))

;; https://orgmode.org/worg/org-contrib/org-protocol.html
(use-package org-protocol
  :ensure org-plus-contrib
  :after org)

;; https://github.com/marsmining/ox-twbs
(use-package ox-twbs
  :defer 10
  :after org)

(use-package ox-extra
  :defer 10
  :ensure org-plus-contrib
  :after org
  :config
  (ox-extras-activate '(ignore-headlines)))

;; https://github.com/yjwen/org-reveal
(use-package ox-reveal
  :defer 10
  :after org)

;; https://github.com/jethrokuan/org-roam/
(use-package org-roam
  :hook
  ((org-mode . org-roam-mode)
   (after-init . org-roam--build-cache-async) ;; optional!
   )
  :straight (:host github :repo "jethrokuan/org-roam" :branch "develop")
  :custom
  (org-roam-directory "~/Dropbox/Org/Roam/")
  :config
  (org-roam--build-cache-async)
  (setq org-roam-graphviz-executable "/usr/local/Cellar/graphviz/2.42.2/bin/dot")
  (setq org-roam-graph-viewer "/usr/bin/open")
  (setq org-roam-link-title-format "r::%s")
  :bind
  ("C-c n l" . org-roam)
  ("C-c n t" . org-roam-today)
  ("C-c n f" . org-roam-find-file)
  ("C-c n i" . org-roam-insert)
  ("C-c n g" . org-roam-show-graph))

;; https://github.com/jrblevin/deft
(use-package deft
  :bind
  ("C-c n d" . deft)
  :custom
  (deft-recursive t)
  (deft-use-filter-string-for-filename t)
  (deft-default-extension "org")
  (deft-directory "~/Dropbox/Org/Roam/"))

;; https://github.com/hniksic/emacs-htmlize
(use-package htmlize
  :defer 10
  :after org)

;; https://github.com/jwiegley/use-package/blob/master/bind-key.el
(use-package bind-key
  :bind
  ("C-<tab>" . leo/tidy)
  ("C-;"     . leo/comment-or-uncomment-region-or-line)
  ("C-c e"   . leo/find-user-init-file)
  ("M-q"     . leo/kill-this-buffer-unless-scratch)
  ("C-c d"   . leo/duplicate-thing)
  ("M-n"     . leo/jump-to-next-symbol)
  ("M-p"     . leo/jump-to-prev-symbol)
  ("M-u"     . upcase-dwim)
  ("M-c"     . capitalize-dwim)
  ("M-l"     . downcase-dwim)
  )

;; https://github.com/nflath/sudo-edit
(use-package sudo-edit
  :commands (sudo-edit))

;; https://www.emacswiki.org/emacs/ParEdit
(use-package paredit
  :hook (
         (emacs-lisp-mode                  . enable-paredit-mode)
         (lisp-mode                        . enable-paredit-mode)
         (lisp-interaction-mode            . enable-paredit-mode)
         (scheme-mode                      . enable-paredit-mode)
         (eval-expression-minibuffer-setup . enable-paredit-mode)
         )
  :config
  (unbind-key "M-q" paredit-mode-map))


(provide '08-custom-packages)
;;; 08-custom-packages.el ends here
