diff options
author | Colin Okay <colin@cicadas.surf> | 2022-07-05 08:46:39 -0500 |
---|---|---|
committer | Colin Okay <colin@cicadas.surf> | 2022-07-05 08:46:39 -0500 |
commit | 76bb19a31986dc22188d0224e4b0929e776409f4 (patch) | |
tree | adadd39d7aabe27ce21256652efdc5f84087319b |
initial commit
-rw-r--r-- | init-el.org | 1927 |
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 |