aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Okay <colin@cicadas.surf>2022-07-05 08:46:39 -0500
committerColin Okay <colin@cicadas.surf>2022-07-05 08:46:39 -0500
commit76bb19a31986dc22188d0224e4b0929e776409f4 (patch)
treeadadd39d7aabe27ce21256652efdc5f84087319b
initial commit
-rw-r--r--init-el.org1927
1 files changed, 1927 insertions, 0 deletions
diff --git a/init-el.org b/init-el.org
new file mode 100644
index 0000000..1cb35a8
--- /dev/null
+++ b/init-el.org
@@ -0,0 +1,1927 @@
+#+auto_tangle: t
+
+* About This Tangle
+
+** Customize This Tangle
+
+ Set these variable src blocks before tangling. When these are set,
+ simply type =C-c C-v t= to build your emacs config.
+
+ Set this to configure [[Configuring offlineimap][offlineimap]] correctly. It should be your email
+ password.
+
+#+name: emailpw
+#+begin_src conf
+PUTSOMETHINGHERE
+#+end_src
+
+** Tags used in this file
+
+ - =prereq= indicates that this involves installing something on the
+ underlying system, and is not part of the tangle
+
+ - =disabled= indicates that the name of the code block under this
+ heading has been disabled. I perform this disabling by commenting
+ out the name of the block so that the tangle operation does
+ nothing when encountering it. Some blocks are a pain to run
+ everytime I want to tangle this file, so by marking them as
+ disabled I can easily see the blocks that might need to be
+ enabled on a fresh emacs install.
+
+So, to use this file for the very first time you must
+
+1) run the code tagged prereq, then
+2) fill in the [[*Customize This Tangle][customize]] section, above, then
+3) enable the disabled sections (by uncommenting the code blocks they contain)
+4) then run the tangle.
+
+
+* init.el
+
+ This section generates the init.el file in the .emacs.d
+ directory. Emacs reads this file on startup.
+
+ Because init.el is generated afresh whenever =org-babel-tangle= is
+ called, and because the default behavior of emacs is to
+ programmatically place customizations at the end of the init.el
+ file, it is prudent to set a =custom-file= location explicitly.
+
+ After setting custom file, emacs is configured. Because many other
+ configuration options depend on properly configured packages, the
+ packages are setup first. After that, the order of the setup
+ operations is more or less insignificant.
+
+#+begin_src elisp :tangle ~/.emacs.d/init.el :noweb yes :results none
+;;;; init.el
+
+;;;; DO NOT EDIT: This file has been generated by org-babel-tangle
+;;;; from a source file called init-el.org.
+
+(setq custom-file (concat user-emacs-directory "custom.el"))
+(load custom-file 'noerror)
+
+<<packages-setup-config>>
+<<org-mode-configuration>>
+<<my-leader-keys-config>>
+<<ui-config>>
+<<communications-config>>
+<<time-management-config>>
+<<reading-notes-and-writing-config>>
+<<software-development-config>>
+<<bells-and-whistles>>
+<<overwrites>>
+#+end_src
+
+** Packages Setup Config
+
+#+name: packages-setup-config
+#+begin_src elisp :results none
+;; PACKAGES SETUP
+(require 'cl)
+
+(defun my-package-install (package &optional dont-select)
+ (package-install package dont-select))
+
+(require 'package)
+(add-to-list 'package-archives
+ '("melpa" . "https://melpa.org/packages/") t)
+(add-to-list 'package-archives
+ '("elpa" . "https://elpa.gnu.org/packages/") t)
+(package-initialize)
+(package-refresh-contents)
+
+(package-install 'use-package)
+#+end_src
+
+** Org Mode and Babel Configuration
+
+
+#+name: org-mode-configuration
+#+begin_src elisp :results none
+
+(package-install 'org)
+(setq org-duration-format 'h:mm)
+
+(setq org-edit-src-content-indentation 0)
+
+(package-install 'graphviz-dot-mode)
+(package-install 'ob-haxe)
+
+(add-hook 'org-mode-hook
+ (lambda () (org-toggle-inline-images)))
+
+(org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((emacs-lisp . t)
+ (lisp . t)
+ (haxe . t)
+ (dot . t)
+ (C . t)
+ (shell . t)))
+
+(add-to-list 'org-src-lang-modes
+ '("dot" . graphviz-dot))
+
+#+end_src
+
+* Leader Keys
+
+#+name: my-leader-keys-config
+#+begin_src elisp :noweb yes :results none
+<<my-leader-key-system>>
+<<my-leader-key-toplevel-menu>>
+<<my-leader-key-major-mode-menu>>
+<<my-leader-key-applications-menu>>
+#+end_src
+
+
+
+ I have written a custom leader key system called "my-leader-keys". A
+ leader key system emulates menus. An initial key (M-m for me) opens
+ the top level menu. The menu presents a key to press that either leads
+ to the next menu or run a specific interative function.
+
+ It all starts with the =def-my-command= macro, which associates a key
+ to a menu of commands. Each 'command' is just an interactive function.
+
+** My Leader Keys Definition
+
+ #+name: my-leader-key-system
+ #+begin_src elisp :results none
+ ;; Leader Keys System
+
+ (setq lexical-binding t)
+
+ (defmacro def-my-command (name forms)
+ `(defun ,name (ch)
+ (interactive (let ((input (read-char (my-prompt-string ,forms))))
+ (list input)))
+ (let ((command (assoc ch ,forms)))
+ (when command
+ (call-interactively (caddr command))))))
+
+ ;; a helper function for navigating command menus
+ (defun my-prompt-string (&optional forms)
+ (concat "Options: "
+ (mapconcat 'identity
+ (mapcar #'cadr
+ (if forms forms *my-leader-command-forms*))
+ ", ")))
+
+ #+end_src
+
+** My Leader Key Toplevel Menu
+
+ The leader key system wouldn't be much good without a top-level leader
+ key. Here the inital leader key menu is defined and bound to M-m.
+
+#+name: my-leader-key-toplevel-menu
+#+begin_src elisp :results none
+;; Leader Key Entry Point
+
+(setq imenu-auto-rescan t)
+
+(def-my-command my-leader-command
+ '((?/ "[/] search buffer" swiper)
+ (?q "[q]uery replace" query-replace)
+ (?i "[i]menu" imenu)
+ (?' "['] shell" persp-shell--jump-to-persp-shell)
+ (?b "[b]uffers" my-buffer-command)
+ (?c "[c]apture" org-capture)
+ (?a "[a]applications" my-utilities-command)
+ (?t "[t]hemes" my-theme-cycler)
+ (?l "[l]ayouts" my-perspective-command)
+ (?w "[w]indows" my-window-comand)
+ (?p "[p]rojectile" my-projectile-command)
+ (?m "[m]ajor mode" my-major-mode-command)
+ (?f "[f]ind file" find-file)
+ (?s "[s]lime selection" my-lisp-switch-command)
+ (?z "[z]ettel" my-zettel-subcommand)
+ ))
+
+
+(global-set-key (kbd "M-m") 'my-leader-command)
+#+end_src
+
+
+** My leader Key Major Mode Menu
+
+#+name: my-leader-key-major-mode-menu
+#+begin_src elisp :results none
+(defvar my-major-mode-list nil "subcommands by major-mode")
+(setf my-major-mode-list
+ '(;(haxe-mode my-haxe-mode-command)
+ (org-mode my-org-command)
+ (zettel-mode my-zettel-mode-command)
+ (slime-repl-mode my-lisp-mode-command)
+ (pdf-view-mode my-pdf-view-mod-command)
+ (lisp-mode my-lisp-mode-command)))
+
+
+(defun my-major-mode-command ()
+ (interactive)
+ (let ((mode-command (assoc major-mode my-major-mode-list)))
+ (when mode-command
+ (call-interactively (cadr mode-command)))))
+
+#+end_src
+
+** My leader key utilities and applications menu
+
+#+name: my-leader-key-applications-menu
+#+begin_src elisp :results none
+
+(def-my-command my-utilities-command
+ '((?o "org clock [o]ut" org-clock-out)
+ (?r "org [r]esume last" org-clock-in-last)
+ (?c "[c]alendar" cfw:open-org-calendar)
+ (?a "[a]genda" org-agenda)
+ (?b "[b]ooks" calibredb)
+ (?d "[d]eft" toggle-deft)
+ (?f "el[f]eed" elfeed)
+ (?j "[j]ournal" toggle-journal)
+ (?s "[s]ecrets" toggle-secrets)
+ (?p "[p]astebin" cicadas-paste-current-buffer)))
+#+end_src
+
+
+
+* UI
+
+#+name: ui-config
+#+begin_src elisp :noweb yes :results none
+;;; UI
+<<ui-chrome-config>>
+<<ui-modeline-config>>
+<<ui-tweaks-config>>
+<<ui-fonts-config>>
+<<ui-bells-and-wistles>>
+
+<<ui-completion-engine>>
+<<ui-windows-and-perspectives>>
+<<ui-themes>>
+<<ui-org-mode-tweaks>>
+#+end_src
+
+** UI Chrome
+
+ I like for my emacs to have as little UI chrome as possible, and to
+ have a consistent UI experience. So I disable the blinking cursor, I
+ set cursor type to 'box by default, and I disable menu, tool, and
+ scroll bars.
+
+ #+name: ui-chrome-config
+ #+begin_src elisp :results none
+ ;; UI Chrome
+
+ (blink-cursor-mode 0)
+ (setq-default cursor-type 'box)
+ (menu-bar-mode 0)
+ (tool-bar-mode 0)
+ (scroll-bar-mode -1)
+ (toggle-frame-fullscreen)
+
+
+ (defun transparency (value)
+ "Sets the transparency of the frame window. 0=transparent/100=opaque"
+ (interactive (let* ((prompt (concat "Transparency Value 0 - 100 opaque ["
+ (prin1-to-string (frame-parameter (selected-frame) 'alpha))
+ "]:"))
+ (input (read-number prompt)))
+ (list input)))
+ (set-frame-parameter (selected-frame) 'alpha value))
+
+ #+end_src
+
+** Modeline Config
+
+#+name: ui-modeline-config
+#+begin_src elisp :results none
+(package-install 'doom-modeline)
+(require 'doom-modeline)
+(doom-modeline-mode 1)
+#+end_src
+** Tweaks
+
+ Bits and bobs.
+
+ I globally unset the C-z keybinding because it is easy to hit by
+ accident and causes the window to suddenly close.
+
+ In addition, for some programming langauges, tabs should not be used
+ to perform indtentation of source code. To ensure that no indentation
+ does not, by default, use tabs, I set indent-tabs-mode to nil.
+
+#+name: ui-tweaks-config
+#+begin_src elisp :results none
+(global-unset-key "\C-z")
+(setq-default indent-tabs-mode nil)
+(global-hl-line-mode 1)
+
+
+#+end_src
+
+** Fonts Config
+
+ I use Victor Mono for most coding work, and Linux Libertine for my
+ variable pitch font. Variable pitch fonts are good for e.g. reading
+ the web using =eww= and writing in distraction-free mode with
+ =writeroom=.
+
+ Fonts must generally be installed. Linux libertine came preinstalled
+ with my Debian system (running Gnome 3), but Victor Mono had to be
+ installed manually. I downloaded it from [[https://rubjo.github.io/victor-mono/][here]] and then installed it
+ using the =font-manager= application.
+
+ Running these two commands should install the font.
+
+
+ : sudo apt install font-manager
+ : font-manager -i ~/Downlaods/VictorMonoAll.zip
+
+ #+name: ui-fonts-config
+ #+begin_src elisp :results none
+ ;; FONTS
+
+ (add-to-list 'default-frame-alist
+ '(font . "Victor Mono-10"))
+
+ (set-face-attribute 'variable-pitch nil
+ :family "Linux Libertine"
+ :height 1.25)
+
+ #+end_src
+
+** Bells and Whistles
+
+#+name: ui-bells-and-wistles
+#+begin_src elisp :results none
+(package-install 'org-superstar)
+(require 'org-superstar)
+(add-hook 'org-mode-hook (lambda ()
+ (org-superstar-mode 1)
+ (visual-line-mode)))
+
+#+end_src
+
+** My Leader Keys
+
+** Completions Engine
+
+#+name: ui-completion-engine
+#+begin_src elisp :results none
+(package-install 'ivy)
+(package-install 'smex)
+(package-install 'swiper)
+(ivy-mode 1)
+(setq ivy-use-selectable-prompt t)
+(smex-initialize)
+(global-set-key (kbd "M-x") 'smex)
+
+#+end_src
+
+** Buffers, Windows, and Perspectives
+
+#+name: ui-windows-and-perspectives
+#+begin_src elisp :noweb yes :results none
+
+<<ui-windows-and-perspectives-packages>>
+<<ui-window-leader-key-menu>>
+<<ui-buffer-leader-key-menu>>
+<<ui-perspectives-leader-key-menu>>
+
+#+end_src
+
+*** Packages
+
+#+name: ui-windows-and-perspectives-packages
+#+begin_src elisp :results none
+ (package-install 'perspective)
+ (persp-mode)
+
+ (package-install 'rotate)
+
+ (package-install 'window-numbering)
+ (window-numbering-mode)
+
+ (package-install 'resize-window)
+ (require 'resize-window)
+#+end_src
+*** Window Leader Key Menu
+
+#+name: ui-window-leader-key-menu
+#+begin_src elisp :results none
+
+
+(setq fit-window-to-buffer-horizontally t)
+
+(defun my-fit-window-to-buffer ()
+ (interactive)
+ (fit-window-to-buffer)
+ (resize-window--enlarge-horizontally))
+
+(def-my-command my-window-comand
+ '((?/ "[/] vertical splitter" split-window-horizontally)
+ (?- "[-] horoziontal splitter" split-window-vertically)
+ (?b "[b]alance windows" balance-windows)
+ (?t "[t]ransparency" transparency)
+ (?k "[k]ill window" delete-window)
+ (?m "[m]aximise window" delete-other-windows)
+ (?R "[R]otate window" rotate-window)
+ (?r "[r]esize widnows" resize-window)
+ (?f "[f]it window" my-fit-window-to-buffer)
+ (?p "font [p]itch shift" variable-pitch-mode)
+ (?v "[v]isual line mode" visual-line-mode)
+ (?w "[w]riteroom mode" writeroom-mode)))
+#+end_src
+*** Buffer Leader Key Menu
+
+#+name: ui-buffer-leader-key-menu
+#+begin_src elisp :results none
+
+(def-my-command my-buffer-command
+ '((?b "switch [b]uffers" ivy-switch-buffer)
+ (?s "[s]ave buffer" save-buffer)
+ (?S "[S]ave all buffers" save-some-buffers)
+ (?k "[k]ill buffer" kill-buffer)))
+
+
+#+end_src
+
+*** Perspectives Leader Key Menu
+
+#+name: ui-perspectives-leader-key-menu
+#+begin_src elisp :results none
+(def-my-command my-perspective-command
+ '((?s "[s]witch perspective" persp-switch)
+ (?k "[k]ill perspective" persp-kill)
+ (?d "[d]rop buffer" persp-remove-buffer)
+ (?n "re[n]ame perspective" persp-rename)
+ (?a "[a]dd buffer" persp-add-buffer)))
+#+end_src
+
+** Themes
+
+#+name: ui-themes
+#+begin_src elisp :noweb yes :results none
+<<ui-themes-installed>>
+<<ui-themes-theme-switcher>>
+#+end_src
+
+*** Installed Themes
+
+#+name: ui-themes-installed
+#+begin_src elisp :results none
+
+(package-install 'autothemer) ;; for custom themes
+
+(setq my-installed-themes
+ '(dracula-theme
+ zenburn-theme
+ moe-theme
+ notink-theme
+ punpun-theme
+ solo-jazz-theme
+ tao-theme
+ yoshi-theme
+ srcery-theme
+ subatomic-theme
+ chocolate-theme
+ poet-theme
+ white-sand-theme
+ foggy-night-theme))
+
+(dolist (package my-installed-themes)
+ (when (not (package-installed-p package))
+ (package-install package)))
+
+;; starting theme
+(load-theme 'dracula t)
+
+#+end_src
+
+*** Theme Switcher
+
+#+name: ui-themes-theme-switcher
+#+begin_src elisp :results none
+
+(setq *my-themes*
+ '(punpun-light
+ white-sand
+ leuven
+ solo-jazz
+ tao-yang
+ notink
+ zenburn
+ subatomic
+ foggy-night
+ chocolate
+ dracula
+ halloweenie ;; <-- ONLY DURING OCTOBER
+ yoshi
+ srcery
+ tao-yin
+ punpun-dark))
+
+
+(defun my-theme-string ()
+ (if (car custom-enabled-themes)
+ (format "%s is current" (car custom-enabled-themes))
+ ""))
+
+(defun my-theme-cycler ()
+ (interactive)
+ (let ((still-cycling t))
+ (message (format "%s [n]ext or [p]evious. Anything else to quit."
+ (my-theme-string)))
+ (while still-cycling
+ (let ((char (read-key)))
+ (cond
+ ((eq char ?n) (my-theme-command-next))
+ ((eq char ?p) (my-theme-command-previous))
+ (t (setq still-cycling nil))))
+ (message (format "%s [n]ext or [p]evious. Anything else to quit."
+ (my-theme-string))))))
+
+(defun my-theme-command-next ()
+ (interactive)
+ (let* ((active-theme (car custom-enabled-themes))
+ (next-theme (cadr (cl-member active-theme *my-themes*))))
+ (when active-theme (disable-theme active-theme))
+ (if next-theme (load-theme next-theme t)
+ (load-theme (car *my-themes*) t))
+ (setq cursor-type 'box)
+ (setq-default cursor-type 'box)))
+
+(defun my-theme-command-previous ()
+ (interactive)
+ (let* ((active-theme (car custom-enabled-themes))
+ (themes (reverse *my-themes*))
+ (next-theme (cadr (cl-member active-theme themes))))
+ (when active-theme (disable-theme active-theme))
+ (if next-theme (load-theme next-theme t)
+ (load-theme (car themes) t))
+ (setq cursor-type 'box)
+ (setq-default cursor-type 'box)))
+
+#+end_src
+
+*** Halloweenie
+
+#+name: halloweenie
+#+begin_src elisp :tangle ~/.emacs.d/halloweenie-theme.el
+;; halloweenie - a Halloween emacs color theme.
+;; Copyright (C) 2021 Colin Okay
+;;
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;; INSTALL by dropping the file at
+;;
+;; http://cicadas.surf/pastebin/halloweenie-theme.el
+;;
+;; into your ~/.emacs.d/ directory before running
+;; M-x load-theme, and typing halloweenie
+;;
+;; Spooky times all.
+
+
+(require 'autothemer)
+
+(autothemer-deftheme
+ halloweenie "Ghost, Ghouls, and worst of all: Pumpkin Spice"
+ ((((class color) (min-colors #xFFFFFF)))
+
+ (halloweenie-pitch "#1c1c1c")
+ (halloweenie-night "#1f213a")
+ (halloweenie-blood "#a2270d")
+ (halloweenie-potion "#832ea1")
+ (halloweenie-slime "#15ed0a")
+ (halloweenie-jackolantern "#FF9430")
+ (halloweenie-spellglow "#d478e0")
+ (halloweenie-bone "#E8E7D5")
+ (halloweenie-rot "#6Bc980")
+ (halloweenie-ghost "#C1CAE8")
+ (halloweenie-shine "#70c2ca")
+ (halloweenie-cateyes "#ffde38")
+ (halloweenie-evileyes "#FF1F1F"))
+
+ (
+ (default (:foreground halloweenie-bone :background halloweenie-pitch) :weight 'semi-bold)
+ (error (:foreground halloweenie-evileyes :weight 'semi-bold))
+ (cursor (:background halloweenie-slime))
+ (region (:background "black"))
+ (hl-line (:background halloweenie-night))
+ (link (:background halloweenie-potion))
+ (mode-line (:background halloweenie-jackolantern :foreground halloweenie-pitch))
+ (mode-line-emphasis (:foreground halloweenie-pitch :weight 'bold))
+ (font-lock-comment-face (:foreground halloweenie-slime))
+ (font-lock-string-face (:foreground halloweenie-rot))
+ (font-lock-type-face (:foreground halloweenie-cateyes :weight 'ultra-bold))
+ (font-lock-constant-face (:foreground halloweenie-evileyes :weight 'extra-bold))
+ (font-lock-variable-name-face ( :weight 'bold :foreground halloweenie-spellglow))
+
+ (font-lock-function-name-face (:foreground halloweenie-spellglow :weight 'bold :slant 'italic))
+ (font-lock-builtin-face (:foreground halloweenie-jackolantern :weight 'semi-bold))
+ (font-lock-keyword-face (:foreground halloweenie-jackolantern :weight 'extra-bold))
+
+ ;; org
+ (org-todo (:weight 'bold :foreground halloweenie-evileyes))
+ (org-done (:weight 'bold :foreground halloweenie-rot ))
+
+ ;; doom modeline
+
+ (doom-modeline-project-dir
+ (:foreground halloweenie-pitch :weight 'bold ))
+ (doom-modeline-project-root-dir
+ (:foreground halloweenie-blood :weight 'bold))
+
+ ;; persp
+
+ (persp-selected-face
+ (:foreground halloweenie-blood :weight 'bold :slant 'italic))))
+
+
+(provide-theme 'halloweenie)
+
+#+end_src
+
+** Org
+
+*** Org mode tweaks
+# #+name: ui-org-mode-tweaks
+ #+begin_src elisp :noweb yes :results none
+ (add-hook 'org-mode-hook
+ '(lambda ()
+ (mapc
+ (lambda (face) ;; Other fonts with fixed-pitch.
+ (set-face-attribute face nil :inherit 'fixed-pitch :height 100))
+ (list 'org-code
+ 'org-link
+ 'org-block
+ 'org-table
+ 'org-block-begin-line
+ 'org-block-end-line
+ 'org-meta-line
+ 'org-document-info-keyword))))
+
+
+ (setq org-adapt-indentation nil)
+
+ #+end_src
+
+* Communications
+
+#+name: communications-config
+#+begin_src elisp :noweb yes :results none
+<<erc-config>>
+<<cicadas-bepasty>>
+;;<<cicadas-scpaste>>
+;; <<mu4e-config>>
+#+end_src
+
+** ERC
+
+ ERC is an IRC client that is built into Emacs. You can use it to
+ log into irc servers and chat with other nerds. ERC is very
+ communicative about changes in status in a particular IRC channel
+ -- too informative. It prints messages everytime somebody joins or
+ leaves a room or quits the server altogether. This can be a bit
+ annoying - active rooms will often contain just as many join/part
+ messages as chat messages. So this little snippit configures ERC
+ to hide certain kinds of message:
+
+#+name: erc-config
+#+begin_src elisp :results none
+;;; ERC
+(setq erc-hide-list '("JOIN" "QUIT" "PART"))
+#+end_src
+
+** Cicadas Pastebin
+
+*** bepasty from emacs
+
+#+name: cicadas-bepasty
+#+begin_src elisp :noweb yes :results none
+
+(setq cicadas-paste-pw "3m4x_1uv3r")
+
+(defun cicadas-paste-current-buffer ()
+ (interactive)
+ (let ((tmpfile
+ (concat "/tmp/" (buffer-name))))
+ (write-region nil nil tmpfile)
+ (let ((url
+ (first (last (butlast
+ (split-string
+ (shell-command-to-string
+ (format "pastebinit -i %s -p %s -t '%s' -f text/plain"
+ tmpfile
+ cicadas-paste-pw
+ (buffer-name)))
+ "\n"))))))
+ (delete-file tmpfile)
+ (kill-new url)
+ (message "Pasted to %s (on kill ring)" url))))
+
+
+#+end_src
+
+*** SCPASTE :disabled:
+# #+name: cicadas-scpaste
+#+begin_src elisp :results none
+(package-install 'scpaste)
+
+(setq scpaste-http-destination "http://cicadas.surf/pastebin"
+ scpaste-scp-destination "colin@cicadas.surf:/srv/http/www.cicadas.surf/pastebin"
+ scpaste-user-name "Colin"
+ scpaste-user-address "https://hyperthings.garden")
+
+
+#+end_src
+
+** Mail on emacs
+
+*** Installing dependencies :prereq:
+
+ On debian 11, I was able to run this to install dependencies.
+
+#+begin_src bash
+sudo apt-get install -y libgmime-3.0-dev libxapian-dev \
+ mu4e guile-3.0-dev html2text xdg-utils offlineimap
+#+end_src
+
+
+*** Configuring offlineimap :disabled:
+
+ The blocks in this file are used to separately tangle to an ~/.offlineimparc
+
+ See the file at
+ /usr/share/doc/offlineimap3/examples/offlineimap.conf for more
+ info.
+
+# #+begin_src conf :tangle ~/.offlineimaprc :noweb yes :results none
+
+[general]
+
+accounts = Cicadas, ToyfulSpace
+
+[Account Cicadas]
+localrepository = CicadasLocal
+remoterepository = CicadasRemote
+
+[Repository CicadasLocal]
+type = Maildir
+localfolders = ~/Maildir/Cicadas
+
+[Repository CicadasRemote]
+type = IMAP
+remotehost = imap.migadu.com
+remoteuser = colin@cicadas.surf
+remotepass = <<emailpw>>
+ssl = yes
+sslcacertfile = /etc/ssl/certs/ca-certificates.crt
+
+
+[Account ToyfulSpace]
+localrepository = ToyfulSpaceLocal
+remoterepository = ToyfulSpaceRemote
+
+[Repository ToyfulSpaceLocal]
+type = Maildir
+localfolders = ~/Maildir/ToyfulSpace
+
+[Repository ToyfulSpaceRemote]
+type = IMAP
+remotehost = imap.migadu.com
+remoteuser = okay@toyful.space
+remotepass = <<emailpw>>
+ssl = yes
+sslcacertfile = /etc/ssl/certs/ca-certificates.crt
+
+
+#+end_src
+
+**** Setup Mu and Sync Initial Mails :setup:
+
+#+begin_src bash
+mu init --maildir=~/Maildir --my-address=colin@cicadas.surf --my-address=okay@toyful.space && \
+offlineimap -a Cicadas && offlineimap -a ToyfulSpace && \
+mu index
+#+end_src
+
+*** Confuguring Mu4e :disabled:
+
+# #+name: mu4e-config
+#+begin_src elisp :noweb yes :results none
+
+
+(require 'mu4e)
+
+<<mu4e-sendmail-config>>
+<<mu4e-fetch-and-sync-mail-config>>
+
+(setq mu4e-contexts
+ (list
+ <<cicadas-mu4e-context>>
+ <<toyfulspace-mu4e-context>>))
+
+;; For viewing patches in emails
+(package-install 'message-view-patch)
+(add-hook 'mu4e-view-mode-hook 'message-view-patch-highlight)
+
+#+end_src
+
+**** Mu4e Sendmail Config
+ #+name: mu4e-sendmail-config
+ #+begin_src elisp :results none
+ (require 'smtpmail)
+
+ (setq mail-user-agent 'mu4e-user-agent
+ message-send-mail-function 'smtpmail-send-it
+ smtpmail-stream-type 'tls
+ smtpmail-default-smtp-server "smtp.migadu.com"
+ smtpmail-smtp-server "smtp.migadu.com"
+ smtpmail-smtp-service 465)
+
+
+ #+end_src
+
+
+**** Mu4e mail sync command
+ #+name: mu4e-fetch-and-sync-mail-config
+ #+begin_src elisp :results none
+ (setq mu4e-get-mail-command "offlineimap -a Cicadas && offlineimap -a ToyfulSpace")
+ #+end_src
+
+**** Mu4e Contexts
+ #+name: cicadas-mu4e-context
+ #+begin_src elisp :results none
+
+ (make-mu4e-context
+ :name "Cicadas"
+ :enter-func (lambda () (mu4e-message "Entering Cicadas Context"))
+ :leave-func (lambda () (mu4e-message "Leaving Cicadas Context"))
+ :match-func (lambda (msg)
+ (when msg
+ (mu4e-message-contact-field-matches msg :to "colin@cicadas.surf")))
+ :vars '((user-full-name . "Colin Okay")
+ (user-mail-address . "colin@cicadas.surf")
+ (smtpmail-smtp-user . "colin@cicadas.surf")
+ (mu4e-sent-folder . "/Cicadas/Sent")
+ (mu4e-compose-signature . "Making Things Wiggle\nColin\n")))
+ #+end_src
+
+ #+name: toyfulspace-mu4e-context
+ #+begin_src elisp :results none
+
+ (make-mu4e-context
+ :name "Toyful Space"
+ :enter-func (lambda () (mu4e-message "Entering Toyful Space Context"))
+ :leave-func (lambda () (mu4e-message "Leaving Toyful Space Context"))
+ :match-func (lambda (msg)
+ (when msg
+ (mu4e-message-contact-field-matches msg :to "okay@toyful.space")))
+ :vars '((user-full-name . "Colin Okay")
+ (user-mail-address . "okay@toyful.space")
+ (smtpmail-smtp-user . "okay@toyful.space")
+ (mu4e-sent-folder . "/ToyfulSpace/Sent")
+ (mu4e-compose-signature . "Making Things Wiggle\nColin\n")))
+ #+end_src
+
+* Time Managment
+
+#+name: time-management-config
+#+begin_src elisp :noweb yes :results none
+;;; TIME MANAGMENT
+
+(setq org-enforce-todo-dependencies t
+ org-enforce-todo-checkbox-dependencies t)
+
+(setq org-edit-src-content-indentation 0)
+
+
+<<calfw-org-config>>
+<<org-refile-config>>
+<<org-capture-config>>
+<<org-agenda-config>>
+#+end_src
+
+
+** CALFW calendar
+
+#+name: calfw-org-config
+#+begin_src elisp :noweb yes :results none
+(package-install 'calfw)
+(package-install 'calfw-org)
+(require 'calfw)
+(require 'calfw-org)
+
+
+#+end_src
+
+** Org Refile
+
+#+name: org-refile-config
+#+begin_src elisp :results none
+(setq my-org-refile-directory "~/notes/deft/")
+
+(defun my-org-refile-targets ()
+ (loop for fname in (directory-files my-org-refile-directory)
+ when (string-match "\.org$" fname)
+ collect (concat my-org-refile-directory fname)))
+
+(setq org-refile-targets
+ '((my-org-refile-targets :maxlevel . 5)))
+#+end_src
+
+
+
+
+** Org Capture
+
+#+name:org-capture-config
+#+begin_src elisp :results none
+
+(setq org-capture-templates
+ (quote
+ (("i" "Inbox" entry
+ (file+headline "~/notes/deft/project-Planner.org" "INBOX")
+ "")
+ ("j" "Journal" entry
+ (file+olp+datetree "~/notes/circadian.org.cpt")
+ "")
+ ("c" "Calendar" entry
+ (file+headline "~/notes/deft/project-Planner.org" "CALENDAR")
+ "* %?\n %(cfw:org-capture-day)"))))
+
+;; ("i" "Inbox" entry
+;; (file "~/notes/deft/project-Inbox.org")
+;; "")
+#+end_src
+
+** Org Agenda
+
+#+name: org-agenda-config
+#+begin_src elisp :noweb yes :results none
+(custom-set-variables
+ '(org-directory "~/notes/deft")
+ '(org-agenda-files "~/notes/org-agenda-files"))
+
+(add-hook 'org-agenda-mode-hook
+ (lambda ()
+ (local-set-key (kbd "M-m") 'my-leader-command)))
+
+#+end_src
+
+
+* Reading, Notes, and Writing
+
+#+name: reading-notes-and-writing-config
+#+begin_src elisp :noweb yes :results none
+
+<<org-mode-leader-key-menu>>
+<<calibre-config>>
+<<pdf-tools>>
+<<pdf-mode-config>>
+<<nov-mode-config>>
+<<elfeed-config>>
+<<zettelgunk>>
+<<ccrypt>>
+<<toggler>>
+<<deft>>
+<<writeroom>>
+<<eww-config>>
+<<markdown-editing>>
+
+#+end_src
+
+** My-Leader Key for Org Major Mode
+#+name: org-mode-leader-key-menu
+#+begin_src elisp :results none
+(defun personal-log-insert ()
+ (interactive)
+ (org-insert-heading)
+ (delete-backward-char 1)
+ (insert "* ")
+ (insert (current-time-string)))
+
+(defun org-insert-internal-link (title)
+ (interactive "sHeading: ")
+ (insert "[[*")
+ (call-interactively 'complete-symbol)
+ (insert (format "][%s]]" title)))
+
+(defun org-insert-named-code-block (name lang)
+ (interactive "sName: \nsLanguage: ")
+ (insert "#+name: ")
+ (insert name)
+ (insert "\n")
+ (insert (format "#+begin_src %s :noweb yes\n\n#+end_src" lang)))
+
+(setq org-goto-interface 'outline-path-completion
+ org-goto-max-level 10
+ org-outline-path-complete-in-steps nil)
+
+(setq org-imenu-depth 10)
+
+(defun my-org-up-heading ()
+ (interactive)
+ (org-up-heading-safe))
+
+(defun my-org-down-heading ()
+ (interactive)
+ (org-down-element))
+
+(def-my-command my-org-command
+ '((?/ "[/] sparse tree" org-sparse-tree)
+ (?g "[g]oto" org-goto)
+ (?u "[u]p heading" my-org-up-heading)
+ (?d "[d]own heading" my-org-down-heading)
+ (?r "Org [r]efile" org-refile)
+ (?k "Org [k]ut" org-cut-special)
+ (?s "Org [s]ort" org-sort)
+ (?A "Org [A]rchive" org-archive-subtree)
+
+
+ (?i "[i]insertion" my-org-insertion-subcommand)
+ (?E "[E]xport" my-org-export-subcommand)
+
+ (?e "[e]dit a code block" org-edit-src-code)
+
+ (?n "[n]arrow" org-narrow-to-subtree)
+ (?w "[w]iden" widen)
+
+ (?I "[I]mages toggle" org-toggle-inline-images)
+
+ (?c "table re[c]alculate" org-table-recalculate)
+
+ (?C "[C]lock" my-org-clock-command)))
+
+
+(def-my-command my-org-clock-command
+ '((?c "[c]lock in" org-clock-in)
+ (?o "clock [o]ut" org-clock-out)
+ (?r "clock [r]eport" org-clock-report)))
+
+(def-my-command my-org-export-subcommand
+ '((?t "[t]angle file" org-babel-tangle)
+ (?e "[e]xport options" org-export-dispatch)))
+
+(def-my-command my-org-insertion-subcommand
+ '((?l "internal [l]ink" org-insert-internal-link)
+ (?L "external [L]ink" org-insert-link)
+ (?d "[d]ated log entry" personal-log-insert)
+ (?D "[D]eadline" org-deadline)
+ (?T "[T]imestamp" org-time-stamp)
+ (?f "[f]ootnote" org-footnote-new)
+ (?b "named code [b]lock" org-insert-named-code-block)
+ (?s "[s]tructure template" org-insert-structure-template)))
+
+#+end_src
+
+** Calibre db
+
+#+name: calibre-config
+#+begin_src elisp :results none
+
+ (package-install 'calibredb)
+
+ (require 'calibredb)
+ (setq calibredb-root-dir "~/Books")
+ (setq calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir))
+
+
+#+end_src
+
+** PDF tools for Reading and Annotating PDFS
+
+*** PDF Tools
+
+ #+name: pdf-tools
+ #+begin_src elisp :results none
+
+ (package-install 'pdf-tools)
+ (pdf-tools-install)
+
+ #+end_src
+
+
+*** Some functions to quickly annotate
+
+ #+name: pdf-mode-config
+ #+begin_src elisp :results none
+ (defun my-pdf-annot-at-position (pos)
+ "Return annotation at POS in the selected window.
+
+ POS should be an absolute image position as a cons \(X . Y\).
+ Alternatively POS may also be an event position, in which case
+ `posn-window' and `posn-object-x-y' is used to find the image
+ position.
+
+ Return nil, if no annotation was found."
+ (let (window)
+ (when (posnp pos)
+ (setq window (posn-window pos)
+ pos (posn-object-x-y pos)))
+ (save-selected-window
+ (when window (select-window window 'norecord))
+ (let* ((annots (pdf-annot-getannots (pdf-view-current-page)))
+ (size (pdf-view-image-size))
+ (rx (/ (car pos) (float (car size))))
+ (ry (/ (cdr pos) (float (cdr size))))
+ (rpos (cons rx ry)))
+ (cl-some (lambda (a)
+ (and (cl-some
+ (lambda (e)
+ (pdf-util-edges-inside-p e rpos))
+ (pdf-annot-get-display-edges a))
+ a))
+ annots)))))
+
+ (defun my-pdf-annot-add-text-annotation ()
+ (interactive)
+ (let ((annot
+ (or (my-pdf-annot-at-position '(0 . 0))
+ (pdf-annot-add-text-annotation '(0 . 0)))))
+ (pdf-annot-edit-contents annot)))
+
+ (def-my-command my-pdf-view-mod-command
+ '((?/ "[/] search pdf" pdf-occur)
+ (?l "[l]ist annotations" pdf-annot-list-annotations)
+ (?m "[m]idnight mode" pdf-view-midnight-minor-mode)
+ (?n "add [n]ote" my-pdf-annot-add-text-annotation)))
+
+ #+end_src
+
+
+
+** Nov for Reading EPUBs
+
+#+name: nov-mode-config
+#+begin_src elisp :results none
+
+(package-install 'nov)
+(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
+
+#+end_src
+
+** Elfeed for Reading RSS Feeds
+
+#+name: elfeed-config
+#+begin_src elisp :results none
+(package-install 'elfeed)
+(require 'elfeed)
+
+(setq elfeed-feeds
+ '(
+ ("https://pointersgonewild.com/feed/" frontpage blog programming)
+ ("https://blog.einval.com/index.rss" blog debian linux)
+ ("https://justinehsmith.substack.com/feed" blog newsletter frontpage)
+ ("https://paper.wf/boutade/feed/" blog newsletter frontpage)
+ ("https://rogersbacon.substack.com/feed" blog newsletter frontpage)
+ ("https://www.residentcontrarian.com/feed" blog newsletter frontpage)
+ ("https://learnui.design/blog/feed.xml" design blog ui webdev)
+ ("https://theconvivialsociety.substack.com/feed"
+ culture media blog newsletter frontpage technology)
+ ("https://mr.gy/blog/index.xml" blog frontpage)
+ ("https://knowablemagazine.org/rss" science blog culture frontpage)
+ ("https://stop.zona-m.net/feed.xml" blog linux yro floss)
+ ("https://blog.veitheller.de/feed.rss" blog)
+ ("https://existentialcomics.com/rss.xml" philosophy comic)
+ ("http://jacek.zlydach.pl/blog/feed.xml" blog lisp frontpage)
+ ("https://wingolog.org/feed/atom" blog frontpage)
+ ("https://www.unixsheikh.com/feed.rss" blog frontpage sysadmin)
+ ("https://ingrids.space/index.xml" blog frontpage)
+ ("https://ngnghm.github.io/feeds/all.rss.xml" lisp programming coolness frontpage)
+ ("https://computer.rip/rss.xml" frontpage)
+ ("http://waywardmonkeys.org/feeds/all.atom.xml" lisp frontpage)
+ ("https://www.sicpers.info/rss" frontpage)
+ ("https://manuelmoreale.com/feed" frontpage)
+ ("https://www.stephendiehl.com/feed.rss" frontpage)
+ ("https://www.raphkoster.com/feed/" frontpage gamedev)
+ ("https://surfingcomplexity.frontpage/feed/" frontpage dev)
+ ("https://fukamachi.hashnode.dev/rss.xml" lisp frontpage)
+ ("https://hyperthings.garden/feeds/colins-daily-log.xml" frontpage)
+ ("https://frontpage.ncase.me/rss" frontpage )
+ ("https://staticadventures.netlib.re/rss.xml" frontpage yro libre)
+ ("https://realcoopstories.org/index.xml" frontpage coops socialism)
+ ("https://mckinley.cc/frontpage/rss.xml" frontpage)
+ ("https://rusingh.com/feeds/" frontpage)
+ ("https://babbagefiles.xyz/posts/index.xml" frontpage lisp)
+ ("https://stumbles.id.au/feeds/all.atom.xml" frontpage guix)
+ ("https://stragu.gitlab.io/feed.xml" frontpage)
+ ("http://gamestudies.org/rss.php" journal gamedev)
+ ("https://www.attacus.net/feed.xml" tech yro)
+ ("https://frontpage.metaobject.com/feeds/posts/default" frontpage programming)
+ ("http://cowlark.com/feed.rss" frontpage retrocomputing)
+ ("https://sfconservancy.org/feeds/frontpage/" foss floss)
+ ("https://aeon.co/feed.rss" philosophy culture magazine frontpage)
+ ("http://malisper.me/category/postgres/feed/" frontpage lisp)
+ ("https://infovore.org/feed/" frontpage culture media)
+ ("https://adam.nels.onl/rss.xml" lisp frontpage)
+ ("https://funcall.frontpagespot.com/feeds/6629439843004430442/comments/default" frontpage lisp)
+ ("https://hkvim.com/rss.xml" emacs frontpage)
+ ("http://turtleware.eu/rss.xml" lisp frontpage)
+ ("https://hyperthings.garden/rss/all-posts.xml" frontpage)
+ ("https://spwhitton.name/frontpage/index.rss" lisp frontpage)
+ ("https://tymoon.eu/api/reader/atom" lisp frontpage gamedev)
+ ("https://hacks.mozilla.org/feed/" frontpage technology)
+ ("https://alliedmedia.tumblr.com/rss" media social)
+ ("https://frontpage.acolyer.org/feed/" academic computerscience)
+ ("https://frontpage.fourthbit.com/atom.xml" scheme programming)
+ ("http://ajroach42.com/feed.xml" frontpage smallinternet)
+ ("https://codeascraft.com/atom" dev web)
+ ("https://daily.jstor.org/feed/" science culture frontpage)
+ ("https://feeds.feedburner.com/GamasutraIndependentNews" games news)
+ ("https://feeds.feedburner.com/HypocriteReader" hypocritereader magazine culture)
+ ("https://feeds.feedburner.com/codinghorror" dev web)
+ ("https://feeds.feedburner.com/ieeespectrum/automaton" technology)
+ ("https://feeds2.feedburner.com/NoTechMagazine" magazine notech anarchism diy culture)
+ ("https://feeds2.feedburner.com/typepad/krisdedecker/lowtechmagazineenglish"
+ magazine diy culture)
+ ("https://harpers.org/feed/" harpers news culture frontpage)
+ ("https://haxe.org/frontpage/rss/" haxe programming)
+ ("https://kcpdchief.frontpagespot.com/feeds/posts/default" police kansascity)
+ ("https://markburgess.org/frontpage_feed.xml" cs science culture)
+ ("https://mkremins.github.io/atom.xml" programming hci)
+ ("https://nlpers.frontpagespot.com/feeds/posts/default" nlp)
+ ("https://prog21.dadgum.com/atom.xml" dev fp games)
+ ("https://publicdomainreview.org/feed/" culture frontpage )
+ ("https://smbc-comics.com/rss.php" comic)
+ ("https://www.allthingsdistributed.com/atom.xml" scalability devops)
+ ("https://www.comicsgrid.com/gateway/plugin/WebFeedGatewayPlugin/rss2/"
+ comics academic journal culture)
+ ("https://www.otaku-dad.com/rss.php" comic anime)
+ ("https://www.philosophybites.libsyn.com/rss" podcast philosophy)
+ ("https://www.viruscomix.com/rss.xml" comic)
+ ("https://www.whompcomic.com/feed/" comic)
+ ("http://feedproxy.google.com/brainpickings/rss" frontpage humanities)
+ ("http://retro-style.software-by-mabe.com/frontpage-atom-feed" lisp frontpage)
+ ;("http://rss.ngfiles.com/weeklytop10.xml" gamedev community dorkistry)
+ ("http://rss.slashdot.org/Slashdot/slashdotMain" news technology)
+ ("https://code.haxe.org/rss.xml" programming)
+ ("https://common-lisp.net/project/ecl/rss.xml" lisp)
+ ("https://datagubbe.se/atom.xml" blog frontpage)
+ ("https://freedom-to-tinker.com/feed/rss/" technology yro)
+ ("https://haxe.org/frontpage/rss/" programming)
+ ("https://kircode.com/feed" frontpage gamedev haxe)
+ ("https://librelounge.org/rss-feed-ogg.rss" podcast foss yro)
+ ("https://nalaginrut.com/feed/atom" frontpage programming)
+ ("https://planet.lisp.org/rss20.xml" lisp)
+ ("https://pluralistic.net/feed/" yro technology)
+ ("https://wasmweekly.news/feed.xml" programming)
+ ("https://www.eff.org/rss" yro)
+ ("https://www.filfre.net/feed/rss/" dorkistry frontpage technology)
+ ("https://www.fsf.org/static/fsforg/rss/news.xml" yro foss floss)
+ ("https://www.gnome.org/feed/" linux foss floss)
+ ("https://www.reddit.com/r/GCSolidarity/new/.rss" reddit lisp)
+ ("https://www.reddit.com/r/common_lisp/new/.rss" reddit lisp)
+ ("https://www.reddit.com/r/lisp/new/.rss" reddit lisp)
+ ("https://www.reddit.com/r/lispadvocates/new/.rss" reddit lisp)
+ ("https://www.rifters.com/crawl/?feed=rss2" frontpage)
+ ("https://www.techdirt.com/techdirt_rss.xml" news technology yro)
+ ("http://turtleware.eu/rss.xml" frontpage lisp)
+ ("https://emacsninja.com/feed.atom" emacs frontpage lisp)
+ ("http://ruricolist.frontpagespot.com/feeds/posts/default" frontpage lisp writing)
+ ("https://www.epic.org/index.xml" yro)
+ ("https://freedom.press/news/feed/" yro )
+ ("https://frontpage.nearlyfreespeech.net/category/news/feed/" frontpage)
+ ("https://www.schneier.com/feed/atom" yro security)
+ ("https://40ants.com/lisp-project-of-the-day/rss.xml" lisp frontpage)
+ ("https://alhassy.github.io/rss.xml" lisp frontpage)
+ ("https://ambrevar.xyz/atom.xml" lisp frontpage)
+ ("https://thesephist.com/index.xml" frontpage programming)
+ ("https://herman.bearfrontpage.dev/feed/" frontpage)
+ ("https://hugo.md/index.xml" frontpage)
+ ("https://capitalaspower.com/frontpage/rss" frontpage activism)
+ ("https://twobithistory.org/feed.xml" frontpage culture)
+ ("https://lambdaland.org/index.xml" frontpage dev)
+ ("https://anarc.at/frontpage/index.rss" yro )
+ ("https://feeds.transistor.fm/hope-in-source" podcast foss floss)
+ ("https://www.sapiens.org/feed/" culture)
+ ("http://tech.oeru.org/rss.xml" foss floss)
+ ("https://yogthos.net/feed.xml" frontpage dev)
+ ("https://psyche.co/feed" culture mind science philosphy magazine)
+ ("https://davelane.nz/rss.xml" foss floss)
+ ("http://frontpages.harvard.edu/doc/feed/" yro)
+ ("https://themarkup.org/feeds/rss.xml" yro)
+ ("https://mdhughes.tech/feed/" frontpage)
+ ("https://uglyduck.ca/feed.xml" frontpage)
+ ("https://xn--gckvb8fzb.com/index.xml" frontpage yro tech)
+ ("https://apenwarr.ca/log/rss.php" frontpage)
+ ("https://joeyh.name/blog/index.rss" frontpage blog)
+ ("http://fossforce.com/feed/" floss blog yro)
+ ("https://xkcd.com/rss.xml" comic)))
+
+
+(setq-default elfeed-search-filter "@2-weeks-ago +unread +frontpage")
+
+#+end_src
+
+** Zettelgunk
+
+ Zettelgunk is a half-hearted zettelkasten system I am sometimes
+ working on.
+
+#+name: zettelgunk
+#+begin_src elisp :results none
+(load "~/notes/elisp/zettel-mode/zettel.el")
+(setq zettel-directory "~/notes/zettel/")
+
+(def-my-command my-zettel-mode-command
+ '((?b "[b]ack " zettel-jump-back)
+ (?t "[t]ag browse" zettel-browse-tags)
+ (?f "[f]ind note" zettel-browse-notes)
+ (?/ "[/] term search" zettel-search-notes)
+ (?h "[h]istorical browse (days)" zettel-browse-notes-days-ago)
+ (?r "browse by [r]everse link" zettel-browse-notes-linking-here)))
+
+(def-my-command my-zettel-subcommand
+ '((?/ "[/] search notes" zettel-search-notes)
+ (?f "[f]ind note" zettel-browse-notes)
+ (?t "[t]ag browse" zettel-browse-tags)
+ (?h "[h]istorical browse (days)" zettel-browse-notes-days-ago)
+ (?n "[n]ew note" zettel-spanking-new-note)
+ (?z "[z]ettel" zettel)))
+#+end_src
+
+
+** CCRYPT
+
+ ccrypt is a standard unix encryption tool. It ships with emacs
+ bindings that allow users to encrypt and ecrypt files just by
+ opening and saving them. Such files have a .cpt extension.
+
+ #+name: ccrypt
+ #+begin_src elisp :results none
+ (load "~/notes/ps-ccrypt.el")
+ #+end_src
+
+** Toggler
+
+ Toggler.el is some code I wrote ages ago. Its sole purpose is to
+ toggle some file/buffers for easy access.
+
+ for now all of the toggling happens in toggler.el, but it shoul be facotred a bit.
+
+#+name: toggler
+#+begin_src elisp :results none
+(load "~/notes/elisp/toggler.el")
+
+#+end_src
+
+** Deft
+
+#+name: deft
+#+begin_src elisp :results none
+(package-install 'deft)
+(require 'subr-x) ;; what i this?
+(setq deft-directory "~/notes/deft/")
+(setq deft-use-filename-as-title nil)
+(setq deft-use-filter-string-for-filename t)
+(setq deft-extensions '("org"))
+
+#+end_src
+
+** Writeroom
+
+#+name: writeroom
+#+begin_src elisp :results none
+(package-install 'writeroom-mode)
+
+(setq my-writeroom-theme 'poet)
+(setq my-writeroom-cached-theme nil)
+
+(add-hook 'writeroom-mode-enable-hook
+ (lambda ()
+ (when my-writeroom-theme
+ (setf my-writeroom-cached-theme
+ (car custom-enabled-themes))
+ (disable-theme (car custom-enabled-themes))
+ (load-theme my-writeroom-theme))
+ (variable-pitch-mode)))
+
+
+(add-hook 'writeroom-mode-disable-hook
+ (lambda ()
+ (variable-pitch-mode 0)
+ (disable-theme (car custom-enabled-themes))
+ (when my-writeroom-cached-theme
+ (enable-theme my-writeroom-cached-theme))
+ (setf my-writeroom-cached-theme nil)))
+
+
+#+end_src
+
+** EWW config
+
+#+name: eww-config
+#+begin_src elisp :noweb yes
+(setq browse-url-browser-function 'eww-browse-url)
+#+end_src
+
+#+RESULTS: eww-config
+: eww-browse-url
+
+** Markdown Eiditing
+
+#+name: markdown-editing
+#+begin_src elisp :noweb yes
+(package-install 'markdown-mode)
+#+end_src
+
+#+RESULTS: markdown-editing
+
+* Software Development
+
+#+name: software-development-config
+#+begin_src elisp :noweb yes :results none
+
+(show-paren-mode 1)
+
+<<literate-programming>>
+<<software-dev-essentials>>
+<<shell-config>>
+<<common-lisp-config>>
+<<haxe-config>>
+;; <<webdev-setup>>
+<<wasm-setup>>
+<<cpp-ide>>
+#+end_src
+** Literate Programming
+
+Hacks and tweaks for literate programming. Org auto tangle will tangle
+a file whenever it is saved.
+
+#+name: literate-programming
+#+begin_src elisp :noweb yes :results none
+(package-install 'org-auto-tangle)
+
+(require 'org-auto-tangle)
+(add-hook 'org-mode-hook 'org-auto-tangle-mode)
+
+
+#+end_src
+
+** Tools Essential To Development
+
+#+name: software-dev-essentials
+#+begin_src elisp :noweb yes :results none
+
+(package-install 'flycheck)
+(package-install 'magit)
+(package-install 'paredit)
+(package-install 'ag)
+(package-install 'lice)
+
+<<projectile>>
+<<company>>
+
+#+end_src
+*** Projectile
+
+#+name: projectile
+#+begin_src elisp :results none
+(require 'cl-lib)
+(package-install 'projectile)
+(projectile-mode +1)
+(setq projectile-project-search-path '("~/projects/"))
+(setq projectile-indexing-method 'alien)
+(setq org-duration-format 'h:mm)
+
+(def-my-command my-projectile-command
+ '((?/ "[/] search project" project-find-regexp)
+ (?r "[r]eplace in project" projectile-replace)
+ (?b "project [b]uffers" projectile-ibuffer)
+ (?o "[o]pen a project" projectile-switch-project)
+ (?g "ma[g]it" magit-status)
+ (?j "[j]ump to file" projectile-find-file-dwim)))
+
+#+end_src
+*** Company
+
+#+name: company
+#+begin_src elisp :results none
+(package-install 'company)
+(add-hook 'after-init-hook 'global-company-mode)
+#+end_src
+
+** Shell Config
+
+#+name: shell-config
+#+begin_src elisp :noweb yes :results none
+
+(defun persp-shell--shell-name ()
+ (format "*shell %s*" (persp-current-name)))
+
+(defun persp-shell--shell-buffer-p (buffer)
+ (string-equal (buffer-name buffer)
+ (persp-shell--shell-name)))
+
+(defun persp-shell--shell ()
+ (cl-find-if 'persp-shell--shell-buffer-p
+ (persp-buffers (persp-curr))))
+
+(defun persp-shell--jump-to-persp-shell ()
+ (interactive)
+ (let ((buff (persp-shell--shell)))
+ (if buff (switch-to-buffer-other-window buff)
+ (shell (persp-shell--shell-name)))))
+
+#+end_src
+
+** Eshell :disabled:
+
+
+# #+name: shell-config
+#+begin_src elisp :noweb yes :results none
+<<eshell-prompt-config>>
+<<persp-eshell>>
+#+end_src
+
+
+*** Eshell Prompt
+ The ehsell prompt can be customized
+
+ #+name: eshell-prompt-config
+ #+begin_src elisp :results none
+
+ (defun shortened-path (path max-len)
+ "Return a modified version of `path', replacing some components
+ with single characters starting from the left to try and get
+ the path down to `max-len'"
+ (let* ((components (split-string (abbreviate-file-name path) "/"))
+ (len (+ (1- (length components))
+ (cl-reduce '+ components :key 'length)))
+ (str ""))
+ (while (and (> len max-len)
+ (cdr components))
+ (setq str (concat str (if (= 0 (length (car components)))
+ "/"
+ (string (elt (car components) 0) ?/)))
+ len (- len (1- (length (car components))))
+ components (cdr components)))
+ (concat str (cl-reduce (lambda (a b) (concat a "/" b)) components))))
+
+ (defun rjs-eshell-prompt-function ()
+ (concat (shortened-path (eshell/pwd) 30)
+ (if (= (user-uid) 0) " # " " $ ")))
+
+ (setq eshell-prompt-function 'rjs-eshell-prompt-function)
+
+ #+end_src
+
+*** Persp-Eshell
+
+ Persp eshell ensures that there is at most one eshell buffer that can
+ be easily reache per "perspective" It depends on perspectives.
+
+ #+name: persp-eshell
+ #+begin_src elisp :results none
+ ;; relies on the package 'perspective' from melpa
+
+ (defun persp-eshell--eshell-buffer-p (buffer)
+ (string-prefix-p "*eshell*" (buffer-name buffer)))
+
+ (defun persp-eshell--persp-eshell ()
+ (cl-find-if 'persp-eshell--eshell-buffer-p
+ (persp-buffers (persp-curr))))
+
+ (defun persp-eshell--get-next-eshell-n ()
+ (let ((n 0))
+ (while (get-buffer (format "*eshell*<%i>" n))
+ (cl-incf n))
+ n))
+
+ ;; bind this to a key of your choice
+ (defun persp-eshell--jump-to-persp-eshell ()
+ (interactive)
+ (let ((buff (persp-eshell--persp-eshell)))
+ (if buff (switch-to-buffer-other-window buff)
+ (eshell (persp-eshell--get-next-eshell-n)))))
+
+
+ #+end_src
+
+
+
+
+
+
+
+** Common Lisp
+
+#+name: common-lisp-config
+#+begin_src elisp :noweb yes :results none
+<<common-lisp-packages>>
+<<common-lisp-switch-commands>>
+<<common-lisp-mode-command>>
+<<common-lisp-editing-config>>
+#+end_src
+
+*** Packages
+
+#+name: common-lisp-packages
+#+begin_src elisp :results none
+(package-install 'paredit)
+(package-install 'slime)
+(package-install 'slime-company)
+
+#+end_src
+
+*** Starting SLIME with different Lisps
+
+#+name: common-lisp-switch-commands
+#+begin_src elisp :results none
+
+(defvar my-current-slime-name "sbcl")
+(setq inferior-lisp-program "~/lisp/sbcl/current/bin/sbcl")
+
+(defmacro start-slime-with (str name)
+ `(lambda ()
+ (interactive)
+ (setq inferior-lisp-program ,str)
+ (setq my-current-slime-name ,name)
+ (my-switch-to-slime)))
+
+(defun slime-in-this-layout-p (name)
+ (cl-find-if (lambda (buffer)
+ (string-search (format "slime-repl %s" name)
+ (or (buffer-name buffer) "")))
+ (persp-buffers (persp-curr))))
+
+(defun my-switch-to-slime ()
+ (interactive)
+ (let ((buff (slime-in-this-layout-p my-current-slime-name)))
+ (if buff (switch-to-buffer-other-window buff)
+ (slime))))
+
+(def-my-command my-lisp-switch-command
+ `((?' "['] repl" my-switch-to-slime)
+ (?s "[s]bcl" ,(start-slime-with "~/lisp/sbcl/current/bin/sbcl" "sbcl"))
+ (?e "[e]cl" ,(start-slime-with "ecl" "ecl"))
+ (?c "[c]cl" ,(start-slime-with "~/lisp/ccl/lx86cl64" "ccl"))))
+
+
+
+#+end_src
+
+*** Lisp Mode Leader Key command
+
+Requires installation of the hyperspec and cltl packages on debain
+from debian contrib
+
+: sudo apt install cltl hyperspec
+
+#+name: common-lisp-mode-command
+#+begin_src elisp :results none
+
+(def-my-command my-lisp-mode-command
+ '((?' "['] open slime repl" my-switch-to-slime)
+ (?c "[c]ompile form" slime-compile-defun)
+ (?l "[l]oad file" slime-load-file)
+ (?< "[<] list callers" slime-list-callers)
+ (?> "[>] list callees" slime-list-callees)
+ (?d "[d]ocumentation" slime-documentation)
+ (?\t "[TAB] inspect-presentation" slime-inspect-presentation-at-point)
+ (?B "Open CLTL2 [B]ook" open-cltl2)
+ (?h "[h]yperspec lookup" hyperspec-lookup)))
+
+(defun open-cltl2 ()
+ (interactive)
+ (eww "file:///usr/share/doc/cltl/clm/clm.html"))
+
+(with-eval-after-load 'lisp-mode
+ (progn
+ (setq common-lisp-hyperspec-root "file:///usr/share/doc/hyperspec/")))
+
+#+end_src
+
+*** Editing Config
+
+#+name: common-lisp-editing-config
+#+begin_src elisp :results none
+
+(slime-setup '(slime-fancy slime-company))
+(setq slime-company-completion 'fuzzy
+ slime-company-after-completion 'slime-company-just-one-space)
+
+
+(autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t)
+(add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode)
+(add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)
+(add-hook 'ielm-mode-hook #'enable-paredit-mode)
+(add-hook 'lisp-mode-hook #'enable-paredit-mode)
+(add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode)
+(add-hook 'scheme-mode-hook #'enable-paredit-mode)
+(add-hook 'clojure-mode-hook #'paredit-mode)
+
+(add-to-list 'auto-mode-alist (cons "\\.parenscript\\'" 'lisp-mode))
+(add-to-list 'auto-mode-alist (cons "\\.lass\\'" 'lisp-mode))
+(add-to-list 'auto-mode-alist (cons "\\.spinneret\\'" 'lisp-mode))
+
+
+(defun space-for-delimiter-after-$-p (delimiter endp)
+ (not (char-equal ?$ (char-before (point)))))
+
+(defun space-for-delimiter-after-@-p (delimiter endp)
+ (not (char-equal ?@ (char-before (point)))))
+
+(defun space-for-delimiter-after-p-p (delimiter endp)
+ (not (char-equal ?P (char-before (point)))))
+
+(setq paredit-space-for-delimiter-predicates
+ (list 'space-for-delimiter-after-$-p
+ 'space-for-delimiter-after-@-p
+ 'space-for-delimiter-after-p-p))
+#+end_src
+
+
+
+** Haxe
+
+#+name: haxe-config
+#+begin_src elisp :results none
+
+(package-install 'battle-haxe)
+
+(use-package haxe-mode
+ :mode ("\\.hx\\'" . haxe-mode)
+ :no-require t
+ :init
+ (require 'js)
+ (define-derived-mode haxe-mode js-mode "Haxe"
+ "Haxe syntax highlighting mode. This is simply using js-mode for now."))
+
+
+(use-package battle-haxe
+ :hook (haxe-mode . battle-haxe-mode)
+ :bind (("M-," . #'pop-global-mark) ;To get back after visiting a definition
+ :map battle-haxe-mode-map
+ ("M-." . #'battle-haxe-goto-definition)
+ ("M-/" . #'battle-haxe-helm-find-references))
+ :custom
+ (battle-haxe-yasnippet-completion-expansion t "Keep this if you want yasnippet to expand completions when it's available.")
+ (battle-haxe-immediate-completion nil "Toggle this if you want to immediately trigger completion when typing '.' and other relevant prefixes."))
+
+
+#+end_src
+
+** Web Development
+
+#+name: webdev-setup
+#+begin_src elisp :results none
+(package-install 'json-mode)
+(package-install 'skewer-mode)
+#+end_src
+** WASM
+
+#+name: wasm-setup
+#+begin_src elisp :noweb yes :results none
+(if (not (file-exists-p "~/.emacs.d/wat-mode"))
+ (shell-command "git clone https://github.com/devonsparks/wat-mode ~/.emacs.d/wat-mode"))
+
+(add-to-list 'load-path "~/.emacs.d/wat-mode")
+
+(require 'wat-mode)
+#+end_src
+
+#+RESULTS: wasm-setup
+: wat-mode
+** CPP development
+*** Language Server :prereq:
+
+clangd is the language server, [[https://github.com/rizsotto/Bear][bear]] is "a tool that generates
+a compilation database for clang tooling.
+
+#+begin_src shell :noweb yes
+sudo apt install clangd bear
+#+end_src
+*** CPP IDE setup
+
+#+name: cpp-ide
+#+begin_src elisp :noweb yes :results none
+(mapc #'package-install
+ '(lsp-mode yasnippet flycheck dap-mode ivy-xref))
+
+
+(add-hook 'c-mode-hook 'lsp)
+(add-hook 'c++-mode-hook 'lsp)
+
+(with-eval-after-load 'lsp-mode
+ (require 'dap-cpptools)
+ (yas-global-mode))
+#+end_src
+
+
+* Bells And Whistles
+
+#+name: bells-and-whistles
+#+begin_src elisp :noweb yes :results none
+<<lifecoach>>
+#+end_src
+
+** Lifecoach
+
+A few functions to start a process where, periodically, motivational
+messages echo to the echo area.
+
+#+name: lifecoach
+#+begin_src elisp :noweb yes :results none
+
+(setq lifecoach-messages
+ '(
+ "You are the only hope you have! Keep working!"
+ "You get hack on stuff you thought up... Keep going!"
+ "You don't have to be working a real job! Enjoy this!"
+ "Trust the process. Act and React!"
+ "Resistence points in the direction of courage. Step into courage!"
+ "There is one path in the world that non can walk but you. Where does it lead? Don't ask, Walk!"
+ "Get it done. Then start the next one!"
+ "Interact! Hack forward!"
+ "Money would be nice. Thinking about it wont help. Ship!"
+ "This is your work. Love it!"
+ "What if it works? Don't give up!"
+ "Dont play the finite games. Keep making moves!"
+ "There is no escape from now. Be free here. Love the task!"
+ "Be Tosk! Challenge the hunter! Surprise him. Delight him."
+ "Expect anything worthwhile to take a long time. This is worth it!"
+ "To know what you're going to draw, you must begin drawing!"
+ "Fire and motion. Move forward a little each day."
+ "Enthusiasm at the price of reinventing the wheel pays for itself."
+ "This is really happening. This is reality. Create More of The Real!"
+ "Allow yourself the uncomfortable luxury of changing your mind."
+ "Do nothing for prestige or status or money or approval alone."
+ "When people try to tell you who you are, don’t believe them."
+ "Presence is far more intricate and rewarding an art than productivity."
+ "Follow Your Wierd"
+ "Do you. -- Charlie Kauffman"
+ "Prefer to work on things you can own"
+ "Beauty rests on necessities"
+ "Every day we see people who are busy distorting their talents in order to enhance their popularity or to make money that they could do without."
+ "Problems worthy of attack prove their worth by fighting back"
+ "To work continuously at the highest level a person needs to be challenged continuously."
+ "Difficulty is an essential element in the creative process."
+ "There's a million races being run. You just got to get in one of them and win"
+ "To invent your own life's meaning is not easy, but it's still allowed, and I think you'll be happier for the trouble"
+ "Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better"
+ "Welcome the accidents."
+ "Occassion that invites no accidents invites nothing and need not occur, for everything is known already."
+ "What is the harder thing? Why is it harder?"
+ "What does the perfectionist want? And the artist?"
+ "What are you doing right now? What do you want one year from now?"
+ "Which impulse is the saboteur?"
+ "Is your exahaustion real?"
+ "Don't be ashamed of the carrot - what is the carrot?"
+ "Who benefits when you do?"
+ "How committed do you feel? Where's the evidence?"
+ "Why do you resist?"
+ "What exactly are your 'core values'?"
+ "What captures your attention? Is your attention ever rewarded?"
+ "What is an ideal future?"
+ "Can you work another ten minutes?"
+ "Do you understand the why?"
+ ))
+
+(setq lifecoach-idle-timer nil)
+
+(defun lifecoach-message ()
+ (message
+ "Lifecoach says: %s"
+ (nth (random (length lifecoach-messages))
+ lifecoach-messages)))
+
+(defun lifecoach-start ()
+ (interactive)
+ (when lifecoach-idle-timer
+ (cancel-timer lifecoach-idle-timer))
+ (setf lifecoach-idle-timer
+ (run-with-idle-timer 30 t #'lifecoach-message)))
+
+(defun lifecoach-stop ()
+ (interactive)
+ (when lifecoach-idle-timer
+ (cancel-timer lifecoach-idle-timer))
+ (setf lifecoach-idle-timer nil))
+#+end_src
+
+
+
+* Overwrites
+
+#+name: overwrites
+#+begin_src elisp :noweb yes :results none
+(setq-default cursor-type 'box)
+(setq cursor-type 'box)
+#+end_src