emacs-config/config-base.org
Benson Chu 8e26f78f0b Use window configurations
Although may not be necessary soon because of Emacs 27 tab support
2020-01-20 08:47:38 -06:00

109 KiB

Emacs Configuration

Enable lexical binding

  ;;; -*- lexical-binding: t -*-

Bugs

Need this to fix broken config

  (use-package magit-popup)

custom-tangle

  (defun tangle-elisp ()
    (interactive)
    (org-babel-tangle nil nil 'emacs-lisp))

Neo keyboard issues

  (global-set-key (kbd "M-Ä") 'eval-expression)
  (defun reset-keyboard ()
    (interactive)
    (shell-command "setxkbmap de neo_dvorak"))

Emacs

Custom file

  (setq custom-file "~/.emacs.d/custom.el")
  (load custom-file 'noerror)
  (setq backup-directory-alist `(("." . ,(concat user-emacs-directory "backups"))))

Reload Config

  (defun reload-config () (interactive) (load-file "~/.emacs.d/init.el"))

New Scratch buffer

  (defun scratch-buffer ()
    (interactive)
    (let ((count 0))
      (while (get-buffer (format "*scratch%d*" count))
        (incf count))
      (switch-to-buffer (get-buffer-create (format "*scratch%d*" count)))
      (lisp-interaction-mode)
      (insert (substitute-command-keys initial-scratch-message))))

Select Help Window

  (setq help-window-select t)

Terminal

  ;; (use-package multi-term)
  ;; (define-key term-mode-map (kbd "M-'") 'scroll-down)

  (use-package vterm)
  (unbind-key (kbd "C-t") term-mode-map)
  (define-key *root-map* (kbd "c") (lambda () (interactive) (or (when-let (b (get-buffer "vterm")) (switch-to-buffer b)) (vterm))))
  (add-hook 'term-mode-hook
        (lambda ()
          (add-to-list 'term-bind-key-alist '("M-[" . multi-term-prev))
          (add-to-list 'term-bind-key-alist '("M-]" . multi-term-next))
          (add-to-list 'term-bind-key-alist '("M-'" . scroll-down))
          (add-to-list 'term-bind-key-alist '("C-t" . *root-map*))))

resize-window

  (use-package resize-window)
  (global-set-key (kbd "M-1") 'resize-window)

which-key

  (use-package which-key)
  (setq which-key-idle-delay 3)
  (which-key-mode)

undo-tree

  (use-package undo-tree)

advice for shell-command

  (defun my/shell-command-advice (&rest args)
    (switch-to-buffer "*Shell Command Output*"))

  ;;(advice-add #'shell-command :after #'my/shell-command-advice)

eval and replace

  (defun my/eval-and-replace ()
    "Replace the preceding sexp with its value."
    (interactive)
    (backward-kill-sexp)
    (condition-case nil
        (prin1 (eval (read (current-kill 0)))
               (current-buffer))
      (error (message "Invalid expression")
             (insert (current-kill 0)))))

  (global-set-key (kbd "C-c C-e") 'my/eval-and-replace)

uniq emacs

  (defun case-fold-string= (a b)
    (eq t (compare-strings a nil nil b nil nil t)))
  (defun case-fold-string-hash (a)
    (sxhash (upcase a)))

  (define-hash-table-test 'case-fold
    'case-fold-string= 'case-fold-string-hash)

  (defun uniq (beg end)
    "Print counts of strings in region."
    (interactive "r")
    (let ((h (make-hash-table :test 'case-fold))
          (lst (split-string (buffer-substring-no-properties beg end) "\n"
                             'omit-nulls " "))
          (output-func (if current-prefix-arg 'insert 'princ)))
      (dolist (str lst)
        (puthash str (1+ (gethash str h 0)) h))
      (maphash (lambda (key val)
                 (apply output-func (list (format "%d: %s\n" val key))))
               h)))

Look and feel

Base look

(tool-bar-mode -1)
(menu-bar-mode -1)
(fringe-mode '(10 . 0))

Theme

  (use-package color-theme-modern)
  ;; (use-package gruvbox-theme)
  (load-theme 'calm-forest t)
  ;; My font and background color
  (load-theme 'dark-default t)

  ;; (load-theme 'gruvbox-dark-medium)
  ;; (load-theme 'gruv-adj)

mode-line

doom-modeline

  (use-package doom-modeline)
  (use-package smart-mode-line)
  (use-package all-the-icons)

  (load-theme 'smart-mode-line-dark)

  (set-face-attribute 'mode-line nil :height 100)
  (set-face-attribute 'mode-line-inactive nil :height 100)
  (setq all-the-icons-scale-factor 1.0)
  (setq doom-modeline-height 24)

  (doom-modeline-mode)

Ocodo

  (use-package ocodo-svg-modelines)

Font

  ;;(set-face-attribute 'default t :font "Dotsies Training Wheels-20")
  ;;(add-to-list 'default-frame-alist '(font . "Dotsies Training Wheels-20"))
  ;; (set-default-font "LinuxLibertine")
  ;; (set-default-font "Hack 10")
  ;; (set-default-font "UbuntuMono 11")
  ;; (set-default-font "OfficeCodePro 11")
  ;; "Tamzen"
  ;; "SourceCodePro"
  ;; "Gohu Gohufont"
  (set-default-font "RobotoMono-10")
  (add-to-list 'default-frame-alist '(font . "RobotoMono-10"))
  (set-fontset-font t nil (font-spec :size 10 :name "RobotoMono"))

  (set-fontset-font t 'unicode (font-spec :size 10 :name "FontAwesome"))
  (set-fontset-font t 'unicode (font-spec :size 16 :name "DejaVu Sans Mono"))
  ;; (set-frame-font "Menlo")
  (defun reading-buffer ()
    (interactive)
     (setq buffer-face-mode-face '(:family "LinuxLibertine" :height 200))
     (buffer-face-mode))

Splash image

  (setq fancy-splash-image "~/.emacs.d/res/icon.png")

term faces

  (set-face-attribute 'term-bold       t :weight 'bold)
  (set-face-attribute 'term-color-blue t :background "dodger blue" :foreground "dodger blue")

Dashboard

  (use-package dashboard)
  ;(dashboard-setup-startup-hook)

beacon

  (use-package beacon)
  (beacon-mode 1)
  (setq beacon-blink-delay 0.1)
  (setq beacon-color "#006400")

Navigation

IDO

  (use-package ido)
  (ido-mode t)

Helm & counsel/ivy

  (use-package helm)
  (require 'helm-config)
  ;(helm-mode 1)
  ;(setq ivy-initial-inputs-alist nil)
  (use-package ivy)
  (use-package smex)
  (use-package counsel)
  (ivy-mode 1)

  ;(advice-add 'ivy-completion-in-region :before (lambda (start end collection &optional predicate) (insert " ")))

  (add-to-list 'ivy-initial-inputs-alist '(org-refile . ""))
  (add-to-list 'ivy-initial-inputs-alist '(org-agenda-refile . ""))
  (add-to-list 'ivy-initial-inputs-alist '(org-capture-refile . ""))
  (add-to-list 'ivy-initial-inputs-alist '(counsel-M-x . ""))

  (define-key ivy-minibuffer-map (kbd "<return>") 'ivy-alt-done)
  (define-key ivy-minibuffer-map (kbd "C-<return>") 'ivy-done)
  (global-set-key (kbd "C-h M-x") 'helm-M-x)
  (global-set-key (kbd "M-x") 'counsel-M-x)
  (global-set-key (kbd "C-c C-r") 'ivy-resume)
  ;;   (global-set-key (kbd "C-x b") 'counsel-switch-buffer)

f3 helm

  (use-package f3)

Swiper or counsel-grep

  (global-set-key (kbd "C-S-s") 'counsel-grep-or-swiper)
  ;;(global-set-key (kbd "C-s") 'isearch-forward)
  (setq counsel-grep-base-command "grep --ignore-case -E -n -e %s %s")

help should still use regular search

  (define-key Info-mode-map (kbd "C-s") 'isearch-forward)

Evil mode

  (use-package evil)
  (global-set-key (kbd "C-z") 'evil-local-mode)
  (setq evil-insert-state-modes nil)  
  (setq evil-motion-state-modes nil)
  (setq evil-default-state 'emacs)
  (evil-set-initial-state 'term-mode 'emacs)
  (evil-set-initial-state 'help-mode 'emacs)
  (evil-mode 1)

Ace window

  (use-package switch-window)
  (global-set-key (kbd "C-x o") 'switch-window)
  (exwm-global-set-key (kbd "s-o") 'other-window)
  (setq switch-window-shortcut-style 'qwerty)
  (setq switch-window-qwerty-shortcuts
        '("a" "o" "e" "u" "i" "d" "h" "t" "n" "s"))

iy-go-to-char

  (use-package iy-go-to-char)
  (global-set-key (kbd "M-m") 'iy-go-to-char)

ibuffer

Keybindings

  (require 'ibuf-ext)
  (global-set-key (kbd "C-x C-b") 'ibuffer)

  (add-to-list 'ibuffer-never-show-predicates
               '(lambda (buf)
                  (with-current-buffer buf
                    (eq major-mode 'helm-major-mode))))

  (setq ibuffer-show-empty-filter-groups nil)

  (add-hook 'ibuffer-mode-hook
            '(lambda ()
                (ibuffer-switch-to-saved-filter-groups "default")
                (ibuffer-do-sort-by-alphabetic)
                ;; (ibuffer-auto-mode)
                ))

  ;; (setq ibuffer-mode-hook nil)(list (car ibuffer-mode-hook)))

Filter Groups

  (setq ibuffer-saved-filter-groups
        '(("default"
           ("X-Windows"       (mode . exwm-mode))
           ("Terminals"       (mode . term-mode))
           ("emacs-config"    (not (or (mode . magit-status-mode)
                                       (not (or (filename . ".emacs.d")
                                                (filename . "emacs-config"))))))
           ("code-aux"        (or (mode . slime-repl-mode)
                                  (mode . magit-status-mode)
                                  (mode . ein:notebooklist-mode)
                                  (mode . cider-repl-mode)
                                  (mode . comint-mode)
                                  (mode . makefile-gmake-mode)))
           ("code"            (or (mode . clojure-mode)
                                  (mode . csharp-mode)
                                  (mode . c++-mode)
                                  (mode . c-mode)
                                  (mode . scala-mode)
                                  (mode . emacs-lisp-mode)
                                  (mode . java-mode)
                                  (mode . js-mode)
                                  (mode . python-mode)
                                  (mode . ng2-ts-mode)
                                  (mode . lisp-mode)
                                  (mode . ein:notebook-multilang-mode)))
           ("web"             (or (mode . web-mode)
                                  (mode . mhtml-mode)
                                  (mode . js2-mode)
                                  (mode . css-mode)))
           ("Org Mode"        (not or (not mode . org-mode)
                                      (directory-name . "agenda")))
           ("text"            (filename . "\\.txt"))
           ("pdfs"            (or (mode . doc-view-mode)
                                  (mode . pdf-view-mode)))
           ("Agenda Buffers"  (mode . org-agenda-mode))
           ("Agenda Files"    (mode . org-mode))
           ("folders"         (mode . dired-mode))
           ("Help"            (or (name . "\*Help\*")
                                  (name . "\*Apropos\*")
                                  (name . "\*info\*"))))))

Custom Filters

  (eval-after-load "ibuf-ext"
    '(define-ibuffer-filter directory-name
         "Filter files in the agenda folder"
       (:description "agenda")
       (and (buffer-file-name buf) 
            (string-match qualifier
                          (buffer-file-name buf)))))

  ;(add-hook 'exwm-workspace-switch-hook 'ibuffer)

view-mode

  (defun my/ibuffer-view ()
    (interactive)
    (ibuffer-visit-buffer)
    (when (null exwm--id)
      (view-mode)))
  (define-key ibuffer-mode-map (kbd "v") #'my/ibuffer-view)

Ace jump

  (use-package ace-jump-mode)
  (global-set-key (kbd "C-c SPC") 'ace-jump-mode)
  (global-set-key (kbd "C-c j") 'ace-jump-line-mode)

Word traversal

  (global-set-key (kbd "M-f") 'forward-to-word)
  (global-set-key (kbd "M-F") 'forward-word)

Tools

Encryption

  (require 'epa-file)
  (epa-file-enable)
  (setq epa-pinentry-mode 'loopback)
  (setq epa-file-cache-passphrase-for-symmetric-encryption t)
  (setenv "GPG_AGENT_INFO" nil)

  (setq epg-gpg-program "gpg2")
  (setq auth-source-debug t)
  (setq auth-sources '((:source "~/.emacs.d/secrets/.authinfo.gpg")))

  ;; (defun always-use-loopback (fun context args)
  ;;   (setf (epg-context-pinentry-mode context) epa-pinentry-mode)
  ;;   (funcall fun context args))

  ;; (advice-remove 'epg--start :around #'always-use-loopback)

dired

Dired+, for formatting

  (add-to-list 'load-path
               "~/.emacs.d/submodule/dired-plus")
  (require 'dired+)
  (setq dired-listing-switches "-al  --group-directories-first --sort=extension")

  (setq diredp-hide-details-initially-flag nil)
  (setq diredp-hide-details-propagate-flag nil)
  (require 'dired-x)
  (setq-default dired-omit-files-p t)
  (setq dired-omit-files (concat dired-omit-files "\\|^\\..+$"))

dired-hacks

  (use-package dired-filter)
  (use-package dired-narrow)
  (define-key dired-filter-map (kbd "F") 'dired-narrow-fuzzy)
  (setq dired-filter-group-saved-groups
        '(("default"
           ("PDF"
            (extension . "pdf"))
           ("LaTeX"
            (extension "tex" "bib"))
           ("Org"
            (extension . "org"))
           ("Archives"
            (extension "zip" "rar" "gz" "bz2" "tar")))))

  (use-package dired-subtree)

  (define-key dired-mode-map (kbd "i") 'dired-subtree-insert)
  (define-key dired-mode-map (kbd "I") 'dired-subtree-remove)

  (use-package dired-collapse)

dired-du

  (use-package dired-du)

youtube-dl

  (require 'dired-aux)

  (defvar dired-filelist-cmd
    '(("vlc" "-L")))

  (defun dired-start-process (cmd &optional file-list)
    (interactive
     (let ((files (dired-get-marked-files
                   t current-prefix-arg)))
       (list
        (dired-read-shell-command "& on %s: "
                                  current-prefix-arg files)
        files)))
    (let (list-switch)
      (start-process
       cmd nil shell-file-name
       shell-command-switch
       (format
        "nohup 1>/dev/null 2>/dev/null %s \"%s\""
        (if (and (> (length file-list) 1)
                 (setq list-switch
                       (cadr (assoc cmd dired-filelist-cmd))))
            (format "%s %s" cmd list-switch)
          cmd)
        (mapconcat #'expand-file-name file-list "\" \"")))))

  (define-key dired-mode-map "r" 'dired-start-process)

  (defun watch-youtube ()
    (interactive)
    (dired "~/big_files/Videos/youtube-dl")
    (local-set-key (kbd "RET") 'dired-start-process))

async-command

  ;; (defun my/async-shell-command (command &optional output-buffer error-buffer)
  ;;   (interactive
  ;;    (list
  ;;     (read-shell-command "Async shell command: " nil nil
  ;;                         (let ((filename
  ;;                                (cond
  ;;                                 (buffer-file-name)
  ;;                                 ((eq major-mode 'dired-mode)
  ;;                                  (dired-get-filename nil t)))))
  ;;                           (and filename (file-relative-name filename))))
  ;;     current-prefix-arg
  ;;     shell-command-default-error-buffer))
  ;;   (unless (string-match "&[ \t]*\\'" command)
  ;;     (setq command (concat command " &")))
  ;;   (shell-command command output-buffer error-buffer))

  ;; (add-to-list 'display-buffer-alist
  ;;              (cons "\\*Async Shell Command\\*.*" (cons #'display-buffer nil)))

  ;; (setq display-buffer-alist (remove-if (lambda (a) (string= (car a) "\\*Async Shell Command\\*.*")) display-buffer-alist)

rename-follow

  (defun my/dired-do-create-files (op-symbol file-creator operation arg
                                             &optional marker-char op1
                                             how-to)
    (or op1 (setq op1 operation))
    (let* ((fn-list (dired-get-marked-files nil arg))
           (rfn-list (mapcar #'dired-make-relative fn-list))
           (dired-one-file	; fluid variable inside dired-create-files
            (and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
           (target-dir (dired-dwim-target-directory))
           (default (and dired-one-file
                         (not dired-dwim-target) ; Bug#25609
                         (expand-file-name (file-name-nondirectory (car fn-list))
                                           target-dir)))
           (defaults (dired-dwim-target-defaults fn-list target-dir))
           (target (expand-file-name ; fluid variable inside dired-create-files
                    (minibuffer-with-setup-hook
                        (lambda ()
                          (set (make-local-variable 'minibuffer-default-add-function) nil)
                          (setq minibuffer-default defaults))
                      (dired-mark-read-file-name
                       (concat (if dired-one-file op1 operation) " %s to: ")
                       target-dir op-symbol arg rfn-list default))))
           (into-dir (cond ((null how-to)
                            ;; Allow users to change the letter case of
                            ;; a directory on a case-insensitive
                            ;; filesystem.  If we don't test these
                            ;; conditions up front, file-directory-p
                            ;; below will return t on a case-insensitive
                            ;; filesystem, and Emacs will try to move
                            ;; foo -> foo/foo, which fails.
                            (if (and (file-name-case-insensitive-p (car fn-list))
                                     (eq op-symbol 'move)
                                     dired-one-file
                                     (string= (downcase
                                               (expand-file-name (car fn-list)))
                                              (downcase
                                               (expand-file-name target)))
                                     (not (string=
                                           (file-name-nondirectory (car fn-list))
                                           (file-name-nondirectory target))))
                                nil
                              (file-directory-p target)))
                           ((eq how-to t) nil)
                           (t (funcall how-to target)))))
      (if (and (consp into-dir) (functionp (car into-dir)))
          (apply (car into-dir) operation rfn-list fn-list target (cdr into-dir))
        (if (not (or dired-one-file into-dir))
            (error "Marked %s: target must be a directory: %s" operation target))
        ;; rename-file bombs when moving directories unless we do this:
        (or into-dir (setq target (directory-file-name target)))
        (dired-create-files
         file-creator operation fn-list
         (if into-dir			; target is a directory
             ;; This function uses fluid variable target when called
             ;; inside dired-create-files:
             (lambda (from)
               (expand-file-name (file-name-nondirectory from) target))
           (lambda (_from) target))
         marker-char)
        (dired target))))

  (defun my/dired-rename-follow (orig &optional arg)
    (when arg
      (advice-add #'dired-do-create-files :override #'my/dired-do-create-files))
    (funcall orig nil)
    (when arg
      (advice-remove #'dired-do-create-files #'my/dired-do-create-files)))

  (advice-add #'dired-do-rename
              :around
              #'my/dired-rename-follow)

Elfeed

Setup feeds

  ;; Load elfeed-org
  (use-package elfeed)
  (use-package elfeed-org)

  (setq rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org"))
  (elfeed-org)
  (setq-default elfeed-search-filter "@1-week-ago +unread -youtube")
  (define-key elfeed-search-mode-map "U" 'elfeed-search-fetch-visible)
  (define-key elfeed-search-mode-map "Y" (lambda ()
                                           (interactive)
                                           (elfeed-search-set-filter "+youtube +unread")))
  (define-key elfeed-search-mode-map "N" (lambda ()
                                           (interactive)
                                           (elfeed-search-set-filter "@1-day-ago +unread -youtube")))
  (define-key elfeed-search-mode-map "h" (lambda ()
                                           (interactive)
                                           (elfeed-search-set-filter nil)))

youtube-dl

  (defun elfeed-show-youtube-dl ()
    "Download the current entry with youtube-dl."
    (interactive)
    (pop-to-buffer (youtube-dl (elfeed-entry-link elfeed-show-entry))))

  (cl-defun elfeed-search-youtube-dl (&key slow)
    "Download the current entry with youtube-dl."
    (interactive)
    (let ((entries (elfeed-search-selected)))
      (dolist (entry entries)
        (if (null (youtube-dl (elfeed-entry-link entry)
                              :title (elfeed-entry-title entry)
                              :slow slow))
            (message "Entry is not a YouTube link!")
          (message "Downloading %s" (elfeed-entry-title entry)))
        (elfeed-untag entry 'unread)
        (elfeed-search-update-entry entry)
        (unless (use-region-p) (forward-line)))))

  (define-key elfeed-search-mode-map "d" 'elfeed-search-youtube-dl)
  (setq youtube-dl-directory "~/big_files/Videos/youtube-dl")

Youtube show thumbnail

  (use-package dash)
  (defun elfeed-entries-from-atom (url xml)
    "Turn parsed Atom content into a list of elfeed-entry structs."
    (let* ((feed-id url)
           (protocol (url-type (url-generic-parse-url url)))
           (namespace (elfeed-url-to-namespace url))
           (feed (elfeed-db-get-feed feed-id))
           (title (elfeed-cleanup (xml-query* (feed title *) xml)))
           (author (elfeed-cleanup (xml-query* (feed author name *) xml)))
           (xml-base (or (xml-query* (feed :base) xml) url))
           (autotags (elfeed-feed-autotags url)))
      (setf (elfeed-feed-url feed) url
            (elfeed-feed-title feed) title
            (elfeed-feed-author feed) author)
      (cl-loop for entry in (xml-query-all* (feed entry) xml) collect
               (let* ((title (or (xml-query* (title *) entry) ""))
                      (xml-base (elfeed-update-location
                                 xml-base (xml-query* (:base) (list entry))))
                      (anylink (xml-query* (link :href) entry))
                      (altlink (xml-query* (link [rel "alternate"] :href) entry))
                      (link (elfeed--fixup-protocol
                             protocol
                             (elfeed-update-location xml-base
                                                     (or altlink anylink))))
                      (date (or (xml-query* (published *) entry)
                                (xml-query* (updated *) entry)
                                (xml-query* (date *) entry)
                                (xml-query* (modified *) entry) ; Atom 0.3
                                (xml-query* (issued *) entry))) ; Atom 0.3
                      (author-name (or (xml-query* (author name *) entry)
                                       ;; Dublin Core
                                       (xml-query* (creator *) entry)))
                      (author-email (xml-query* (author email *) entry))
                      (author (cond ((and author-name author-email)
                                     (format "%s <%s>" author-name author-email))
                                    (author-name)))
                      (categories (xml-query-all* (category :term) entry))
                      (content (elfeed--atom-content entry))
                      (id (or (xml-query* (id *) entry) link
                              (elfeed-generate-id content)))
                      (type (or (xml-query* (content :type) entry)
                                (xml-query* (summary :type) entry)
                                ""))
                      (tags (elfeed-normalize-tags autotags elfeed-initial-tags))
                      (content-type (if (string-match-p "html" type) 'html nil))
                      (etags (xml-query-all* (link [rel "enclosure"]) entry))
                      (thumb (xml-query* (group thumbnail :url) entry))
                      (enclosures
                       (cl-loop for enclosure in etags
                                for wrap = (list enclosure)
                                for href = (xml-query* (:href) wrap)
                                for type = (xml-query* (:type) wrap)
                                for length = (xml-query* (:length) wrap)
                                collect (list href type length)))
                      (db-entry (elfeed-entry--create
                                 :title (elfeed-cleanup title)
                                 :feed-id feed-id
                                 :id (cons namespace (elfeed-cleanup id))
                                 :link (elfeed-cleanup link)
                                 :tags tags
                                 :date (or (elfeed-float-time date) (float-time))
                                 :content content
                                 :enclosures enclosures
                                 :content-type content-type
                                 :meta `(,@(when author
                                             (list :author author))
                                         ,@(when categories
                                             (list :categories categories))
                                         ,@(when thumb
                                             (list :thumbnail (elfeed-get-thumbnail thumb)))))))
                 (setq debug/entry db-entry)
                 (dolist (hook elfeed-new-entry-parse-hook)
                   (funcall hook :atom entry db-entry))
                 db-entry))))

  (defun elfeed-insert-sliced-thumbnail (orig-fun entry)
    (let ((thumbnail (elfeed-meta entry :thumbnail)))
      (if (null thumbnail)
          (funcall orig-fun entry)
        (insert-sliced-image (create-image thumbnail 'imagemagick nil :height 150) nil nil 4)
        (delete-backward-char 1)
        (previous-line)
        (previous-line)
        (end-of-line)
        (let* ((date (elfeed-search-format-date (elfeed-entry-date entry)))
               (title (or (elfeed-meta entry :title) (elfeed-entry-title entry) ""))
               (title-faces (elfeed-search--faces (elfeed-entry-tags entry)))
               (feed (elfeed-entry-feed entry))
               (feed-title
                (when feed
                  (or (elfeed-meta feed :title) (elfeed-feed-title feed))))
               (tags (mapcar #'symbol-name (elfeed-entry-tags entry)))
               (tags-str (mapconcat
                          (lambda (s) (propertize s 'face 'elfeed-search-tag-face))
                          tags ","))
               (title-width (- (window-width) 10 elfeed-search-trailing-width))
               (title-column (elfeed-format-column
                              title (elfeed-clamp
                                     elfeed-search-title-min-width
                                     title-width
                                     elfeed-search-title-max-width)
                              :left)))
          (insert " " (propertize title-column 'face title-faces 'kbd-help title) " ")
          (next-line)
          (insert " " (propertize date 'face 'elfeed-search-date-face) " ")
          (when feed-title
            (insert (propertize feed-title 'face 'elfeed-search-feed-face) " "))
          (when tags
            (insert "(" tags-str ")")))
        (next-line)
        (end-of-line))))

  (defun elfeed-insert-sliced-thumbnail (orig-fun entry)
    (let ((thumbnail (elfeed-meta entry :thumbnail)))
      (if (null thumbnail)
          (funcall orig-fun entry)
        (insert-sliced-image (create-image thumbnail 'imagemagick nil :height 150) nil nil 4)
        (delete-backward-char 1)
        (previous-line)
        (previous-line)
        (end-of-line)
        (let* ((date (elfeed-search-format-date (elfeed-entry-date entry)))
               (title (or (elfeed-meta entry :title) (elfeed-entry-title entry) ""))
               (title-faces (elfeed-search--faces (elfeed-entry-tags entry)))
               (feed (elfeed-entry-feed entry))
               (feed-title
                (when feed
                  (or (elfeed-meta feed :title) (elfeed-feed-title feed))))
               (tags (mapcar #'symbol-name (elfeed-entry-tags entry)))
               (tags-str (mapconcat
                          (lambda (s) (propertize s 'face 'elfeed-search-tag-face))
                          tags ","))
               (title-width (- (window-width) 10 elfeed-search-trailing-width))
               (title-column (elfeed-format-column
                              title (elfeed-clamp
                                     elfeed-search-title-min-width
                                     title-width
                                     elfeed-search-title-max-width)
                              :left)))
          (insert " " (propertize title-column 'face title-faces 'kbd-help title) " ")
          (next-line)
          (insert " " (propertize date 'face 'elfeed-search-date-face) " ")
          (when feed-title
            (insert (propertize feed-title 'face 'elfeed-search-feed-face) " "))
          (when tags
            (insert "(" tags-str ")")))
        (next-line)
        (end-of-line))))

  (defun elfeed-insert-thumbnail (entry)
    (let ((thumbnail (elfeed-meta entry :thumbnail)))
      (if (null thumbnail)
          (insert "")
        (insert " ")
        (insert-image (create-image thumbnail 'imagemagick nil :height 150))
        (insert " "))))

  (advice-add 'elfeed-search-print-entry--default :before #'elfeed-insert-thumbnail)

  (defvar elfeed-link-org-capture nil)
  (defun elfeed-show-insert-thumbnail ()
    (let ((inhibit-read-only t)
          (thumbnail (elfeed-meta elfeed-show-entry :thumbnail)))
      (if (null thumbnail)
          (insert "")
        (insert-image (create-image thumbnail 'imagemagick nil :height 150))
        (insert "\n"))
      (goto-char (point-min))
      (setq elfeed-link-org-capture
            (format "[[%s][%s]] :%s:%s:"
                    (elfeed-entry-link elfeed-show-entry)
                    (elfeed-entry-title elfeed-show-entry)
                    (elfeed-meta elfeed-show-entry :author)
                    (string-join (mapcar #'symbol-name (elfeed-entry-tags elfeed-show-entry)) ":")))))

  (advice-add 'elfeed-show-refresh--mail-style :after #'elfeed-show-insert-thumbnail)

  (defun elfeed-get-thumbnail (url)
    (let* ((file (--> url
                      (split-string it "/")
                      (nth 4 it)
                      (concat it ".jpg")))
           (img-url (replace-regexp-in-string "/hqdefault.jpg$" "/mqdefault.jpg" url))
           (img-folder (--> "images"
                            (expand-file-name it elfeed-db-directory)
                            (file-name-as-directory it)))
           (filepath (concat img-folder file)))
      (unless (file-directory-p img-folder)
        (make-directory img-folder))
      (unless (file-exists-p filepath)
        (start-process-shell-command "wget" nil (format "wget %s -O %s" img-url filepath)))
      filepath))

w3m

  ;; Remove when Emacs 27 releases
  (setq w3m-use-tabs nil)
  (use-package w3m)

  (defun dired-browse-with-w3m (arg)
    (interactive "P")
    (let ((browse-url-browser-function (if arg
                                           (symbol-function browse-url-browser-function)
                                         #'w3m-browse-url)))
      (browse-url-of-dired-file)))

  (define-key dired-mode-map (kbd "W") 'dired-browse-with-w3m)

  (exwm-global-set-key (kbd "C-c g")
          (lambda ()
            (interactive)
            (w3m-goto-url "https://google.com")))

Ledger mode

  (use-package ledger-mode
    :mode "\\.dat\\'"
    :config
    (defconst new-report-str (concat "%(binary) -f %(ledger-file) --cleared-format "
                                     "'%(justify(scrub(get_at(display_total, 0)), 16, 16 + int(prepend_width), true, color))"
                                     "  %(justify(scrub(get_at(display_total, 1)), 18, 36 + int(prepend_width), true, color))"
                                     "  %(justify(scrub(get_at(display_total, 0) - get_at(display_total, 1)), 18, 36 + int(prepend_width), true, color))"
                                     "    %(latest_cleared ? format_date(latest_cleared) : \"         \")"
                                     "    %(!options.flat ? depth_spacer : \"\")%-(ansify_if(partial_account(options.flat), blue if color))\\n"
                                   "%/%$1  %$2  %$3    %$4\\n"
                                   "%/%(prepend_width ? \" \" * int(prepend_width) : \"\")----------------    ----------------    ----------------    ---------\\n'"
                                   " cleared"))

    (setq ledger-reports
          `(("account" "%(binary) -f %(ledger-file) reg %(account)")
            ("bal" "%(binary) -f %(ledger-file) bal")
            ("reg" "%(binary) -f %(ledger-file) reg")
            ("cleared" ,new-report-str)
            ;; ("cleared" "%(binary) -f %(ledger-file) cleared")
            ("expmonth" "%(binary) -f %(ledger-file) -M reg Expenses")
            ("owedmom" "%(binary) -f %(ledger-file) reg Liabilities")
            ("progress" "%(binary) -f %(ledger-file) reg Assets Equity Liabilities")
            ;; ("food" "%(binary) -f %(ledger-file) --add-budget reg Assets")
            ("payee" "%(binary) -f %(ledger-file) reg @%(payee)")))

    (setq dynamic-reports
          '(("budgetcal" "%(binary) -f ~/MEGA/org/entries/food.ledger --daily --add-budget reg Expenses")))

    (defun ledger-dynamic-report ()
      (interactive)
      (let* ((ledger-reports dynamic-reports)
             (report-name (ledger-report-read-name)))
        (ledger-report report-name nil)))

    (setq ledger-reconcile-buffer-line-format
          "%(date)s %-4(code)s %-30(payee)s %-30(account)s %15(amount)s\n"))

Reconciliation accept "^" at front

  (defun ledger-reconcile-check-ignore-carrot (orig account)
    (funcall orig (if (= ?^ (aref account 0))
                      (substring account 1)
                    account)))

  (advice-add #'ledger-reconcile-check-valid-account
              :around
              #'ledger-reconcile-check-ignore-carrot)

Email

general-options

  (setq user-mail-address "bensonchu457@gmail.com"
        user-full-name "Benson Chu")

  (setq smtpmail-smtp-server "smtp.gmail.com"
        smtpmail-smtp-service 587
        send-mail-function 'smtpmail-send-it
        message-send-mail-function 'smtpmail-send-it)

  ;; (setq smtpmail-smtp-server "smtp.office365.com"
  ;;       smtpmail-smtp-service 587
  ;;       smtpmail-local-domain nil)

Gnus

  (add-hook 'gnus-group-mode-hook 'gnus-topic-mode)

  (setq user-mail-address "bensonchu457@gmail.com"
        user-full-name "Benson Chu")

  (setq gnus-select-method 
        '(nnmaildir "gmail" 
                    (directory "~/.offlineimap_mail/personal")
                    (directory-files nnheader-directory-files-safe) 
                    (get-new-mail nil)))

  (setq gnus-secondary-select-methods
        '((nnmaildir "work" 
                     (directory "~/.offlineimap_mail/work")
                     (directory-files nnheader-directory-files-safe) 
                     (get-new-mail nil))))

  ;; (setq gnus-select-method
  ;;       '(nnimap "Local"
  ;;                (nnimap-address "localhost")
  ;;                (nnimap-stream network)
  ;;                (nnimap-server-port 143)))

  ;; (setq gnus-select-method
  ;;       '(nnimap "gmail"
  ;;                (nnimap-address "imap.gmail.com")
  ;;                (nnimap-server-port "imaps")
  ;;                (nnimap-stream ssl)
  ;;                (nnimap-authinfo-file "~/.emacs.d/secrets/.authinfo.gpg")))

  (setq gnus-mark-article-hook nil)

  (gnus-add-configuration
   '(article
     (horizontal 1.0
                 (vertical 25
                           (group 1.0))
                 (vertical 1.0
                           (summary 0.25 point)
                           (article 1.0)))))

  (gnus-add-configuration
   '(summary
     (horizontal 1.0
                 (vertical 25
                           (group 1.0))
                 (vertical 1.0
                           (summary 1.0 point)))))


  ;;(setq gnus-summary-line-format "%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n")
  (setq gnus-summary-line-format "%d %U%R%z%I%(%[%4L: %-23,23f%]%) %s\n")

notmuch

  (setq mail-specify-envelope-from t
        message-sendmail-envelope-from 'header
        mail-envelope-from 'header)

  (use-package notmuch
    :commands notmuch
    :bind (:map notmuch-message-mode-map
                ("C-c C-c" . #'my/choose-email-address-and-send)
                :map notmuch-search-mode-map
                ("d" . #'my/notmuch-delete-mail)
                ("u" . #'my/undelete-mail)
                ("f" . #'my/recruiting-mail)
                ("<mouse-1>" . nil)
                :map notmuch-tree-mode-map
                ("N" . #'notmuch-tree-next-sibling)
                ("P" . #'notmuch-tree-prev-sibling)
                ("t" . #'notmuch-tree-toggle-folding-thread)
                ("S-SPC" . #'notmuch-tree-scroll-message-window-back))
    :config
    (custom-set-faces
     '(notmuch-tree-match-tree-face ((t (:family "DejaVu Sans Mono"))) t)
     '(notmuch-tree-no-match-tree-face ((t (:family "DejaVu Sans Mono"))) t))
    (set-face-attribute 'notmuch-search-unread-face nil :foreground "white")
    (set-face-attribute 'notmuch-message-summary-face nil :background "steel blue" :foreground "snow")

    (setq notmuch-search-oldest-first nil
          notmuch-saved-searches
          '((:name "inbox" :query "tag:inbox" :key "i")
            (:name "inbox today" :query "date:7d.. tag:inbox" :key "t")
            (:name "work" :query "tag:work" :key "w")
            (:name "mailing lists" :query "tag:mlist" :key "m")
            (:name "recruiting" :query "tag:recruiting" :key "r")
            (:name "unread" :query "tag:unread" :key "u")
            (:name "flagged" :query "tag:flagged" :key "f")
            (:name "cs" :query "tag:cs" :key "c")
            (:name "receipts" :query "tag:receipts" :key "R")
            ;; (:name "sent" :query "tag:sent" :key "s")
            ;; (:name "drafts" :query "tag:draft" :key "d")
            (:name "all mail" :query "*" :key "a")))

    (defun my/choose-email-address-and-send ()
      (interactive)
      (let ((resp (completing-read "Which email? " '("bchu3@cougarnet.uh.edu" "bensonchu457@gmail.com") nil t "^")))
        (setq smtpmail-smtp-server
              (if (string= resp "bensonchu457@gmail.com")
                  "smtp.gmail.com"
                "smtp.office365.com"))
        (notmuch-mua-send-and-exit)))

    (defun my/notmuch-delete-mail ()
      (interactive)
      (notmuch-search-tag '("+deleted"))
      (notmuch-search-next-thread))

    (defun my/undelete-mail ()
      (interactive)
      (notmuch-search-tag '("-deleted")))

    (defun my/recruiting-mail ()
      (interactive)
      (notmuch-search-tag '("-inbox" "+recruiting"))
      (notmuch-search-next-thread))

    (add-to-list 'notmuch-tagging-keys
                 '("r" ("-inbox" "+recruiting") "Recruiting")))

Code Snippet from Julien Masson for tree-folding in notmuch-tree

  (defcustom notmuch-tree-overlay-string " [...]"
    "String displayed at the beginning of the overlay"
    :type 'string
    :group 'notmuch-tree)

  ;; Faces for overlays
  (defface notmuch-tree-overlay-fold-face
    '((t :inherit 'font-lock-keyword-face))
    "Default face used to display `notmuch-tree-overlay-string'"
    :group 'notmuch-tree
    :group 'notmuch-faces)

  (defvar notmuch-tree-overlays nil
    "List of overlays used to fold/unfold thread")

  (defun notmuch-tree-find-overlay (buffer start end)
    "Return the first overlay found in `notmuch-tree-overlays'.

  The overlay found is located between START and END position in BUFFER."
    (cl-find-if (lambda (ov)
                  (and (eq (overlay-buffer ov) buffer)
                       (<= (overlay-start ov) start)
                       (>= (overlay-end ov) end)))
                notmuch-tree-overlays))

  (defun notmuch-tree-clean-up-overlays (&rest args)
    "Remove overlays not referenced to any buffer"
    (setq notmuch-tree-overlays (cl-remove-if #'overlay-buffer notmuch-tree-overlays)))

  (defun notmuch-tree-remove-overlay (overlay)
    "Delete OVERLAY and remove it from `notmuch-tree-overlays' list"
    (setq notmuch-tree-overlays (remove overlay notmuch-tree-overlays))
    (delete-overlay overlay))

  (defun notmuch-tree-add-overlay (start end)
    "Add an overlay from START to END in the current buffer.

  If non nil, `notmuch-tree-overlay-string' is added at the end of the line.
  The overlay created is added to `notmuch-tree-overlays' list"
    (let ((overlay (make-overlay start end)))
      (add-to-list 'notmuch-tree-overlays overlay)
      (overlay-put overlay 'invisible t)
      (when notmuch-tree-overlay-string
        (overlay-put overlay 'before-string
                     (propertize notmuch-tree-overlay-string
                                 'face 'notmuch-tree-overlay-fold-face)))))

  (defun notmuch-tree-thread-range ()
    "Return list of Start and End position of the current thread"
    (let (start end)
      (save-excursion
        (while (not (or (notmuch-tree-get-prop :first) (eobp)))
          (forward-line -1))
        (setq start (line-end-position))
        (notmuch-tree-next-thread)
        (setq end (- (point) 1))
        (list start end))))

  (defun notmuch-tree-sub-thread-range ()
    "Return list of Start and End position of the current sub-thread"
    (if (notmuch-tree-get-prop :first)
        (notmuch-tree-thread-range)
      (let ((level (length (notmuch-tree-get-prop :tree-status)))
            (start (line-end-position))
            end)
        ;; find end position
        (save-excursion
          (forward-line)
          (while (and (< level (length (notmuch-tree-get-prop :tree-status)))
                      (not (eobp)))
            (forward-line))
          (setq end (- (point) 1)))
        (list start end))))

  (defun notmuch-tree-toggle-folding-thread (&optional arg)
    "Fold / Unfold the current thread or sub-thread.

  With prefix arg (C-u) the whole thread is folded"
    (interactive "p")
    (cl-multiple-value-bind (start end)
        (if (and arg (= arg 1))
            (notmuch-tree-sub-thread-range)
          (notmuch-tree-thread-range))
      (unless (= start end)
        (let ((overlay (notmuch-tree-find-overlay (current-buffer) start end)))
          (if overlay
              (notmuch-tree-remove-overlay overlay)
            (notmuch-tree-add-overlay start end))))))

  (advice-add #'notmuch-tree-worker
              :before
              #'notmuch-tree-clean-up-overlays)

  (defun advice-replace-forward-line-with-next-line (orig &rest args)
    (letf (((symbol-function 'forward-line) (symbol-function 'next-line)))
      (apply orig args)))

  ;; Needed for n and p to work
  (advice-add #'notmuch-tree-prev-matching-message
              :around
              #'advice-replace-forward-line-with-next-line)

  (advice-add #'notmuch-tree-next-matching-message
              :around
              #'advice-replace-forward-line-with-next-line)


  (defun notmuch-tree-next-sibling ()
    (interactive)
    (let ((l (length (notmuch-tree-get-prop :tree-status))))
      (while (progn (next-line)
                    (and (not (bobp))
                         (< l (length (notmuch-tree-get-prop :tree-status)))))))
    (when (window-live-p notmuch-tree-message-window)
      (notmuch-tree-show-message-in)))

  (defun notmuch-tree-prev-sibling ()
    (interactive)
    (let ((l (length (notmuch-tree-get-prop :tree-status))))
      (while (progn (previous-line)
                    (and (not (bobp))
                         (< l (length (notmuch-tree-get-prop :tree-status)))))))
    (when (window-live-p notmuch-tree-message-window)
      (notmuch-tree-show-message-in)))

mu4e

  (unless (eq system-type 'windows-nt)
    (require 'mu4e)

    (add-to-list 'mu4e-view-actions
         '("ViewInBrowser" . mu4e-action-view-in-browser) t)

    ;; (global-set-key (kbd "<f8>") 'mu4e)

    (setq mu4e-maildir "~/.offlineimap_mail"
      mu4e-sent-folder   "/personal/[Gmail].Sent Mail"
      mu4e-drafts-folder "/personal/[Gmail].Drafts"
      mu4e-refile-folder "/personal/[Gmail].Archive")

    (defvar my-mu4e-account-alist
  '(("Gmail"
     (mu4e-sent-folder "/work/Sent Mail")
     (mu4e-drafts-folder "/Gmail/[Gmail].Drafts")
     (mu4e-refile-folder "/Gmail/[Gmail].Archive")
     (user-mail-address "bensonchu457@gmail.com")
     (smtpmail-default-smtp-server "smtp.gmail.com")
     (smtpmail-smtp-user "bensonchu457")
     (smtpmail-smtp-server "smtp.gmail.com"))
    ("work"
     (mu4e-sent-folder "/work/Sent")
     (mu4e-drafts-folder "/work/Drafts")
     (mu4e-refile-folder "/work/Archive")
     (user-mail-address "bchu3@uh.edu")
     (smtpmail-default-smtp-server "smtp.account2.example.com")
     (smtpmail-smtp-user "bchu3")
     (smtpmail-smtp-server "smtp.account2.example.com")))))

    ;;(defun my-mu4e-set-account ()
    ;;  "Set the account for composing a message."
    ;;  (let* ((account
    ;;    (if mu4e-compose-parent-message
    ;;        (let ((maildir (mu4e-message-field mu4e-compose-parent-message :maildir)))
    ;;      (string-match "/\\(.*?\\)/" maildir)
    ;;      (match-string 1 maildir))
    ;;      (completing-read (format "Compose with account: (%s) "
    ;;                   (mapconcat #'(lambda (var) (car var))
    ;;                      my-mu4e-account-alist "/"))
    ;;               (mapcar #'(lambda (var) (car var)) my-mu4e-account-alist)
    ;;               nil t nil nil (caar my-mu4e-account-alist))))
    ;;   (account-vars (cdr (assoc account my-mu4e-account-alist))))
    ;;    (if account-vars
    ;;        (mapc #'(lambda (var)
    ;;        (set (car var) (cadr var)))
    ;;        account-vars)
    ;;      (error "No email account found"))))

    ;;  (add-hook 'mu4e~headers-jump-to-maildir 'my-mu4e-set-account)

html view firefox no copiousoutput

  (mailcap-add "text/html" "/usr/bin/xdg-open %s ")

Programming

Autocompletion

  (use-package company)
  (setq company-idle-delay 0.2)
  (add-hook 'emacs-lisp-mode-hook
            'company-mode)

Magit

  (use-package magit)
  (global-set-key (kbd "C-x g") 'magit-status)
  (global-set-key (kbd "C-x M-g") 'magit-dispatch-popup)

irony

  (use-package irony
    :hook ((c++-mode . irony-mode)
           (c-mode . irony-mode)
           (objc-mode . irony-mode)))

  ;; (add-hook 'c++-mode-hook 'irony-mode)
  ;; (add-hook 'c-mode-hook 'irony-mode)
  ;; (add-hook 'objc-mode-hook 'irony-mode)

  ;; (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)

  ;; (global-company-mode)

Yasnippets

  (use-package yasnippet)
  (use-package java-snippets)
  (define-key yas/keymap (kbd "<backtab>") 'yas-expand)
  (yas-global-mode 0)

Projectile and dumb-jump

  (use-package projectile
    :custom
    (projectile-enable-caching t))

  (use-package treemacs-projectile)
  (use-package helm-projectile)
  (use-package counsel-projectile)

  (defun projectile-stop-project-running ()
    (interactive)
    (if-let (buf (get-buffer "*compilation*"))
        (let ((kill-buffer-query-functions nil))
          (kill-buffer buf)
          (delete-window))
      (message "Project is not running")))

  (projectile-global-mode)
  ;; Deprecated?
  (counsel-projectile-mode)

  (ivy-set-occur 'counsel-projectile-switch-to-buffer 'ivy-switch-buffer-occur)

  (cons 'projectile-root-bottom-up
        (remove 'projectile-root-bottom-up
                projectile-project-root-files-functions))
  (setq projectile-indexing-method 'native)
  (setq projectile-completion-system 'ivy)
  (define-key projectile-mode-map (kbd "C-c C-p") 'projectile-command-map)
  (define-key projectile-command-map (kbd "C-a") 'projectile-add-known-project)
  (define-key projectile-command-map (kbd "C-r") 'projectile-remove-known-project)
  (define-key projectile-command-map (kbd "C-f") 'counsel-projectile-find-file)
  (define-key projectile-command-map (kbd "C-b") 'projectile-ibuffer)
  (define-key projectile-command-map (kbd "C-c") 'projectile-compile-project)
  (define-key projectile-command-map (kbd "C-d") 'projectile-stop-project-running)

  (defun this-is-a-project (dir)
    (interactive "f")
    (setq projectile-project-root dir)
    (set (make-local-variable 'dumb-jump-project) dir))

  (define-key projectile-command-map (kbd "C-t") 'this-is-a-project)
  (use-package dumb-jump)
  (dumb-jump-mode)

hs-minor-mode

  (defun set-hiding-indentation (column)
    (interactive "P")
    (set-selective-display
     (or column
         (unless selective-display
           (1+ (current-column))))))

  (defun set-hiding-indentation-to-point (column)
    (interactive "P")
    (if hs-minor-mode
        (if (condition-case nil
                (hs-toggle-hiding)
              (error t))
            (hs-show-all))
      (set-hiding-indentation column)))

  (global-set-key (kbd "C-=") 'hs-toggle-hiding)
  (global-set-key (kbd "C--") 'set-hiding-indentation-to-point)
  (add-hook 'c-mode-common-hook   'hs-minor-mode)
  (add-hook 'emacs-lisp-mode-hook 'hs-minor-mode)
  (add-hook 'java-mode-hook       'hs-minor-mode)
  (add-hook 'lisp-mode-hook       'hs-minor-mode)
  (add-hook 'perl-mode-hook       'hs-minor-mode)
  (add-hook 'sh-mode-hook         'hs-minor-mode)

Ensime (scala)

  (use-package ensime)

SPACES

  (setq TeX-auto-untabify 't)
  (setq indent-tabs-mode nil)
  (add-hook 'java-mode-hook
            (lambda () 
              (setq indent-tabs-mode nil)))
  (add-hook 'clojure-mode
             (lambda ()
              (setq indent-tabs-mode nil)))

Geiser

  (use-package geiser)
  (setq geiser-default-implementation 'chez)

Paredit

  (use-package paredit)

Cider

  (use-package clj-refactor)
  (use-package cider)
  (use-package clojure-mode)

YAML

  (use-package yaml-mode)

show parens

  (show-paren-mode t)

lsp-mode

  (use-package flycheck)
  ;; (global-flycheck-mode)

  (add-to-list 'display-buffer-alist
               `(,(rx bos "*Flycheck errors*" eos)
                 (display-buffer-reuse-window
                  display-buffer-in-side-window)
                 (side            . bottom)
                 (reusable-frames . visible)
                 (window-height   . 0.10)))

  (require 'ansi-color)
  (defun colorize-compilation-buffer ()
    (let ((buffer-read-only nil))
      (ansi-color-apply-on-region (point-min) (point-max))))
    ;; (ansi-color-apply-on-region compilation-filter-start (point)))
  (add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

  (use-package lsp-mode)
  (use-package lsp-ui)

  (add-hook 'java-mode-hook
            'lsp)

  (define-key lsp-mode-map (kbd "M-.") 'lsp-ui-peek-find-definitions)
  (define-key lsp-mode-map (kbd "M-?") 'lsp-ui-peek-find-references)
  (define-key lsp-mode-map (kbd "M-,") 'lsp-ui-peek-jump-backward)
  (define-key lsp-mode-map (kbd "M-p") 'lsp-ui-peek-jump-forward)

  (setq lsp-ui-flycheck-enable t)
  (setq lsp-ui-flycheck-live-reporting t)
  (use-package dap-mode
    :config
    (add-hook 'java-mode-hook
              'dap-mode)
    (add-hook 'java-mode-hook
              'dap-ui-mode)
    (define-key dap-mode-map (kbd "C-c h") 'dap-hydra)
    (define-key dap-mode-map (kbd "C-c b") 'dap-breakpoint-toggle)
    (define-key dap-mode-map (kbd "C-c d r") 'dap-java-debug)
    (define-key dap-mode-map (kbd "C-c d m") 'dap-java-debug-test-class)
    (define-key dap-mode-map (kbd "C-c r t") 'mvn-test))

  ;; (defhydra dap-hydra (:color pink :hint nil :foreign-keys run)
  ;;   ;;   "
  ;;   ;; ^Stepping^          ^Switch^                 ^Breakpoints^           ^Eval
  ;;   ;; ^^^^^^^^-----------------------------------------------------------------------------------------
  ;;   ;; _n_: Next           _ss_: Session            _bt_: Toggle            _ee_: Eval
  ;;   ;; _i_: Step in        _st_: Thread             _bd_: Delete            _er_: Eval region
  ;;   ;; _o_: Step out       _sf_: Stack frame        _ba_: Add               _es_: Eval thing at point
  ;;   ;; _c_: Continue       _sl_: List locals        _bc_: Set condition     _eii_: Inspect
  ;;   ;; _r_: Restart frame  _sb_: List breakpoints   _bh_: Set hit count     _eir_: Inspect region
  ;;   ;; _Q_: Disconnect     _sS_: List sessions      _bl_: Set log message   _eis_: Inspect thing at point
  ;;   ;; "
  ;;   ("n" dap-next)
  ;;   ("i" dap-step-in)
  ;;   ("o" dap-step-out)
  ;;   ("c" dap-continue)
  ;;   ("r" dap-restart-frame)
  ;;   ("ss" dap-switch-session)
  ;;   ("st" dap-switch-thread)
  ;;   ("sf" dap-switch-stack-frame)
  ;;   ("sl" dap-ui-locals)
  ;;   ("sb" dap-ui-breakpoints)
  ;;   ("sS" dap-ui-sessions)
  ;;   ("bt" dap-breakpoint-toggle)
  ;;   ("ba" dap-breakpoint-add)
  ;;   ("bd" dap-breakpoint-delete)
  ;;   ("bc" dap-breakpoint-condition)
  ;;   ("bh" dap-breakpoint-hit-condition)
  ;;   ("bl" dap-breakpoint-log-message)
  ;;   ("ee" dap-eval) 
  ;;   ("er" dap-eval-region)
  ;;   ("es" dap-eval-thing-at-point)
  ;;   ("eii" dap-ui-inspect)
  ;;   ("eir" dap-ui-inspect-region)
  ;;   ("eis" dap-ui-inspect-thing-at-point)
  ;;   ("q" nil "quit" :color blue)
  ;;   ("Q" dap-disconnect :color red))
  ;(use-package lsp-python)

Java

  (use-package lsp-java)
  (require 'dap-java)

ccls

  (use-package ccls)
  (require 'ccls)

Rainbow delimiters

  (use-package rainbow-delimiters)
  (rainbow-delimiters-mode)
  (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
  (add-hook 'org-mode-hook #'rainbow-delimiters-mode)

  (let ((rainbow-purple  "#9E1CB2")
        (rainbow-blue  "#1194f6")
        (rainbow-green  "#47B04B")
        (rainbow-yellow  "#FFED18")
        (rainbow-orange  "#E7B500")
        (rainbow-red  "#C90067")
        (rainbow-7  "#00AA5D")
        (rainbow-8  "#FE7380"))
    (set-face-attribute 'rainbow-delimiters-depth-1-face  t :foreground rainbow-purple)
    (set-face-attribute 'rainbow-delimiters-depth-2-face  t :foreground rainbow-green)
    (set-face-attribute 'rainbow-delimiters-depth-3-face  t :foreground rainbow-blue)
    (set-face-attribute 'rainbow-delimiters-depth-4-face  t :foreground rainbow-red)
    (set-face-attribute 'rainbow-delimiters-depth-5-face  t :foreground rainbow-yellow)
    (set-face-attribute 'rainbow-delimiters-depth-6-face  t :foreground rainbow-blue)
    (set-face-attribute 'rainbow-delimiters-depth-7-face  t :foreground rainbow-red)
    (set-face-attribute 'rainbow-delimiters-depth-8-face  t :foreground rainbow-8)
    (set-face-attribute 'rainbow-delimiters-depth-9-face  t :foreground rainbow-purple))

elisp

Macroexpand

  (use-package macrostep)

  (define-key macrostep-keymap (kbd "C-c C-c") nil)

  (define-key macrostep-keymap (kbd "DEL") nil)
  (define-key macrostep-keymap (kbd "c") nil)
  (define-key macrostep-keymap (kbd "u") nil)
  (define-key macrostep-keymap (kbd "C-c q") #'macrostep-collapse)

  (define-key macrostep-keymap (kbd "RET") nil)
  (define-key macrostep-keymap (kbd "e") nil)
  (define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand)


  (define-key macrostep-keymap (kbd "n") nil)
  (define-key macrostep-keymap (kbd "C-c C-n") #'macrostep-next-macro)

  (define-key macrostep-keymap (kbd "p") nil)
  (define-key macrostep-keymap (kbd "C-c C-p") #'macrostep-prev-macro)

auto-highlight-symbol

  (use-package auto-highlight-symbol)
  (add-hook 'emacs-lisp-mode-hook
            'auto-highlight-symbol-mode)

C#

  (use-package csharp-mode)
  (use-package dotnet)
  (use-package omnisharp
    :bind (:map omnisharp-mode-map
            ([remap xref-find-definitions] . omnisharp-go-to-definition)
            ([remap xref-find-references] . omnisharp-find-usages)))
  (add-hook 'csharp-mode-hook 'omnisharp-mode)
  (add-hook 'csharp-mode-hook 'company-mode)
  (add-hook 'csharp-mode-hook 'flycheck-mode)
  (add-hook 'csharp-mode-hook 'auto-highlight-symbol-mode)
  (add-hook 'csharp-mode-hook 'dotnet-mode)

React js

  (use-package rjsx-mode)

Golang

  (use-package go-mode)
  (add-hook 'go-mode-hook
         (lambda ()
           (add-hook 'before-save-hook 'gofmt-before-save)
           (setq indent-tabs-mode nil)))

Elpy

  (use-package elpy)
  (elpy-enable)

EIN

  (use-package ein)
  (add-to-list 'exec-path
               "/home/benson/anaconda3/bin/")

Web-mode

  (use-package web-mode
    :commands web-mode
    :init
    (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.cshtml\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
    :config
    (setq web-mode-auto-close-style 2))

Processing

  (use-package processing-mode)

  (setq processing-location "/usr/bin/processing-java")

Treemacs

  (use-package treemacs)

Hy-mode

  (use-package hy-mode)

glsl-mode

  (autoload 'glsl-mode "glsl-mode" nil t)
  (add-to-list 'auto-mode-alist '("\\.glsl\\'" . glsl-mode))
  (add-to-list 'auto-mode-alist '("\\.vert\\'" . glsl-mode))
  (add-to-list 'auto-mode-alist '("\\.frag\\'" . glsl-mode))
  (add-to-list 'auto-mode-alist '("\\.geom\\'" . glsl-mode))

indent-guide

  (use-package indent-guide)
  ;(indent-guide-global-mode)

rust cargo

  (use-package cargo)

maven support

  (use-package mvn)

multiple-cursors

  (use-package multiple-cursors)

  (define-prefix-command '*multiple-cursors-map*)
  (define-key *multiple-cursors-map* (kbd "a") 'mc/mark-all-like-this)
  (define-key *multiple-cursors-map* (kbd "A") 'mc/vertical-align)
  (define-key *multiple-cursors-map* (kbd "SPC") 'mc/vertical-align-with-space)
  (define-key *multiple-cursors-map* (kbd "n") 'mc/insert-numbers)

  (defhydra mc-interactive (*multiple-cursors-map* "i")
    "For those looping commands"
    ("n" mc/mark-next-like-this)
    ("p" mc/mark-previous-like-this)
    ("s" mc/skip-to-next-like-this)
    ("S" mc/skip-to-previous-like-this)
    ("q" nil))

  (global-set-key (kbd "C-c m") '*multiple-cursors-map*)

Setup-dev-environment

  (defun setup-devenv ()
    (interactive)
    (flycheck-list-errors)
    (treemacs)
    (dap-ui-locals)
    (when (y-or-n-p "Enter lsp? ")
      (lsp)))

skeletor project templates

  (use-package skeletor)

  (skeletor-define-template "java-maven"
    :title "Java with Maven")

Erlang

  (use-package erlang)

  (add-to-list 'load-path
               "~/.emacs.d/submodule/erlang_ls/")

  (setq lsp-erlang-server-install-dir "~/.emacs.d/submodule/erlang_ls")

  (defun my/erlang-keymap-hook ()
    (local-set-key (kbd "C-c C-c") 'erlang-compile))

  (add-hook 'erlang-mode-hook 'my/erlang-keymap-hook)

Spaces

  (setq default-tab-width 4)
  (setq-default indent-tabs-mode nil)
  (setq-default tab-width 4)

New

Youtube-dl

  (add-to-list 'load-path "~/.emacs.d/submodule/youtube-dl-emacs/")
  (require 'youtube-dl)

  (defun youtube-dl-song (url)
    (interactive
     (list (read-from-minibuffer
            "URL: " (or (thing-at-point 'url)
                        (when interprogram-paste-function
                          (funcall interprogram-paste-function))))))
    (async-shell-command (format "youtube-dl -x -f \"bestaudio[ext=m4a]\" \"%s\"; tageditor -s album=\"youtube-dl\" -f *.m4a" url)))

pdf-tools use isearch

  (use-package pdf-tools)
  (pdf-tools-install)
  (define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)
  (define-key pdf-view-mode-map (kbd "d") (lambda () (interactive) (pdf-view-next-line-or-next-page 8)))
  (define-key pdf-view-mode-map (kbd "u") (lambda () (interactive) (pdf-view-previous-line-or-previous-page 8)))

Time to game!

  (defvar my/games '("desmume" "mednaffe" "dolphin-emu" "m64py" "citra-qt" "steam " "th12"))

  (defun time-to-game ()
    (interactive)
    (let ((selection (completing-read "What would you like to play? "
                                      my/games)))
      (launch-program selection)))

Winner Mode

  (require 'winner)
  (winner-mode)

Skewer Mode (web development)

  (use-package js2-mode)
  (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
  (use-package skewer-mode)
  (add-hook 'js2-mode-hook 'skewer-mode)
  (add-hook 'css-mode-hook 'skewer-css-mode)
  (add-hook 'html-mode-hook 'skewer-html-mode)

ediff

  (setq ediff-window-setup-function 'ediff-setup-windows-plain)

Scroll interval

  (setq scroll-margin 1
        hscroll-margin 2
        hscroll-step 1
        scroll-conservatively 101
        scroll-preserve-screen-position t
        mouse-wheel-scroll-amount '(3)
        mouse-wheel-progressive-speed nil)

AUR PKGBUILD

  (use-package pkgbuild-mode)

Eyebrowse

  (use-package eyebrowse
    :init (setq eyebrowse-keymap-prefix (kbd "C-c w"))
    :config
    (eyebrowse-mode)
    (global-set-key (kbd "C->") 'eyebrowse-next-window-config)
    (global-set-key (kbd "C-<") 'eyebrowse-prev-window-config))

Writing mode

  (defun org-writing-mode ()
    (interactive)
    (setq org-bullets-bullet-list (quote ("  ")))
    (buffer-face-set '(:family "ETBookOT")))

re-builder specify read method

  (require 're-builder)
  (setq reb-re-syntax 'string)

scrollkeeper

  (use-package scrollkeeper)
  (global-set-key (kbd "C-v") 'scrollkeeper-down)
  (global-set-key (kbd "M-v") 'scrollkeeper-up)

set-default-directory

  (defun set-default-directory (dir)
    (interactive "f")
    (setq default-directory dir))

World time include Taiwan

  ;; (("America/Los_Angeles" "Seattle")
  ;;  ("America/New_York" "New York")
  ;;  ("Europe/London" "London")
  ;;  ("Europe/Paris" "Paris")
  ;;  ("Asia/Calcutta" "Bangalore")
  ;;  ("Asia/Tokyo" "Tokyo"))
  (setq display-time-world-list
        '(("America/Chicago" "Houston")
          ("Asia/Taipei" "Taiwan")))

arch-linux

  (use-package arch-packer)

Compile java run test

  (defun compile-java ()
    (interactive)
    (let ((fname (file-name-nondirectory buffer-file-name)))
    (shell-command (format "javac %s" fname))
    (message (shell-command-to-string (format "java %s" (substring fname 0 (- (length fname) 5)))))))

  (global-set-key (kbd "C-<f1>") 'compile-java)

ansi-term colors

  (setq ansi-color-names-vector
  ["black" "red3" "green3" "yellow3" "DodgerBlue2" "magenta3" "cyan3" "gray90"])

expand-region

  (use-package expand-region)
  (global-set-key (kbd "C-'") 'er/expand-region)

wtf

  (use-package wtf)

auto-save files in same directory

  (setq backup-directory-alist `(("." . "~/.emacs.d/backups/")))
  (setq backup-by-copying t)

csv-mode

  (use-package csv-mode)

kdeconnect

  (use-package kdeconnect)
  (setq kdeconnect-devices "ddcc003536dcf16d")
  (setq kdeconnect-active-device "ddcc003536dcf16d")

Purpose-mode

   (use-package window-purpose)
   (add-to-list 'purpose-user-mode-purposes '(exwm-mode . research))
   (add-to-list 'purpose-user-mode-purposes '(js2-mode . dev))
   (purpose-compile-user-configuration)
   (purpose-mode)

erc

  (use-package erc)
  (use-package erc-hl-nicks)
  (use-package erc-colorize)
  (require 'netrc)
  (erc-hl-nicks-mode)
  (erc-colorize-mode)
  (setq erc-user-full-name "Benson Chu")
  (setq erc-kill-buffer-on-part t)
  (setq erc-autojoin-channels-alist
        '(("freenode.net" "#emacs" "#org-mode"
           ;; "##linux" "#compilers" "#pltclub" 
           ;; "##cs" "##computerscience" "##programming" "#lisp" "##lisp"
           ;; "#sbcl" "#ecl"
           )))

  (defun get-authinfo (host port)
    (let* ((netrc (netrc-parse (expand-file-name "~/.emacs.d/secrets/.authinfo.gpg")))
           (hostentry (netrc-machine netrc host port)))
      (when hostentry (netrc-get hostentry "password"))))

  (defun freenode-connect (nick password)
    (erc :server "irc.freenode.net" :port 6667
         :password password :nick nick))

  (defun irc-connect ()
    (interactive)
    (when (y-or-n-p "Connect to IRC? ")
      (freenode-connect "pest-ctrl" (get-authinfo "irc.freenode.net" "6667"))))

posting sourc code

  (use-package webpaste)

  (setq webpaste-paste-confirmation t)
  (setq webpaste-provider-priority '("ix.io"))

eosd

  ;; (add-to-list 'load-path 
  ;;              "~/.emacs.d/submodule/eosd")
  ;; (require 'eosd)

helpful

  (use-package helpful)
  (global-set-key (kbd "C-h f") #'helpful-function)
  (global-set-key (kbd "C-h v") #'helpful-variable)
  (global-set-key (kbd "C-h k") #'helpful-key)

ediff snippet

  (defun ediff-copy-both-to-C ()
    (interactive)
    (ediff-copy-diff ediff-current-difference nil 'C nil
                     (concat
                      (ediff-get-region-contents ediff-current-difference 'A ediff-control-buffer)
                      (ediff-get-region-contents ediff-current-difference 'B ediff-control-buffer))))
  (defun add-d-to-ediff-mode-map () (define-key ediff-mode-map "d" 'ediff-copy-both-to-C))
  (add-hook 'ediff-keymap-setup-hook 'add-d-to-ediff-mode-map)

leetcode

  (use-package ctable)
  (use-package names)
  (add-to-list 'load-path
               "~/.emacs.d/submodule/leetcode-emacs")

  (require 'leetcode)

  (setq leetcode-path "~/MEGA/personal/programming_problems/Leetcode"
        leetcode-language "java")

freezing time

  (defvar my/frozen-time nil)

  (defvar my/format-time-string-function nil)

  (defun my/current-time ()
    my/frozen-time)

  (defun my/format-time-string (original format-string &optional time zone)
    (apply original
           format-string
           (if time
               time
             my/frozen-time)
           zone))

  (defun my/decode-time (original &optional time zone)
    (apply original
           (if time
               time
             my/frozen-time)
           zone))

  ;; Change and freeze time
  (defun za-warudo ()
    "Freeze `current-time' at the current active or inactive timestamp. If point
  is not on a timestamp, the function prompts for one. If time is not specified,
  either by the timstamp under point or prompt, the time defaults to the
  current HH:MM of today at the selected date."
    (interactive)
    (let* ((org-read-date-prefer-future nil)
           (time (org-read-date t 'totime nil "Input freeze time: ")))
      (setq my/frozen-time (append time '(0 0)))
      (advice-add #'current-time :override #'my/current-time)
      (advice-add #'format-time-string :around #'my/format-time-string)
      (advice-add #'decode-time :around #'my/decode-time)
      (set-face-background 'fringe "firebrick2")
      (message "Toki yo tomare")))

  (define-key *root-map* (kbd "C-z") 'za-warudo)

  ;; Release changed / frozen time
  (defun un-za-warudo ()
    "Release the time frozen by `freeze-time'."
    (interactive)
    (advice-remove #'current-time #'my/current-time)
    (advice-remove #'format-time-string #'my/format-time-string)
    (advice-remove #'decode-time #'my/decode-time)
    (setq my/frozen-time nil)
    (set-face-background 'fringe nil)
    (message "Soshite, toki wa ugoki dasu"))

  (define-key *root-map* (kbd "C-r") 'un-za-warudo)

Ace-window

  (use-package ace-window)
  (defhydra window-management-hydra (*root-map* "C-w")
    "Manage window splits"
    ("2" split-window-below)
    ("3" split-window-right)
    ("h" windmove-left)
    ("j" windmove-down)
    ("k" windmove-up)
    ("l" windmove-right)
    ("+" enlarge-window-horizontally)
    ("-" shrink-window-horizontally)
    ("M-+" enlarge-window)
    ("M--" shrink-window)
    ("x" delete-window)
    ("q" nil))

function to set tabwith

  (defun my/TABS (num)
    (interactive "p")
    (setq tab-width (if (= num 1)
                        8
                      num)))

bookmark+

  (add-to-list 'load-path
               "~/.emacs.d/submodule/bookmark-plus")

  (require 'bookmark+)

Custom bookmarks location

      (bookmark-load "~/.emacs.d/my-bookmarks")

      (defun my/bookmark-set (&optional name no-overwrite)
        (interactive (list nil current-prefix-arg))
        (bookmark-set name no-overwrite)
        (let* ((buffer (find-file-noselect "~/.emacs.d/my-bookmarks"))
               (bookmark (car bookmark-alist))
               (bookmark-name (car bookmark))
               (bookmark-file (and (buffer-file-name)
                                   (file-name-nondirectory (buffer-file-name)))))
          (with-current-buffer buffer
            (goto-char (point-min))
            (when (not (or (save-excursion (re-search-forward bookmark-name))
                           (and bookmark-file
                                (save-excursion (re-search-forward bookmark-file)))))
              (re-search-forward "(")
              (insert (pp bookmark))
              (save-buffer)
              (kill-buffer)))))

      ;; (global-set-key (kbd "C-x r m") #'my/bookmark-set)

Subtitles editing

  (add-to-list 'load-path "~/.emacs.d/submodule/subed/subed")

  (require 'subed)

  ;; Disable automatic movement of point by default
  (add-hook 'subed-mode-hook 'subed-disable-sync-point-to-player)
  ;; Break lines automatically while typing
  (add-hook 'subed-mode-hook 'turn-on-auto-fill)
  ;; Break lines at 50 characters
  (add-hook 'subed-mode-hook (lambda () (setq-local fill-column 50)))

docker

  (use-package docker)
  (global-set-key (kbd "C-x C-d") #'docker)

compilation buffer in same window

  ;; (add-to-list 'display-buffer-alist
  ;;              '("\\*compilation\\*" (display-buffer-reuse-window . display-buffer-same-window) ))

  (add-to-list 'same-window-buffer-names "*compilation*")

  ;; (setq display-buffer-alist (remove-if (lambda (x) (string= "\\*compilation\\*" (car x))) display-buffer-alist))

compilation scroll

  (setq compilation-scroll-output t)

google-it with qutebrowser

  (require 'url-util)

  (defun my/google-it ()
    (interactive)
    (let* ((resp (read-from-minibuffer "What is your query? "))
           (cleaned-resp (url-hexify-string resp)))
      (launch-program (format "qutebrowser \"https://google.com/search?q=%s\"" cleaned-resp))))

  (define-key *root-map* (kbd "g") #'my/google-it)

256-color   fix

  (use-package eterm-256color)
  (add-hook 'term-mode-hook #'eterm-256color-mode)

read only buffers in view-mode

  (setq view-read-only t)

hyperbole

  (use-package hyperbole)

  ;; I don't care about smart scrolling in org mode, unless I actually do

  (defun my/smart-scroll-up (old)
    (if (eq major-mode 'org-mode)
        (org-meta-return)
      (funcall old)))

  (advice-add #'smart-scroll-up
              :around
              #'my/smart-scroll-up)

Go to work

  (defvar my/working nil)

  (defvar my/dev-agenda nil)

  (defun toggle-working ()
    (interactive)
    (setq my/working (not my/working))
    (cond (my/working
           (define-key *firefox-map* (kbd "f") nil)
           (setq my/dev-agenda (assoc "d" org-agenda-custom-commands))
           (setq org-agenda-custom-commands
                 (delq (assoc "d" org-agenda-custom-commands)
                       org-agenda-custom-commands))
           (message "Back to work!"))
          ((not my/working)
           (define-key *firefox-map* (kbd "f") (quickrun-lambda "firefox" "firefox"))
           (add-to-list 'org-agenda-custom-commands my/dev-agenda)
           (message "Break time!"))))

  (global-set-key (kbd "s-w") #'toggle-working)

magit-todos

 (use-package magit-todos)

wgrep

  (use-package wgrep)

Use cider's display result

  (autoload 'cider--make-result-overlay "cider-overlays")

  (defun endless/eval-overlay (value point)
    (cider--make-result-overlay (format "%S" value)
      :where point
      :duration 'command)
    ;; Preserve the return value.
    value)

  (advice-add 'eval-region :around
              (lambda (f beg end &rest r)
                (endless/eval-overlay
                 (apply f beg end r)
                 end)))

  (advice-add 'eval-last-sexp :filter-return
              (lambda (r)
                (endless/eval-overlay r (point))))

  (advice-add 'eval-defun :filter-return
              (lambda (r)
                (endless/eval-overlay
                 r
                 (save-excursion
                   (end-of-defun)
                   (point)))))

centaur tabs

 (use-package centaur-tabs)

solaire-mode

 (use-package solaire-mode)

Hydra's don't show your faces

  (add-to-list 'hydra-props-alist
               '(exwm-background/window-transparency-hydra :verbosity 0))

  (add-to-list 'hydra-props-alist
               '(clementine-volume-hydra :verbosity 0))

tramp things

  (use-package docker-tramp)
  (use-package tramp-hdfs)

CASA Schedule

  (defvar my/schedule "https://uofh-my.sharepoint.com/:x:/g/personal/nsingh29_cougarnet_uh_edu/ERfp7g_6FbFAsxIlV0YP1goB9iXnUcTm__kTvakvXmvcvQ?rtime=-JcPFVIj10g")

  (defun my/view-casa-schedule ()
    (interactive)
    (funcall browse-url-browser-function my/schedule))

Credit Card Statement Macro

  (fset 'credit_card_statement
     [?\M-x ?o ?r ?g ?- ?m ?o ?d ?e return ?\M-x ?q backspace ?r ?e ?p ?l ?a ?c ?e ?- ?r ?e ?g ?e ?x ?p return ?^ ?\C-q tab return ?  ?  ?  ?  return ?\M-< ?\C-  ?\C-f ?\C-f ?\C-f ?\C-f ?\C-c ?m ?a ?\C-w ?- ?  ?\[ ?  ?\] ?  ?\C-e ?\C-k ?\C-c ?m ?  ?\C-q tab ?\C-q tab ?\C-e ?\C-j ?y ?\C-a ?_ ?_ ?_ ?_ backspace backspace backspace backspace ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?\C-p ?\C-p ?\C-k ?\C-c ?m ?  ?\C-q tab ?\C-q tab ?\C-d ?\C-d return ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n])

Vivaldi

  (defun browse-url-vivaldi (url &optional new-window)
    (interactive (browse-url-interactive-arg "URL: "))
    (setq url (browse-url-encode-url url))
    (let* ((process-environment (browse-url-process-environment)))
      (apply 'start-process
             (concat "vivaldi " url) nil
             "vivaldi-stable"
             (list url))))

  (setq browse-url-browser-function #'browse-url-firefox)

Magit Push All

  (defun my/magit-push-all ()
    "Push all branches."
    (interactive)
    (magit-run-git-async "push" "-v"
                         (magit-read-remote "Remote")
                         "--all"))

  (transient-append-suffix 'magit-push "m"
    '("a" "all remotes" my/magit-push-all))
  ;; (transient-remove-suffix 'magit-push '(1 1))
  ;; (transient-get-suffix 'magit-push "m")

New stuff, lost to git stupidity

  (defun my/query-replace-rx (&rest _)
    "Call `query-replace-regexp', reading regexp in `rx' syntax.
  Automatically wraps in parens and adds `seq' to the beginning of
  the form."
    (interactive)
    (cl-letf (((symbol-function #'query-replace-read-from) (lambda (&rest _)
                                                             (--> (read-string "rx form: ")
                                                                  (concat "'(seq " it ")")
                                                                  (read it)
                                                                  (cadr it)
                                                                  (rx-to-string it)))))
      (call-interactively #'query-replace-regexp)))

Profiler Keymap

  (define-prefix-command '*profiler-map*)

  (define-key *profiler-map* (kbd "s") #'profiler-start)
  (define-key *profiler-map* (kbd "r") #'profiler-report)
  (define-key *profiler-map* (kbd "S") #'profiler-stop)

  (define-key *root-map* (kbd "p") '*profiler-map*)

Slime mode

  (use-package slime)
  (use-package slime-company)

  (add-hook 'lisp-mode-hook #'slime-mode)
  (add-hook 'inferior-lisp-mode-hook #'inferior-slime-mode)

  (setq inferior-lisp-program "/usr/bin/sbcl")

  (let ((clhs-file "~/quicklisp/clhs-use-local.el"))
    (if (file-exists-p clhs-file)
        (load-file clhs-file)
      (warn "clhs not installed. Please install")))

  (slime-setup '(slime-fancy slime-asdf slime-company))

new etzy

  (load-file "~/.emacs.d/my-etzy.el")

Google Translate

  (use-package google-translate)

ivy-posframe

  (use-package ivy-posframe)
  ;; (setq ivy-posframe-parameters '((parent-frame t)))
  ;; Different command can use different display function.
  (setq ivy-posframe-display-functions-alist
        '((swiper          . nil)
          (complete-symbol . ivy-posframe-display-at-point)
          (t               . ivy-posframe-display-at-window-top-center)))
  (ivy-posframe-mode 1)

  (defun disable-ivy-posframe-on-exwm-windows (orig &rest args)
    (if (not (eq major-mode 'exwm-mode))
        (apply orig args)
      (letf (((symbol-function 'display-graphic-p) (lambda (&optional display) nil)))
        (apply orig args))))

  (advice-add #'ivy-posframe--read
              :around
              #'disable-ivy-posframe-on-exwm-windows)


  (defun ivy-posframe-display-at-window-top-center (str)
    (ivy-posframe--display str #'posframe-poshandler-window-top-center))

  (defun posframe-poshandler-window-top-center (info)
    "Posframe's position handler.

    Get a position which let posframe stay onto current window's
    center.  The structure of INFO can be found in docstring
    of `posframe-show'."
    (let* ((frame-width (plist-get info :parent-frame-width))
           (window-left (plist-get info :parent-window-left))
           (window-top (plist-get info :parent-window-top))
           (window-width (plist-get info :parent-window-width))
           (posframe-width (plist-get info :posframe-width)))
      (cons (+ window-left (/ (- window-width posframe-width) 2))
            (+ window-top 50))))

  (use-package ivy-rich)
  (ivy-rich-mode 1)

Setup convenient headers

  (setq auto-insert-alist
        '(((emacs-lisp-mode . "Emacs lisp mode") nil
           ";;; " (file-name-nondirectory buffer-file-name) " --- " _ " -*- lexical-binding: t -*-\n\n"

           ";; Copyright (C) " (format-time-string "%Y") " Benson Chu\n\n"

           ";; Author: Benson Chu <bensonchu457@gmail.com>\n"
           ";; Created: " (format-time-string "[%Y-%m-%d %H:%M]") "\n\n"

           ";; This file is not part of GNU Emacs\n\n"

           ";; This program is free software: you can redistribute it and/or modify\n"
           ";; it under the terms of the GNU General Public License as published by\n"
           ";; the Free Software Foundation, either version 3 of the License, or\n"
           ";; (at your option) any later version.\n\n"

           ";; This program is distributed in the hope that it will be useful,\n"
           ";; but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
           ";; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
           ";; GNU General Public License for more details.\n\n"

           ";; You should have received a copy of the GNU General Public License\n"
           ";; along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n"

           ";;; Commentary:\n\n"

           ";;; Code:\n\n"

           "(provide '" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) ")\n"
           ";;; " (file-name-nondirectory buffer-file-name) " ends here\n")
          ((lisp-mode . "Common Lisp") nil
           "(defpackage :" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) "\n"
           "  (:use :cl :alexandria)\n"
           "  (:export))\n\n"

           "(in-package :" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) ")")))

  (auto-insert-mode)

read-identifier too slow

  (add-to-list 'xref-prompt-for-identifier
               'xref-find-references
               'append)

workgroups2

  ;; (use-package workgroups2)

  ;; (setq wg-prefix-key (kbd "C-c z"))

  ;; (setq wg-session-file "~/.emacs.d/.emacs_workgroups")

  (require 'ivy-window-configurations)

  (define-key *root-map* (kbd "b") #'iwc-switch-to-wc)
  (define-key *root-map* (kbd "R") #'iwc-rename)

  (iwc-mode)
  ;; (define-key *root-map* (kbd "u") #'wg-undo-wconfig-change)
  ;; (define-key *root-map* (kbd "q") #'wg-kill-workgroup)
  ;; (define-key *root-map* (kbd "Q") #'wg-delete-other-workgroups)

  ;; (setq wg-emacs-exit-save-behavior nil
  ;;       wg-workgroups-mode-exit-save-behavior nil)


  ;; ;; Advice for frames, don't switch to an active workgroup
  ;; (defun get-active-workgroups ()
  ;;   (loop for frame in exwm-workspace--list
  ;;         unless (eq (selected-frame) frame)
  ;;         collect (with-selected-frame frame
  ;;                   (wg-workgroup-name (wg-current-workgroup)))))

  ;; (defun wg-dont-switch-to-active (orig &optional workgroup noerror)
  ;;   (interactive)
  ;;   (if workgroup
  ;;       (funcall orig workgroup noerror)
  ;;     (let ((active (get-active-workgroups))
  ;;           (to-switch (wg-read-workgroup-name)))
  ;;       (if (member to-switch active)
  ;;           (message "Workgroup \"%s\" already active" to-switch)
  ;;         (funcall orig to-switch noerror)))))

  ;; (advice-add #'wg-switch-to-workgroup
  ;;             :around
  ;;             #'wg-dont-switch-to-active)

opml to elfeed-org

  (defun convert-opml-feed-to-org-mode ()
    (interactive)
    (goto-char (point-min))
    (save-excursion 
      (perform-replace "><" ">\n<" nil nil nil nil))
    (save-excursion
      (keep-lines "\\(?:^<outline text=\"\\([^\"]+?\\)\" title=\"\\1\" type=\"rss\" xmlUrl=\"\\([^\"]+?\\)\" />\\)"))
    (perform-replace "\\(?:^<outline text=\"\\([^\"]+?\\)\" title=\"\\1\" type=\"rss\" xmlUrl=\"\\([^\"]+?\\)\" />\\)"
                     "*** [[\\2][\\1]]" nil t nil))

  (defun delete-org-headings ()
    (interactive)
    (goto-char (point-min))
    (let ((lines '()))
      (while (and (outline-next-heading)
                  (not (eobp)))
        (let ((heading (org-get-heading t t t t)))
          (if (not (member heading lines))
              (push heading lines)
            (org-cut-subtree)
            (outline-previous-heading))))))

Broken

Wunderlist

     (use-package org-wunderlist)

     (save-excursion
       (let ((filename "~/.emacs.d/wunderlist.el"))
         (if (not (file-exists-p filename))
             (message "Wunderlist secret file missing")
           (set-buffer (find-file-noselect filename))
           (let ((var (eval (read (buffer-string)))))
             (setq org-wunderlist-client-id (car var)
                   org-wunderlist-token (cadr var)))
           (kill-buffer))))

     (setq org-wunderlist-file  "~/MEGA/org/agenda/Wunderlist.org"
           org-wunderlist-dir "~/MEGA/org/agenda/org-wunderlist/")

poshint

   (use-package pophint)

buffer-time-tracking   fix

  (use-package switch-buffer-functions)
  ;;(load "switch-buffer-functions-autoloads.el")
  (defun my/insert-into-buffers-csv (str str2 symb str3)
    (let* ((buffer (find-file-noselect "~/MEGA/org/agenda/buffer_times.csv"))
          (inhibit-message t))
      (with-current-buffer buffer
        (goto-char (point-max))
        (insert (format-time-string "%Y-%m-%d %H:%M:%S" (current-time)))
        (insert "," str "," (if str2 str2 "") "," str3 "," (if symb (symbol-name symb) ""))
        (insert "\n")
        (save-buffer))))

  (defun my/record-buffer-switch (prev cur)
    (let* (obuffer-name buffer-name buffer-fname buffer-mode buffer-def-dir)
      (with-current-buffer cur
        (setq buffer-name (buffer-name)
              buffer-fname (buffer-file-name)
              buffer-mode major-mode
              buffer-def-dir default-directory))
      (when (buffer-live-p prev)
        (with-current-buffer prev
          (setq obuffer-name (buffer-name))))
      (when (and (not (string= buffer-name " *Minibuf-1*"))
                 ;; (or (not obuffer-name) (not (string= obuffer-name " *Minibuf-1*")))
                 )
        (my/insert-into-buffers-csv buffer-name buffer-fname buffer-mode buffer-def-dir))))

  ;; (add-hook 'switch-buffer-functions
  ;;           'my/record-buffer-switch)

  (defun leaving-computer ()
    (interactive)
    (my/insert-into-buffers-csv "Inactive" "" nil "")
    (org-clock-out nil t)
    (message "Computer is now inactive!"))

Disabled

nnreddit

 (use-package nnredit "~/.emacs.d/nnreddit/nnreddit.el")
 (add-to-list 'gnus-secondary-select-methods '(nnreddit ""))

xwidget

   (define-key xwidget-webkit-mode-map [mouse-4] 'xwidget-webkit-scroll-down)
   (define-key xwidget-webkit-mode-map [mouse-5] 'xwidget-webkit-scroll-up)

i3wm interaction

  (use-package i3wm)
  (defun insert-mode ()
    (interactive)
    (i3wm-command "mode insert"))
  (global-set-key (kbd "M-\"") 'insert-mode)

Cyberpunk Theme

 (load-theme 'cyberpunk t)
(use-package moe-theme)
(moe-dark)
(powerline-moe-theme)

Wanderlust

(autoload 'wl "wl" "Wanderlust" t)

linum

 (use-package linum)
 (linum-relative-global-mode)
 (setq linum-relative-current-symbol "")

 ;(setq linum-format 
 ;  (lambda (line) 
 ;    (propertize (format (let ((w (length (number-to-string (count-lines (point-min) (point-max))))))
 ;                          (concat "%" (number-to-string w) "d ")) 
 ;              line) 
 ;      'face 
 ;      'linum)))

 ;(setq linum-relative-format "%3s\u2502 ")

CTD Minor Mode

Keybinding

    (use-package multi-term)
    (define-minor-mode ctd-mode
    "This is the mode for the CoderTillDeath"
    :init-value t
    :lighter " ctd"
    :keymap (let ((map (make-sparse-keymap)))
          (define-key map (kbd "M-e") 'launch-program)
          (define-key map (kbd "C-x p") 'launch-program)
          (define-key map (kbd "M-`") 'multi-term)
          (define-key map (kbd "M-1") 'windresize)
          map))
      (ctd-mode 1)

Precedence

 (add-hook 'after-load-functions 'ctd-mode-priority)

 (defun ctd-mode-priority (_file)
   "Try to ensure that my keybindings retain priority over other minor modes.

 Called via the `after-load-functions' special hook."
   (unless (eq (caar minor-mode-map-alist) 'ctd-mode)
     (let ((mykeys (assq 'ctd-mode minor-mode-map-alist)))
       (assq-delete-all 'ctd-mode minor-mode-map-alist)
       (add-to-list 'minor-mode-map-alist mykeys))))

Screw delete

     (global-set-key (kbd "C-d") 'delete-backward-char)
     (global-set-key (kbd "M-d") 'backward-kill-word)

Custom Journal Attempt 1

(defvar yearly-theme "Insight")

  (defun insert-time-stamp ()
    (insert "** "
            (format-time-string "%A, %x")))

  (defun current-date-exists? () 
    (save-excursion
      (let ((match (re-search-forward (format-time-string "\\(* %A, %x\\)")
                                      nil t)))
        (match-beginning 1))))

  (defun add-date () 
    (search-forward "* Journal")
    (beginning-of-line)
    (org-narrow-to-subtree)
    (let ((point (current-date-exists?)))
      (if point
          (goto-char point)
        (goto-char (point-max))
        (insert-time-stamp)))
    (widen))

  (defun add-weekly-journal-entry () 
    (add-date))

  (defun org-capture-function ()
    (unless (file-exists-p "~/MEGA/org/entries/review/current.org")
      (create-weekly-review-file))
    (set-buffer (org-capture-target-buffer "~/MEGA/org/entries/review/current.org"))
    (let ((m (point-marker)))
      (set-buffer (marker-buffer m))
      (org-capture-put-target-region-and-position)
      (widen)
      (goto-char m)
      (set-marker m nil)
      (add-weekly-journal-entry)))

  (defun create-weekly-review-file ()
    (save-excursion
      (let ((entry-path "~/MEGA/org/entries/review/current.org"))
        (find-file-other-window entry-path)
        (insert (format "#+TITLE: Year of %s, week %s\n\n"
                        yearly-theme
                        (format-time-string "%V"))
                "* Log\n"
                "* Journal\n")
        (save-buffer)
        (kill-buffer))))

  (defun weekly-review ()
    (interactive)
    (let ((entry-path "~/MEGA/org/entries/review/current.org"))
      (find-file entry-path)
      (goto-char (point-max))
      (insert "\n* Review\n")))

  (defun wr/done ()
    (interactive)
    (save-buffer)
    (kill-buffer)
    (unless (file-directory-p (format-time-string "~/MEGA/org/entries/review/%Y"))
      (make-directory (format-time-string "~/MEGA/org/entries/review/%Y")))
    (rename-file "~/MEGA/org/entries/review/current.org" 
                 (format-time-string "~/MEGA/org/entries/review/%Y/Year of Insight, Week %V.org")
                 t)
    (create-weekly-review-file))

Custom Journal Attempt 2

  (defvar yearly-theme "Surpass")

  (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 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)
        (org-shiftmetaleft)
        (setq string (concat string "\n" (buffer-string)))
        (org-shiftmetaright)
        (widen))))
    (not-modified)
    (kill-buffer))
      string))

  (defun generate-view-between (start-date end-date)
    (let ((start-date (or start-date
              (org-read-date)))
      (end-date (or end-date
            (org-read-date)))
      (org-agenda-skip-archived-trees nil))
      (get-buffer-create "review.org")
      (switch-to-buffer "review.org")
      (org-mode)
      (insert (format "#+Title of %s, Week %s\n\n"
              yearly-theme
              (format-time-string "%V")))
      (insert "* Log\n")
      (insert (get-tasks-from start-date end-date))
      (insert "\n* Journal"))
      (insert (get-journal-entries-from start-date end-date))
      (when (> (funcall outline-level) 1) (outline-up-heading 2))
      (org-cycle)
      (org-cycle)
      (goto-char (point-max)))

  (defun generate-view-from ()
    (interactive)
    (let ((date (org-read-date)))
      (generate-view-between date
                 (org-read-date nil nil ""))))

  (defun generate-weekly-view () 
    (interactive)
    (let ((start-date (org-read-date nil nil "-1w"))
      (end-date (org-read-date nil nil "")))
      (generate-view-between start-date end-date)))

  (defun weekly-review ()
    (interactive)
    (generate-weekly-view)
    (goto-char (point-max))
    (insert "\n* Review\n"))

  (defun offday-review ()
    (interactive)
    (generate-view-from)
    (goto-char (point-max))
    (insert "\n* Review\n"))

  (defun wr/done ()
    (interactive)
    (write-file (concat "~/MEGA/org/entries/review/"
            (format-time-string "%Y/")
            (format "Year of %s, Week "
                yearly-theme)
            (format-time-string "%V")
            ".org"))
    (kill-buffer))

  (defun view-reports ()
    (interactive)
    (dired (format-time-string "~/MEGA/org/entries/review/%Y/")))

Norang Projects code

     (require 'org-habit)

     (defun bh/find-project-task ()
       "Move point to the parent (project) task if any"
       (save-restriction
         (widen)
         (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point))))
           (while (org-up-heading-safe)
             (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
               (setq parent-task (point))))
           (goto-char parent-task)
           parent-task)))

     (defun bh/is-project-p ()
       "Any task with a todo keyword subtask"
       (or (equal (org-get-todo-state) "PROJECT")
           (save-restriction
             (widen)
             (let ((subtree-end (save-excursion (org-end-of-subtree t)))
                   (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))
                   has-subtask has-task)
               (save-excursion
                 (forward-line 1)
                 (while (and (not has-subtask)
                             (< (point) subtree-end)
                             (re-search-forward "^\*+ " subtree-end t))
                   (when (member (org-get-todo-state) org-todo-keywords-1)
                     (setq has-subtask t)
                     (when (not (equal (org-get-todo-state) "DONE"))
                       (setq has-task t)))))
               (and is-a-task (or has-task
                                  (and has-subtask
                                       (equal "TODO"
                                              (org-get-todo-state)))))))))

     (defun bh/is-project-subtree-p ()
       "Any task with a todo keyword that is in a project subtree.
      Callers of this function already widen the buffer view."
       (let ((task (save-excursion (org-back-to-heading 'invisible-ok)
                                   (point))))
         (save-excursion
           (bh/find-project-task)
           (if (equal (point) task)
               nil
             t))))

     (defun bh/is-task-p ()
       "Any task with a todo keyword and no subtask"
       (save-restriction
         (widen)
         (let ((has-subtask)
               (subtree-end (save-excursion (org-end-of-subtree t)))
               (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
           (save-excursion
             (forward-line 1)
             (while (and (not has-subtask)
                         (< (point) subtree-end)
                         (re-search-forward "^\*+ " subtree-end t))
               (when (member (org-get-todo-state) org-todo-keywords-1)
                 (setq has-subtask t))))
           (and is-a-task (or (equal (org-get-todo-state)
                                     "ONE")
                              (not has-subtask))))))

     (defun my/is-standalone-task-p ()
       (and (my/is-a-task)
            (not (bh/is-subproject-p))))

     (defun bh/is-next-task-p ()
       (and (bh/is-task-p)
            (or (equal (org-get-todo-state)
                       "NEXT")
                (and (equal (org-get-todo-state)
                            "TODO")
                     (or (org-get-scheduled-time (point))
                         (org-get-deadline-time (point)))))))

     (defun bh/is-subproject-p ()
       "Any task which is a subtask of another project"
       (let ((is-subproject)
             (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
         (save-excursion
           (while (and (not is-subproject) (org-up-heading-safe))
             (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
               (setq is-subproject t))))
         (and is-a-task is-subproject)))

     (defvar memoized-stuck-function nil
       "DO NOT SETQ. Use in agenda views")

     (defun my/make-memoized-stuck-projects ()
       (memoize (lambda (point)
                  (message "Hello, world!")
                  (my/is-stuck-project-p))))

     (defun my/is-stuck-project-p ()
       (let ((subtree-end (save-excursion (org-end-of-subtree t)))
             has-next
             has-stuck-project)
         (save-restriction
           (save-excursion 
             (while (and (or (not has-next)
                             (not has-stuck-project))
                         (outline-next-heading)
                         (< (point) subtree-end))
               (cond ((and (bh/is-project-p)
                           (my/is-stuck-project-p))
                      (setq has-stuck-project t))
                     ((or (bh/is-next-task-p)
                          (equal (org-get-todo-state) "WAIT"))
                      (setq has-next t))))))
         (and (bh/is-project-p)
              (or (not has-next)
                  has-stuck-project))))


     (defun my/is-inactive-project-p ()
       (let (has-next
             has-stuck-project)
         (and (bh/is-project-p)
              (or (not (member (org-get-todo-state)
                               '("TASK" "PROJECT" "TODO")))
                  (org-time> (org-entry-get (point) "SCHEDULED") "<now>")))))

     (defun my/is-delayed-project-p ()
        (and (bh/is-project-p)
             (org-entry-get (point) "SCHEDULED")
             (org-time> (org-entry-get (point) "SCHEDULED") "<now>")))

     (defun my/is-ignored-project ()
       ;; Need to finish
       )

     (defun my/is-active-project-p ()
       ;; Need to finish
       )

     (defun bh/list-sublevels-for-projects-indented ()
       "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
        This is normally used by skipping functions where this variable is already local to the agenda."
       (if (marker-buffer org-agenda-restrict-begin)
           (setq org-tags-match-list-sublevels 'indented)
         (setq org-tags-match-list-sublevels nil))
       nil)

     (defun bh/list-sublevels-for-projects ()
       "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
        This is normally used by skipping functions where this variable is already local to the agenda."
       (if (marker-buffer org-agenda-restrict-begin)
           (setq org-tags-match-list-sublevels t)
         (setq org-tags-match-list-sublevels nil))
       nil)

     (defvar bh/hide-scheduled-and-waiting-next-tasks t)

     (defun bh/toggle-next-task-display ()
       (interactive)
       (setq bh/hide-scheduled-and-waiting-next-tasks (not bh/hide-scheduled-and-waiting-next-tasks))
       (when  (equal major-mode 'org-agenda-mode)
         (org-agenda-redo))
       (message "%s WAITING and SCHEDULED NEXT Tasks" (if bh/hide-scheduled-and-waiting-next-tasks "Hide" "Show")))

     (defun bh/skip-stuck-projects ()
       "Skip trees that are not stuck projects"
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
           (when (my/is-stuck-project-p)
             next-headline))))

     (defun my/show-stuck-projects ()
       "Only show subtrees that are stuck projects"
       ;; (bh/list-sublevels-for-projects-indented)
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
               (subtree-end (save-excursion (org-end-of-subtree t))))
           (cond ((my/is-inactive-project-p)
                   subtree-end)
                  ((not (my/is-stuck-project-p))
                   next-headline)))))

     (defun my/show-inactive-projects ()
       "Only show subtrees that are stuck projects"
       ;; (bh/list-sublevels-for-projects-indented)
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
               (subtree-end (save-excursion (org-end-of-subtree t))))
           (unless (my/is-inactive-project-p)
                   subtree-end))))

     (defun my/show-delayed-projects ()
       "Only show subtrees that are stuck projects"
       ;; (bh/list-sublevels-for-projects-indented)
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
               (subtree-end (save-excursion (org-end-of-subtree t))))
           (unless (my/is-delayed-project-p)
                   subtree-end))))

     (defun bh/show-active-projects ()
       "Skip trees that are not projects"
       ;; (bh/list-sublevels-for-projects-indented)
       (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
         (unless (and (bh/is-project-p)
                      (not (my/is-stuck-project-p)))
             next-headline)))

     (defun bh/skip-non-tasks ()
       "Show non-project tasks.
      Skip project and sub-project tasks, habits, and project related tasks."
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
           (cond
            ((bh/is-task-p)
             nil)
            (t
             next-headline)))))

     (defun bh/skip-project-trees-and-habits ()
       "Skip trees that are projects"
       (save-restriction
         (widen)
         (let ((subtree-end (save-excursion (org-end-of-subtree t))))
           (cond
            ((bh/is-project-p)
             subtree-end)
            ((org-is-habit-p)
             subtree-end)
            (t
             nil)))))

     (defun bh/skip-projects-and-habits-and-single-tasks ()
       "Skip trees that are projects, tasks that are habits, single non-project tasks"
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
           (cond
            ((org-is-habit-p)
             next-headline)
            ((and bh/hide-scheduled-and-waiting-next-tasks
                  (member "WAITING" (org-get-tags-at)))
             next-headline)
            ((bh/is-project-p)
             next-headline)
            ((and (bh/is-task-p) (not (bh/is-project-subtree-p)))
             next-headline)
            (t
             nil)))))

     (defun my/only-next-projects-and-tasks ()
       (save-restriction
         (widen)
         (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
           (cond
            ((org-is-habit-p)
             next-headline)
            ((and bh/hide-scheduled-and-waiting-next-tasks
                  (member "WAITING" (org-get-tags-at)))
             next-headline)
            ((bh/is-project-p)
             next-headline)
            (t (unless (or (bh/is-next-task-p)
                           (my/is-standalone-task-p))
                 next-headline))))))

     (defun bh/skip-project-tasks-maybe ()
       "Show tasks related to the current restriction.
      When restricted to a project, skip project and sub project tasks, habits, NEXT tasks, and loose tasks.
      When not restricted, skip project and sub-project tasks, habits, and project related tasks."
       (save-restriction
         (widen)
         (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
                (next-headline (save-excursion (or (outline-next-heading) (point-max))))
                (limit-to-project (marker-buffer org-agenda-restrict-begin)))
           (cond
            ((bh/is-project-p)
             next-headline)
            ((org-is-habit-p)
             subtree-end)
            ((and (not limit-to-project)
                  (bh/is-project-subtree-p))
             subtree-end)
            ((and limit-to-project
                  (bh/is-project-subtree-p)
                  (member (org-get-todo-state) (list "NEXT")))
             subtree-end)
            (t
             nil)))))

     (defun bh/show-non-project-tasks ()
       "Show non-project tasks.
      Skip project and sub-project tasks, habits, and project related tasks."
       (save-restriction
         (widen)
         (let* ((subtree-end (save-excursion (org-end-of-subtree t))))
           (cond
            ((bh/is-project-p)
             subtree-end)
            ((org-is-habit-p)
             subtree-end)
            ((bh/is-project-subtree-p)
             subtree-end)
            (t
             nil)))))

     (defun bh/skip-non-project-tasks ()
       "Show project tasks.
      Skip project and sub-project tasks, habits, and loose non-project tasks."
       (save-restriction
         (widen)
         (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
                (next-headline (save-excursion (or (outline-next-heading) (point-max)))))
           (cond
            ((bh/is-project-p)
             next-headline)
            ((org-is-habit-p)
             subtree-end)
            ((and (bh/is-project-subtree-p)
                  (member (org-get-todo-state) (list "NEXT")))
             subtree-end)
            ((not (bh/is-project-subtree-p))
             subtree-end)
            (t
             nil)))))

     (defun bh/skip-projects-and-habits ()
       "Skip trees that are projects and tasks that are habits"
       (save-restriction
         (widen)
         (let ((subtree-end (save-excursion (org-end-of-subtree t))))
           (cond
            ((bh/is-project-p)
             subtree-end)
            ((org-is-habit-p)
             subtree-end)
            (t
             nil)))))

     (defun bh/skip-non-subprojects ()
       "Skip trees that are not projects"
       (let ((next-headline (save-excursion (outline-next-heading))))
         (if (bh/is-subproject-p)
             nil
           next-headline)))


     (defun bh/widen ()
       (interactive)
       (if (equal major-mode 'org-agenda-mode)
           (progn
             (org-agenda-remove-restriction-lock)
             (when org-agenda-sticky
               (org-agenda-redo)))
         (widen)))