mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-02-16 16:24:18 +00:00
61 KiB
61 KiB
Emacs Configuration
- Enable lexical binding
- Bugs
- custom-tangle
- Neo keyboard issues
- Emacs
- Look and feel
- Navigation
- Tools
- New
- Time to game!
- Winner Mode
- Skewer Mode (web development)
- AUR PKGBUILD
- Eyebrowse
- Writing mode
- arch-linux
- Compile java run test
- wtf
- kdeconnect
- Purpose-mode
- eosd
- leetcode
- Ace-window
- function to set tabwith
- bookmark+
- Custom bookmarks location
- Subtitles editing
- docker
- compilation buffer in same window
- compilation scroll
- google-it with qutebrowser
- 256-color
- read only buffers in view-mode
- hyperbole
- Go to work
- centaur tabs
- solaire-mode
- tramp things
- CASA Schedule
- Vivaldi
- Google Translate
- read-identifier too slow
- workgroups2
- opml to elfeed-org
- Broken
- Disabled
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
Reload Config
(defun reload-config () (interactive) (load-file "~/.emacs.d/init.el"))
which-key
(use-package which-key)
(setq which-key-idle-delay 3)
(which-key-mode)
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)
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
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-face-attribute 'default nil :family "RobotoMono" :weight 'normal)
(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))
Navigation
Helm & counsel/ivy
(use-package helm)
(require 'helm-config)
;; (helm-mode 1)
;; (setq ivy-initial-inputs-alist nil)
(use-package smex)
(use-package counsel)
;; (advice-add 'ivy-completion-in-region :before (lambda (start end collection &optional predicate) (insert " ")))
;; (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)
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-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-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))
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")
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)
New
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)
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")))
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)
wtf
(use-package wtf)
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)
eosd
;; (add-to-list 'load-path
;; "~/.emacs.d/submodule/eosd")
;; (require 'eosd)
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")
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)
centaur tabs
(use-package centaur-tabs)
solaire-mode
(use-package solaire-mode)
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))
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)
Google Translate
(use-package google-translate)
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)))